From 98a95376f3bdd385aa24995dde8218e6756f9aba Mon Sep 17 00:00:00 2001 From: Wizou Date: Wed, 13 Oct 2021 00:27:40 +0200 Subject: [PATCH] Improved examples documentation --- Examples/Program_CollectAccessHash.cs | 8 ++++++++ Examples/Program_GetAllChats.cs | 7 ++++--- Examples/Program_ListenUpdates.cs | 4 ++-- README.md | 6 +++--- src/Client.cs | 6 +++++- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Examples/Program_CollectAccessHash.cs b/Examples/Program_CollectAccessHash.cs index ab34217..19c1e6f 100644 --- a/Examples/Program_CollectAccessHash.cs +++ b/Examples/Program_CollectAccessHash.cs @@ -43,6 +43,14 @@ namespace WTelegramClientTest } else { + // Zero means the access hash for Durov's Channel was not collected yet. + // So we need to obtain it through Client API calls whose results contains the access_hash field, such as: + // - Messages_GetAllChats (see Program_GetAllChats.cs for an example on how to use it) + // - Messages_GetDialogs (see Program_ListenUpdates.cs for an example on how to use it) + // - Contacts_ResolveUsername (see below for an example on how to use it) + // and many more API methods... + // The access_hash fields can be found inside instance of User, Channel, Photo, Document, etc.. + // usually listed through their base class UserBase, ChatBase, PhotoBase, DocumentBase, etc... Console.WriteLine("Resolving channel @durov to get its ID, access hash and other infos..."); var durovResolved = await client.Contacts_ResolveUsername("durov"); // @durov = Durov's Channel if (durovResolved.peer.ID != DurovID) diff --git a/Examples/Program_GetAllChats.cs b/Examples/Program_GetAllChats.cs index 0de1333..4f532d6 100644 --- a/Examples/Program_GetAllChats.cs +++ b/Examples/Program_GetAllChats.cs @@ -9,6 +9,7 @@ namespace WTelegramClientTest class Program_GetAllChats { // This code is similar to what you should have obtained if you followed the README introduction + // I've just added a few comments to explain further what's going on // go to Project Properties > Debug > Environment variables and add at least these: api_id, api_hash, phone_number static string Config(string what) @@ -30,7 +31,7 @@ namespace WTelegramClientTest var user = await client.LoginUserIfNeeded(); Console.WriteLine($"We are logged-in as {user.username ?? user.first_name + " " + user.last_name} (id {user.id})"); - var chats = await client.Messages_GetAllChats(null); + var chats = await client.Messages_GetAllChats(null); // chats = groups/channels (does not include users dialogs) Console.WriteLine("This user has joined the following:"); foreach (var chat in chats.chats) switch (chat) @@ -42,7 +43,7 @@ namespace WTelegramClientTest Console.WriteLine($"{channel.id}: Channel {channel.username}: {channel.title}"); //Console.WriteLine($" → access_hash = {channel.access_hash:X}"); break; - case Channel group: + case Channel group: // no broadcast flag => it's a big group, also called supergroup or megagroup Console.WriteLine($"{group.id}: Group {group.username}: {group.title}"); //Console.WriteLine($" → access_hash = {group.access_hash:X}"); break; @@ -52,7 +53,7 @@ namespace WTelegramClientTest long id = long.Parse(Console.ReadLine()); var target = chats.chats.First(chat => chat.ID == id); Console.WriteLine($"Sending a message in chat {target.ID}: {target.Title}"); - // This line implicitely creates an adequate InputPeer (with eventual access_hash) from ChatBase: + // Next line implicitely creates an adequate InputPeer from ChatBase: (with the access_hash if these is one) InputPeer peer = target; await client.SendMessageAsync(peer, "Hello, World"); } diff --git a/Examples/Program_ListenUpdates.cs b/Examples/Program_ListenUpdates.cs index 275094b..1dc3c22 100644 --- a/Examples/Program_ListenUpdates.cs +++ b/Examples/Program_ListenUpdates.cs @@ -20,7 +20,7 @@ namespace WTelegramClientTest users[my.id] = my; // note that on login Telegram may sends a bunch of updates/messages that happened in the past and were not acknowledged Console.WriteLine($"We are logged-in as {my.username ?? my.first_name + " " + my.last_name} (id {my.id})"); - var dialogsBase = await client.Messages_GetDialogs(default, 0, null, 0, 0); + var dialogsBase = await client.Messages_GetDialogs(default, 0, null, 0, 0); // dialogs = groups/channels/users if (dialogsBase is Messages_Dialogs dialogs) while (dialogs.dialogs.Length != 0) { @@ -33,7 +33,7 @@ namespace WTelegramClientTest dialogs = (Messages_Dialogs)await client.Messages_GetDialogs(lastMsg?.Date ?? default, lastDialog.top_message, offsetPeer, 500, 0); } Console.ReadKey(); - await client.Ping(43); // dummy API call.. this is used to force an acknowledge on this session's updates + await client.Ping(42); // dummy API call } diff --git a/README.md b/README.md index a9c513b..a80773f 100644 --- a/README.md +++ b/README.md @@ -99,15 +99,15 @@ await client.SendMessageAsync(target, "Hello, World"); # Other things to know -The Client class also offers an `Update` event that is triggered when Telegram servers sends unsollicited Updates or notifications/information/status/service messages, independently of your API requests. +The Client class also offers an `Update` event that is triggered when Telegram servers sends unsollicited Updates or notifications/information/status/service messages, independently of your API requests. See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs) 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. The other configuration items that you can override include: **session_pathname, server_address, device_model, system_version, app_version, system_lang_code, lang_pack, lang_code, user_id** -Optional API parameters have a default value of `null` when unset. Passing `null` for a required string/array is the same as *empty* (0-length). Required API parameters/fields can sometimes be set to 0 or `null` when unused (check API documentation). +Optional API parameters have a default value of `null` when unset. Passing `null` for a required string/array is the same as *empty* (0-length). Required API parameters/fields can sometimes be set to 0 or `null` when unused (check API documentation or experiment). -I've added several useful converters or implicit cast to various API object so that they are more easy to manipulate. +I've added several useful converters, implicit cast or helper properties to various API object so that they are more easy to manipulate. Beyond the TL async methods, the Client class offers a few other methods to simplify the sending/receiving of files, medias or messages. diff --git a/src/Client.cs b/src/Client.cs index c71847f..3adec35 100644 --- a/src/Client.cs +++ b/src/Client.cs @@ -22,6 +22,8 @@ namespace WTelegram { public sealed class Client : IDisposable { + /// This event will be called when an unsollicited update/message is sent by Telegram servers + /// See Examples/Program_ListenUpdate.cs for how to use this public event Action Update; public Config TLConfig { get; private set; } public int MaxAutoReconnects { get; set; } = 5; // number of automatic reconnections on connection/reactor failure @@ -1218,7 +1220,9 @@ namespace WTelegram readonly Dictionary> _accessHashes = new(); public IEnumerable> AllAccessHashesFor() where T : ITLObject => _accessHashes.GetValueOrDefault(typeof(T)); - /// Retrieve the access_hash associated with this id (for a TL class) + /// Retrieve the access_hash associated with this id (for a TL class) if it was collected + /// This requires to be set to first. + ///
See Examples/Program_CollectAccessHash.cs for how to use this
/// a TL object class. For example User, Channel or Photo public long GetAccessHashFor(long id) where T : ITLObject {