mirror of
https://github.com/wiz0u/WTelegramClient.git
synced 2025-12-06 06:52:01 +01:00
Improved GetMessageByLink (topics, cache)
This commit is contained in:
parent
b9aad47c8e
commit
33f239fc8e
|
|
@ -238,6 +238,7 @@ var inputMedias = new List<InputMedia>
|
||||||
photoFromTelegram, // PhotoBase has implicit conversion to InputMediaPhoto
|
photoFromTelegram, // PhotoBase has implicit conversion to InputMediaPhoto
|
||||||
new InputMediaUploadedPhoto { file = uploadedFile },
|
new InputMediaUploadedPhoto { file = uploadedFile },
|
||||||
new InputMediaPhotoExternal { url = photoUrl },
|
new InputMediaPhotoExternal { url = photoUrl },
|
||||||
|
//or Document, InputMediaDocument, InputMediaUploadedDocument, InputMediaDocumentExternal...
|
||||||
};
|
};
|
||||||
await client.SendAlbumAsync(InputPeer.Self, inputMedias, "My first album");
|
await client.SendAlbumAsync(InputPeer.Self, inputMedias, "My first album");
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -769,7 +769,7 @@ namespace WTelegram
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Return chat and message details based on a Message Link (URL)</summary>
|
/// <summary>Return chat and message details based on a Message Link (URL)</summary>
|
||||||
/// <param name="url">Message Link, like https://t.me/c/1234567890/1234 or https://t.me/channelname/1234</param>
|
/// <param name="url">Message Link, like https://t.me/c/1234567890/1234 or t.me/channelname/1234</param>
|
||||||
/// <param name="chats">previously collected chats, to prevent unnecessary ResolveUsername</param>
|
/// <param name="chats">previously collected chats, to prevent unnecessary ResolveUsername</param>
|
||||||
/// <returns>Structure containing the message, chat and user details</returns>
|
/// <returns>Structure containing the message, chat and user details</returns>
|
||||||
/// <remarks>If link is for private group (<c>t.me/c/..</c>), user must have joined that group</remarks>
|
/// <remarks>If link is for private group (<c>t.me/c/..</c>), user must have joined that group</remarks>
|
||||||
|
|
@ -778,17 +778,28 @@ namespace WTelegram
|
||||||
int start = url.IndexOf("//");
|
int start = url.IndexOf("//");
|
||||||
start = url.IndexOf('/', start + 2) + 1;
|
start = url.IndexOf('/', start + 2) + 1;
|
||||||
int slash = url.IndexOf('/', start + 2);
|
int slash = url.IndexOf('/', start + 2);
|
||||||
if (start == 0 || slash == -1) throw new ArgumentException("Invalid URL");
|
int msgStart = slash + 1;
|
||||||
int end = url.IndexOfAny(UrlSeparator, slash + 1);
|
int end = url.IndexOfAny(UrlSeparator, msgStart);
|
||||||
if (end == -1) end = url.Length;
|
if (end == -1) end = url.Length;
|
||||||
int msgId = int.Parse(url[(slash + 1)..end]);
|
else if (url[end] == '/' && char.IsDigit(url[msgStart]) && url.Length > end + 1 && char.IsDigit(url[end + 1]))
|
||||||
|
{
|
||||||
|
end = url.IndexOfAny(UrlSeparator, msgStart = end + 1);
|
||||||
|
if (end == -1) end = url.Length;
|
||||||
|
}
|
||||||
|
if (start == 0 || slash == -1 || end <= slash + 1 || !char.IsDigit(url[msgStart])) throw new ArgumentException("Invalid URL");
|
||||||
|
int msgId = int.Parse(url[msgStart..end]);
|
||||||
ChatBase chat;
|
ChatBase chat;
|
||||||
if (url[start] is 'c' or 'C' && url[start + 1] == '/')
|
if (url[start] is 'c' or 'C' && url[start + 1] == '/')
|
||||||
{
|
{
|
||||||
long chatId = long.Parse(url[(start + 2)..slash]);
|
long chatId = long.Parse(url[(start + 2)..slash]);
|
||||||
var mc = await this.Channels_GetChannels(new InputChannel(chatId, 0));
|
if (chats?.TryGetValue(chatId, out chat) != true)
|
||||||
if (!mc.chats.TryGetValue(chatId, out chat))
|
{
|
||||||
throw new WTException($"Channel {chatId} not found");
|
var mc = await this.Channels_GetChannels(new InputChannel(chatId, 0));
|
||||||
|
if (!mc.chats.TryGetValue(chatId, out chat))
|
||||||
|
throw new WTException($"Channel {chatId} not found");
|
||||||
|
else if (chats != null)
|
||||||
|
chats[chatId] = chat;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
chat = await CachedOrResolveUsername(url[start..slash], chats);
|
chat = await CachedOrResolveUsername(url[start..slash], chats);
|
||||||
|
|
|
||||||
|
|
@ -522,7 +522,7 @@ namespace WTelegram
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var msg = array[i] = new _Message(reader.ReadInt64(), reader.ReadInt32(), null) { bytes = reader.ReadInt32() };
|
var msg = array[i] = new _Message(reader.ReadInt64(), reader.ReadInt32(), null) { bytes = reader.ReadInt32() };
|
||||||
if ((msg.seqno & 1) != 0) lock (_msgsToAck) _msgsToAck.Add(msg.msg_id);
|
if ((msg.seq_no & 1) != 0) lock (_msgsToAck) _msgsToAck.Add(msg.msg_id);
|
||||||
var pos = reader.BaseStream.Position;
|
var pos = reader.BaseStream.Position;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -535,7 +535,7 @@ namespace WTelegram
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var obj = msg.body = reader.ReadTLObject(ctorNb);
|
var obj = msg.body = reader.ReadTLObject(ctorNb);
|
||||||
Helpers.Log(1, $" → {obj.GetType().Name,-38} {MsgIdToStamp(msg.msg_id):u} {((msg.seqno & 1) != 0 ? "" : "(svc)")} {((msg.msg_id & 2) == 0 ? "" : "NAR")}");
|
Helpers.Log(1, $" → {obj.GetType().Name,-38} {MsgIdToStamp(msg.msg_id):u} {((msg.seq_no & 1) != 0 ? "" : "(svc)")} {((msg.msg_id & 2) == 0 ? "" : "NAR")}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ using System.Net;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
//( Don't change this code to lower the security. That's contrary to Telegram recommended practices. Read the official API documentation.
|
// Don't change this code to lower the security. It's following Telegram security recommendations https://corefork.telegram.org/mtproto/description
|
||||||
|
|
||||||
namespace WTelegram
|
namespace WTelegram
|
||||||
{
|
{
|
||||||
|
|
@ -81,7 +81,7 @@ namespace WTelegram
|
||||||
|
|
||||||
public DateTime SessionStart => _sessionStart;
|
public DateTime SessionStart => _sessionStart;
|
||||||
private readonly DateTime _sessionStart = DateTime.UtcNow;
|
private readonly DateTime _sessionStart = DateTime.UtcNow;
|
||||||
private readonly SHA256 _sha256 = SHA256.Create(); // put
|
private readonly SHA256 _sha256 = SHA256.Create();
|
||||||
private Stream _store;
|
private Stream _store;
|
||||||
private byte[] _reuseKey; // used only if AES Encryptor.CanReuseTransform = false (Mono)
|
private byte[] _reuseKey; // used only if AES Encryptor.CanReuseTransform = false (Mono)
|
||||||
private byte[] _encrypted = new byte[16];
|
private byte[] _encrypted = new byte[16];
|
||||||
|
|
@ -95,7 +95,7 @@ namespace WTelegram
|
||||||
_store.Dispose();
|
_store.Dispose();
|
||||||
_encryptor.Dispose();
|
_encryptor.Dispose();
|
||||||
_jsonWriter.Dispose();
|
_jsonWriter.Dispose();
|
||||||
_jsonStream.Dispose(); // this
|
_jsonStream.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Session LoadOrCreate(Stream store, byte[] rgbKey)
|
internal static Session LoadOrCreate(Stream store, byte[] rgbKey)
|
||||||
|
|
@ -107,7 +107,7 @@ namespace WTelegram
|
||||||
var length = (int)store.Length;
|
var length = (int)store.Length;
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
{
|
{
|
||||||
var input = new byte[length]; // code
|
var input = new byte[length];
|
||||||
if (store.Read(input, 0, length) != length)
|
if (store.Read(input, 0, length) != length)
|
||||||
throw new WTException($"Can't read session block ({store.Position}, {length})");
|
throw new WTException($"Can't read session block ({store.Position}, {length})");
|
||||||
using var sha256 = SHA256.Create();
|
using var sha256 = SHA256.Create();
|
||||||
|
|
@ -141,7 +141,7 @@ namespace WTelegram
|
||||||
int encryptedLen = 64 + (utf8JsonLen & ~15);
|
int encryptedLen = 64 + (utf8JsonLen & ~15);
|
||||||
lock (_store) // while updating _encrypted buffer and writing to store
|
lock (_store) // while updating _encrypted buffer and writing to store
|
||||||
{
|
{
|
||||||
if (encryptedLen > _encrypted.Length) // back
|
if (encryptedLen > _encrypted.Length)
|
||||||
Array.Copy(_encrypted, _encrypted = new byte[encryptedLen + 256], 16);
|
Array.Copy(_encrypted, _encrypted = new byte[encryptedLen + 256], 16);
|
||||||
_encryptor.TransformBlock(_sha256.ComputeHash(utf8Json, 0, utf8JsonLen), 0, 32, _encrypted, 16);
|
_encryptor.TransformBlock(_sha256.ComputeHash(utf8Json, 0, utf8JsonLen), 0, 32, _encrypted, 16);
|
||||||
_encryptor.TransformBlock(utf8Json, 0, encryptedLen - 64, _encrypted, 48);
|
_encryptor.TransformBlock(utf8Json, 0, encryptedLen - 64, _encrypted, 48);
|
||||||
|
|
@ -192,7 +192,6 @@ namespace WTelegram
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// QWxp couldn't be bothered to write such a simple SessionStore, so here it is:
|
|
||||||
internal class ActionStore : MemoryStream
|
internal class ActionStore : MemoryStream
|
||||||
{
|
{
|
||||||
private readonly Action<byte[]> _save;
|
private readonly Action<byte[]> _save;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -39,9 +40,13 @@ namespace TL
|
||||||
public static void CollectUsersChats(this IPeerResolver structure, IDictionary<long, User> users, IDictionary<long, ChatBase> chats)
|
public static void CollectUsersChats(this IPeerResolver structure, IDictionary<long, User> users, IDictionary<long, ChatBase> chats)
|
||||||
=> structure.UserOrChat(new CollectorPeer { _users = users, _chats = chats });
|
=> structure.UserOrChat(new CollectorPeer { _users = users, _chats = chats });
|
||||||
|
|
||||||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
public static Task<Messages_Chats> Messages_GetChats(this Client _) => throw new WTException("The method you're looking for is Messages_GetAllChats");
|
public static Task<Messages_Chats> Messages_GetChats(this Client _) => throw new WTException("The method you're looking for is Messages_GetAllChats");
|
||||||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
public static Task<Messages_Chats> Channels_GetChannels(this Client _) => throw new WTException("The method you're looking for is Messages_GetAllChats");
|
public static Task<Messages_Chats> Channels_GetChannels(this Client _) => throw new WTException("The method you're looking for is Messages_GetAllChats");
|
||||||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
public static Task<UserBase[]> Users_GetUsers(this Client _) => throw new WTException("The method you're looking for is Messages_GetAllDialogs");
|
public static Task<UserBase[]> Users_GetUsers(this Client _) => throw new WTException("The method you're looking for is Messages_GetAllDialogs");
|
||||||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
public static Task<Messages_MessagesBase> Messages_GetMessages(this Client _) => throw new WTException("If you want to get all messages from a chat, use method Messages_GetHistory");
|
public static Task<Messages_MessagesBase> Messages_GetMessages(this Client _) => throw new WTException("If you want to get all messages from a chat, use method Messages_GetHistory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
10
src/TL.cs
10
src/TL.cs
|
|
@ -198,10 +198,10 @@ namespace TL
|
||||||
foreach (var msg in messages)
|
foreach (var msg in messages)
|
||||||
{
|
{
|
||||||
writer.Write(msg.msg_id);
|
writer.Write(msg.msg_id);
|
||||||
writer.Write(msg.seqno);
|
writer.Write(msg.seq_no);
|
||||||
var patchPos = writer.BaseStream.Position;
|
var patchPos = writer.BaseStream.Position;
|
||||||
writer.Write(0); // patched below
|
writer.Write(0); // patched below
|
||||||
if ((msg.seqno & 1) != 0)
|
if ((msg.seq_no & 1) != 0)
|
||||||
WTelegram.Helpers.Log(1, $" → {msg.body.GetType().Name.TrimEnd('_'),-38} #{(short)msg.msg_id.GetHashCode():X4}");
|
WTelegram.Helpers.Log(1, $" → {msg.body.GetType().Name.TrimEnd('_'),-38} #{(short)msg.msg_id.GetHashCode():X4}");
|
||||||
else
|
else
|
||||||
WTelegram.Helpers.Log(1, $" → {msg.body.GetType().Name.TrimEnd('_'),-38}");
|
WTelegram.Helpers.Log(1, $" → {msg.body.GetType().Name.TrimEnd('_'),-38}");
|
||||||
|
|
@ -372,11 +372,11 @@ namespace TL
|
||||||
}
|
}
|
||||||
|
|
||||||
[TLDef(0x5BB8E511)] //message#5bb8e511 msg_id:long seqno:int bytes:int body:Object = Message
|
[TLDef(0x5BB8E511)] //message#5bb8e511 msg_id:long seqno:int bytes:int body:Object = Message
|
||||||
public class _Message
|
public class _Message : IObject
|
||||||
{
|
{
|
||||||
public _Message(long msgId, int seqNo, IObject obj) { msg_id = msgId; seqno = seqNo; body = obj; }
|
public _Message(long msgId, int seqNo, IObject obj) { msg_id = msgId; seq_no = seqNo; body = obj; }
|
||||||
public long msg_id;
|
public long msg_id;
|
||||||
public int seqno;
|
public int seq_no;
|
||||||
public int bytes;
|
public int bytes;
|
||||||
public IObject body;
|
public IObject body;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue