This commit is contained in:
Mark West 2021-12-09 16:51:48 +08:00 committed by GitHub
commit 9ded8c75c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 553 additions and 41 deletions

214
README.md
View file

@ -151,6 +151,220 @@ To download file you should call **GetFile** method
Full code you can see at [DownloadFileFromContactTest](https://github.com/sochix/TLSharp/blob/master/TLSharp.Tests/TLSharpTests.cs#L167)
# Events Sample code
```csharp
using System;
using System.Threading.Tasks;
using TeleSharp.TL;
using TLSharp.Core;
using System.Linq;
using TeleSharp.TL.Messages;
namespace TLSharpPOC
{
class MainClass
{
const int APIId = 0;
const string APIHash = "???";
const string phone = "???";
public static void Main(string[] args)
{
new MainClass().MainAsync(args).Wait();
}
private async Task MainAsync(string[] args)
{
TelegramClient client = null;
client = new TelegramClient(APIId, APIHash);
// subscribe an event to receive live messages
client.Updates += ClientUpdates;
await client.ConnectAsync();
Console.WriteLine($"Authorised: {client.IsUserAuthorized()}");
TLUser user = null;
// -- If the user has already authenticated, this step will prevent account from being blocked as it
// -- reuses the data from last authorisation.
if (client.IsUserAuthorized())
user = client.Session.TLUser;
else
{
var registered = await client.IsPhoneRegisteredAsync(phone);
var hash = await client.SendCodeRequestAsync(phone);
Console.Write("Code: ");
var code = Console.ReadLine();
if (!registered)
{
Console.WriteLine($"Sign up {phone}");
user = await client.SignUpAsync(phone, hash, code, "First", "Last");
}
Console.WriteLine($"Sign in {phone}");
user = await client.MakeAuthAsync(phone, hash, code);
}
var contacts = await client.GetContactsAsync();
Console.WriteLine("Contacts:");
foreach (var contact in contacts.Users.OfType<TLUser>())
{
var contactUser = contact as TLUser;
Console.WriteLine($"\t{contact.Id} {contact.Phone} {contact.FirstName} {contact.LastName}");
}
var dialogs = (TLDialogs) await client.GetUserDialogsAsync();
Console.WriteLine("Channels: ");
foreach (var channelObj in dialogs.Chats.OfType<TLChannel>())
{
var channel = channelObj as TLChannel;
Console.WriteLine($"\tChat: {channel.Title}");
}
Console.WriteLine("Groups:");
TLChat chat = null;
foreach (var chatObj in dialogs.Chats.OfType<TLChat>())
{
chat = chatObj as TLChat;
Console.WriteLine($"Chat name: {chat.Title}");
var request = new TLRequestGetFullChat() { ChatId = chat.Id };
var fullChat = await client.SendRequestAsync<TeleSharp.TL.Messages.TLChatFull>(request);
var participants = (fullChat.FullChat as TeleSharp.TL.TLChatFull).Participants as TLChatParticipants;
foreach (var p in participants.Participants)
{
if (p is TLChatParticipant chatParticipant)
{
Console.WriteLine($"\t{chatParticipant.UserId}");
}
else if (p is TLChatParticipantAdmin chatParticipantAdmin)
{
Console.WriteLine($"\t{chatParticipantAdmin.UserId}**");
}
else if (p is TLChatParticipantCreator chatParticipantCreator)
{
Console.WriteLine($"\t{chatParticipantCreator.UserId}**");
}
}
var peer = new TLInputPeerChat() { ChatId = chat.Id };
var msg = await client.GetHistoryAsync(peer, 0, 0, 0);
Console.WriteLine(msg);
if (msg is TLMessages messages)
{
foreach (var message in messages.Messages)
{
if (message is TLMessage m1)
{
Console.WriteLine($"\t\t{m1.Id} {m1.Message}");
}
else if (message is TLMessageService msgService)
{
Console.WriteLine($"\t\t{msgService.Id} {msgService.Action}");
}
}
}
else if (msg is TLMessagesSlice messagesSlice)
{
bool done = false;
int total = 0;
while (!done)
{
foreach (var m1 in messagesSlice.Messages)
{
if (m1 is TLMessage message)
{
Console.WriteLine($"\t\t{message.Id} {message.Message}");
++total;
}
else if (m1 is TLMessageService messageService)
{
Console.WriteLine($"\t\t{messageService.Id} {messageService.Action}");
++total;
done = messageService.Action is TLMessageActionChatCreate;
}
}
msg = await client.GetHistoryAsync(peer, total, 0, 0);
}
}
}
// -- Wait in a loop to handle incoming updates. No need to poll.
while(true)
{
await client.WaitEventAsync(TimeSpan.FromSeconds(1));
}
}
private void ClientUpdates(TelegramClient client, TLAbsUpdates updates)
{
Console.WriteLine($"Got update: {updates}");
if (updates is TLUpdateShort updateShort)
{
Console.WriteLine($"Short: {updateShort.Update}");
if (updateShort.Update is TLUpdateUserStatus status)
{
Console.WriteLine($"User {status.UserId} is {status.Status}");
if (status.Status is TLUserStatusOnline)
{
var peer = new TLInputPeerUser() { UserId = status.UserId };
client.SendMessageAsync(peer, "Você está online.").Wait();
}
}
}
else if (updates is TLUpdateShortMessage message)
{
Console.WriteLine($"Message: {message.Message}");
MarkMessageRead(client, new TLInputPeerUser() { UserId = message.UserId }, message.Id);
}
else if (updates is TLUpdateShortChatMessage shortChatMessage)
{
Console.WriteLine($"Chat Message: {shortChatMessage.Message}");
MarkMessageRead(client, new TLInputPeerChat() { ChatId = shortChatMessage.ChatId }, shortChatMessage.Id);
}
else if (updates is TLUpdates allUpdates)
{
foreach (var update in allUpdates.Updates)
{
Console.WriteLine($"\t{update}");
if (update is TLUpdateNewChannelMessage metaMessage)
{
var channelMsg = metaMessage.Message as TLMessage;
Console.WriteLine($"Channel message: {channelMsg.Message}");
var channel = allUpdates.Chats[0] as TLChannel;
MarkMessageRead(client,
new TLInputPeerChannel() { ChannelId = channel.Id, AccessHash = channel.AccessHash.Value },
channelMsg.Id);
}
}
foreach (var user in allUpdates.Users)
{
Console.WriteLine($"{user}");
}
foreach (var chat in allUpdates.Chats)
{
Console.WriteLine($"{chat}");
}
}
}
private void MarkMessageRead(TelegramClient client, TLAbsInputPeer peer, int id)
{
try
{
var request = new TLRequestReadHistory();
request.MaxId = id;
request.Peer = peer;
client.SendRequestAsync<bool>(request).Wait();
}
catch (InvalidOperationException e)
{
Console.WriteLine($"MarkMessageRead Error: {e.Message}");
}
}
}
}
```
# Available Methods
For your convenience TLSharp have wrappers for several Telegram API methods. You could add your own, see details below.

View file

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
@ -24,8 +23,14 @@ namespace TLSharp.Core.Network
private readonly TcpTransport transport;
private readonly Session session;
private readonly uint UpdatesTooLongID = (uint) new TLUpdatesTooLong().Constructor;
public readonly List<ulong> needConfirmation = new List<ulong>();
public delegate void HandleUpdates (TLAbsUpdates updates);
public event HandleUpdates UpdatesEvent;
public MtProtoSender(TcpTransport transport, Session session)
{
this.transport = transport;
@ -60,7 +65,6 @@ namespace TLSharp.Core.Network
}
}
using (var memory = new MemoryStream())
using (var writer = new BinaryWriter(memory))
{
@ -90,11 +94,12 @@ namespace TLSharp.Core.Network
plaintextWriter.Write(packet.Length);
plaintextWriter.Write(packet);
msgKey = Helpers.CalcMsgKey(plaintextPacket.GetBuffer());
ciphertext = AES.EncryptAES(Helpers.CalcKey(session.AuthKey.Data, msgKey, true), plaintextPacket.GetBuffer());
var buffer = plaintextPacket.GetBuffer();
msgKey = Helpers.CalcMsgKey(buffer);
ciphertext = AES.EncryptAES(Helpers.CalcKey(session.AuthKey.Data, msgKey, true),
plaintextPacket.GetBuffer());
}
}
using (MemoryStream ciphertextPacket = makeMemory(8 + 16 + ciphertext.Length))
{
using (BinaryWriter writer = new BinaryWriter(ciphertextPacket))
@ -108,6 +113,23 @@ namespace TLSharp.Core.Network
}
}
private async Task Ack(CancellationToken token = default(CancellationToken))
{
token.ThrowIfCancellationRequested();
if (needConfirmation.Any())
{
var ackRequest = new AckRequest(needConfirmation);
using (var memory = new MemoryStream())
using (var writer = new BinaryWriter(memory))
{
ackRequest.SerializeBody(writer);
await Send(memory.ToArray(), ackRequest);
needConfirmation.Clear();
}
}
}
private Tuple<byte[], ulong, int> DecodeMessage(byte[] body)
{
byte[] message;
@ -149,7 +171,7 @@ namespace TLSharp.Core.Network
using (var messageStream = new MemoryStream(result.Item1, false))
using (var messageReader = new BinaryReader(messageStream))
{
processMessage(result.Item2, result.Item3, messageReader, request, token);
await ProcessMessageAsync(result.Item2, result.Item3, messageReader, request, token);
}
token.ThrowIfCancellationRequested();
@ -158,6 +180,21 @@ namespace TLSharp.Core.Network
return null;
}
public async Task<byte[]> Receive(TimeSpan timeToWait, CancellationToken token = default(CancellationToken))
{
var result = DecodeMessage((await transport.Receive(timeToWait)).Body);
using (var messageStream = new MemoryStream(result.Item1, false))
using (var messageReader = new BinaryReader(messageStream))
{
await ProcessMessageAsync(result.Item2, result.Item3, messageReader, null);
}
token.ThrowIfCancellationRequested();
return null;
}
public async Task SendPingAsync(CancellationToken token = default(CancellationToken))
{
token.ThrowIfCancellationRequested();
@ -173,7 +210,7 @@ namespace TLSharp.Core.Network
await Receive(pingRequest, token).ConfigureAwait(false);
}
private bool processMessage(ulong messageId, int sequence, BinaryReader messageReader, TLMethod request, CancellationToken token = default(CancellationToken))
private async Task<bool> ProcessMessageAsync(ulong messageId, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request, CancellationToken token = default(CancellationToken))
{
token.ThrowIfCancellationRequested();
@ -181,8 +218,10 @@ namespace TLSharp.Core.Network
// TODO: check sessionid
// TODO: check seqno
//logger.debug("processMessage: msg_id {0}, sequence {1}, data {2}", BitConverter.ToString(((MemoryStream)messageReader.BaseStream).GetBuffer(), (int) messageReader.BaseStream.Position, (int) (messageReader.BaseStream.Length - messageReader.BaseStream.Position)).Replace("-","").ToLower());
needConfirmation.Add(messageId);
await Ack(token);
uint code = messageReader.ReadUInt32();
messageReader.BaseStream.Position -= 4;
@ -190,7 +229,7 @@ namespace TLSharp.Core.Network
{
case 0x73f1f8dc: // container
//logger.debug("MSG container");
return HandleContainer(messageId, sequence, messageReader, request, token);
return await HandleContainerAsync(messageId, sequence, messageReader, request, token);
case 0x7abe77ec: // ping
//logger.debug("MSG ping");
return HandlePing(messageId, sequence, messageReader);
@ -208,7 +247,7 @@ namespace TLSharp.Core.Network
return HandleMsgsAck(messageId, sequence, messageReader);
case 0xedab447b: // bad_server_salt
//logger.debug("MSG bad_server_salt");
return HandleBadServerSalt(messageId, sequence, messageReader, request, token);
return await HandleBadServerSaltAsync(messageId, sequence, messageReader, request, token);
case 0xa7eff811: // bad_msg_notification
//logger.debug("MSG bad_msg_notification");
return HandleBadMsgNotification(messageId, sequence, messageReader);
@ -220,39 +259,61 @@ namespace TLSharp.Core.Network
return HandleRpcResult(messageId, sequence, messageReader, request);
case 0x3072cfa1: // gzip_packed
//logger.debug("MSG gzip_packed");
return HandleGzipPacked(messageId, sequence, messageReader, request, token);
return await HandleGzipPackedAsync(messageId, sequence, messageReader, request, token);
case 0xe317af7e:
case 0xd3f45784:
case 0x2b2fbd4e:
case 0x78d4dec1:
case 0x725b04c3:
case 0x74ae4240:
return HandleUpdate(messageId, sequence, messageReader);
case 0x11f1331c:
return HandleUpdate(code, sequence, messageReader, request);
default:
//logger.debug("unknown message: {0}", code);
return false;
}
}
private bool HandleUpdate(ulong messageId, int sequence, BinaryReader messageReader)
private bool HandleUpdate(uint code, int sequence, BinaryReader messageReader, TLMethod request)
{
return false;
/*
try
{
UpdatesEvent(TL.Parse<Updates>(messageReader));
return true;
}
catch (Exception e)
{
logger.warning("update processing exception: {0}", e);
return false;
}
*/
var update = ParseUpdate(code, messageReader);
if (update != null && UpdatesEvent != null)
{
UpdatesEvent(update);
}
return true;
}
private bool HandleGzipPacked(ulong messageId, int sequence, BinaryReader messageReader, TLMethod request, CancellationToken token = default(CancellationToken))
private TLAbsUpdates ParseUpdate(uint code, BinaryReader messageReader)
{
switch (code)
{
case 0xe317af7e:
return DecodeUpdate<TLUpdatesTooLong>(messageReader);
case 0x914fbf11:
return DecodeUpdate<TLUpdateShortMessage> (messageReader);
case 0x16812688:
return DecodeUpdate<TLUpdateShortChatMessage> (messageReader);
case 0x78d4dec1:
return DecodeUpdate<TLUpdateShort> (messageReader);
case 0x725b04c3:
return DecodeUpdate<TLUpdatesCombined> (messageReader);
case 0x74ae4240:
return DecodeUpdate<TLUpdates> (messageReader);
case 0x11f1331c:
return DecodeUpdate<TLUpdateShortSentMessage> (messageReader);
default:
return null;
}
}
private TLAbsUpdates DecodeUpdate<T>(BinaryReader messageReader) where T : TLAbsUpdates
{
var ms = messageReader.BaseStream as MemoryStream;
var update = (T)ObjectUtils.DeserializeObject(messageReader);
return update;
}
private async Task<bool> HandleGzipPackedAsync(ulong messageId, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request, CancellationToken token = default(CancellationToken))
{
token.ThrowIfCancellationRequested();
@ -269,7 +330,7 @@ namespace TLSharp.Core.Network
}
using (BinaryReader compressedReader = new BinaryReader(ms))
{
processMessage(messageId, sequence, compressedReader, request, token);
await ProcessMessageAsync(messageId, sequence, compressedReader, request, token);
}
}
@ -305,6 +366,7 @@ namespace TLSharp.Core.Network
{ // rpc_error
int errorCode = messageReader.ReadInt32();
string errorMessage = Serializers.String.Read(messageReader);
Console.Error.WriteLine($"ERROR: {errorMessage} - {errorCode}");
if (errorMessage.StartsWith("FLOOD_WAIT_"))
{
@ -415,7 +477,7 @@ namespace TLSharp.Core.Network
throw new InvalidOperationException("invalid container");
}
throw new NotImplementedException("This should never happens");
throw new NotImplementedException("This should never happen!");
/*
logger.debug("bad_msg_notification: msgid {0}, seq {1}, errorcode {2}", requestId, requestSequence,
errorCode);
@ -435,7 +497,7 @@ namespace TLSharp.Core.Network
return true;
}
private bool HandleBadServerSalt(ulong messageId, int sequence, BinaryReader messageReader, TLMethod request, CancellationToken token = default(CancellationToken))
private async Task<bool> HandleBadServerSaltAsync(ulong messageId, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request, CancellationToken token = default(CancellationToken))
{
token.ThrowIfCancellationRequested();
@ -450,7 +512,7 @@ namespace TLSharp.Core.Network
session.Salt = newSalt;
//resend
Send(request, token);
await Send(request, token);
/*
if(!runningRequests.ContainsKey(badMsgId)) {
logger.debug("bad server salt on unknown message");
@ -516,7 +578,7 @@ namespace TLSharp.Core.Network
return false;
}
private bool HandleContainer(ulong messageId, int sequence, BinaryReader messageReader, TLMethod request, CancellationToken token = default(CancellationToken))
private async Task<bool> HandleContainerAsync(ulong messageId, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request, CancellationToken token = default(CancellationToken))
{
token.ThrowIfCancellationRequested();
@ -530,11 +592,16 @@ namespace TLSharp.Core.Network
long beginPosition = messageReader.BaseStream.Position;
try
{
if (!processMessage(innerMessageId, sequence, messageReader, request, token))
var processedMessage = await ProcessMessageAsync(innerMessageId, sequence, messageReader, request, token);
if (!processedMessage)
{
messageReader.BaseStream.Position = beginPosition + innerLength;
}
}
catch (InvalidOperationException e)
{
throw;
}
catch (Exception e)
{
// logger.error("failed to process message in container: {0}", e);

View file

@ -0,0 +1,25 @@
using System;
using System.Text;
namespace TLSharp.Core.Network
{
public static class Sniffer
{
public static string MessageOut(byte[] data)
{
return WriteMessage(new StringBuilder("[OUT]:"), data);
}
public static string MessageIn(byte[] data)
{
return WriteMessage(new StringBuilder("[IN]:"), data);
}
private static string WriteMessage(StringBuilder log, byte[] data)
{
foreach (var b in data)
log.AppendFormat(" {0:x2}", b);
return log.ToString();
}
}
}

View file

@ -15,6 +15,7 @@ namespace TLSharp.Core.Network
private readonly TcpClient tcpClient;
private readonly NetworkStream stream;
private int sendCounter = 0;
private CancellationTokenSource tokenSource = new CancellationTokenSource();
public TcpTransport(string address, int port, TcpClientConnectionHandler handler = null)
{
@ -54,11 +55,76 @@ namespace TLSharp.Core.Network
public async Task<TcpMessage> Receive(CancellationToken token = default(CancellationToken))
{
var stream = tcpClient.GetStream();
var packetLengthBytes = new byte[4];
if (await stream.ReadAsync(packetLengthBytes, 0, 4, token).ConfigureAwait(false) != 4)
throw new InvalidOperationException("Couldn't read the packet length");
int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);
var seqBytes = new byte[4];
if (await stream.ReadAsync(seqBytes, 0, 4) != 4)
throw new InvalidOperationException("Couldn't read the sequence");
int seq = BitConverter.ToInt32(seqBytes, 0);
int readBytes = 0;
var body = new byte[packetLength - 12];
int neededToRead = packetLength - 12;
do
{
var bodyByte = new byte[packetLength - 12];
var availableBytes = await stream.ReadAsync(bodyByte, 0, neededToRead);
neededToRead -= availableBytes;
Buffer.BlockCopy(bodyByte, 0, body, readBytes, availableBytes);
readBytes += availableBytes;
}
while (readBytes != packetLength - 12);
var crcBytes = new byte[4];
if (await stream.ReadAsync(crcBytes, 0, 4) != 4)
throw new InvalidOperationException("Couldn't read the crc");
int checksum = BitConverter.ToInt32(crcBytes, 0);
byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + body.Length];
Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length);
Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length);
Buffer.BlockCopy(body, 0, rv, packetLengthBytes.Length + seqBytes.Length, body.Length);
var crc32 = new Crc32();
var computedChecksum = crc32.ComputeHash(rv).Reverse();
if (!crcBytes.SequenceEqual(computedChecksum))
{
throw new InvalidOperationException("invalid checksum! skip");
}
return new TcpMessage(seq, body);
}
public async Task<TcpMessage> Receive(TimeSpan timeToWait)
{
var stream = tcpClient.GetStream();
var packetLengthBytes = new byte[4];
var token = tokenSource.Token;
stream.ReadTimeout = (int)timeToWait.TotalMilliseconds;
int bytes = 0;
try
{
bytes = stream.Read(packetLengthBytes, 0, 4);
}
catch (System.IO.IOException io)
{
var socketError = io.InnerException as SocketException;
if (socketError != null && socketError.SocketErrorCode == SocketError.TimedOut)
throw new OperationCanceledException();
throw;
}
if (bytes != 4)
throw new InvalidOperationException("Couldn't read the packet length");
int packetLength = BitConverter.ToInt32(packetLengthBytes, 0);
var seqBytes = new byte[4];
if (await stream.ReadAsync(seqBytes, 0, 4, token).ConfigureAwait(false) != 4)
throw new InvalidOperationException("Couldn't read the sequence");
@ -106,7 +172,6 @@ namespace TLSharp.Core.Network
}
}
public void Dispose()
{
if (tcpClient.Connected)

View file

@ -75,6 +75,7 @@
<Compile Include="Session.cs" />
<Compile Include="TelegramClient.cs" />
<Compile Include="Utils\Helpers.cs" />
<Compile Include="Network\Sniffer.cs" />
<Compile Include="DataCenter.cs" />
</ItemGroup>
<ItemGroup>

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
@ -25,6 +25,7 @@ namespace TLSharp.Core
public class TelegramClient : IDisposable
{
private MtProtoSender sender;
private AuthKey key;
private TcpTransport transport;
private string apiHash = String.Empty;
private int apiId = 0;
@ -33,6 +34,15 @@ namespace TLSharp.Core
private TcpClientConnectionHandler handler;
private DataCenterIPVersion dcIpVersion;
private bool looping = true;
public delegate void UpdatesEvent (TelegramClient source, TLAbsUpdates updates);
public delegate void ClientEvent(TelegramClient source);
public event UpdatesEvent Updates;
public event ClientEvent ScheduledTasks;
public event ClientEvent IdleTasks;
public Session Session
{
get { return session; }
@ -80,6 +90,7 @@ namespace TLSharp.Core
}
sender = new MtProtoSender(transport, session);
sender.UpdatesEvent += SenderUpdatesEvent;
//set-up layer
var config = new TLRequestGetConfig();
@ -149,6 +160,50 @@ namespace TLSharp.Core
}
}
public void Close()
{
looping = false;
}
public async Task MainLoopAsync(TimeSpan timeToWait, CancellationToken token = default(CancellationToken))
{
var lastPing = DateTime.UtcNow;
await SendPingAsync();
while (looping)
{
try
{
await WaitEventAsync(timeToWait, token);
}
catch (OperationCanceledException)
{
// Handle timeout, no problem
}
finally
{
var now = DateTime.UtcNow;
if ((now - lastPing).TotalSeconds >= 30)
{
await SendPingAsync();
lastPing = now;
}
if (ScheduledTasks != null)
{
ScheduledTasks.Invoke(this);
ScheduledTasks = null;
}
IdleTasks?.Invoke(this);
}
token.ThrowIfCancellationRequested();
}
}
private void SenderUpdatesEvent (TLAbsUpdates updates)
{
Updates?.Invoke(this, updates);
}
private async Task RequestWithDcMigration(TLMethod request, CancellationToken token = default(CancellationToken))
{
if (sender == null)
@ -178,6 +233,11 @@ namespace TLSharp.Core
}
}
public async Task WaitEventAsync(TimeSpan timeToWait, CancellationToken token = default(CancellationToken))
{
await sender.Receive (timeToWait, token);
}
public bool IsUserAuthorized()
{
return session.TLUser != null;

View file

@ -81,5 +81,11 @@ namespace TLSharp.Tests
{
await base.SendMessageByUserNameTest();
}
[Test]
public override async Task GetUpdatesForUser()
{
await base.GetUpdatesForUser();
}
}
}

View file

@ -79,5 +79,12 @@ namespace TLSharp.Tests
{
await base.SendMessageByUserNameTest();
}
[TestMethod]
public override async Task GetUpdatesForUser()
{
await base.GetUpdatesForUser();
}
}
}

View file

@ -1,5 +1,6 @@

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
@ -11,7 +12,6 @@ using TeleSharp.TL;
using TeleSharp.TL.Messages;
using TLSharp.Core;
using TLSharp.Core.Exceptions;
using TLSharp.Core.Network;
using TLSharp.Core.Network.Exceptions;
using TLSharp.Core.Utils;
@ -377,5 +377,72 @@ namespace TLSharp.Tests
Thread.Sleep(3000);
await client.SendMessageAsync(new TLInputPeerUser() { UserId = user.Id }, "TEST");
}
public virtual async Task GetUpdatesForUser()
{
IList<TLMessage> newMsgs = new List<TLMessage>();
TLUser user = null;
var updateMsg = "Send yourself an UPDATE_1 message to trigger update during loop";
var client = NewClient();
await client.ConnectAsync();
if (client.IsUserAuthorized())
user = client.Session.TLUser;
else
{
var hash = await client.SendCodeRequestAsync(NumberToAuthenticate);
var code = CodeToAuthenticate; // you can change code in debugger too
if (string.IsNullOrWhiteSpace(code))
{
throw new Exception("CodeToAuthenticate is empty in the app.config file, fill it with the code you just got now by SMS/Telegram");
}
try
{
user = await client.MakeAuthAsync(NumberToAuthenticate, hash, code);
}
catch (CloudPasswordNeededException)
{
var passwordSetting = await client.GetPasswordSetting();
var password = PasswordToAuthenticate;
user = await client.MakeAuthWithPasswordAsync(passwordSetting, password);
}
catch (InvalidPhoneCodeException ex)
{
throw new Exception("CodeToAuthenticate is wrong in the app.config file, fill it with the code you just got now by SMS/Telegram", ex);
}
}
// Things to note:- If the updates are not getting triggered, please re-authenticate the user
// Would trigger the updates on a seperate thread if possible
client.Updates += (TelegramClient tclient, TLAbsUpdates updates) =>
{
if (updates is TLUpdates)
{
var allUpdates = updates as TLUpdates;
foreach (var update in allUpdates.Updates)
{
if (update is TLUpdateNewMessage)
{
var metaMsg = update as TLUpdateNewMessage;
var msg = metaMsg.Message as TLMessage;
newMsgs.Add(msg);
}
}
}
};
Console.WriteLine(updateMsg);
Debug.WriteLine(updateMsg);
await client.MainLoopAsync(new TimeSpan(0, 0, 1));
Assert.IsTrue(newMsgs.Count == 1);
Assert.IsTrue(newMsgs.First().Message.Equals("UPDATE_1"));
}
}
}