mirror of
https://github.com/wiz0u/WTelegramClient.git
synced 2025-12-06 06:52:01 +01:00
Renamed OnUpdate => OnUpdates (with temporary compatibility shim)
This commit is contained in:
parent
270a7d89e6
commit
3d224afb23
|
|
@ -187,7 +187,7 @@ Notes:
|
|||
<a name="updates"></a>
|
||||
## Monitor all Telegram events happening for the user
|
||||
|
||||
This is done through the `client.OnUpdate` callback event.
|
||||
This is done through the `client.OnUpdates` callback event.
|
||||
Your event handler implementation can either return `Task.CompletedTask` or be an `async Task` method.
|
||||
|
||||
See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L23).
|
||||
|
|
@ -195,7 +195,7 @@ See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient
|
|||
<a name="monitor-msg"></a>
|
||||
## Monitor new messages being posted in chats in real-time
|
||||
|
||||
You have to handle `client.OnUpdate` events containing an `UpdateNewMessage`.
|
||||
You have to handle `client.OnUpdates` events containing an `UpdateNewMessage`.
|
||||
|
||||
See the `HandleMessage` method in [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L23).
|
||||
|
||||
|
|
@ -453,7 +453,7 @@ finally
|
|||
## Collect Users/Chats description structures and access hash
|
||||
|
||||
Many API calls return a structure with a `users` and a `chats` field at the root of the structure.
|
||||
This is also the case for updates passed to `client.OnUpdate`.
|
||||
This is also the case for updates passed to `client.OnUpdates`.
|
||||
|
||||
These two dictionaries give details *(including access hash)* about the various users/chats that will be typically referenced in subobjects deeper in the structure,
|
||||
typically in the form of a `Peer` object or a `user_id`/`chat_id` field.
|
||||
|
|
@ -473,7 +473,7 @@ private Dictionary<long, ChatBase> _chats = new();
|
|||
var dialogs = await client.Messages_GetAllDialogs();
|
||||
dialogs.CollectUsersChats(_users, _chats);
|
||||
|
||||
private async Task OnUpdate(UpdatesBase updates)
|
||||
private async Task OnUpdates(UpdatesBase updates)
|
||||
{
|
||||
updates.CollectUsersChats(_users, _chats);
|
||||
...
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TL;
|
||||
|
||||
|
|
@ -15,10 +13,10 @@ namespace WTelegramClientTest
|
|||
Console.WriteLine("The program will download photos/medias from messages you send/forward to yourself (Saved Messages)");
|
||||
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
|
||||
var user = await client.LoginUserIfNeeded();
|
||||
client.OnUpdate += Client_OnUpdate;
|
||||
client.OnUpdates += Client_OnUpdates;
|
||||
Console.ReadKey();
|
||||
|
||||
async Task Client_OnUpdate(UpdatesBase updates)
|
||||
async Task Client_OnUpdates(UpdatesBase updates)
|
||||
{
|
||||
foreach (var update in updates.UpdateList)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TL;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace WTelegramClientTest
|
|||
Client = new WTelegram.Client(store.Length == 0 ? null : Environment.GetEnvironmentVariable, store);
|
||||
using (Client)
|
||||
{
|
||||
Client.OnUpdate += Client_OnUpdate;
|
||||
Client.OnUpdates += Client_OnUpdates;
|
||||
My = await Client.LoginUserIfNeeded();
|
||||
Console.WriteLine($"We are logged-in as {My.username ?? My.first_name + " " + My.last_name} (id {My.id})");
|
||||
var dialogs = await Client.Messages_GetAllDialogs();
|
||||
|
|
@ -39,7 +39,7 @@ namespace WTelegramClientTest
|
|||
}
|
||||
}
|
||||
|
||||
private static async Task Client_OnUpdate(UpdatesBase updates)
|
||||
private static async Task Client_OnUpdates(UpdatesBase updates)
|
||||
{
|
||||
updates.CollectUsersChats(Users, Chats);
|
||||
foreach (var update in updates.UpdateList)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace WTelegramClientTest
|
|||
Client = new WTelegram.Client(Environment.GetEnvironmentVariable);
|
||||
using (Client)
|
||||
{
|
||||
Client.OnUpdate += Client_OnUpdate;
|
||||
Client.OnUpdates += Client_OnUpdates;
|
||||
My = await Client.LoginUserIfNeeded();
|
||||
Users[My.id] = My;
|
||||
// Note: on login, Telegram may sends a bunch of updates/messages that happened in the past and were not acknowledged
|
||||
|
|
@ -33,7 +33,7 @@ namespace WTelegramClientTest
|
|||
}
|
||||
|
||||
// if not using async/await, we could just return Task.CompletedTask
|
||||
private static async Task Client_OnUpdate(UpdatesBase updates)
|
||||
private static async Task Client_OnUpdates(UpdatesBase updates)
|
||||
{
|
||||
updates.CollectUsersChats(Users, Chats);
|
||||
if (updates is UpdateShortMessage usm && !Users.ContainsKey(usm.user_id))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot.Types;
|
||||
using TL;
|
||||
|
||||
namespace WTelegramClientTest
|
||||
|
|
@ -28,7 +27,7 @@ namespace WTelegramClientTest
|
|||
private static async Task CreateAndConnect()
|
||||
{
|
||||
Client = new WTelegram.Client(Environment.GetEnvironmentVariable);
|
||||
Client.OnUpdate += Client_OnUpdate;
|
||||
Client.OnUpdates += Client_OnUpdates;
|
||||
Client.OnOther += Client_OnOther;
|
||||
var my = await Client.LoginUserIfNeeded();
|
||||
Console.WriteLine($"We are logged-in as " + my);
|
||||
|
|
@ -61,7 +60,7 @@ namespace WTelegramClientTest
|
|||
Console.WriteLine("Other: " + arg.GetType().Name);
|
||||
}
|
||||
|
||||
private static Task Client_OnUpdate(UpdatesBase updates)
|
||||
private static Task Client_OnUpdates(UpdatesBase updates)
|
||||
{
|
||||
foreach (var update in updates.UpdateList)
|
||||
Console.WriteLine(update.GetType().Name);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace WTelegramClientTest
|
|||
AppDomain.CurrentDomain.ProcessExit += (s, e) => { Secrets.Dispose(); Client.Dispose(); };
|
||||
SelectActiveChat();
|
||||
|
||||
Client.OnUpdate += Client_OnUpdate;
|
||||
Client.OnUpdates += Client_OnUpdates;
|
||||
var myself = await Client.LoginUserIfNeeded();
|
||||
Users[myself.id] = myself;
|
||||
Console.WriteLine($"We are logged-in as {myself}");
|
||||
|
|
@ -76,7 +76,7 @@ Type a command, or a message to send to the active secret chat:");
|
|||
} while (true);
|
||||
}
|
||||
|
||||
private static async Task Client_OnUpdate(UpdatesBase updates)
|
||||
private static async Task Client_OnUpdates(UpdatesBase updates)
|
||||
{
|
||||
updates.CollectUsersChats(Users, Chats);
|
||||
foreach (var update in updates.UpdateList)
|
||||
|
|
|
|||
4
FAQ.md
4
FAQ.md
|
|
@ -143,7 +143,7 @@ Here are some advices from [another similar library](https://github.com/gotd/td/
|
|||
|
||||
Some additional advices from me:
|
||||
|
||||
5. Avoid repetitive polling or repetitive sequence of actions/requests: Save the initial results of your queries, and update those results when you're informed of a change through `OnUpdate` events.
|
||||
5. Avoid repetitive polling or repetitive sequence of actions/requests: Save the initial results of your queries, and update those results when you're informed of a change through `OnUpdates` events.
|
||||
6. Don't buy fake user accounts/sessions and don't extract api_id/hash/authkey/sessions from official clients, this is [specifically forbidden by API TOS](https://core.telegram.org/api/terms#2-transparency). You must use your own api_id and create your own sessions associated with it.
|
||||
7. If a phone number is brand new, it will be closely monitored by Telegram for abuse, and it can even already be considered a bad user due to bad behavior from the previous owner of that phone number (which may happen often with VoIP or other easy-to-buy-online numbers, so expect fast ban)
|
||||
8. You may want to use your new phone number account with an official Telegram client and act like a normal user for some time (some weeks/months), before using it for automation with WTelegramClient.
|
||||
|
|
@ -261,7 +261,7 @@ The following choices were made while implementing Secret Chats in WTelegramClie
|
|||
If for some reason, we received them in incorrect order, messages are kept in memory until the requested missing messages are obtained.
|
||||
If those missing messages are never obtained during the session, incoming messages might get stuck and lost.
|
||||
- SecretChats file data is only valid for the current user, so make sure to pick the right file *(or a new file name)* if you change logged-in user.
|
||||
- If you want to accept incoming Secret Chats request only from specific user, you must check it in OnUpdate before:
|
||||
- If you want to accept incoming Secret Chats request only from specific user, you must check it in OnUpdates before:
|
||||
`await Secrets.HandleUpdate(ue, ue.chat is EncryptedChatRequested ecr && ecr.admin_id == EXPECTED_USER_ID);`
|
||||
- As recommended, new encryption keys are negotiated every 100 sent/received messages or after one week.
|
||||
If remote client doesn't complete this negotiation before reaching 200 messages, the Secret Chat is aborted.
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ See [FAQ #4](https://wiz0u.github.io/WTelegramClient/FAQ#access-hash) to learn m
|
|||
|
||||
# Other things to know
|
||||
|
||||
The Client class also offers `OnUpdate` and `OnOther` events that are triggered when Telegram servers sends Updates (like new messages or status) or other notifications, independently of your API requests.
|
||||
The Client class also offers `OnUpdates` and `OnOther` events that are triggered when Telegram servers sends Updates (like new messages or status) or other notifications, independently of your API requests.
|
||||
See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L23) and [Examples/Program_ReactorError.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ReactorError.cs?ts=4#L32)
|
||||
|
||||
An invalid API request can result in a `RpcException` being raised, reflecting the [error code and status text](https://revgram.github.io/errors.html) of the problem.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ using System.Collections.Generic;
|
|||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
|
@ -25,11 +24,13 @@ namespace WTelegram
|
|||
{
|
||||
/// <summary>This event will be called when unsollicited updates/messages are sent by Telegram servers</summary>
|
||||
/// <remarks>Make your handler <see langword="async"/>, or return <see cref="Task.CompletedTask"/> or <see langword="null"/><br/>See <see href="https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L23">Examples/Program_ListenUpdate.cs</see> for how to use this</remarks>
|
||||
public event Func<UpdatesBase, Task> OnUpdate;
|
||||
public event Func<UpdatesBase, Task> OnUpdates;
|
||||
[Obsolete("This event was renamed OnUpdates (plural)")]
|
||||
public event Func<UpdatesBase, Task> OnUpdate { add { OnUpdates += value; } remove { OnUpdates -= value; } }
|
||||
/// <summary>This event is called for other types of notifications (login states, reactor errors, ...)</summary>
|
||||
public event Func<IObject, Task> OnOther;
|
||||
/// <summary>Use this handler to intercept Updates that resulted from your own API calls</summary>
|
||||
public event Func<UpdatesBase, Task> OnOwnUpdate;
|
||||
public event Func<UpdatesBase, Task> OnOwnUpdates;
|
||||
/// <summary>Used to create a TcpClient connected to the given address/port, or throw an exception on failure</summary>
|
||||
public TcpFactory TcpHandler { get; set; } = DefaultTcpHandler;
|
||||
public delegate Task<TcpClient> TcpFactory(string host, int port);
|
||||
|
|
@ -355,13 +356,13 @@ namespace WTelegram
|
|||
if (IsMainDC)
|
||||
{
|
||||
var updatesState = await this.Updates_GetState(); // this call reenables incoming Updates
|
||||
RaiseUpdate(updatesState);
|
||||
RaiseUpdates(updatesState);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (IsMainDC)
|
||||
RaiseUpdate(reactorError);
|
||||
RaiseUpdates(reactorError);
|
||||
lock (_pendingRpcs) // abort all pending requests
|
||||
{
|
||||
foreach (var rpc in _pendingRpcs.Values)
|
||||
|
|
@ -583,11 +584,11 @@ namespace WTelegram
|
|||
else
|
||||
{
|
||||
Helpers.Log(1, $" → {result?.GetType().Name,-37} #{(short)msgId.GetHashCode():X4}");
|
||||
if (OnOwnUpdate != null)
|
||||
if (OnOwnUpdates != null)
|
||||
if (result is UpdatesBase updates)
|
||||
RaiseOwnUpdate(updates);
|
||||
RaiseOwnUpdates(updates);
|
||||
else if (result is Messages_AffectedMessages affected)
|
||||
RaiseOwnUpdate(new UpdateShort { update = new UpdateAffectedMessages { affected = affected }, date = MsgIdToStamp(_lastRecvMsgId) });
|
||||
RaiseOwnUpdates(new UpdateShort { update = new UpdateAffectedMessages { affected = affected }, date = MsgIdToStamp(_lastRecvMsgId) });
|
||||
}
|
||||
|
||||
rpc.tcs.SetResult(result);
|
||||
|
|
@ -611,8 +612,8 @@ namespace WTelegram
|
|||
else
|
||||
{
|
||||
result = reader.ReadTLObject(ctorNb);
|
||||
if (OnOwnUpdate != null && result is UpdatesBase updates)
|
||||
RaiseOwnUpdate(updates);
|
||||
if (OnOwnUpdates != null && result is UpdatesBase updates)
|
||||
RaiseOwnUpdates(updates);
|
||||
}
|
||||
|
||||
var typeName = result?.GetType().Name;
|
||||
|
|
@ -673,7 +674,7 @@ namespace WTelegram
|
|||
break;
|
||||
case Pong pong:
|
||||
SetResult(pong.msg_id, pong);
|
||||
RaiseUpdate(pong);
|
||||
RaiseUpdates(pong);
|
||||
break;
|
||||
case FutureSalts futureSalts:
|
||||
SetResult(futureSalts.req_msg_id, futureSalts);
|
||||
|
|
@ -733,10 +734,10 @@ namespace WTelegram
|
|||
rpc.tcs.SetException(new WTException($"BadMsgNotification {badMsgNotification.error_code}"));
|
||||
}
|
||||
else
|
||||
RaiseUpdate(badMsgNotification);
|
||||
RaiseUpdates(badMsgNotification);
|
||||
break;
|
||||
default:
|
||||
RaiseUpdate(obj);
|
||||
RaiseUpdates(obj);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -746,32 +747,32 @@ namespace WTelegram
|
|||
if (rpc != null)
|
||||
rpc.tcs.SetResult(result);
|
||||
else
|
||||
RaiseUpdate(obj);
|
||||
RaiseUpdates(obj);
|
||||
}
|
||||
}
|
||||
|
||||
private async void RaiseUpdate(IObject obj)
|
||||
private async void RaiseUpdates(IObject obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
var task = obj is UpdatesBase updates ? OnUpdate?.Invoke(updates) : OnOther?.Invoke(obj);
|
||||
var task = obj is UpdatesBase updates ? OnUpdates?.Invoke(updates) : OnOther?.Invoke(obj);
|
||||
if (task != null) await task;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Helpers.Log(4, $"{nameof(OnUpdate)}({obj?.GetType().Name}) raised {ex}");
|
||||
Helpers.Log(4, $"{nameof(OnUpdates)}({obj?.GetType().Name}) raised {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
private async void RaiseOwnUpdate(UpdatesBase updates)
|
||||
private async void RaiseOwnUpdates(UpdatesBase updates)
|
||||
{
|
||||
try
|
||||
{
|
||||
await OnOwnUpdate(updates);
|
||||
await OnOwnUpdates(updates);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Helpers.Log(4, $"{nameof(OnOwnUpdate)}({updates.GetType().Name}) raised {ex}");
|
||||
Helpers.Log(4, $"{nameof(OnOwnUpdates)}({updates.GetType().Name}) raised {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1050,7 +1051,7 @@ namespace WTelegram
|
|||
if (self.id == long.Parse(botToken.Split(':')[0]))
|
||||
{
|
||||
_session.UserId = _dcSession.UserId = self.id;
|
||||
RaiseUpdate(self);
|
||||
RaiseUpdates(self);
|
||||
return User = self;
|
||||
}
|
||||
Helpers.Log(3, $"Current logged user {self.id} mismatched bot_token. Logging out and in...");
|
||||
|
|
@ -1089,7 +1090,7 @@ namespace WTelegram
|
|||
self.phone == string.Concat((phone_number = Config("phone_number")).Where(char.IsDigit)))
|
||||
{
|
||||
_session.UserId = _dcSession.UserId = self.id;
|
||||
RaiseUpdate(self);
|
||||
RaiseUpdates(self);
|
||||
return User = self;
|
||||
}
|
||||
var mismatch = $"Current logged user {self.id} mismatched user_id or phone_number";
|
||||
|
|
@ -1124,7 +1125,7 @@ namespace WTelegram
|
|||
{
|
||||
phone_code_hash = setupSentCode.phone_code_hash;
|
||||
Helpers.Log(3, "A login email is required");
|
||||
RaiseUpdate(sentCodeBase);
|
||||
RaiseUpdates(sentCodeBase);
|
||||
var email = _config("email");
|
||||
if (string.IsNullOrEmpty(email))
|
||||
sentCodeBase = await this.Auth_ResendCode(phone_number, phone_code_hash);
|
||||
|
|
@ -1135,7 +1136,7 @@ namespace WTelegram
|
|||
{
|
||||
var sentEmail = await this.Account_SendVerifyEmailCode(purpose, email);
|
||||
Helpers.Log(3, "An email verification code has been sent to " + sentEmail.email_pattern);
|
||||
RaiseUpdate(sentEmail);
|
||||
RaiseUpdates(sentEmail);
|
||||
}
|
||||
Account_EmailVerified verified = null;
|
||||
for (int retry = 1; verified == null; retry++)
|
||||
|
|
@ -1166,7 +1167,7 @@ namespace WTelegram
|
|||
phone_code_hash = sentCode.phone_code_hash;
|
||||
var timeout = DateTime.UtcNow + TimeSpan.FromSeconds(sentCode.timeout);
|
||||
Helpers.Log(3, $"A verification code has been sent via {sentCode.type.GetType().Name[17..]}");
|
||||
RaiseUpdate(sentCode);
|
||||
RaiseUpdates(sentCode);
|
||||
if (sentCode.type is Auth_SentCodeTypeFirebaseSms firebaseSms)
|
||||
{
|
||||
var token = await ConfigAsync("firebase");
|
||||
|
|
@ -1210,7 +1211,7 @@ namespace WTelegram
|
|||
try
|
||||
{
|
||||
var accountPassword = await this.Account_GetPassword();
|
||||
RaiseUpdate(accountPassword);
|
||||
RaiseUpdates(accountPassword);
|
||||
var checkPasswordSRP = await Check2FA(accountPassword, () => ConfigAsync("password"));
|
||||
authorization = await this.Auth_CheckPassword(checkPasswordSRP);
|
||||
}
|
||||
|
|
@ -1230,7 +1231,7 @@ namespace WTelegram
|
|||
if (authorization is Auth_AuthorizationSignUpRequired signUpRequired)
|
||||
{
|
||||
var waitUntil = DateTime.UtcNow.AddSeconds(3);
|
||||
RaiseUpdate(signUpRequired); // give caller the possibility to read and accept TOS
|
||||
RaiseUpdates(signUpRequired); // give caller the possibility to read and accept TOS
|
||||
var first_name = Config("first_name");
|
||||
var last_name = Config("last_name");
|
||||
var wait = waitUntil - DateTime.UtcNow;
|
||||
|
|
@ -1257,7 +1258,7 @@ namespace WTelegram
|
|||
throw new WTException("Failed to get Authorization: " + authorization.GetType().Name);
|
||||
_session.UserId = _dcSession.UserId = self.id;
|
||||
lock (_session) _session.Save();
|
||||
RaiseUpdate(self);
|
||||
RaiseUpdates(self);
|
||||
return User = self;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace WTelegram
|
|||
int RemoteLayer { get; }
|
||||
}
|
||||
|
||||
[TLDef(0xFEFEFEFE)]
|
||||
[TLDef(0xFEFEFEFE)] [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles")]
|
||||
internal sealed partial class SecretChat : IObject, ISecretChat
|
||||
{
|
||||
[Flags] public enum Flags : uint { requestChat = 1, renewKey = 2, acceptKey = 4, originator = 8, commitKey = 16 }
|
||||
|
|
@ -170,7 +170,7 @@ namespace WTelegram
|
|||
return chat_id;
|
||||
}
|
||||
|
||||
/// <summary>Processes the <see cref="UpdateEncryption"/> you received from Telegram (<see cref="Client.OnUpdate"/>).</summary>
|
||||
/// <summary>Processes the <see cref="UpdateEncryption"/> you received from Telegram (<see cref="Client.OnUpdates"/>).</summary>
|
||||
/// <param name="update">If update.chat is <see cref="EncryptedChatRequested"/>, you might want to first make sure you want to accept this secret chat initiated by user <see cref="EncryptedChatRequested.admin_id"/></param>
|
||||
/// <param name="acceptChatRequests">Incoming requests for secret chats are automatically: accepted (<see langword="true"/>), rejected (<see langword="false"/>) or ignored (<see langword="null"/>)</param>
|
||||
/// <returns><see langword="true"/> if the update was handled successfully</returns>
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ namespace TL
|
|||
public static implicit operator byte[](Int256 int256) => int256.raw;
|
||||
}
|
||||
|
||||
public sealed partial class UpdateAffectedMessages : Update // auto-generated for OnOwnUpdate in case of such API call result
|
||||
public sealed partial class UpdateAffectedMessages : Update // auto-generated for OnOwnUpdates in case of such API call result
|
||||
{
|
||||
public Messages_AffectedMessages affected;
|
||||
public override (long, int, int) GetMBox() => (0, affected.pts, affected.pts_count);
|
||||
|
|
|
|||
Loading…
Reference in a new issue