From d858411a879585594a5ff6c6ca347813e6ec6bfb Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Fri, 6 Jan 2023 13:28:58 +0100
Subject: [PATCH 001/304] demonstrate doc.Filename in
Program_DownloadSavedMedia
---
.github/dev.yml | 2 +-
Examples/Program_DownloadSavedMedia.cs | 6 +++---
FAQ.md | 1 +
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index 3b5849b..27a4134 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -2,7 +2,7 @@ pr: none
trigger:
- master
-name: 3.2.1-dev.$(Rev:r)
+name: 3.2.2-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/Examples/Program_DownloadSavedMedia.cs b/Examples/Program_DownloadSavedMedia.cs
index d8ca67d..c65c13a 100644
--- a/Examples/Program_DownloadSavedMedia.cs
+++ b/Examples/Program_DownloadSavedMedia.cs
@@ -10,7 +10,7 @@ namespace WTelegramClientTest
static class Program_DownloadSavedMedia
{
// go to Project Properties > Debug > Environment variables and add at least these: api_id, api_hash, phone_number
- static async Task Main(string[] args)
+ static async Task Main(string[] _)
{
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);
@@ -30,8 +30,8 @@ namespace WTelegramClientTest
if (message.media is MessageMediaDocument { document: Document document })
{
- int slash = document.mime_type.IndexOf('/'); // quick & dirty conversion from MIME type to file extension
- var filename = slash > 0 ? $"{document.id}.{document.mime_type[(slash + 1)..]}" : $"{document.id}.bin";
+ var filename = document.Filename; // use document original filename, or build a name from document ID & MIME type:
+ filename ??= $"{document.id}.{document.mime_type[(document.mime_type.IndexOf('/') + 1)..]}";
Console.WriteLine("Downloading " + filename);
using var fileStream = File.Create(filename);
await client.DownloadFileAsync(document, fileStream);
diff --git a/FAQ.md b/FAQ.md
index 2363f45..1c1d382 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -299,6 +299,7 @@ Also, remember to add a `using TL;` at the top of your files to have access to a
# Troubleshooting guide
Here is a list of common issues and how to fix them so that your program work correctly:
+
1) Are you using the Nuget package or the library source code?
It is not recommended to copy/compile the source code of the library for a normal usage.
When built in DEBUG mode, the source code connects to Telegram test servers (see also [FAQ #6](#wrong-server)).
From 750dbef33b521cca0ebdc9232762be8b00c65a3b Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Fri, 6 Jan 2023 13:29:33 +0100
Subject: [PATCH 002/304] default value for offset_topic arg
---
src/TL.SchemaFuncs.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index 83fa378..a940a30 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -4298,7 +4298,7 @@ namespace TL
});
/// See
- public static Task Channels_GetForumTopics(this Client client, InputChannelBase channel, int offset_topic, DateTime offset_date = default, int offset_id = default, int limit = int.MaxValue, string q = null)
+ public static Task Channels_GetForumTopics(this Client client, InputChannelBase channel, DateTime offset_date = default, int offset_id = default, int offset_topic = default, int limit = int.MaxValue, string q = null)
=> client.Invoke(new Channels_GetForumTopics
{
flags = (Channels_GetForumTopics.Flags)(q != null ? 0x1 : 0),
From 014f563b899c539678f512be7f5e1641e5c2f1d3 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Sat, 7 Jan 2023 13:22:40 +0100
Subject: [PATCH 003/304] added Channel.MainUsername helper | simplified
GetAllChats example
---
Examples/Program_GetAllChats.cs | 4 ++--
README.md | 16 +++-------------
src/TL.Helpers.cs | 1 +
3 files changed, 6 insertions(+), 15 deletions(-)
diff --git a/Examples/Program_GetAllChats.cs b/Examples/Program_GetAllChats.cs
index b39e31f..02fc287 100644
--- a/Examples/Program_GetAllChats.cs
+++ b/Examples/Program_GetAllChats.cs
@@ -34,10 +34,10 @@ namespace WTelegramClientTest
foreach (var (id, chat) in chats.chats)
switch (chat)
{
- case Chat smallgroup when (smallgroup.flags & Chat.Flags.deactivated) == 0:
+ case Chat smallgroup when smallgroup.IsActive:
Console.WriteLine($"{id}: Small group: {smallgroup.title} with {smallgroup.participants_count} members");
break;
- case Channel channel when (channel.flags & Channel.Flags.broadcast) != 0:
+ case Channel channel when channel.IsChannel:
Console.WriteLine($"{id}: Channel {channel.username}: {channel.title}");
//Console.WriteLine($" → access_hash = {channel.access_hash:X}");
break;
diff --git a/README.md b/README.md
index 1c342a3..e40d404 100644
--- a/README.md
+++ b/README.md
@@ -129,18 +129,8 @@ using TL;
var chats = await client.Messages_GetAllChats();
Console.WriteLine("This user has joined the following:");
foreach (var (id, chat) in chats.chats)
- switch (chat) // example of downcasting to their real classes:
- {
- case Chat basicChat when basicChat.IsActive:
- Console.WriteLine($"{id}: Basic chat: {basicChat.title}");
- break;
- case Channel group when group.IsGroup:
- Console.WriteLine($"{id}: Group {group.username}: {group.title}");
- break;
- case Channel channel:
- Console.WriteLine($"{id}: Channel {channel.username}: {channel.title}");
- break;
- }
+ if (chat.IsActive)
+ Console.WriteLine($"{id,10}: {chat}");
Console.Write("Type a chat ID to send a message: ");
long chatId = long.Parse(Console.ReadLine());
var target = chats.chats[chatId];
@@ -149,7 +139,7 @@ await client.SendMessageAsync(target, "Hello, World");
```
➡️ You can find lots of useful code snippets in [EXAMPLES](https://wiz0u.github.io/WTelegramClient/EXAMPLES)
-and in the [Examples subdirectory](https://github.com/wiz0u/WTelegramClient/tree/master/Examples).
+and more detailed programs in the [Examples subdirectory](https://github.com/wiz0u/WTelegramClient/tree/master/Examples).
➡️ Check [the FAQ](https://wiz0u.github.io/WTelegramClient/FAQ#compile) if example codes don't compile correctly on your machine, or other troubleshooting.
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index 625fdae..50689e1 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -216,6 +216,7 @@ namespace TL
partial class Channel
{
public override bool IsActive => (flags & Flags.left) == 0;
+ public string MainUsername => username ?? usernames?.FirstOrDefault(u => u.flags.HasFlag(Username.Flags.active))?.username;
public override ChatPhoto Photo => photo;
public override bool IsBanned(ChatBannedRights.Flags flags = 0) => ((banned_rights?.flags ?? 0) & flags) != 0 || ((default_banned_rights?.flags ?? 0) & flags) != 0;
public override InputPeer ToInputPeer() => new InputPeerChannel(id, access_hash);
From 8f10df88497031db9713dbecc5b5b74c6ddeaa80 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Mon, 9 Jan 2023 13:22:35 +0100
Subject: [PATCH 004/304] made Peer.UserOrChat as protected internal to be
user-overridable
---
src/TL.Extensions.cs | 2 +-
src/TL.Helpers.cs | 8 ++++----
src/WTelegramClient.csproj | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/TL.Extensions.cs b/src/TL.Extensions.cs
index be79d66..01fe82d 100644
--- a/src/TL.Extensions.cs
+++ b/src/TL.Extensions.cs
@@ -14,7 +14,7 @@ namespace TL
public override long ID => 0;
internal Dictionary _users;
internal Dictionary _chats;
- internal override IPeerInfo UserOrChat(Dictionary users, Dictionary chats)
+ protected internal override IPeerInfo UserOrChat(Dictionary users, Dictionary chats)
{
lock (_users)
foreach (var user in users.Values)
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index 50689e1..62b48e2 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -117,25 +117,25 @@ namespace TL
partial class Peer
{
public abstract long ID { get; }
- internal abstract IPeerInfo UserOrChat(Dictionary users, Dictionary chats);
+ protected internal abstract IPeerInfo UserOrChat(Dictionary users, Dictionary chats);
}
partial class PeerUser
{
public override string ToString() => "user " + user_id;
public override long ID => user_id;
- internal override IPeerInfo UserOrChat(Dictionary users, Dictionary chats) => users.TryGetValue(user_id, out var user) ? user : null;
+ protected internal override IPeerInfo UserOrChat(Dictionary users, Dictionary chats) => users.TryGetValue(user_id, out var user) ? user : null;
}
partial class PeerChat
{
public override string ToString() => "chat " + chat_id;
public override long ID => chat_id;
- internal override IPeerInfo UserOrChat(Dictionary users, Dictionary chats) => chats.TryGetValue(chat_id, out var chat) ? chat : null;
+ protected internal override IPeerInfo UserOrChat(Dictionary users, Dictionary chats) => chats.TryGetValue(chat_id, out var chat) ? chat : null;
}
partial class PeerChannel
{
public override string ToString() => "channel " + channel_id;
public override long ID => channel_id;
- internal override IPeerInfo UserOrChat(Dictionary users, Dictionary chats) => chats.TryGetValue(channel_id, out var chat) ? chat : null;
+ protected internal override IPeerInfo UserOrChat(Dictionary users, Dictionary chats) => chats.TryGetValue(channel_id, out var chat) ? chat : null;
}
partial class UserBase : IPeerInfo
diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj
index ce3ce87..6eedad4 100644
--- a/src/WTelegramClient.csproj
+++ b/src/WTelegramClient.csproj
@@ -14,7 +14,7 @@
0.0.0
Wizou
Telegram Client API (MTProto) library written 100% in C# and .NET Standard | Latest API layer: 151
Release Notes:
$(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))
- Copyright © Olivier Marcoux 2021-2022
+ Copyright © Olivier Marcoux 2021-2023
MIT
https://github.com/wiz0u/WTelegramClient
logo.png
From 66d8b7546354f228b592dcd60d7759cb8775ed2e Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Thu, 12 Jan 2023 01:37:12 +0100
Subject: [PATCH 005/304] deprecate the experimental CollectAccessHash system
---
EXAMPLES.md | 38 +++++++++++--
Examples/Program_CollectAccessHash.cs | 82 ---------------------------
src/Client.Helpers.cs | 5 +-
src/TL.Extensions.cs | 11 ++--
src/TL.cs | 2 +
5 files changed, 45 insertions(+), 93 deletions(-)
delete mode 100644 Examples/Program_CollectAccessHash.cs
diff --git a/EXAMPLES.md b/EXAMPLES.md
index de51ccf..933e51e 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -76,7 +76,7 @@ var sent2 = await client.SendMessageAsync(InputPeer.Self, text2, entities: entit
text2 = client.EntitiesToMarkdown(sent2.message, sent2.entities);
```
See [HTML formatting style](https://core.telegram.org/bots/api/#html-style) and [MarkdownV2 formatting style](https://core.telegram.org/bots/api/#markdownv2-style) for details.
-*Note: For the `tg://user?id=` notation to work, that user's access hash must have been collected first ([see below](#collect-access-hash))*
+*Note: For the `tg://user?id=` notation to work, you need to pass the _users dictionary in arguments ([see below](#collect-users-chats))*
## List all dialogs (chats/groups/channels/user chat) we are currently in
@@ -442,13 +442,39 @@ finally
```
-## Collect Access Hash and save them for later use
+
+
+## Collect Users/Chats description structures and access hash
-You can automate the collection of `access_hash` for the various resources obtained in response to API calls or Updates,
-so that you don't have to remember them by yourself or ask the API about them each time.
+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 done by activating the experimental `client.CollectAccessHash` system.
-See [Examples/Program_CollectAccessHash.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_CollectAccessHash.cs?ts=4#L22) for how to enable it, and save/restore them for later use.
+These two dictionaries give details 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` field.
+
+In such case, the root structure inherits the `IPeerResolver` interface, and you can use the `UserOrChat(peer)` method to resolve a `Peer`
+into either a `User` or `ChatBase` (`Chat`,`Channel`...) description structure *(depending what kind of peer it was describing)*
+
+You can also use the `CollectUsersChats` helper method to collect these 2 fields into 2 aggregate dictionaries to remember details
+*(including access hashes)* about all the users/chats you've encountered so far.
+
+Example of usage for `CollectUsersChats`:
+```csharp
+static Dictionary _users = new();
+static Dictionary _chats = new();
+...
+var dialogs = await client.Messages_GetAllDialogs();
+dialogs.CollectUsersChats(_users, _chats);
+...
+private static async Task OnUpdate(IObject arg)
+{
+ if (arg is not UpdatesBase updates) return;
+ updates.CollectUsersChats(_users, _chats);
+ ...
+}
+```
+
+*Note: If you need to save/restore those dictionaries between runs of your program, it's up to you to serialize their content to disk*
## Use a proxy or MTProxy to connect to Telegram
diff --git a/Examples/Program_CollectAccessHash.cs b/Examples/Program_CollectAccessHash.cs
deleted file mode 100644
index 9537987..0000000
--- a/Examples/Program_CollectAccessHash.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text.Json;
-using System.Threading.Tasks;
-using TL;
-
-namespace WTelegramClientTest
-{
- static class Program_CollectAccessHash
- {
- private const string StateFilename = "SavedState.json";
- private const long DurovID = 1006503122; // known ID for Durov's Channel
- private static SavedState savedState = new();
-
- // go to Project Properties > Debug > Environment variables and add at least these: api_id, api_hash, phone_number
- static async Task Main(string[] _)
- {
- Console.WriteLine("The program demonstrate how to load/save/use collected access hash.");
- WTelegram.Helpers.Log = (l, s) => System.Diagnostics.Debug.WriteLine(s);
- using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
- client.CollectAccessHash = true;
-
- if (File.Exists(StateFilename))
- {
- Console.WriteLine("Loading previously saved access hashes from disk...");
- using (var stateStream = File.OpenRead(StateFilename))
- savedState = await JsonSerializer.DeserializeAsync(stateStream);
- foreach (var id_hash in savedState.Channels) client.SetAccessHashFor(id_hash.Key, id_hash.Value);
- foreach (var id_hash in savedState.Users) client.SetAccessHashFor(id_hash.Key, id_hash.Value);
- }
-
- Console.WriteLine("Connecting to Telegram...");
- await client.LoginUserIfNeeded();
-
- var durovAccessHash = client.GetAccessHashFor(DurovID);
- if (durovAccessHash != 0)
- {
- // we already know the access hash for Durov's Channel, so we can directly use it
- Console.WriteLine($"Channel @durov has ID {DurovID} and access hash was already collected: {durovAccessHash:X}");
- }
- 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_GetAllDialogs (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)
- throw new Exception("@durov has changed channel ID ?!");
- durovAccessHash = client.GetAccessHashFor(DurovID); // should have been collected from the previous API result
- if (durovAccessHash == 0)
- throw new Exception("No access hash was automatically collected !? (shouldn't happen)");
- Console.WriteLine($"Channel @durov has ID {DurovID} and access hash was automatically collected: {durovAccessHash:X}");
- }
-
- Console.WriteLine("With the access hash, we can now join the channel for example.");
- await client.Channels_JoinChannel(new InputChannel(DurovID, durovAccessHash));
-
- Console.WriteLine("Channel joined. Press any key to save and exit");
- Console.ReadKey(true);
-
- Console.WriteLine("Saving all collected access hashes to disk for next run...");
- savedState.Channels = client.AllAccessHashesFor().ToList();
- savedState.Users = client.AllAccessHashesFor().ToList();
- using (var stateStream = File.Create(StateFilename))
- await JsonSerializer.SerializeAsync(stateStream, savedState);
- }
-
- class SavedState
- {
- public List> Channels { get; set; } = new();
- public List> Users { get; set; } = new();
- }
- }
-}
diff --git a/src/Client.Helpers.cs b/src/Client.Helpers.cs
index 115f05a..ce1580d 100644
--- a/src/Client.Helpers.cs
+++ b/src/Client.Helpers.cs
@@ -16,7 +16,9 @@ namespace WTelegram
partial class Client
{
#region Collect Access Hash system
- /// Enable the collection of id/access_hash pairs (experimental)
See
+ #pragma warning disable CS0618 // Type or member is obsolete
+ /// Enable the collection of id/access_hash pairs (deprecated)
+ [Obsolete("This system will be removed in a future version. You should use CollectUsersChats helper on API results or updates instead. See https://wiz0u.github.io/WTelegramClient/EXAMPLES#collect-users-chats")]
public bool CollectAccessHash { get; set; }
public IEnumerable> AllAccessHashesFor() where T : IObject => _accessHashes.GetValueOrDefault(typeof(T));
private readonly Dictionary> _accessHashes = new();
@@ -53,6 +55,7 @@ namespace WTelegram
lock (_accessHashes)
_accessHashes.GetOrCreate(type)[id] = accessHash;
}
+ #pragma warning restore CS0618 // Type or member is obsolete
#endregion
#region Client TL Helpers
diff --git a/src/TL.Extensions.cs b/src/TL.Extensions.cs
index 01fe82d..9139778 100644
--- a/src/TL.Extensions.cs
+++ b/src/TL.Extensions.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
+using WTelegram; // for GetValueOrDefault
namespace TL
{
@@ -48,8 +49,9 @@ namespace TL
/// Client, used for getting access_hash for tg://user?id= URLs
/// [in] The Markdown text
[out] The same (plain) text, stripped of all Markdown notation
/// Generate premium entities if any
+ /// Dictionary used for tg://user?id= notation
/// The array of formatting entities that you can pass (along with the plain text) to SendMessageAsync or SendMediaAsync
- public static MessageEntity[] MarkdownToEntities(this WTelegram.Client client, ref string text, bool premium = false)
+ public static MessageEntity[] MarkdownToEntities(this WTelegram.Client client, ref string text, bool premium = false, Dictionary users = null)
{
var entities = new List();
var sb = new StringBuilder(text);
@@ -119,7 +121,7 @@ namespace TL
else if (c == ')') break;
}
textUrl.url = sb.ToString(offset + 2, offset2 - offset - 3);
- if (textUrl.url.StartsWith("tg://user?id=") && long.TryParse(textUrl.url[13..], out var id) && client.GetAccessHashFor(id) is long hash)
+ if (textUrl.url.StartsWith("tg://user?id=") && long.TryParse(textUrl.url[13..], out var id) && (users?.GetValueOrDefault(id)?.access_hash ?? client.GetAccessHashFor(id)) is long hash)
entities[lastIndex] = new InputMessageEntityMentionName { offset = textUrl.offset, length = textUrl.length, user_id = new InputUser(id, hash) };
else if ((textUrl.url.StartsWith("tg://emoji?id=") || textUrl.url.StartsWith("emoji?id=")) && long.TryParse(textUrl.url[(textUrl.url.IndexOf('=') + 1)..], out id))
if (premium) entities[lastIndex] = new MessageEntityCustomEmoji { offset = textUrl.offset, length = textUrl.length, document_id = id };
@@ -247,8 +249,9 @@ namespace TL
/// Client, used for getting access_hash for tg://user?id= URLs
/// [in] The HTML-formatted text
[out] The same (plain) text, stripped of all HTML tags
/// Generate premium entities if any
+ /// Dictionary used for tg://user?id= notation
/// The array of formatting entities that you can pass (along with the plain text) to SendMessageAsync or SendMediaAsync
- public static MessageEntity[] HtmlToEntities(this WTelegram.Client client, ref string text, bool premium = false)
+ public static MessageEntity[] HtmlToEntities(this WTelegram.Client client, ref string text, bool premium = false, Dictionary users = null)
{
var entities = new List();
var sb = new StringBuilder(text);
@@ -303,7 +306,7 @@ namespace TL
else if (tag.StartsWith("a href=\"") && tag.EndsWith("\""))
{
tag = tag[8..^1];
- if (tag.StartsWith("tg://user?id=") && long.TryParse(tag[13..], out var user_id) && client.GetAccessHashFor(user_id) is long hash)
+ if (tag.StartsWith("tg://user?id=") && long.TryParse(tag[13..], out var user_id) && (users?.GetValueOrDefault(user_id)?.access_hash ?? client.GetAccessHashFor(user_id)) is long hash)
entities.Add(new InputMessageEntityMentionName { offset = offset, length = -1, user_id = new InputUser(user_id, hash) });
else
entities.Add(new MessageEntityTextUrl { offset = offset, length = -1, url = tag });
diff --git a/src/TL.cs b/src/TL.cs
index c7b1767..b5544b4 100644
--- a/src/TL.cs
+++ b/src/TL.cs
@@ -95,7 +95,9 @@ namespace TL
if (field.FieldType.IsEnum)
if (field.Name == "flags") flags = (uint)value;
else if (field.Name == "flags2") flags |= (ulong)(uint)value << 32;
+#pragma warning disable CS0618 // Type or member is obsolete
if (reader.Client?.CollectAccessHash == true) reader.Client.CollectField(field, obj, value);
+#pragma warning restore CS0618 // Type or member is obsolete
}
return (IObject)obj;
}
From 553934c5ad11a630454eb4ffb229b795908adbbf Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Thu, 26 Jan 2023 14:42:50 +0100
Subject: [PATCH 006/304] add GetAllDialogs to WinForms example app
---
EXAMPLES.md | 19 ++++++++++++-------
Examples/WinForms_app.zip | Bin 10412 -> 10502 bytes
FAQ.md | 30 +++++++++++++++++-------------
README.md | 2 +-
4 files changed, 30 insertions(+), 21 deletions(-)
diff --git a/EXAMPLES.md b/EXAMPLES.md
index 933e51e..c871113 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -12,7 +12,7 @@ await client.LoginUserIfNeeded();
In this case, environment variables are used for configuration so make sure to
go to your **Project Properties > Debug > Environment variables**
-and add at least these variables with adequate value: **api_id, api_hash, phone_number**
+and add at least these variables with adequate values: **api_id, api_hash, phone_number**
Remember that these are just simple example codes that you should adjust to your needs.
In real production code, you might want to properly test the success of each operation or handle exceptions,
@@ -453,25 +453,30 @@ These two dictionaries give details about the various users/chats that will be t
typically in the form of a `Peer` object or a `user_id` field.
In such case, the root structure inherits the `IPeerResolver` interface, and you can use the `UserOrChat(peer)` method to resolve a `Peer`
-into either a `User` or `ChatBase` (`Chat`,`Channel`...) description structure *(depending what kind of peer it was describing)*
+into either a `User` or `ChatBase` (`Chat`,`Channel`...) description structure *(depending on the kind of peer it was describing)*
You can also use the `CollectUsersChats` helper method to collect these 2 fields into 2 aggregate dictionaries to remember details
*(including access hashes)* about all the users/chats you've encountered so far.
-Example of usage for `CollectUsersChats`:
+Example of usage:
```csharp
-static Dictionary _users = new();
-static Dictionary _chats = new();
+private Dictionary _users = new();
+private Dictionary _chats = new();
...
var dialogs = await client.Messages_GetAllDialogs();
dialogs.CollectUsersChats(_users, _chats);
-...
-private static async Task OnUpdate(IObject arg)
+
+private async Task OnUpdate(IObject arg)
{
if (arg is not UpdatesBase updates) return;
updates.CollectUsersChats(_users, _chats);
...
}
+
+// example of UserOrChat usage:
+var firstPeer = dialogs.UserOrChat(dialogs.dialogs[0].Peer);
+if (firstPeer is User firstUser) Console.WriteLine($"First dialog is with user {firstUser}");
+else if (firstPeer is ChatBase firstChat) Console.WriteLine($"First dialog is {firstChat}");
```
*Note: If you need to save/restore those dictionaries between runs of your program, it's up to you to serialize their content to disk*
diff --git a/Examples/WinForms_app.zip b/Examples/WinForms_app.zip
index b92e8323ffc1454655a318c82c93514a1e9511a1..e04d6b7ff5859af685d2de9da48dad18d1a6c8b2 100644
GIT binary patch
delta 5475
zcmZ`-cQ{;I*B?E4XY?`{H6e&jj38QcqSsNQ6Nz@TA$pk!i7skHbP|TBA$p1EoiJL|
zh!#G%-@Whq-9Ns4p7We%pJ%P#T6>*!*52z^t{bICrlWy_O9T2ds(q!6QpkkK-UNvn
z;h%FJPGf;U>$u2DI%Xsp7ZLE@VAOp^m?k*44yd}6P8&%`H1am(Fg>aAgFyt6UaH-;
zUY=U0Cxu%nKt(v;m&F)rS+2a>UiBH45#%dBIp~aYn@wg!Pd6OW)=NA%Ai_?@%L?BhE
z`9zbRQH1Unk+=nL0$E?KrIc>F$kwc4wjcU{K`Uf#9ceAMBL=t!5FlZl!csM{Q@drE
z8=ZwvXz5W&-Ak~ddshT6AK_HE#sPuKy{-Wp3`Qkge8$f$UiiAh!Ur7^XkR-)#EPn<
z3x&S13buAWI#}V`J-~7q#=^cGLn=NP?e@{1-
z0e|=Bs
zq0{J(o>oJ~@&IDMxARaldzFnNb4aQL>>^{uNsc{q(${4se
z1=MboNP%ZyXM1G!BC7fzfo^H_TE=1eW6Eg-HVuFoS_JH$Sq^wIN|DI9D5qxU0$Cujpm
zu0Q>>4UL)m}$rOR3-Qgw&a3c*Wo{SgYSLp|i)A
z(rW+Jw7I8i{%-A~SE;KMobyVtb>(!2*q3^v@_eprMf~HvyYAX=!ykN{7dhDp1z((A
zQtGo4;fuCtB9oeIkNTP<$ElsmS9^C!?nK%!D9$n^fM*gZg5L4UUX9~OJ_rWTAR8BM
zEwNAcY8f=PF{hq{CeKbU*<*V9^p|UDDZw
zQvU{`1b!`DNn7SeAqfOOe&(8*mu5+t)RLooL}>8DZQT`clx?)>g}xx=oP|WC4!oJ&
z0(WD)WcgrBxAI?R_V@nj39HBn0ua`O}sa1H5k+h$YF`W~Iu*vz+KgtOkwe0=;o
zMw4%fOFk*mcddZ7U3pR+eX=o6e!E4>p7*pa{&<3`9|H(0!dOHKwWO8$Z@;RE?*hFMO#0$BH^CXBw1N#kyUTjY6%w|+^LDrUHI|4h
zNm=mFPwym;9j1+6!&d3Hqa@kYA~$eb0=0r_;=MfA^r;Rfxt8}>t(s1E$37ENCQ5yl
z&$y6O8zC%Swxc7^;o!e>d=cymH30~)5+#1ch8wS~W^{Kcv8rM2a*3Qr+QmA`S8F_K
zeH3eZPUsU}oEeF1lebmuf?;|Hk6w7Nu~jE4p{*S)$GI@Ki6%b*7h}q95{W_KN_B}8
zWD>kQgl0WHsd)_f%T({FSNH<-)7q-MLc2)j>t!<@2x6uACH1(5W3cfgy8sQa4g8)-
zb^TtLAF8AM(yi+>wky{eb~1{6L0G+atdBm+V}SaQsZ2qsdd49b>H^jb`{RXp5w@3F
zdsy6=hr}a6m4d3qm2WKFOm90L)j;?0mSKh-^b^0_OAHmpT1B&x-xS}?Rt&Kh4dUj}
z=z|?6MzLOGv2$RH@m-?1fPMP7>VbB6`t1e{2z$_H**a@4IJb!^Wt>z~qHGkbTenTN
zX^O`Dm8LM;p>Ng`tX5~esWZ(peu6exsw8i^JsLCl=^hT+tzs)Rz9vhzGG*$MCxcSN
zxz*gHh^;Rhu#z+LDcjpr7dAu@G4l@c9G6ar=VK{5Un3Rlt)5or0PtiU(%~0-JNAT;
z170%TPNy6~^J)V3y?r_p2V+tpp6(KiP^&JIdP*xtVZ>1}*D)@-;E0o%>bgCvGj)3N
zS2{Ly*cGingevZb_SV=XX}r%#wpLlGa2bT2e~(3EJ4$cJzrg5cl|LGm&++}97LjwG
z!n(gAq9SlQrviBkaJXVvs1mPi7ZayQkG*!qD(2NwVY^_+v>Sa~n~4MiQJ!wC_B3xM
z_xC;7NPA2KYGO7dDXywr;A!~Mh|OifXitJ7W>O3GFhmxo)Fqx8={
zMelR%?ClI@Mm87qGG6F^I_OoBz4q)1qQkM0MT&Dx4Gky&d9DeHvgf#pSA1l0xm_)8
z-4`ehbSXnG{EqncATyr(n1Z0Xs(74`Q2sXyocuVZbGmI-CMVsZuX&(BfB(1dhKVep
zA85IXBFKh)Q-G|C
z)-07Qx4h{GXcuSocSQBX)|qjScxeLtDm{@Ta#2P(R5nDyL!=Bgb)W~Ao>|pz?i8IK
zEvAt;BQKm}@f*nvCbnVz=4!&z`05iHMr2=Uyy0kPtzqf>qgUKd+DBp;STIWg%3nPRbj-OjCspJ`LoY*=~}+^foC!)F@jt<0SJ!*ahzwZjX@6
zT>8{e8(E!DwMG(LL5NT%S!+iiU~>J3(tgACmu3|mq)Web6y!W7;Dca2*gOF|cO-~E
z`H*DjSs^MSkVopHmej{IT**vkbF|-2f$vKb-l#gyPh`b}
zpePN1?n0SU0+DtZhrF)iERJ}`a#`tzB7hl84=0$yFRmhsQ2o+Y)th`0S7e(kqt={w@40~0zS=snjeIlnn3mz9Nm*`AjC(eTjk
zp2EqEj8D3p47O_@`437@EDSwlr63y)DLtw0#nwwqp70U!)QUYF3rb5{l$0Rzt#UDJrY)Pr
zTznOmOFgvrz=UNV^5UtbtG?Zkh64nXt}>1Wri$H!FI!*HImbV24vT+HE;vk$bb7hf9}|3n|xrdWNY9Q4lS{3gnX(L@O}S~|ULfB$?)?7$~4d#0Q7saW2`
zGvh|j9+44oDT1bXvhWJYiljnF>RH&erzDMuL_OXaFGd~uT9kDWL0AB3mH`-Dv?JWN
zy+*_($(v>gVD1EkR+fm+wVmIQox9O!R^nwubpTJF({+3Z`zDi9?vU-X$sjhCuvFfx
zy``Eq0uf_ySpK-8i++g=ThsMM=+q0JvW+zRtGt_%4>My6v$5_n2_qC0sw{AXR=mlyfxmIHe#U
z?G>%0lu+=!&a3xkeQ~xY{jZd9D`F@;!OODZ3LM1EC(Bj#MGS~vCV&c-X3X@oaYM$5
zN5(=)0QGYUZ|yFg6XjQ#i*52;<}l&0IT^`~9@waIZ9$SKqrnDjTBR{{3z5b+7l83n
zk$6{|uUT1{!^Eih$@@_yCAxw_ZE<8kgYsiO%n7J-z94{_$!|`BA_wU?BDLD!)4kx?#E8Lk$T|
z%2HpbiP4+;3DY2OCti-woMLQh#!3|dRL94WTrJr=DexAA@T_}N#ni9ere5Qr{ilc`
zXtp!@b*59Z&BSWPtk!Uz>->jIhT5a2q6M1`ncwL_snFUdKo9eUJq(A6hco3(Zhwzl
zwPiL_Qa;{vhg!g@5v_H@{Y|P$lP||J85lnsz;IZ|qo}noGMSYRs#8C;1%D_bXqC0w
zwnLkfQteyYKyAWuMat-xz&Mzjfq%lRAJ~Ir`LdOf9y2^9lk2xcNa|cgHiIk1{GuOT
z&k{iE5&KgY5L$P6FVR_cIN705qS+xg6?@Cy5bDRUX@8!5^tplEWbn@U_s!XPNo5Cgb{gQQ
zJICz?UGpDgl4*Ks)O2`w5uH8aF4Kh3^)YEU>MOL-e|dC|-Oz%mq2OJGp-ox#%X-~N
zeVh&>QHMfvVZ%s?f}&i%ajVx1F9cm(WE3Y~zACw%F)>RNN9j(a)xF1g^SE>K?iJ3z
zPk6OC6nX@>7SWFlYme!#vFV9!ded8=dw$YJBbp6JPiznfeslg4M`D4wkhhs=0Rt_M
zulFfhjJJTtXKS~byqpmaOq11Nlmrx<`Emw^^_JQ@DHG_4kV17`fPo-{3J9C#@k-?>
z3q8Sy^jG^kE_{0Kk(Ij$_@V=~8PPKHw`J(sGh3*{9xvxV^Z5X_Gsw3aqiL%^*tuc%
zmuL!m#ILw*rRT{_v<4I&RlPOPL)~2(`pvel
z@D>@^#km}B(}e8htGsGWOt?jXUR?*uD`)wm@)7NTBvmRRZ7qJr%U{DoTWI-5BAxh0
zm50_F5FH&;-CwlfClJr8OBB#hjJ2JTan*pPHmO{=qYn4Z4`^8)e_nb9m}@LZ_$iG|
zaZC}ad+v5zD9b<>%myN&>wFqn-f8!dXwIh{Hr)FmxQ$HWeedP4bH>obK0XqSO$r$2
zNlYAYJWFcw#qoSh1w#uLW`^r`BVOw)(nQ0_HTR1!`1<8z7cUWqh?59x=Q=jgUQ#{I6~
zG&5p9y|0klv8{@$+{ydTG5L(iIk#ERV
zh$8vtDpUxy;5612?xp$PQtW@Ix_`4YTz?q6o56l_YhWW4!C+)47d`nD_WzoQvh>XQ
zNBQ5)5(vZ(`oGGg1b-_NA}?Rv~Nsd%}0hNME`G`kSRQ@SUJcl9t)oTrwaUo{uhoD(;v{AqCkU8gz{qx
zu>L(IM6N@Hk$1RnvHyuXSph+%6k
z$;3ljRUWNoa*1nhO7$UNGJ1JJhhda(8m)@gKkb?YPVYdwOi#Ykq^r9~XwiMMR;HrZ
z&~KNMKLVbnj{jW&=W^Qu2-cLUQPxQlV}KpPzJ;CxEQ6%sHVfqou9_h0@t(pnZHmQX
zNWE_e62HV&!b}eSbvv@8vX8@yv_X?D&U*u7iJ7XMx_P17M2vYa=Xr5){JkIWkZ!=Q
z9jMO7o3l@C8Qwvv0yp-}Vm&ZfRf|lDsfUqi#$AZYxRC$J3$d?wuDzY9CA?U(PoR4J
z%8CPj_W=^i*;2_+gt#3^grd`I2q1*Gs%b-pQf&2R?
z&i6-FR|dO8vI}NqW%#Bo?Z>br3=uG~Xxp-Fyl;`S&A>gydDiL;Bt+1;YD??h3C@@H
z@kT67kg6u{OZAhgN?OJ`8lBjZFAZ
z2s{u{rGJuu%Y*-`D*8;5NgkOYC`7;s`;i)M9nss`N@fg(^gYeTMQqFIcJy(Z?jCJp
z)h7f={|z2=ous6bYJUTKstS2})D!!(@4^gp&dK!qt<`2+mfkn|^{}(u^Nsg5i2aVz
zPa~#PaB{rw#66yf@MSbGkbUjG_cn8`*hmcWdu8dH4;a+*;qKI_4$&YQercH)A68}P
zlZtpUy!E(z6z~SJ)*et=UaCx3iMybZZ
zU6Wl9W7%a?+~^x5-cmPLQKsvbU1Vn~oMCYn$1qv_=q{~iK|z%v5-{X7Z&y8-CvFcB
z&sYEl+Z9KK&Ly@V_$e7RZ|TdYWv}6NSjTjIFr9^#BiH}3n
z^g5-2U)hrLD{53p2b#Uzp*yGiMRC@vIyZKeWSGC+*pf20kHCW@K(bZC*>p%g7G&{m
z$YFR7VEL{H5XlYtlD>aGR8L^ts3`yeGm?WhXkpeZ9(OWCIO`3!8xAh*bI`;$RLh?D
zVs4MAggQtJmx6d>(k>avlimEAzEliHzNPF}$VQ6}@%c*CSedlujEzE-T5x*}Y}#=9
zB-+b4ST8dQ#Uu#`{VvbrFJH4RpIz`sG_1I^-|Dx>8LC+h8Y@ouGvY(0f8=p$
z=JbB&QY%ba6CNTQ)_(A}^C3-XS^!FKS$FB8zn>(l2~(Ohq=cPW*EMS6v&*-a(`xUKcI;i$AC82KdsKzJn3v8aKEW(BosHw8AAz5>n}}iNV|GLf=2v?P
z`Pv3^6U0>GXwHm!ny%rOh=gAsx-XS@Q|^n<6&u&Ssw+*qc0wHB^D<60@F_|J8>ukd
zXn&bWr{4A?ko0?I!{pVme}qBb=eHjz;^fgz7*V;i=!jx2PBL-0;EwkO)Vl3al#G6NS#f<+?w
z@^+T-B=4)S2{daHxl5n=9l|mk8
zsC@wRz~-u=G0CH4TJrZVxWB(VxiS2D8jGYZUZ?@)1RfQtjEn(UO_=4z
z4tfy{;g*&$tt(P%QyDj{{q`9b80F>n(ru@SP>CFuh&i2WCsgAr5wY0aid(WN_BcY>
zt%&t77<8cuJNwYhX^QSCm5efl>VKE@!-iyMYowHZw??UNQ@qRjVzoGyh?X226U2Y#
znfwt?wSSl$^P{Y{*}>h<1NF}kOn7ql({C6xBf|pm(UG9!X+
znyR=>3H$WYd@}tE#!LgVuo8#R;UPF&Ht)qt2i!VD!v%558q@+H{uVZbYa3Oiel(^k
z2&<9~75SE80flL2jDMZw=xNWw*e56C)#x3CvHLLcf&JW^PzjI3jB8ohOZc
z#Bn$>>ncd>i%u-`5jrO=VKJZ+`efgSofi`9DJgu`!26vTv^?k!Nt5}`52EX;hcaNZ
z4xfzVZzC_aLDSyNZAVZ<;&CW!t-0~5cSR96(RQg@lJ2W19iaLs?8^z$|9&SD$x%Oh
z#)YJAx@ZU4W$sVWNVXj&Au<-H>5UsOozLR99wz{b)p!pDVb7Eb8|CH&fey#2+D7xL
zp(tsmBpbB?H9hDMacsj&2pbNq`B9l;yTQcW!R_)sLF{rwtQNvPS*vgZK~PKdmJ)GKWsB46pqbJnA?oQdqP
zj^a_$pE_L^qq3kUkAXl!1oIAE40_@BFv*Y3jgh|Bs0G&$9ddt(=z!I@yX5?~GRhb|
zuKAye-zUKZ^kMcky&C-ia_MYc
z&7~sDiu`*Ja>OfU{76@>H&8V32(3I^OEm6D41yUags30e!qyY7&@Sw|IS9Vc-_7`<
zdr=)!8ib#=#8`a6ODs=sSP!nCTB|=x17Gc#&SdrAoi&}n-Wu@1IGnfk3;x}$a{*5g!8e7zy
zJg4f7*Yuq{hv=%z*7yzwtBwX6@q3o9zplhz$W{1}In%;oMP+5M_sZHcg`(N{
zLz=gcI9$4D&lP#trJ$O-hbS9|iz_za1aG|{$E+t^H9fc2p`H#Xas4Gd!l0>8&n2hf
zo?sE;vNgW&K}&IVOb#TE2eq^>*`K4{B?)q3R;(Ur9&%iFtAEra8fBM!6)O|UC`H&v
zst1x=^h=A(FlP%VkBi8Z*F~^Tj^@^6E_SH%uB|_mGjvFUaYN(As>B$u#
zvjRa};O
zQ+t+Y(|Vvzc!Sp~qnx>))yM9g!gTv~W~@3@a|@*#E{>?K`i{pV$(c#!Dr(4#hOKNH
zX!EYHt3%_^B+xvWokgj(nmTW)Q~5WD?tJh3#-v=fyyj8Xgn4DhT%KZJaa<-A`_!ta
zLo0=1BWbX`nNhbShThz^>VS`cmKH84hALysiJ@!5_12Jo89O!wae7k|9tA=fk3%Xa
zKYc*F-dp%Nj&-n{wuClr{;lJ$Z4c&hus_hLZ=dykj0Ea!S)f;Nnh>#)qcI9uh%|l~
zTRF9^{~4SA#_AzLLztYTARr4
zA&Q*^gf0?;CjenXhOvSB)
z&aZ>}Lq>fj4+X3Y2nr6`gE3y}`F1`@I)a`!&ugx8#n|F2=k(oGrLBdydPHO*et(Gxk2H}R$FcdIgz7HrO)lB{
zZ5llw(Hkv)i&0|auiz`L`4<^{09Ap^wIDd_QS
zMJ1FZpG&C&5IY8;SYf1Nt$Bc8SpbWlegT5hg?_wQSF1J~?OczCE=p%RF5moojIiRP
zX@C1F;7O={cXHgV@wH6*#6h6^jq5UuO&VrucO`y;$NIx1paA}ir&XJv&d>ldX-LY1+pHA!@LB2uW?>Gwv=B>Gq9WWUdVEg+
zjrNMHo}P1n)%%8x##=f)DG&)VWwe0>Ig|RAu$bhv1A4E8cE0XkQ<0ZP!&B<}7Nt$y
zi-$cbBpo6nnuV#9vx~D6W0PR7#0>mxeNhK;>bwv{_c+}6qy3NK1Smuf6eR0ngb-8D
zIdRcInuHIp+t8Bf?GG{lU2T>x(ee}V6m2|EitwyC7%8n_-!kHmKIybD6#F8l
zcv3p>m-4_n$E$u`io$>Gl-s!GW8U{moCD}xtcuM!rDbVnJ7W;G@}cl5-To_7fWcTJ
z=eqemhH!E78~8kjMJx{d|lAX;@!9B&ILta?qO-H1>R}8F?gt7^#H`th*i1d
z$Zv$~(8G8klS99_n5PtN5-jz(g>EnjeXM&i@MEiE4Ry?3;U8
z-_=)yjmzqS$~2RC`9iiFMk*Fmj@rt8_4M8k9$=YUea
z_;H;(`;icvlK7pq9AXRd&*+d7g+exC0e=XxksdGGgz8YZuBG4G3MCV+YFmv&hIP${
z+GKexinWAt$xjvf6Aq@$tJ&r4+|8M7Xxm9-^^e2yt`54Krd>f5tYes2dX~She8gKz
z&28QIHx4uh9GZ`oc^${QI0`AJ#eQ#}x&IxXf1*%VTc#dF=?sVX@Jw&jS5S!{qDun)
zCcL2MbW&IoS&!QuQ%i9FlF&MO0*wD+!JwA((pdOC&CBMaOK_rZEwKD`MiZiBIsXRfU+`D
z!lx5Hn~_0n8HN6l$VO$bx=#@=b22D@C?NNP_7eW
zK`ohBp*{33sQ;bv@Bo1AbMYqdUkf=SeV!onmoZd;5*PD7*I7mJtY(KwF?0XRJ1BrZ
z{(=TFlfqL`J?n^}wam<%a>3-1p3jc@OG<
-## 4. How to use IDs? Where to get the access_hash? Why the error `CHANNEL_INVALID` or `USER_ID_INVALID`?
+## 4. How to use IDs and access_hash? Why the error `CHANNEL_INVALID` or `USER_ID_INVALID`?
-Having only the ID is **not enough**: An `access_hash` is required by Telegram when dealing with a channel, user, photo, document, etc...
-This serves as a proof that the logged-in user is entitled to access it (otherwise, anybody with the ID could access it)
+⚠️ In Telegram Client API *(contrary to Bot API)*, you **cannot** interact with channels/users/etc. with only their IDs.
+
+You also need to obtain their `access_hash` which is specific to the resource you want to access AND to the currently logged-in user.
+This serves as a proof that the logged-in user is entitled to access that channel/user/photo/document/...
+(otherwise, anybody with the ID could access it)
> A small private `Chat` don't need an access_hash and can be queried using their `chat_id` only.
However most common chat groups are not `Chat` but a `Channel` supergroup (without the `broadcast` flag). See [Terminology in ReadMe](README.md#terminology).
Some TL methods only applies to private `Chat`, some only applies to `Channel` and some to both.
The `access_hash` must usually be provided within the `Input...` structure you pass in argument to an API method (`InputPeer`, `InputChannel`, `InputUser`, etc...).
-You obtain the `access_hash` through **description structures** like `Channel`, `User`, `Photo`, `Document` that you receive through updates or when you query them through API methods like `Messages_GetAllChats`, `Messages_GetAllDialogs`, `Contacts_ResolveUsername`, etc...
-*(if you have a `Peer` object, you can convert it to a `User`/`Channel`/`Chat` via the `UserOrChat` helper from the root class that contained the peer)*
-Once you obtained the description structure, there are 3 methods for building your `Input...` request structure:
-* **Recommended:** If you take a look at the **description structure** base class `ChatBase/UserBase`,
-you will see that they have conversion implicit operators or methods that can create the `Input...` structure for you automatically.
-So you can just pass that structure you already have, in place of the `Input...` argument, it will work!
-* Alternatively, you can manually create the `Input...` structure yourself by extracting the `access_hash` from the **description structure**
-* If you have enabled the [CollectAccessHash system](EXAMPLES.md#collect-access-hash) at the start of your session, it will have collected the `access_hash` automatically when you obtained the description structure.
-You can then retrieve it with `client.GetAccessHashFor(id)`
+You obtain the `access_hash` through TL **description structures** like `Channel`, `User`, `Photo`, `Document` that you receive through updates
+or when you query them through API methods like `Messages_GetAllChats`, `Messages_GetAllDialogs`, `Contacts_ResolveUsername`, etc...
-⚠️ *An `access_hash` obtained from a User/Channel structure with flag `min` may not be usable for most requests. See [Min constructors](https://core.telegram.org/api/min).*
+You can use the [`UserOrChat` and `CollectUsersChats` methods](EXAMPLES.md#collect-users-chats) to help you in obtaining/collecting
+the description structures you receive via API calls or updates.
+
+Once you obtained the description structure, there are 2 methods for building your `Input...` request structure:
+* **Recommended:** Just pass that description structure you already have, in place of the `Input...` argument, it will work!
+*The implicit conversion operators on base classes like `ChatBase/UserBase` will create the `Input...` structure for you automatically.*
+* Alternatively, you can manually create the `Input...` structure yourself by extracting the `access_hash` from the description structure
+
+*Note: An `access_hash` obtained from a User/Channel structure with flag `min` may not be usable for most requests. See [Min constructors](https://core.telegram.org/api/min).*
## 5. I need to test a feature that has been recently developed but seems not available in my program
diff --git a/README.md b/README.md
index e40d404..4a2b470 100644
--- a/README.md
+++ b/README.md
@@ -89,7 +89,7 @@ Its `int` argument is the log severity, compatible with the [LogLevel enum](http
Since version 3.0.0, a new approach to login/configuration has been added. Some people might find it easier to deal with:
```csharp
-WTelegram.Client client = new WTelegram.Client(YOUR_API_ID, "YOUR_API_HASH");
+WTelegram.Client client = new WTelegram.Client(YOUR_API_ID, "YOUR_API_HASH"); // this constructor doesn't need a Config method
await DoLogin("+12025550156"); // initial call with user's phone_number
async Task DoLogin(string loginInfo) // (add this method to your code)
From f86291117f2c6fbb9659f3434226a2d49e659326 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Sat, 4 Feb 2023 10:36:19 +0100
Subject: [PATCH 007/304] API Layer 152: emoji pfp, autosave medias,
auto-translations, media permissions, Firebase...
---
EXAMPLES.md | 1 +
README.md | 2 +-
src/Client.cs | 102 +++++++-------
src/TL.Schema.cs | 248 ++++++++++++++++++++++++++++++---
src/TL.SchemaFuncs.cs | 275 +++++++++++++++++++++++++++++++------
src/TL.Table.cs | 34 ++++-
src/WTelegramClient.csproj | 2 +-
7 files changed, 547 insertions(+), 117 deletions(-)
diff --git a/EXAMPLES.md b/EXAMPLES.md
index c871113..ff7700d 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -373,6 +373,7 @@ var chatInvite = await client.Messages_CheckChatInvite("HASH"); // optional: get
await client.Messages_ImportChatInvite("HASH"); // join the channel/group
// Note: This works also with HASH invite links from public channel/group
```
+Note: `CheckChatInvite` can return [3 different types of invitation object](https://corefork.telegram.org/type/ChatInvite)
## Add/Invite/Remove someone in a chat
diff --git a/README.md b/README.md
index 4a2b470..edd746b 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[](https://corefork.telegram.org/methods)
+[](https://corefork.telegram.org/methods)
[](https://www.nuget.org/packages/WTelegramClient/)
[](https://dev.azure.com/wiz0u/WTelegramClient/_build?definitionId=7)
[](http://t.me/WTelegramBot?start=donate)
diff --git a/src/Client.cs b/src/Client.cs
index 7918d1f..b0c76b0 100644
--- a/src/Client.cs
+++ b/src/Client.cs
@@ -1016,29 +1016,31 @@ namespace WTelegram
User = null;
}
phone_number ??= Config("phone_number");
- Auth_SentCode sentCode;
+ Auth_SentCodeBase sentCodeBase;
#pragma warning disable CS0618 // Auth_* methods are marked as obsolete
try
{
- sentCode = await this.Auth_SendCode(phone_number, _session.ApiId, _apiHash ??= Config("api_hash"), settings ??= new());
+ sentCodeBase = await this.Auth_SendCode(phone_number, _session.ApiId, _apiHash ??= Config("api_hash"), settings ??= new());
}
catch (RpcException ex) when (ex.Code == 500 && ex.Message == "AUTH_RESTART")
{
- sentCode = await this.Auth_SendCode(phone_number, _session.ApiId, _apiHash, settings);
+ sentCodeBase = await this.Auth_SendCode(phone_number, _session.ApiId, _apiHash, settings);
}
Auth_AuthorizationBase authorization = null;
+ string phone_code_hash = null;
try
{
- if (sentCode.type is Auth_SentCodeTypeSetUpEmailRequired setupEmail)
+ if (sentCodeBase is Auth_SentCode { type: Auth_SentCodeTypeSetUpEmailRequired setupEmail } setupSentCode)
{
+ phone_code_hash = setupSentCode.phone_code_hash;
Helpers.Log(3, "A login email is required");
- RaiseUpdate(sentCode);
+ RaiseUpdate(sentCodeBase);
var email = _config("email");
if (string.IsNullOrEmpty(email))
- sentCode = await this.Auth_ResendCode(phone_number, sentCode.phone_code_hash);
+ sentCodeBase = await this.Auth_ResendCode(phone_number, phone_code_hash);
else
{
- var purpose = new EmailVerifyPurposeLoginSetup { phone_number = phone_number, phone_code_hash = sentCode.phone_code_hash };
+ var purpose = new EmailVerifyPurposeLoginSetup { phone_number = phone_number, phone_code_hash = phone_code_hash };
if (email is not "Google" and not "Apple")
{
var sentEmail = await this.Account_SendVerifyEmailCode(purpose, email);
@@ -1063,55 +1065,61 @@ namespace WTelegram
if (retry >= MaxCodePwdAttempts) throw;
}
if (verified is Account_EmailVerifiedLogin verifiedLogin) // (it should always be)
- sentCode = verifiedLogin.sent_code;
+ sentCodeBase = verifiedLogin.sent_code;
}
}
resent:
- 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);
- for (int retry = 1; authorization == null; retry++)
- try
- {
- var verification_code = await ConfigAsync("verification_code");
- if (verification_code == "" && sentCode.next_type != 0)
+ if (sentCodeBase is Auth_SentCodeSuccess success)
+ authorization = success.authorization;
+ else if (sentCodeBase is Auth_SentCode sentCode)
+ {
+ 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);
+ for (int retry = 1; authorization == null; retry++)
+ try
{
- var mustWait = timeout - DateTime.UtcNow;
- if (mustWait.Ticks > 0)
+ var verification_code = await ConfigAsync("verification_code");
+ if (verification_code == "" && sentCode.next_type != 0)
{
- Helpers.Log(3, $"You must wait {(int)(mustWait.TotalSeconds + 0.5)} more seconds before requesting the code to be sent via {sentCode.next_type}");
- continue;
+ var mustWait = timeout - DateTime.UtcNow;
+ if (mustWait.Ticks > 0)
+ {
+ Helpers.Log(3, $"You must wait {(int)(mustWait.TotalSeconds + 0.5)} more seconds before requesting the code to be sent via {sentCode.next_type}");
+ continue;
+ }
+ sentCodeBase = await this.Auth_ResendCode(phone_number, phone_code_hash);
+ goto resent;
}
- sentCode = await this.Auth_ResendCode(phone_number, sentCode.phone_code_hash);
- goto resent;
+ authorization = await this.Auth_SignIn(phone_number, phone_code_hash, verification_code);
}
- authorization = await this.Auth_SignIn(phone_number, sentCode.phone_code_hash, verification_code);
- }
- catch (RpcException e) when (e.Code == 400 && e.Message == "PHONE_CODE_INVALID")
- {
- Helpers.Log(4, "Wrong verification code!");
- if (retry >= MaxCodePwdAttempts) throw;
- }
- catch (RpcException e) when (e.Code == 401 && e.Message == "SESSION_PASSWORD_NEEDED")
- {
- for (int pwdRetry = 1; authorization == null; pwdRetry++)
- try
- {
- var accountPassword = await this.Account_GetPassword();
- RaiseUpdate(accountPassword);
- var checkPasswordSRP = await Check2FA(accountPassword, () => ConfigAsync("password"));
- authorization = await this.Auth_CheckPassword(checkPasswordSRP);
- }
- catch (RpcException pe) when (pe.Code == 400 && pe.Message == "PASSWORD_HASH_INVALID")
- {
- Helpers.Log(4, "Wrong password!");
- if (pwdRetry >= MaxCodePwdAttempts) throw;
- }
- }
+ catch (RpcException e) when (e.Code == 400 && e.Message == "PHONE_CODE_INVALID")
+ {
+ Helpers.Log(4, "Wrong verification code!");
+ if (retry >= MaxCodePwdAttempts) throw;
+ }
+ catch (RpcException e) when (e.Code == 401 && e.Message == "SESSION_PASSWORD_NEEDED")
+ {
+ for (int pwdRetry = 1; authorization == null; pwdRetry++)
+ try
+ {
+ var accountPassword = await this.Account_GetPassword();
+ RaiseUpdate(accountPassword);
+ var checkPasswordSRP = await Check2FA(accountPassword, () => ConfigAsync("password"));
+ authorization = await this.Auth_CheckPassword(checkPasswordSRP);
+ }
+ catch (RpcException pe) when (pe.Code == 400 && pe.Message == "PASSWORD_HASH_INVALID")
+ {
+ Helpers.Log(4, "Wrong password!");
+ if (pwdRetry >= MaxCodePwdAttempts) throw;
+ }
+ }
+ }
}
catch (Exception ex) when (ex is not RpcException { Message: "FLOOD_WAIT_X" })
{
- try { await this.Auth_CancelCode(phone_number, sentCode.phone_code_hash); } catch { }
+ try { await this.Auth_CancelCode(phone_number, phone_code_hash); } catch { }
throw;
}
if (authorization is Auth_AuthorizationSignUpRequired signUpRequired)
@@ -1122,7 +1130,7 @@ namespace WTelegram
var last_name = Config("last_name");
var wait = waitUntil - DateTime.UtcNow;
if (wait > TimeSpan.Zero) await Task.Delay(wait); // we get a FLOOD_WAIT_3 if we SignUp too fast
- authorization = await this.Auth_SignUp(phone_number, sentCode.phone_code_hash, first_name, last_name);
+ authorization = await this.Auth_SignUp(phone_number, phone_code_hash, first_name, last_name);
}
#pragma warning restore CS0618
LoginAlreadyDone(authorization);
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index 92f176b..a62ef21 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -452,7 +452,7 @@ namespace TL
/// a value means inputChatPhotoEmpty
public abstract class InputChatPhotoBase : IObject { }
/// New photo to be set as group profile photo. See
- [TLDef(0xC642724E)]
+ [TLDef(0xBDCDAEC0)]
public class InputChatUploadedPhoto : InputChatPhotoBase
{
/// Flags, see TL conditional fields
@@ -463,6 +463,7 @@ namespace TL
[IfFlag(1)] public InputFileBase video;
/// Timestamp that should be shown as static preview to the user (seconds)
[IfFlag(2)] public double video_start_ts;
+ [IfFlag(3)] public VideoSizeBase video_emoji_markup;
[Flags] public enum Flags : uint
{
@@ -472,6 +473,8 @@ namespace TL
has_video = 0x2,
/// Field has a value
has_video_start_ts = 0x4,
+ /// Field has a value
+ has_video_emoji_markup = 0x8,
}
}
/// Existing photo to be set as a chat profile photo. See
@@ -1169,6 +1172,7 @@ namespace TL
has_requests_pending = 0x20000,
/// Field has a value
has_available_reactions = 0x40000,
+ translations_disabled = 0x80000,
}
/// ID of the chat
@@ -1353,6 +1357,7 @@ namespace TL
can_delete_channel = 0x1,
antispam = 0x2,
participants_hidden = 0x4,
+ translations_disabled = 0x8,
}
/// ID of the channel
@@ -2213,6 +2218,13 @@ namespace TL
/// See
[TLDef(0xE7E75F97)]
public class MessageActionAttachMenuBotAllowed : MessageAction { }
+ /// See
+ [TLDef(0xFE77345D)]
+ public class MessageActionRequestedPeer : MessageAction
+ {
+ public int button_id;
+ public Peer peer;
+ }
/// Chat info. See Derived classes: ,
public abstract class DialogBase : IObject
@@ -2332,7 +2344,7 @@ namespace TL
/// Available sizes for download
public PhotoSizeBase[] sizes;
/// For animated profiles, the MPEG4 videos
- [IfFlag(1)] public VideoSize[] video_sizes;
+ [IfFlag(1)] public VideoSizeBase[] video_sizes;
/// DC ID to use for download
public int dc_id;
@@ -2457,9 +2469,11 @@ namespace TL
}
}
+ /// Contains info on a confirmation code message sent via SMS, phone call or Telegram. See Derived classes:
+ public abstract class Auth_SentCodeBase : IObject { }
/// Contains info about a sent verification code. See
[TLDef(0x5E002502)]
- public class Auth_SentCode : IObject
+ public class Auth_SentCode : Auth_SentCodeBase
{
/// Flags, see TL conditional fields
public Flags flags;
@@ -2480,11 +2494,17 @@ namespace TL
has_timeout = 0x4,
}
}
+ /// See
+ [TLDef(0x2390FE44)]
+ public class Auth_SentCodeSuccess : Auth_SentCodeBase
+ {
+ public Auth_AuthorizationBase authorization;
+ }
/// Object contains info on user authorization. See Derived classes: ,
public abstract class Auth_AuthorizationBase : IObject { }
/// Contains user authorization info. See
- [TLDef(0x33FB7BB8)]
+ [TLDef(0x2EA2C0D4)]
public class Auth_Authorization : Auth_AuthorizationBase
{
/// Flags, see TL conditional fields
@@ -2493,6 +2513,7 @@ namespace TL
[IfFlag(1)] public int otherwise_relogin_days;
/// Temporary passport sessions
[IfFlag(0)] public int tmp_sessions;
+ [IfFlag(2)] public byte[] future_auth_token;
/// Info on authorized user
public UserBase user;
@@ -2502,6 +2523,8 @@ namespace TL
has_tmp_sessions = 0x1,
/// Suggests the user to set up a 2-step verification password to be able to log in again
setup_password_required = 0x2,
+ /// Field has a value
+ has_future_auth_token = 0x4,
}
}
/// An account with this phone number doesn't exist on telegram: the user has to enter basic information and sign up See
@@ -2837,6 +2860,7 @@ namespace TL
has_personal_photo = 0x200000,
/// Field has a value
has_fallback_photo = 0x400000,
+ translations_disabled = 0x800000,
}
}
@@ -4414,6 +4438,9 @@ namespace TL
{
public long user_id;
}
+ /// See
+ [TLDef(0xEC05B097)]
+ public class UpdateAutoSaveSettings : Update { }
/// Updates state. See
[TLDef(0xA56C2A3E)]
@@ -5377,7 +5404,7 @@ namespace TL
/// Thumbnails
[IfFlag(0)] public PhotoSizeBase[] thumbs;
/// Video thumbnails
- [IfFlag(1)] public VideoSize[] video_thumbs;
+ [IfFlag(1)] public VideoSizeBase[] video_thumbs;
/// DC ID
public int dc_id;
/// Attributes
@@ -6574,6 +6601,13 @@ namespace TL
public class KeyboardButtonSimpleWebView : KeyboardButtonWebView
{
}
+ /// See
+ [TLDef(0x0D0B468C, inheritBefore = true)]
+ public class KeyboardButtonRequestPeer : KeyboardButton
+ {
+ public int button_id;
+ public RequestPeerType peer_type;
+ }
/// Inline keyboard row See
[TLDef(0x77608B83)]
@@ -7863,6 +7897,21 @@ namespace TL
{
public string url;
}
+ /// See
+ [TLDef(0xE57B1432)]
+ public class Auth_SentCodeTypeFirebaseSms : Auth_SentCodeTypeSms
+ {
+ public Flags flags;
+ [IfFlag(0)] public byte[] nonce;
+ [IfFlag(1)] public string receipt;
+ [IfFlag(1)] public int push_timeout;
+
+ [Flags] public enum Flags : uint
+ {
+ has_nonce = 0x1,
+ has_receipt = 0x2,
+ }
+ }
/// Callback answer sent by the bot in response to a button press See
[TLDef(0x36585EA4)]
@@ -11378,6 +11427,13 @@ namespace TL
/// If set, does not allow any user to pin messages in a supergroup/chat
pin_messages = 0x20000,
manage_topics = 0x40000,
+ send_photos = 0x80000,
+ send_videos = 0x100000,
+ send_roundvideos = 0x200000,
+ send_audios = 0x400000,
+ send_voices = 0x800000,
+ send_docs = 0x1000000,
+ send_plain = 0x2000000,
}
}
@@ -11419,13 +11475,15 @@ namespace TL
}
/// Settings used by telegram servers for sending the confirm code. See
- [TLDef(0x8A6469C2)]
+ [TLDef(0xAD253D78)]
public class CodeSettings : IObject
{
/// Flags, see TL conditional fields
public Flags flags;
/// Previously stored logout tokens, see the documentation for more info »
[IfFlag(6)] public byte[][] logout_tokens;
+ [IfFlag(8)] public string token;
+ [IfFlag(8)] public bool app_sandbox;
[Flags] public enum Flags : uint
{
@@ -11439,6 +11497,9 @@ namespace TL
allow_missed_call = 0x20,
/// Field has a value
has_logout_tokens = 0x40,
+ allow_firebase = 0x80,
+ /// Field has a value
+ has_token = 0x100,
}
}
@@ -12241,9 +12302,11 @@ namespace TL
public IPeerInfo UserOrChat => peer?.UserOrChat(users, chats);
}
+ /// Represents an animated video thumbnail See Derived classes:
+ public abstract class VideoSizeBase : IObject { }
/// Animated profile picture in MPEG4 format See
[TLDef(0xDE33B094)]
- public class VideoSize : IObject
+ public class VideoSize : VideoSizeBase
{
/// Flags, see TL conditional fields
public Flags flags;
@@ -12264,6 +12327,21 @@ namespace TL
has_video_start_ts = 0x1,
}
}
+ /// See
+ [TLDef(0xF85C413C)]
+ public class VideoSizeEmojiMarkup : VideoSizeBase
+ {
+ public long emoji_id;
+ public int[] background_colors;
+ }
+ /// See
+ [TLDef(0x0DA082FE)]
+ public class VideoSizeStickerMarkup : VideoSizeBase
+ {
+ public InputStickerSet stickerset;
+ public long sticker_id;
+ public int[] background_colors;
+ }
/// Information about an active user in a supergroup See
[TLDef(0x9D04AF9B)]
@@ -13354,19 +13432,6 @@ namespace TL
public AvailableReaction[] reactions;
}
- /// Translated text, or no result See Derived classes: ,
- public abstract class Messages_TranslatedText : IObject { }
- /// No translation is available See
- [TLDef(0x67CA4737)]
- public class Messages_TranslateNoResult : Messages_TranslatedText { }
- /// Translated text See
- [TLDef(0xA214F7D0)]
- public class Messages_TranslateResultText : Messages_TranslatedText
- {
- /// Translated text
- public string text;
- }
-
/// How a certain peer reacted to the message See
[TLDef(0xB156FE9C)]
public class MessagePeerReaction : IObject
@@ -13685,6 +13750,7 @@ namespace TL
{
/// Pass true if this is a restore of a Telegram Premium purchase; only for the App Store
restore = 0x1,
+ upgrade = 0x2,
}
}
/// Info about a gifted Telegram Premium purchase See
@@ -13867,15 +13933,16 @@ namespace TL
public class Account_EmailVerifiedLogin : Account_EmailVerified
{
/// Info about the sent login code
- public Auth_SentCode sent_code;
+ public Auth_SentCodeBase sent_code;
}
/// Describes a Telegram Premium subscription option See
- [TLDef(0xB6F11EBE)]
+ [TLDef(0x5F2D1DF2)]
public class PremiumSubscriptionOption : IObject
{
/// Flags, see TL conditional fields
public Flags flags;
+ [IfFlag(3)] public string transaction;
/// Duration of subscription in months
public int months;
/// Three-letter ISO 4217 currency code
@@ -13893,6 +13960,8 @@ namespace TL
has_store_product = 0x1,
current = 0x2,
can_purchase_upgrade = 0x4,
+ /// Field has a value
+ has_transaction = 0x8,
}
}
@@ -14041,4 +14110,139 @@ namespace TL
public string url;
public DateTime expires;
}
+
+ /// See
+ public abstract class RequestPeerType : IObject { }
+ /// See
+ [TLDef(0x5F3B8A00)]
+ public class RequestPeerTypeUser : RequestPeerType
+ {
+ public Flags flags;
+ [IfFlag(0)] public bool bot;
+ [IfFlag(1)] public bool premium;
+
+ [Flags] public enum Flags : uint
+ {
+ has_bot = 0x1,
+ has_premium = 0x2,
+ }
+ }
+ /// See
+ [TLDef(0xC9F06E1B)]
+ public class RequestPeerTypeChat : RequestPeerType
+ {
+ public Flags flags;
+ [IfFlag(3)] public bool has_username;
+ [IfFlag(4)] public bool forum;
+ [IfFlag(1)] public ChatAdminRights user_admin_rights;
+ [IfFlag(2)] public ChatAdminRights bot_admin_rights;
+
+ [Flags] public enum Flags : uint
+ {
+ creator = 0x1,
+ has_user_admin_rights = 0x2,
+ has_bot_admin_rights = 0x4,
+ has_has_username = 0x8,
+ has_forum = 0x10,
+ bot_participant = 0x20,
+ }
+ }
+ /// See
+ [TLDef(0x339BEF6C)]
+ public class RequestPeerTypeBroadcast : RequestPeerType
+ {
+ public Flags flags;
+ [IfFlag(3)] public bool has_username;
+ [IfFlag(1)] public ChatAdminRights user_admin_rights;
+ [IfFlag(2)] public ChatAdminRights bot_admin_rights;
+
+ [Flags] public enum Flags : uint
+ {
+ creator = 0x1,
+ has_user_admin_rights = 0x2,
+ has_bot_admin_rights = 0x4,
+ has_has_username = 0x8,
+ }
+ }
+
+ /// See
+ /// a value means emojiListNotModified
+ [TLDef(0x7A1E11D1)]
+ public class EmojiList : IObject
+ {
+ public long hash;
+ public long[] document_id;
+ }
+
+ /// See
+ [TLDef(0x7A9ABDA9)]
+ public class EmojiGroup : IObject
+ {
+ public string title;
+ public long icon_emoji_id;
+ public string[] emoticons;
+ }
+
+ /// See
+ /// a value means messages.emojiGroupsNotModified
+ [TLDef(0x881FB94B)]
+ public class Messages_EmojiGroups : IObject
+ {
+ public int hash;
+ public EmojiGroup[] groups;
+ }
+
+ /// See
+ [TLDef(0x751F3146)]
+ public class TextWithEntities : IObject
+ {
+ public string text;
+ public MessageEntity[] entities;
+ }
+
+ /// Translated text, or no result See Derived classes: ,
+ public abstract class Messages_TranslatedText : IObject { }
+ /// See
+ [TLDef(0x33DB32F8)]
+ public class Messages_TranslateResult : Messages_TranslatedText
+ {
+ public TextWithEntities[] result;
+ }
+
+ /// See
+ [TLDef(0xC84834CE)]
+ public class AutoSaveSettings : IObject
+ {
+ public Flags flags;
+ [IfFlag(2)] public long video_max_size;
+
+ [Flags] public enum Flags : uint
+ {
+ photos = 0x1,
+ videos = 0x2,
+ has_video_max_size = 0x4,
+ }
+ }
+
+ /// See
+ [TLDef(0x81602D47)]
+ public class AutoSaveException : IObject
+ {
+ public Peer peer;
+ public AutoSaveSettings settings;
+ }
+
+ /// See
+ [TLDef(0x4C3E069D)]
+ public class Account_AutoSaveSettings : IObject, IPeerResolver
+ {
+ public AutoSaveSettings users_settings;
+ public AutoSaveSettings chats_settings;
+ public AutoSaveSettings broadcasts_settings;
+ public AutoSaveException[] exceptions;
+ public Dictionary chats;
+ public Dictionary users;
+ /// returns a or for the given Peer
+ public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats);
+ }
}
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index a940a30..de02856 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -98,7 +98,7 @@ namespace TL
/// Application secret hash (see App configuration)
/// Settings for the code type to send
[Obsolete("Use LoginUserIfNeeded instead of this method. See https://wiz0u.github.io/WTelegramClient/FAQ#tlsharp")]
- public static Task Auth_SendCode(this Client client, string phone_number, int api_id, string api_hash, CodeSettings settings)
+ public static Task Auth_SendCode(this Client client, string phone_number, int api_id, string api_hash, CodeSettings settings)
=> client.Invoke(new Auth_SendCode
{
phone_number = phone_number,
@@ -224,7 +224,7 @@ namespace TL
/// The phone number
/// The phone code hash obtained from Auth_SendCode
[Obsolete("Use LoginUserIfNeeded instead of this method. See https://wiz0u.github.io/WTelegramClient/FAQ#tlsharp")]
- public static Task Auth_ResendCode(this Client client, string phone_number, string phone_code_hash)
+ public static Task Auth_ResendCode(this Client client, string phone_number, string phone_code_hash)
=> client.Invoke(new Auth_ResendCode
{
phone_number = phone_number,
@@ -295,6 +295,17 @@ namespace TL
web_auth_token = web_auth_token,
});
+ /// See
+ public static Task Auth_RequestFirebaseSms(this Client client, string phone_number, string phone_code_hash, string safety_net_token = null, string ios_push_secret = null)
+ => client.Invoke(new Auth_RequestFirebaseSms
+ {
+ flags = (Auth_RequestFirebaseSms.Flags)((safety_net_token != null ? 0x1 : 0) | (ios_push_secret != null ? 0x2 : 0)),
+ phone_number = phone_number,
+ phone_code_hash = phone_code_hash,
+ safety_net_token = safety_net_token,
+ ios_push_secret = ios_push_secret,
+ });
+
/// Register device to receive PUSH notifications See Possible codes: 400 (details)
/// Avoid receiving (silent and invisible background) notifications. Useful to save battery.
/// Device token type, see PUSH updates for the possible values.
@@ -453,7 +464,7 @@ namespace TL
/// Verify a new phone number to associate to the current account See Possible codes: 400,406 (details)
/// New phone number
/// Phone code settings
- public static Task Account_SendChangePhoneCode(this Client client, string phone_number, CodeSettings settings)
+ public static Task Account_SendChangePhoneCode(this Client client, string phone_number, CodeSettings settings)
=> client.Invoke(new Account_SendChangePhoneCode
{
phone_number = phone_number,
@@ -521,7 +532,7 @@ namespace TL
/// Send confirmation code to cancel account deletion, for more info click here » See Possible codes: 400 (details)
/// The hash from the service notification, for more info click here »
/// Phone code settings
- public static Task Account_SendConfirmPhoneCode(this Client client, string hash, CodeSettings settings)
+ public static Task Account_SendConfirmPhoneCode(this Client client, string hash, CodeSettings settings)
=> client.Invoke(new Account_SendConfirmPhoneCode
{
hash = hash,
@@ -631,7 +642,7 @@ namespace TL
/// Send the verification phone code for telegram passport. See Possible codes: 400 (details)
/// The phone number to verify
/// Phone code settings
- public static Task Account_SendVerifyPhoneCode(this Client client, string phone_number, CodeSettings settings)
+ public static Task Account_SendVerifyPhoneCode(this Client client, string phone_number, CodeSettings settings)
=> client.Invoke(new Account_SendVerifyPhoneCode
{
phone_number = phone_number,
@@ -1066,6 +1077,43 @@ namespace TL
active = active,
});
+ /// See
+ /// a null value means emojiListNotModified
+ public static Task Account_GetDefaultProfilePhotoEmojis(this Client client, long hash = default)
+ => client.Invoke(new Account_GetDefaultProfilePhotoEmojis
+ {
+ hash = hash,
+ });
+
+ /// See
+ /// a null value means emojiListNotModified
+ public static Task Account_GetDefaultGroupPhotoEmojis(this Client client, long hash = default)
+ => client.Invoke(new Account_GetDefaultGroupPhotoEmojis
+ {
+ hash = hash,
+ });
+
+ /// See
+ public static Task Account_GetAutoSaveSettings(this Client client)
+ => client.Invoke(new Account_GetAutoSaveSettings
+ {
+ });
+
+ /// See
+ public static Task Account_SaveAutoSaveSettings(this Client client, AutoSaveSettings settings, InputPeer peer = null, bool users = false, bool chats = false, bool broadcasts = false)
+ => client.Invoke(new Account_SaveAutoSaveSettings
+ {
+ flags = (Account_SaveAutoSaveSettings.Flags)((peer != null ? 0x8 : 0) | (users ? 0x1 : 0) | (chats ? 0x2 : 0) | (broadcasts ? 0x4 : 0)),
+ peer = peer,
+ settings = settings,
+ });
+
+ /// See
+ public static Task Account_DeleteAutoSaveExceptions(this Client client)
+ => client.Invoke(new Account_DeleteAutoSaveExceptions
+ {
+ });
+
/// Returns basic user info according to their identifiers. See [bots: ✓] Possible codes: 400 (details)
/// List of user identifiers
public static Task Users_GetUsers(this Client client, params InputUserBase[] id)
@@ -1455,7 +1503,7 @@ namespace TL
/// The destination where the message will be sent
/// The message ID to which this message will reply to
/// The message
- /// Unique client message ID required to prevent message resending
+ /// Unique client message ID required to prevent message resending You can use
/// Reply markup for sending bot buttons
/// Message entities for sending styled text
/// Scheduled message date for scheduled messages
@@ -1485,7 +1533,7 @@ namespace TL
/// Message ID to which this message should reply to
/// Attached media
/// Caption
- /// Random ID to avoid resending the same message
+ /// Random ID to avoid resending the same message You can use
/// Reply markup for bot keyboards
/// Message entities for styled text
/// Scheduled message date for scheduled messages
@@ -1515,7 +1563,7 @@ namespace TL
/// Only for bots, disallows further re-forwarding and saving of the messages, even if the destination chat doesn't have content protection enabled
/// Source of messages
/// IDs of messages
- /// Random ID to prevent resending of messages
+ /// Random ID to prevent resending of messages You can use
/// Destination peer
/// Scheduled message date for scheduled messages
/// Forward the messages as the specified peer
@@ -1701,7 +1749,7 @@ namespace TL
/// Sends a text message to a secret chat. See Possible codes: 400,403 (details)
/// Send encrypted message without a notification
/// Secret chat ID
- /// Unique client message ID, necessary to avoid message resending
+ /// Unique client message ID, necessary to avoid message resending You can use
/// TL-serialization of type, encrypted with a key that was created during chat initialization
public static Task Messages_SendEncrypted(this Client client, InputEncryptedChat peer, long random_id, byte[] data, bool silent = false)
=> client.Invoke(new Messages_SendEncrypted
@@ -1715,7 +1763,7 @@ namespace TL
/// Sends a message with a file attachment to a secret chat See Possible codes: 400 (details)
/// Whether to send the file without triggering a notification
/// Secret chat ID
- /// Unique client message ID necessary to prevent message resending
+ /// Unique client message ID necessary to prevent message resending You can use
/// TL-serialization of type, encrypted with a key generated during chat initialization
/// File attachment for the secret chat
public static Task Messages_SendEncryptedFile(this Client client, InputEncryptedChat peer, long random_id, byte[] data, InputEncryptedFileBase file, bool silent = false)
@@ -1730,7 +1778,7 @@ namespace TL
/// Sends a service message to a secret chat. See Possible codes: 400,403 (details)
/// Secret chat ID
- /// Unique client message ID required to prevent message resending
+ /// Unique client message ID required to prevent message resending You can use
/// TL-serialization of type, encrypted with a key generated during chat initialization
public static Task Messages_SendEncryptedService(this Client client, InputEncryptedChat peer, long random_id, byte[] data)
=> client.Invoke(new Messages_SendEncryptedService
@@ -1861,7 +1909,7 @@ namespace TL
/// Start a conversation with a bot using a deep linking parameter See Possible codes: 400,403,500 (details)
/// The bot
/// The chat where to start the bot, can be the bot's private chat or a group
- /// Random ID to avoid resending the same message
+ /// Random ID to avoid resending the same message You can use
/// Deep linking parameter
public static Task Messages_StartBot(this Client client, InputUserBase bot, InputPeer peer, long random_id, string start_param)
=> client.Invoke(new Messages_StartBot
@@ -2014,7 +2062,7 @@ namespace TL
/// Whether to hide the via @botname in the resulting message (only for bot usernames encountered in the )
/// Destination
/// ID of the message this message should reply to
- /// Random ID to avoid resending the same query
+ /// Random ID to avoid resending the same query You can use
/// Query ID from Messages_GetInlineBotResults
/// Result ID from Messages_GetInlineBotResults
/// Scheduled message date for scheduled messages
@@ -2376,7 +2424,7 @@ namespace TL
/// Notify the other user in a private chat that a screenshot of the chat was taken See Possible codes: 400 (details)
/// Other user
/// ID of message that was screenshotted, can be 0
- /// Random ID to avoid message resending
+ /// Random ID to avoid message resending You can use
public static Task Messages_SendScreenshotNotification(this Client client, InputPeer peer, int reply_to_msg_id, long random_id)
=> client.Invoke(new Messages_SendScreenshotNotification
{
@@ -3178,18 +3226,15 @@ namespace TL
/// Translate a given text See Possible codes: 400 (details)
/// If the text is a chat message, the peer ID
- /// If the text is a chat message, the message ID
/// The text to translate
- /// Two-letter ISO 639-1 language code of the language from which the message is translated, if not set will be autodetected
/// Two-letter ISO 639-1 language code of the language to which the message is translated
- public static Task Messages_TranslateText(this Client client, string to_lang, InputPeer peer = null, int? msg_id = null, string text = null, string from_lang = null)
+ public static Task Messages_TranslateText(this Client client, string to_lang, InputPeer peer = null, int[] id = null, TextWithEntities[] text = null)
=> client.Invoke(new Messages_TranslateText
{
- flags = (Messages_TranslateText.Flags)((peer != null ? 0x1 : 0) | (msg_id != null ? 0x1 : 0) | (text != null ? 0x2 : 0) | (from_lang != null ? 0x4 : 0)),
+ flags = (Messages_TranslateText.Flags)((peer != null ? 0x1 : 0) | (id != null ? 0x1 : 0) | (text != null ? 0x2 : 0)),
peer = peer,
- msg_id = msg_id.GetValueOrDefault(),
+ id = id,
text = text,
- from_lang = from_lang,
to_lang = to_lang,
});
@@ -3335,7 +3380,7 @@ namespace TL
/// Used by the user to relay data from an opened reply keyboard bot web app to the bot that owns it. See
/// Bot that owns the web app
- /// Unique client message ID to prevent duplicate sending of the same event
+ /// Unique client message ID to prevent duplicate sending of the same event You can use
/// Text of the that was pressed to open the web app.
/// Data to relay to the bot, obtained from a web_app_data_send JS event.
public static Task Messages_SendWebViewData(this Client client, InputUserBase bot, long random_id, string button_text, string data)
@@ -3457,6 +3502,57 @@ namespace TL
{
});
+ /// See
+ public static Task Messages_SendBotRequestedPeer(this Client client, InputPeer peer, int msg_id, int button_id, InputPeer requested_peer)
+ => client.Invoke(new Messages_SendBotRequestedPeer
+ {
+ peer = peer,
+ msg_id = msg_id,
+ button_id = button_id,
+ requested_peer = requested_peer,
+ });
+
+ /// See
+ /// a null value means messages.emojiGroupsNotModified
+ public static Task Messages_GetEmojiGroups(this Client client, int hash = default)
+ => client.Invoke(new Messages_GetEmojiGroups
+ {
+ hash = hash,
+ });
+
+ /// See
+ /// a null value means messages.emojiGroupsNotModified
+ public static Task Messages_GetEmojiStatusGroups(this Client client, int hash = default)
+ => client.Invoke(new Messages_GetEmojiStatusGroups
+ {
+ hash = hash,
+ });
+
+ /// See
+ /// a null value means messages.emojiGroupsNotModified
+ public static Task Messages_GetEmojiProfilePhotoGroups(this Client client, int hash = default)
+ => client.Invoke(new Messages_GetEmojiProfilePhotoGroups
+ {
+ hash = hash,
+ });
+
+ /// See
+ /// a null value means emojiListNotModified
+ public static Task Messages_SearchCustomEmoji(this Client client, string emoticon, long hash = default)
+ => client.Invoke(new Messages_SearchCustomEmoji
+ {
+ emoticon = emoticon,
+ hash = hash,
+ });
+
+ /// See
+ public static Task Messages_TogglePeerTranslations(this Client client, InputPeer peer, bool disabled = false)
+ => client.Invoke(new Messages_TogglePeerTranslations
+ {
+ flags = (Messages_TogglePeerTranslations.Flags)(disabled ? 0x1 : 0),
+ peer = peer,
+ });
+
/// Returns a current state of updates. See [bots: ✓]
public static Task Updates_GetState(this Client client)
=> client.Invoke(new Updates_GetState
@@ -3507,13 +3603,14 @@ namespace TL
/// File saved in parts by means of Upload_SaveFilePart method
/// Animated profile picture video
/// Floating point UNIX timestamp in seconds, indicating the frame of the video that should be used as static preview.
- public static Task Photos_UploadProfilePhoto(this Client client, InputFileBase file = null, InputFileBase video = null, double? video_start_ts = null, bool fallback = false)
+ public static Task Photos_UploadProfilePhoto(this Client client, InputFileBase file = null, InputFileBase video = null, double? video_start_ts = null, VideoSizeBase video_emoji_markup = null, bool fallback = false)
=> client.Invoke(new Photos_UploadProfilePhoto
{
- flags = (Photos_UploadProfilePhoto.Flags)((file != null ? 0x1 : 0) | (video != null ? 0x2 : 0) | (video_start_ts != null ? 0x4 : 0) | (fallback ? 0x8 : 0)),
+ flags = (Photos_UploadProfilePhoto.Flags)((file != null ? 0x1 : 0) | (video != null ? 0x2 : 0) | (video_start_ts != null ? 0x4 : 0) | (video_emoji_markup != null ? 0x10 : 0) | (fallback ? 0x8 : 0)),
file = file,
video = video,
video_start_ts = video_start_ts.GetValueOrDefault(),
+ video_emoji_markup = video_emoji_markup,
});
/// Deletes profile photos. The method returns a list of successfully deleted photo IDs. See
@@ -3539,14 +3636,15 @@ namespace TL
});
/// See
- public static Task Photos_UploadContactProfilePhoto(this Client client, InputUserBase user_id, InputFileBase file = null, InputFileBase video = null, double? video_start_ts = null, bool suggest = false, bool save = false)
+ public static Task Photos_UploadContactProfilePhoto(this Client client, InputUserBase user_id, InputFileBase file = null, InputFileBase video = null, double? video_start_ts = null, VideoSizeBase video_emoji_markup = null, bool suggest = false, bool save = false)
=> client.Invoke(new Photos_UploadContactProfilePhoto
{
- flags = (Photos_UploadContactProfilePhoto.Flags)((file != null ? 0x1 : 0) | (video != null ? 0x2 : 0) | (video_start_ts != null ? 0x4 : 0) | (suggest ? 0x8 : 0) | (save ? 0x10 : 0)),
+ flags = (Photos_UploadContactProfilePhoto.Flags)((file != null ? 0x1 : 0) | (video != null ? 0x2 : 0) | (video_start_ts != null ? 0x4 : 0) | (video_emoji_markup != null ? 0x20 : 0) | (suggest ? 0x8 : 0) | (save ? 0x10 : 0)),
user_id = user_id,
file = file,
video = video,
video_start_ts = video_start_ts.GetValueOrDefault(),
+ video_emoji_markup = video_emoji_markup,
});
/// Saves a part of file for further sending to one of the methods. See [bots: ✓] Possible codes: 400 (details)
@@ -3917,10 +4015,10 @@ namespace TL
/// Channel description
/// Geogroup location
/// Geogroup address
- public static Task Channels_CreateChannel(this Client client, string title, string about, InputGeoPoint geo_point = null, string address = null, int? ttl_period = null, bool broadcast = false, bool megagroup = false, bool for_import = false)
+ public static Task Channels_CreateChannel(this Client client, string title, string about, InputGeoPoint geo_point = null, string address = null, int? ttl_period = null, bool broadcast = false, bool megagroup = false, bool for_import = false, bool forum = false)
=> client.Invoke(new Channels_CreateChannel
{
- flags = (Channels_CreateChannel.Flags)((geo_point != null ? 0x4 : 0) | (address != null ? 0x4 : 0) | (ttl_period != null ? 0x10 : 0) | (broadcast ? 0x1 : 0) | (megagroup ? 0x2 : 0) | (for_import ? 0x8 : 0)),
+ flags = (Channels_CreateChannel.Flags)((geo_point != null ? 0x4 : 0) | (address != null ? 0x4 : 0) | (ttl_period != null ? 0x10 : 0) | (broadcast ? 0x1 : 0) | (megagroup ? 0x2 : 0) | (for_import ? 0x8 : 0) | (forum ? 0x20 : 0)),
title = title,
about = about,
geo_point = geo_point,
@@ -5212,7 +5310,7 @@ namespace TL.Methods
}
[TLDef(0xA677244F)]
- public class Auth_SendCode : IMethod
+ public class Auth_SendCode : IMethod
{
public string phone_number;
public int api_id;
@@ -5305,7 +5403,7 @@ namespace TL.Methods
}
[TLDef(0x3EF1A9BF)]
- public class Auth_ResendCode : IMethod
+ public class Auth_ResendCode : IMethod
{
public string phone_number;
public string phone_code_hash;
@@ -5358,6 +5456,22 @@ namespace TL.Methods
public string web_auth_token;
}
+ [TLDef(0x89464B50)]
+ public class Auth_RequestFirebaseSms : IMethod
+ {
+ public Flags flags;
+ public string phone_number;
+ public string phone_code_hash;
+ [IfFlag(0)] public string safety_net_token;
+ [IfFlag(1)] public string ios_push_secret;
+
+ [Flags] public enum Flags : uint
+ {
+ has_safety_net_token = 0x1,
+ has_ios_push_secret = 0x2,
+ }
+ }
+
[TLDef(0xEC86017A)]
public class Account_RegisterDevice : IMethod
{
@@ -5482,7 +5596,7 @@ namespace TL.Methods
}
[TLDef(0x82574AE5)]
- public class Account_SendChangePhoneCode : IMethod
+ public class Account_SendChangePhoneCode : IMethod
{
public string phone_number;
public CodeSettings settings;
@@ -5528,7 +5642,7 @@ namespace TL.Methods
}
[TLDef(0x1B3FAA88)]
- public class Account_SendConfirmPhoneCode : IMethod
+ public class Account_SendConfirmPhoneCode : IMethod
{
public string hash;
public CodeSettings settings;
@@ -5601,7 +5715,7 @@ namespace TL.Methods
}
[TLDef(0xA5A356F9)]
- public class Account_SendVerifyPhoneCode : IMethod
+ public class Account_SendVerifyPhoneCode : IMethod
{
public string phone_number;
public CodeSettings settings;
@@ -5954,6 +6068,40 @@ namespace TL.Methods
public bool active;
}
+ [TLDef(0xE2750328)]
+ public class Account_GetDefaultProfilePhotoEmojis : IMethod
+ {
+ public long hash;
+ }
+
+ [TLDef(0x915860AE)]
+ public class Account_GetDefaultGroupPhotoEmojis : IMethod
+ {
+ public long hash;
+ }
+
+ [TLDef(0xADCBBCDA)]
+ public class Account_GetAutoSaveSettings : IMethod { }
+
+ [TLDef(0xD69B8361)]
+ public class Account_SaveAutoSaveSettings : IMethod
+ {
+ public Flags flags;
+ [IfFlag(3)] public InputPeer peer;
+ public AutoSaveSettings settings;
+
+ [Flags] public enum Flags : uint
+ {
+ users = 0x1,
+ chats = 0x2,
+ broadcasts = 0x4,
+ has_peer = 0x8,
+ }
+ }
+
+ [TLDef(0x53BC0020)]
+ public class Account_DeleteAutoSaveExceptions : IMethod { }
+
[TLDef(0x0D91A548)]
public class Users_GetUsers : IMethod
{
@@ -7742,21 +7890,19 @@ namespace TL.Methods
public Reaction reaction;
}
- [TLDef(0x24CE6DEE)]
+ [TLDef(0x63183030)]
public class Messages_TranslateText : IMethod
{
public Flags flags;
[IfFlag(0)] public InputPeer peer;
- [IfFlag(0)] public int msg_id;
- [IfFlag(1)] public string text;
- [IfFlag(2)] public string from_lang;
+ [IfFlag(0)] public int[] id;
+ [IfFlag(1)] public TextWithEntities[] text;
public string to_lang;
[Flags] public enum Flags : uint
{
has_peer = 0x1,
has_text = 0x2,
- has_from_lang = 0x4,
}
}
@@ -7977,6 +8123,52 @@ namespace TL.Methods
[TLDef(0x658B7188)]
public class Messages_GetDefaultHistoryTTL : IMethod { }
+ [TLDef(0xFE38D01B)]
+ public class Messages_SendBotRequestedPeer : IMethod
+ {
+ public InputPeer peer;
+ public int msg_id;
+ public int button_id;
+ public InputPeer requested_peer;
+ }
+
+ [TLDef(0x7488CE5B)]
+ public class Messages_GetEmojiGroups : IMethod
+ {
+ public int hash;
+ }
+
+ [TLDef(0x2ECD56CD)]
+ public class Messages_GetEmojiStatusGroups : IMethod
+ {
+ public int hash;
+ }
+
+ [TLDef(0x21A548F3)]
+ public class Messages_GetEmojiProfilePhotoGroups : IMethod
+ {
+ public int hash;
+ }
+
+ [TLDef(0x2C11C0D7)]
+ public class Messages_SearchCustomEmoji : IMethod
+ {
+ public string emoticon;
+ public long hash;
+ }
+
+ [TLDef(0xE47CB579)]
+ public class Messages_TogglePeerTranslations : IMethod
+ {
+ public Flags flags;
+ public InputPeer peer;
+
+ [Flags] public enum Flags : uint
+ {
+ disabled = 0x1,
+ }
+ }
+
[TLDef(0xEDD4882A)]
public class Updates_GetState : IMethod { }
@@ -8022,13 +8214,14 @@ namespace TL.Methods
}
}
- [TLDef(0x89F30F69)]
+ [TLDef(0x093C9A51)]
public class Photos_UploadProfilePhoto : IMethod
{
public Flags flags;
[IfFlag(0)] public InputFileBase file;
[IfFlag(1)] public InputFileBase video;
[IfFlag(2)] public double video_start_ts;
+ [IfFlag(4)] public VideoSizeBase video_emoji_markup;
[Flags] public enum Flags : uint
{
@@ -8036,6 +8229,7 @@ namespace TL.Methods
has_video = 0x2,
has_video_start_ts = 0x4,
fallback = 0x8,
+ has_video_emoji_markup = 0x10,
}
}
@@ -8054,7 +8248,7 @@ namespace TL.Methods
public int limit;
}
- [TLDef(0xB91A83BF)]
+ [TLDef(0xE14C4A71)]
public class Photos_UploadContactProfilePhoto : IMethod
{
public Flags flags;
@@ -8062,6 +8256,7 @@ namespace TL.Methods
[IfFlag(0)] public InputFileBase file;
[IfFlag(1)] public InputFileBase video;
[IfFlag(2)] public double video_start_ts;
+ [IfFlag(5)] public VideoSizeBase video_emoji_markup;
[Flags] public enum Flags : uint
{
@@ -8070,6 +8265,7 @@ namespace TL.Methods
has_video_start_ts = 0x4,
suggest = 0x8,
save = 0x10,
+ has_video_emoji_markup = 0x20,
}
}
@@ -8330,6 +8526,7 @@ namespace TL.Methods
has_geo_point = 0x4,
for_import = 0x8,
has_ttl_period = 0x10,
+ forum = 0x20,
}
}
diff --git a/src/TL.Table.cs b/src/TL.Table.cs
index cc4740e..f7e6dbe 100644
--- a/src/TL.Table.cs
+++ b/src/TL.Table.cs
@@ -6,7 +6,7 @@ namespace TL
{
public static class Layer
{
- public const int Version = 151; // fetched 29/12/2022 21:30:31
+ public const int Version = 152; // fetched 03/02/2023 21:46:20
internal const int SecretChats = 144;
internal const int MTProto2 = 73;
internal const uint VectorCtor = 0x1CB5C415;
@@ -99,7 +99,7 @@ namespace TL
[0x0F94E5F1] = typeof(InputMediaPoll),
[0xE66FBF7B] = typeof(InputMediaDice),
[0x1CA48F57] = null,//InputChatPhotoEmpty
- [0xC642724E] = typeof(InputChatUploadedPhoto),
+ [0xBDCDAEC0] = typeof(InputChatUploadedPhoto),
[0x8953AD37] = typeof(InputChatPhoto),
[0xE4C123D6] = null,//InputGeoPointEmpty
[0x48222FAF] = typeof(InputGeoPoint),
@@ -195,6 +195,7 @@ namespace TL
[0xC0944820] = typeof(MessageActionTopicEdit),
[0x57DE635E] = typeof(MessageActionSuggestProfilePhoto),
[0xE7E75F97] = typeof(MessageActionAttachMenuBotAllowed),
+ [0xFE77345D] = typeof(MessageActionRequestedPeer),
[0xD58A08C6] = typeof(Dialog),
[0x71BD134C] = typeof(DialogFolder),
[0x2331B22D] = typeof(PhotoEmpty),
@@ -208,7 +209,8 @@ namespace TL
[0x1117DD5F] = null,//GeoPointEmpty
[0xB2A2F663] = typeof(GeoPoint),
[0x5E002502] = typeof(Auth_SentCode),
- [0x33FB7BB8] = typeof(Auth_Authorization),
+ [0x2390FE44] = typeof(Auth_SentCodeSuccess),
+ [0x2EA2C0D4] = typeof(Auth_Authorization),
[0x44747E9A] = typeof(Auth_AuthorizationSignUpRequired),
[0xB434E2B8] = typeof(Auth_ExportedAuthorization),
[0xB8BC5B0C] = typeof(InputNotifyPeer),
@@ -367,6 +369,7 @@ namespace TL
[0x192EFBE3] = typeof(UpdateChannelPinnedTopic),
[0xFE198602] = typeof(UpdateChannelPinnedTopics),
[0x20529438] = typeof(UpdateUser),
+ [0xEC05B097] = typeof(UpdateAutoSaveSettings),
[0xA56C2A3E] = typeof(Updates_State),
[0x5D75A138] = typeof(Updates_DifferenceEmpty),
[0x00F49CA0] = typeof(Updates_Difference),
@@ -515,6 +518,7 @@ namespace TL
[0x308660C1] = typeof(KeyboardButtonUserProfile),
[0x13767230] = typeof(KeyboardButtonWebView),
[0xA0C0505C] = typeof(KeyboardButtonSimpleWebView),
+ [0x0D0B468C] = typeof(KeyboardButtonRequestPeer),
[0x77608B83] = typeof(KeyboardButtonRow),
[0xA03E5B85] = typeof(ReplyKeyboardHide),
[0x86B40B08] = typeof(ReplyKeyboardForceReply),
@@ -601,6 +605,7 @@ namespace TL
[0x5A159841] = typeof(Auth_SentCodeTypeEmailCode),
[0xA5491DEA] = typeof(Auth_SentCodeTypeSetUpEmailRequired),
[0xD9565C39] = typeof(Auth_SentCodeTypeFragmentSms),
+ [0xE57B1432] = typeof(Auth_SentCodeTypeFirebaseSms),
[0x36585EA4] = typeof(Messages_BotCallbackAnswer),
[0x26B5DDE6] = typeof(Messages_MessageEditData),
[0x890C3D89] = typeof(InputBotInlineMessageID),
@@ -868,7 +873,7 @@ namespace TL
[0x967A462E] = typeof(InputWallPaperNoFile),
[0x1C199183] = null,//Account_WallPapersNotModified
[0xCDC3858C] = typeof(Account_WallPapers),
- [0x8A6469C2] = typeof(CodeSettings),
+ [0xAD253D78] = typeof(CodeSettings),
[0x1DC1BCA4] = typeof(WallPaperSettings),
[0x8EFAB953] = typeof(AutoDownloadSettings),
[0x63CACF26] = typeof(Account_AutoDownloadSettings),
@@ -922,6 +927,8 @@ namespace TL
[0x98F6AC75] = typeof(Help_PromoDataEmpty),
[0x8C39793F] = typeof(Help_PromoData),
[0xDE33B094] = typeof(VideoSize),
+ [0xF85C413C] = typeof(VideoSizeEmojiMarkup),
+ [0x0DA082FE] = typeof(VideoSizeStickerMarkup),
[0x9D04AF9B] = typeof(StatsGroupTopPoster),
[0xD7584C87] = typeof(StatsGroupTopAdmin),
[0x535F779D] = typeof(StatsGroupTopInviter),
@@ -987,8 +994,6 @@ namespace TL
[0xC077EC01] = typeof(AvailableReaction),
[0x9F071957] = null,//Messages_AvailableReactionsNotModified
[0x768E3AAD] = typeof(Messages_AvailableReactions),
- [0x67CA4737] = typeof(Messages_TranslateNoResult),
- [0xA214F7D0] = typeof(Messages_TranslateResultText),
[0xB156FE9C] = typeof(MessagePeerReaction),
[0x80EB48AF] = typeof(GroupCallStreamChannel),
[0xD0E482B2] = typeof(Phone_GroupCallStreamChannels),
@@ -1043,7 +1048,7 @@ namespace TL
[0x96D074FD] = typeof(EmailVerificationApple),
[0x2B96CD1B] = typeof(Account_EmailVerified),
[0xE1BB0D61] = typeof(Account_EmailVerifiedLogin),
- [0xB6F11EBE] = typeof(PremiumSubscriptionOption),
+ [0x5F2D1DF2] = typeof(PremiumSubscriptionOption),
[0xB81C7034] = typeof(SendAsPeer),
[0xAD628CC8] = typeof(MessageExtendedMediaPreview),
[0xEE479C64] = typeof(MessageExtendedMedia),
@@ -1054,6 +1059,19 @@ namespace TL
[0x367617D3] = typeof(Messages_ForumTopics),
[0x43B46B20] = typeof(DefaultHistoryTTL),
[0x41BF109B] = typeof(ExportedContactToken),
+ [0x5F3B8A00] = typeof(RequestPeerTypeUser),
+ [0xC9F06E1B] = typeof(RequestPeerTypeChat),
+ [0x339BEF6C] = typeof(RequestPeerTypeBroadcast),
+ [0x481EADFA] = null,//EmojiListNotModified
+ [0x7A1E11D1] = typeof(EmojiList),
+ [0x7A9ABDA9] = typeof(EmojiGroup),
+ [0x6FB4AD87] = null,//Messages_EmojiGroupsNotModified
+ [0x881FB94B] = typeof(Messages_EmojiGroups),
+ [0x751F3146] = typeof(TextWithEntities),
+ [0x33DB32F8] = typeof(Messages_TranslateResult),
+ [0xC84834CE] = typeof(AutoSaveSettings),
+ [0x81602D47] = typeof(AutoSaveException),
+ [0x4C3E069D] = typeof(Account_AutoSaveSettings),
// from TL.Secret:
[0x6ABD9782] = typeof(Layer143.DecryptedMessageMediaDocument),
[0x91CC4674] = typeof(Layer73.DecryptedMessage),
@@ -1170,6 +1188,8 @@ namespace TL
[typeof(ChatReactions)] = 0xEAFC32BC, //chatReactionsNone
[typeof(Messages_Reactions)] = 0xB06FDBDF, //messages.reactionsNotModified
// from TL.Secret:
+ [typeof(EmojiList)] = 0x481EADFA, //emojiListNotModified
+ [typeof(Messages_EmojiGroups)] = 0x6FB4AD87, //messages.emojiGroupsNotModified
[typeof(DecryptedMessageMedia)] = 0x089F5C4A, //decryptedMessageMediaEmpty
};
}
diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj
index 6eedad4..f65b2bf 100644
--- a/src/WTelegramClient.csproj
+++ b/src/WTelegramClient.csproj
@@ -13,7 +13,7 @@
WTelegramClient
0.0.0
Wizou
- Telegram Client API (MTProto) library written 100% in C# and .NET Standard | Latest API layer: 151
Release Notes:
$(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))
+ Telegram Client API (MTProto) library written 100% in C# and .NET Standard | Latest API layer: 152
Release Notes:
$(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))
Copyright © Olivier Marcoux 2021-2023
MIT
https://github.com/wiz0u/WTelegramClient
From bf7207fa7d2b082211ec03c95e605034e0da8df1 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Sun, 5 Feb 2023 15:43:49 +0100
Subject: [PATCH 008/304] Support for Firebase SMS
---
src/Client.cs | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/src/Client.cs b/src/Client.cs
index b0c76b0..452a82d 100644
--- a/src/Client.cs
+++ b/src/Client.cs
@@ -1074,6 +1074,21 @@ namespace WTelegram
else if (sentCodeBase is Auth_SentCode sentCode)
{
phone_code_hash = sentCode.phone_code_hash;
+ if (sentCode.type is Auth_SentCodeTypeFirebaseSms firebaseSms)
+ {
+ var token = await ConfigAsync("firebase:" + Convert.ToHexString(firebaseSms.nonce));
+ int index = token?.IndexOf(':') ?? -1;
+ if (!(index > 0 && token[..index] switch
+ {
+ "safety_net_token" => await this.Auth_RequestFirebaseSms(phone_number, phone_code_hash, safety_net_token: token[(index + 1)..]),
+ "ios_push_secret" => await this.Auth_RequestFirebaseSms(phone_number, phone_code_hash, ios_push_secret: token[(index + 1)..]),
+ _ => false
+ }))
+ {
+ sentCodeBase = await this.Auth_ResendCode(phone_number, phone_code_hash);
+ goto resent;
+ }
+ }
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);
From b5d7ef311de4dbc618395628301aee31c01dd8a8 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Mon, 13 Feb 2023 11:29:02 +0100
Subject: [PATCH 009/304] Small change to support Firebase SMS
---
src/Client.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Client.cs b/src/Client.cs
index 452a82d..a9db6c5 100644
--- a/src/Client.cs
+++ b/src/Client.cs
@@ -1074,9 +1074,12 @@ namespace WTelegram
else if (sentCodeBase is Auth_SentCode sentCode)
{
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);
if (sentCode.type is Auth_SentCodeTypeFirebaseSms firebaseSms)
{
- var token = await ConfigAsync("firebase:" + Convert.ToHexString(firebaseSms.nonce));
+ var token = await ConfigAsync("firebase");
int index = token?.IndexOf(':') ?? -1;
if (!(index > 0 && token[..index] switch
{
@@ -1089,9 +1092,6 @@ namespace WTelegram
goto resent;
}
}
- 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);
for (int retry = 1; authorization == null; retry++)
try
{
From 08a0802ed3c6685695e0d71e2d1594ce9677e5f9 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Mon, 13 Feb 2023 11:32:45 +0100
Subject: [PATCH 010/304] Small change to support Firebase SMS
---
.github/dev.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index 27a4134..ca7837f 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -2,7 +2,7 @@ pr: none
trigger:
- master
-name: 3.2.2-dev.$(Rev:r)
+name: 3.2.3-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest
From 7948dbd8e3d1b68636d7ebc8c15a334578f4c8aa Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Tue, 14 Feb 2023 11:14:17 +0100
Subject: [PATCH 011/304] Remove deprecated CollectAccessHash system
---
src/Client.Helpers.cs | 43 -------------------------------------------
src/Client.cs | 10 +++++-----
src/Encryption.cs | 2 +-
src/SecretChats.cs | 4 ++--
src/TL.Extensions.cs | 28 ++++++++++++++--------------
src/TL.cs | 11 +----------
6 files changed, 23 insertions(+), 75 deletions(-)
diff --git a/src/Client.Helpers.cs b/src/Client.Helpers.cs
index ce1580d..430bbde 100644
--- a/src/Client.Helpers.cs
+++ b/src/Client.Helpers.cs
@@ -15,49 +15,6 @@ namespace WTelegram
{
partial class Client
{
- #region Collect Access Hash system
- #pragma warning disable CS0618 // Type or member is obsolete
- /// Enable the collection of id/access_hash pairs (deprecated)
- [Obsolete("This system will be removed in a future version. You should use CollectUsersChats helper on API results or updates instead. See https://wiz0u.github.io/WTelegramClient/EXAMPLES#collect-users-chats")]
- public bool CollectAccessHash { get; set; }
- public IEnumerable> AllAccessHashesFor() where T : IObject => _accessHashes.GetValueOrDefault(typeof(T));
- private readonly Dictionary> _accessHashes = new();
- private static readonly FieldInfo userFlagsField = typeof(User).GetField("flags");
- private static readonly FieldInfo channelFlagsField = typeof(Channel).GetField("flags");
-
- /// 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 : IObject
- {
- if (!CollectAccessHash) Helpers.Log(4, "GetAccessHashFor doesn't do what you think. See https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#access-hash");
- lock (_accessHashes)
- return _accessHashes.GetOrCreate(typeof(T)).TryGetValue(id, out var access_hash) ? access_hash : 0;
- }
- public void SetAccessHashFor(long id, long access_hash) where T : IObject
- {
- lock (_accessHashes)
- _accessHashes.GetOrCreate(typeof(T))[id] = access_hash;
- }
- internal void CollectField(FieldInfo fieldInfo, object obj, object access_hash)
- {
- if (fieldInfo.Name != "access_hash") return;
- if (access_hash is not long accessHash) return;
- var type = fieldInfo.ReflectedType;
- if ((type == typeof(User) && ((User.Flags)userFlagsField.GetValue(obj)).HasFlag(User.Flags.min)) ||
- (type == typeof(Channel) && ((Channel.Flags)channelFlagsField.GetValue(obj)).HasFlag(Channel.Flags.min)))
- return; // access_hash from Min constructors are mostly useless. see https://core.telegram.org/api/min
- if (type.GetField("id") is not FieldInfo idField) return;
- if (idField.GetValue(obj) is not long id)
- if (idField.GetValue(obj) is not int idInt) return;
- else id = idInt;
- lock (_accessHashes)
- _accessHashes.GetOrCreate(type)[id] = accessHash;
- }
- #pragma warning restore CS0618 // Type or member is obsolete
- #endregion
-
#region Client TL Helpers
/// Used to indicate progression of file download/upload
/// transmitted bytes
diff --git a/src/Client.cs b/src/Client.cs
index a9db6c5..2b24c02 100644
--- a/src/Client.cs
+++ b/src/Client.cs
@@ -384,7 +384,7 @@ namespace WTelegram
throw new ApplicationException($"Received a packet encrypted with unexpected key {authKeyId:X}");
if (authKeyId == 0) // Unencrypted message
{
- using var reader = new TL.BinaryReader(new MemoryStream(data, 8, dataLen - 8), this);
+ using var reader = new BinaryReader(new MemoryStream(data, 8, dataLen - 8));
long msgId = _lastRecvMsgId = reader.ReadInt64();
if ((msgId & 1) == 0) throw new ApplicationException($"Invalid server msgId {msgId}");
int length = reader.ReadInt32();
@@ -407,7 +407,7 @@ namespace WTelegram
if (!data.AsSpan(8, 16).SequenceEqual(_sha256Recv.Hash.AsSpan(8, 16)))
throw new ApplicationException("Mismatch between MsgKey & decrypted SHA256");
_sha256Recv.Initialize();
- using var reader = new TL.BinaryReader(new MemoryStream(decrypted_data), this);
+ using var reader = new BinaryReader(new MemoryStream(decrypted_data));
var serverSalt = reader.ReadInt64(); // int64 salt
var sessionId = reader.ReadInt64(); // int64 session_id
var msgId = reader.ReadInt64(); // int64 message_id
@@ -470,7 +470,7 @@ namespace WTelegram
};
}
- internal MsgContainer ReadMsgContainer(TL.BinaryReader reader)
+ internal MsgContainer ReadMsgContainer(BinaryReader reader)
{
int count = reader.ReadInt32();
var array = new _Message[count];
@@ -502,7 +502,7 @@ namespace WTelegram
return new MsgContainer { messages = array };
}
- private RpcResult ReadRpcResult(TL.BinaryReader reader)
+ private RpcResult ReadRpcResult(BinaryReader reader)
{
long msgId = reader.ReadInt64();
var rpc = PullPendingRequest(msgId);
@@ -519,7 +519,7 @@ namespace WTelegram
if (peek == Layer.RpcErrorCtor)
result = reader.ReadTLObject(Layer.RpcErrorCtor);
else if (peek == Layer.GZipedCtor)
- using (var gzipReader = new TL.BinaryReader(new GZipStream(new MemoryStream(reader.ReadTLBytes()), CompressionMode.Decompress), reader.Client))
+ using (var gzipReader = new BinaryReader(new GZipStream(new MemoryStream(reader.ReadTLBytes()), CompressionMode.Decompress)))
result = gzipReader.ReadTLValue(rpc.type);
else
{
diff --git a/src/Encryption.cs b/src/Encryption.cs
index 03b72c0..01f8cc9 100644
--- a/src/Encryption.cs
+++ b/src/Encryption.cs
@@ -97,7 +97,7 @@ namespace WTelegram
var (tmp_aes_key, tmp_aes_iv) = ConstructTmpAESKeyIV(resPQ.server_nonce, pqInnerData.new_nonce);
var answer = AES_IGE_EncryptDecrypt(serverDHparamsOk.encrypted_answer, tmp_aes_key, tmp_aes_iv, false);
- using var answerReader = new TL.BinaryReader(new MemoryStream(answer), client);
+ using var answerReader = new BinaryReader(new MemoryStream(answer));
var answerHash = answerReader.ReadBytes(20);
var answerObj = answerReader.ReadTLObject();
if (answerObj is not ServerDHInnerData serverDHinnerData) throw new ApplicationException("not server_DH_inner_data");
diff --git a/src/SecretChats.cs b/src/SecretChats.cs
index b857422..53bdec0 100644
--- a/src/SecretChats.cs
+++ b/src/SecretChats.cs
@@ -94,7 +94,7 @@ namespace WTelegram
}
public void Load(Stream input)
{
- using var reader = new TL.BinaryReader(input, null, true);
+ using var reader = new BinaryReader(input, Encoding.UTF8, true);
if (reader.ReadInt32() != 0) throw new ApplicationException("Unrecognized Secrets format");
dh = (Messages_DhConfig)reader.ReadTLObject();
if (dh?.p != null) dh_prime = BigEndianInteger(dh.p);
@@ -359,7 +359,7 @@ namespace WTelegram
}
if (!success) throw new ApplicationException("Could not decrypt message");
if (length % 4 != 0) throw new ApplicationException($"Invalid message_data_length: {length}");
- using var reader = new TL.BinaryReader(new MemoryStream(decrypted_data, 4, length), null);
+ using var reader = new BinaryReader(new MemoryStream(decrypted_data, 4, length));
return reader.ReadTLObject();
}
diff --git a/src/TL.Extensions.cs b/src/TL.Extensions.cs
index 9139778..c9205f8 100644
--- a/src/TL.Extensions.cs
+++ b/src/TL.Extensions.cs
@@ -37,21 +37,21 @@ namespace TL
public static void CollectUsersChats(this IPeerResolver structure, Dictionary users, Dictionary chats)
=> structure.UserOrChat(new CollectorPeer { _users = users, _chats = chats });
- public static Task Messages_GetChats(this WTelegram.Client _) => throw new ApplicationException("The method you're looking for is Messages_GetAllChats");
- public static Task Channels_GetChannels(this WTelegram.Client _) => throw new ApplicationException("The method you're looking for is Messages_GetAllChats");
- public static Task Users_GetUsers(this WTelegram.Client _) => throw new ApplicationException("The method you're looking for is Messages_GetAllDialogs");
- public static Task Messages_GetMessages(this WTelegram.Client _) => throw new ApplicationException("If you want to get the messages from a chat, use Messages_GetHistory");
+ public static Task Messages_GetChats(this Client _) => throw new ApplicationException("The method you're looking for is Messages_GetAllChats");
+ public static Task Channels_GetChannels(this Client _) => throw new ApplicationException("The method you're looking for is Messages_GetAllChats");
+ public static Task Users_GetUsers(this Client _) => throw new ApplicationException("The method you're looking for is Messages_GetAllDialogs");
+ public static Task Messages_GetMessages(this Client _) => throw new ApplicationException("If you want to get the messages from a chat, use Messages_GetHistory");
}
public static class Markdown
{
/// Converts a Markdown text into the (plain text + entities) format used by Telegram messages
- /// Client, used for getting access_hash for tg://user?id= URLs
+ /// not used anymore, you can pass null
/// [in] The Markdown text
[out] The same (plain) text, stripped of all Markdown notation
/// Generate premium entities if any
/// Dictionary used for tg://user?id= notation
- /// The array of formatting entities that you can pass (along with the plain text) to SendMessageAsync or SendMediaAsync
- public static MessageEntity[] MarkdownToEntities(this WTelegram.Client client, ref string text, bool premium = false, Dictionary users = null)
+ /// The array of formatting entities that you can pass (along with the plain text) to SendMessageAsync or SendMediaAsync
+ public static MessageEntity[] MarkdownToEntities(this Client _, ref string text, bool premium = false, Dictionary users = null)
{
var entities = new List();
var sb = new StringBuilder(text);
@@ -121,7 +121,7 @@ namespace TL
else if (c == ')') break;
}
textUrl.url = sb.ToString(offset + 2, offset2 - offset - 3);
- if (textUrl.url.StartsWith("tg://user?id=") && long.TryParse(textUrl.url[13..], out var id) && (users?.GetValueOrDefault(id)?.access_hash ?? client.GetAccessHashFor(id)) is long hash)
+ if (textUrl.url.StartsWith("tg://user?id=") && long.TryParse(textUrl.url[13..], out var id) && users?.GetValueOrDefault(id)?.access_hash is long hash)
entities[lastIndex] = new InputMessageEntityMentionName { offset = textUrl.offset, length = textUrl.length, user_id = new InputUser(id, hash) };
else if ((textUrl.url.StartsWith("tg://emoji?id=") || textUrl.url.StartsWith("emoji?id=")) && long.TryParse(textUrl.url[(textUrl.url.IndexOf('=') + 1)..], out id))
if (premium) entities[lastIndex] = new MessageEntityCustomEmoji { offset = textUrl.offset, length = textUrl.length, document_id = id };
@@ -154,7 +154,7 @@ namespace TL
/// The array of formatting entities, typically obtained from
/// Convert premium entities (might lead to non-standard markdown)
/// The message text with MarkdownV2 formattings
- public static string EntitiesToMarkdown(this WTelegram.Client client, string message, MessageEntity[] entities, bool premium = false)
+ public static string EntitiesToMarkdown(this Client client, string message, MessageEntity[] entities, bool premium = false)
{
if (entities == null || entities.Length == 0) return Escape(message);
var closings = new List<(int offset, string md)>();
@@ -246,12 +246,12 @@ namespace TL
public static class HtmlText
{
/// Converts an HTML-formatted text into the (plain text + entities) format used by Telegram messages
- /// Client, used for getting access_hash for tg://user?id= URLs
+ /// not used anymore, you can pass null
/// [in] The HTML-formatted text
[out] The same (plain) text, stripped of all HTML tags
/// Generate premium entities if any
/// Dictionary used for tg://user?id= notation
- /// The array of formatting entities that you can pass (along with the plain text) to SendMessageAsync or SendMediaAsync
- public static MessageEntity[] HtmlToEntities(this WTelegram.Client client, ref string text, bool premium = false, Dictionary users = null)
+ /// The array of formatting entities that you can pass (along with the plain text) to SendMessageAsync or SendMediaAsync
+ public static MessageEntity[] HtmlToEntities(this Client _, ref string text, bool premium = false, Dictionary users = null)
{
var entities = new List();
var sb = new StringBuilder(text);
@@ -306,7 +306,7 @@ namespace TL
else if (tag.StartsWith("a href=\"") && tag.EndsWith("\""))
{
tag = tag[8..^1];
- if (tag.StartsWith("tg://user?id=") && long.TryParse(tag[13..], out var user_id) && (users?.GetValueOrDefault(user_id)?.access_hash ?? client.GetAccessHashFor(user_id)) is long hash)
+ if (tag.StartsWith("tg://user?id=") && long.TryParse(tag[13..], out var user_id) && users?.GetValueOrDefault(user_id)?.access_hash is long hash)
entities.Add(new InputMessageEntityMentionName { offset = offset, length = -1, user_id = new InputUser(user_id, hash) });
else
entities.Add(new MessageEntityTextUrl { offset = offset, length = -1, url = tag });
@@ -342,7 +342,7 @@ namespace TL
/// The array of formatting entities, typically obtained from
/// Convert premium entities
/// The message text with HTML formatting tags
- public static string EntitiesToHtml(this WTelegram.Client client, string message, MessageEntity[] entities, bool premium = false)
+ public static string EntitiesToHtml(this Client client, string message, MessageEntity[] entities, bool premium = false)
{
if (entities == null || entities.Length == 0) return Escape(message);
var closings = new List<(int offset, string tag)>();
diff --git a/src/TL.cs b/src/TL.cs
index b5544b4..4ec4923 100644
--- a/src/TL.cs
+++ b/src/TL.cs
@@ -42,12 +42,6 @@ namespace TL
public Exception Exception;
}
- internal class BinaryReader : System.IO.BinaryReader
- {
- public readonly WTelegram.Client Client;
- public BinaryReader(Stream stream, WTelegram.Client client, bool leaveOpen = false) : base(stream, Encoding.UTF8, leaveOpen) => Client = client;
- }
-
internal static class Serialization
{
internal static void WriteTLObject(this BinaryWriter writer, T obj) where T : IObject
@@ -76,7 +70,7 @@ namespace TL
{
if (ctorNb == 0) ctorNb = reader.ReadUInt32();
if (ctorNb == Layer.GZipedCtor)
- using (var gzipReader = new BinaryReader(new GZipStream(new MemoryStream(reader.ReadTLBytes()), CompressionMode.Decompress), reader.Client))
+ using (var gzipReader = new BinaryReader(new GZipStream(new MemoryStream(reader.ReadTLBytes()), CompressionMode.Decompress)))
return ReadTLObject(gzipReader);
if (!Layer.Table.TryGetValue(ctorNb, out var type))
throw new ApplicationException($"Cannot find type for ctor #{ctorNb:x}");
@@ -95,9 +89,6 @@ namespace TL
if (field.FieldType.IsEnum)
if (field.Name == "flags") flags = (uint)value;
else if (field.Name == "flags2") flags |= (ulong)(uint)value << 32;
-#pragma warning disable CS0618 // Type or member is obsolete
- if (reader.Client?.CollectAccessHash == true) reader.Client.CollectField(field, obj, value);
-#pragma warning restore CS0618 // Type or member is obsolete
}
return (IObject)obj;
}
From 514015639d82d909d4f6f1945c06373d1ba04e49 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Wed, 15 Feb 2023 18:42:52 +0100
Subject: [PATCH 012/304] ToString use MainUsername rather than username
---
README.md | 2 +-
src/TL.Helpers.cs | 5 ++---
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index edd746b..1456e40 100644
--- a/README.md
+++ b/README.md
@@ -166,7 +166,7 @@ See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient
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, email, email_verification_code, session_key, server_address, device_model, system_version, app_version, system_lang_code, lang_pack, lang_code, user_id, bot_token**
+The other configuration items that you can override include: **session_pathname, email, email_verification_code, session_key, server_address, device_model, system_version, app_version, system_lang_code, lang_pack, lang_code, firebase, user_id, bot_token**
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).
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index 62b48e2..1acaff5 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -161,7 +161,7 @@ namespace TL
public override bool IsActive => (flags & Flags.deleted) == 0;
public bool IsBot => (flags & Flags.bot) != 0;
public string MainUsername => username ?? usernames?.FirstOrDefault(u => u.flags.HasFlag(Username.Flags.active))?.username;
- public override string ToString() => username != null ? '@' + username : last_name == null ? first_name : $"{first_name} {last_name}";
+ public override string ToString() => MainUsername is string uname ? '@' + uname : last_name == null ? first_name : $"{first_name} {last_name}";
public override InputPeer ToInputPeer() => new InputPeerUser(id, access_hash);
protected override InputUser ToInputUser() => new(id, access_hash);
/// An estimation of the number of days ago the user was last seen (Online=0, Recently=1, LastWeek=5, LastMonth=20, LongTimeAgo=150)
@@ -221,8 +221,7 @@ namespace TL
public override bool IsBanned(ChatBannedRights.Flags flags = 0) => ((banned_rights?.flags ?? 0) & flags) != 0 || ((default_banned_rights?.flags ?? 0) & flags) != 0;
public override InputPeer ToInputPeer() => new InputPeerChannel(id, access_hash);
public static implicit operator InputChannel(Channel channel) => new(channel.id, channel.access_hash);
- public override string ToString() =>
- (flags.HasFlag(Flags.broadcast) ? "Channel " : "Group ") + (username != null ? '@' + username : $"\"{title}\"");
+ public override string ToString() => (flags.HasFlag(Flags.broadcast) ? "Channel " : "Group ") + (MainUsername is string uname ? '@' + uname : $"\"{title}\"");
public bool IsChannel => (flags & Flags.broadcast) != 0;
public bool IsGroup => (flags & Flags.broadcast) == 0;
}
From 5d0fd6452fe8a6aea72eb0142c0d7b0d07895e8b Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Fri, 17 Feb 2023 19:31:01 +0100
Subject: [PATCH 013/304] Added helpers AnalyzeInviteLink & GetMessageByLink
---
src/Client.Helpers.cs | 98 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 98 insertions(+)
diff --git a/src/Client.Helpers.cs b/src/Client.Helpers.cs
index 430bbde..961934e 100644
--- a/src/Client.Helpers.cs
+++ b/src/Client.Helpers.cs
@@ -675,6 +675,104 @@ namespace WTelegram
/// If a positive value is passed, only messages with identifiers less or equal than the given one will be marked read
public async Task ReadHistory(InputPeer peer, int max_id = default)
=> peer is InputPeerChannel channel ? await this.Channels_ReadHistory(channel, max_id) : (await this.Messages_ReadHistory(peer, max_id)) != null;
+
+ private static readonly char[] QueryOrFragment = new[] { '?', '#' };
+
+ /// Return information about a chat/channel based on Invite Link
+ /// Channel or Invite Link, like https://t.me/+InviteHash, https://t.me/joinchat/InviteHash or https://t.me/channelname
+ /// to also join the chat/channel
+ /// a Chat or Channel, possibly partial Channel information only (with flag )
+ public async Task AnalyzeInviteLink(string url, bool join = false)
+ {
+ int start = url.IndexOf("//");
+ start = url.IndexOf('/', start + 2) + 1;
+ int end = url.IndexOfAny(QueryOrFragment, start);
+ if (end == -1) end = url.Length;
+ if (start == 0 || end == start) throw new ArgumentException("Invalid URI");
+ string hash;
+ if (url[start] == '+')
+ hash = url[(start + 1)..end];
+ else if (string.Compare(url, start, "joinchat/", 0, 9, StringComparison.OrdinalIgnoreCase) == 0)
+ hash = url[(start + 9)..end];
+ else
+ {
+ var resolved = await this.Contacts_ResolveUsername(url[start..end]);
+ var chat = resolved.Chat;
+ if (join && chat != null)
+ {
+ var res = await this.Channels_JoinChannel((Channel)chat);
+ chat = res.Chats[chat.ID];
+ }
+ return chat;
+ }
+ var chatInvite = await this.Messages_CheckChatInvite(hash);
+ if (join)
+ try
+ {
+ var res = await this.Messages_ImportChatInvite(hash);
+ if (res.Chats.Values.FirstOrDefault() is ChatBase chat) return chat;
+ }
+ catch (RpcException ex) when (ex.Code == 400 && ex.Message == "INVITE_REQUEST_SENT") { }
+ switch (chatInvite)
+ {
+ case ChatInviteAlready cia: return cia.chat;
+ case ChatInvitePeek cip: return cip.chat;
+ case ChatInvite ci:
+ ChatPhoto chatPhoto = null;
+ if (ci.photo is Photo photo)
+ {
+ var stripped_thumb = photo.sizes.OfType().FirstOrDefault()?.bytes;
+ chatPhoto = new ChatPhoto
+ {
+ dc_id = photo.dc_id,
+ photo_id = photo.id,
+ stripped_thumb = stripped_thumb,
+ flags = (stripped_thumb != null ? ChatPhoto.Flags.has_stripped_thumb : 0) |
+ (photo.flags.HasFlag(Photo.Flags.has_video_sizes) ? ChatPhoto.Flags.has_video : 0),
+ };
+ }
+ var rrAbout = ci.about == null ? null : new RestrictionReason[] { new() { text = ci.about } };
+ return !ci.flags.HasFlag(ChatInvite.Flags.channel)
+ ? new Chat { title = ci.title, photo = chatPhoto, participants_count = ci.participants_count }
+ : new Channel { title = ci.title, photo = chatPhoto, participants_count = ci.participants_count,
+ restriction_reason = rrAbout,
+ flags = (ci.flags.HasFlag(ChatInvite.Flags.broadcast) ? Channel.Flags.broadcast | Channel.Flags.min : Channel.Flags.min) |
+ (ci.flags.HasFlag(ChatInvite.Flags.public_) ? Channel.Flags.has_username : 0) |
+ (ci.flags.HasFlag(ChatInvite.Flags.megagroup) ? Channel.Flags.megagroup : 0) |
+ (ci.flags.HasFlag(ChatInvite.Flags.request_needed) ? Channel.Flags.join_request : 0) };
+ }
+ return null;
+ }
+
+ /// Return chat and message details based on a message URL
+ /// Message Link, like https://t.me/c/1234567890/1234 or https://t.me/channelname/1234
+ /// Structure containing the message, chat and user details
+ /// If link is for private group (t.me/c/..), user must have joined the group
+ public async Task GetMessageByLink(string url)
+ {
+ int start = url.IndexOf("//");
+ start = url.IndexOf('/', start + 2) + 1;
+ int slash = url.IndexOf('/', start + 2);
+ if (start == 0 || slash == -1) throw new ArgumentException("Invalid URI");
+ int end = url.IndexOfAny(QueryOrFragment, slash + 1);
+ if (end == -1) end = url.Length;
+ ChatBase chat;
+ if (url[start] is 'c' or 'C' && url[start + 1] == '/')
+ {
+ long chatId = long.Parse(url[(start + 2)..slash]);
+ var chats = await this.Channels_GetChannels(new InputChannel(chatId, 0));
+ if (!chats.chats.TryGetValue(chatId, out chat))
+ throw new ApplicationException($"Channel {chatId} not found");
+ }
+ else
+ {
+ var resolved = await this.Contacts_ResolveUsername(url[start..slash]);
+ chat = resolved.Chat;
+ if (chat is null) throw new ApplicationException($"@{url[start..slash]} is not a Chat/Channel");
+ }
+ int msgId = int.Parse(url[(slash + 1)..end]);
+ return await this.Channels_GetMessages((Channel)chat, msgId) as Messages_ChannelMessages;
+ }
#endregion
}
}
From 86796ebf0c5f8bc3ff1bcf27aa20c8bf1ca2a8e5 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Sun, 26 Feb 2023 17:09:45 +0100
Subject: [PATCH 014/304] Correctly dispose session store on ctor exception
(#128)
---
README.md | 2 +-
src/Client.cs | 12 ++----------
src/Session.cs | 14 +++++++-------
3 files changed, 10 insertions(+), 18 deletions(-)
diff --git a/README.md b/README.md
index 1456e40..26656db 100644
--- a/README.md
+++ b/README.md
@@ -166,7 +166,7 @@ See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient
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, email, email_verification_code, session_key, server_address, device_model, system_version, app_version, system_lang_code, lang_pack, lang_code, firebase, user_id, bot_token**
+The other configuration items that you can provide include: **session_pathname, email, email_verification_code, session_key, server_address, device_model, system_version, app_version, system_lang_code, lang_pack, lang_code, firebase, user_id, bot_token**
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).
diff --git a/src/Client.cs b/src/Client.cs
index 2b24c02..edf2018 100644
--- a/src/Client.cs
+++ b/src/Client.cs
@@ -96,8 +96,8 @@ namespace WTelegram
public Client(Func configProvider = null, Stream sessionStore = null)
{
_config = configProvider ?? DefaultConfigOrAsk;
- sessionStore ??= new SessionStore(Config("session_pathname"));
var session_key = _config("session_key") ?? (_apiHash = Config("api_hash"));
+ sessionStore ??= new SessionStore(Config("session_pathname"));
_session = Session.LoadOrCreate(sessionStore, Convert.FromHexString(session_key));
if (_session.ApiId == 0) _session.ApiId = int.Parse(Config("api_id"));
if (_session.MainDC != 0) _session.DCSessions.TryGetValue(_session.MainDC, out _dcSession);
@@ -699,15 +699,7 @@ namespace WTelegram
static async Task DefaultTcpHandler(string host, int port)
{
var tcpClient = new TcpClient();
- try
- {
- await tcpClient.ConnectAsync(host, port);
- }
- catch
- {
- tcpClient.Dispose();
- throw;
- }
+ await tcpClient.ConnectAsync(host, port);
return tcpClient;
}
diff --git a/src/Session.cs b/src/Session.cs
index e5a8f12..76580ec 100644
--- a/src/Session.cs
+++ b/src/Session.cs
@@ -113,19 +113,19 @@ namespace WTelegram
session = JsonSerializer.Deserialize(utf8Json.AsSpan(32), Helpers.JsonOptions);
Helpers.Log(2, "Loaded previous session");
}
+ session ??= new Session();
+ session._store = store;
+ Encryption.RNG.GetBytes(session._encrypted, 0, 16);
+ session._encryptor = aes.CreateEncryptor(rgbKey, session._encrypted);
+ if (!session._encryptor.CanReuseTransform) session._reuseKey = rgbKey;
+ session._jsonWriter = new Utf8JsonWriter(session._jsonStream, default);
+ return session;
}
catch (Exception ex)
{
store.Dispose();
throw new ApplicationException($"Exception while reading session file: {ex.Message}\nUse the correct api_hash/id/key, or delete the file to start a new session", ex);
}
- session ??= new Session();
- session._store = store;
- Encryption.RNG.GetBytes(session._encrypted, 0, 16);
- session._encryptor = aes.CreateEncryptor(rgbKey, session._encrypted);
- if (!session._encryptor.CanReuseTransform) session._reuseKey = rgbKey;
- session._jsonWriter = new Utf8JsonWriter(session._jsonStream, default);
- return session;
}
internal void Save() // must be called with lock(session)
From 22ea4c6de8972f0630c6a5e4c33b7393c5e69c50 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Wed, 8 Mar 2023 20:10:09 +0100
Subject: [PATCH 015/304] update doc
---
.github/dev.yml | 2 +-
.github/release.yml | 2 +-
EXAMPLES.md | 5 +++--
FAQ.md | 2 +-
src/TL.Schema.cs | 8 ++++----
5 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index ca7837f..e53e55a 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -2,7 +2,7 @@ pr: none
trigger:
- master
-name: 3.2.3-dev.$(Rev:r)
+name: 3.3.1-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/.github/release.yml b/.github/release.yml
index 8d4f504..c5423ff 100644
--- a/.github/release.yml
+++ b/.github/release.yml
@@ -1,7 +1,7 @@
pr: none
trigger: none
-name: 3.2.$(Rev:r)
+name: 3.3.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/EXAMPLES.md b/EXAMPLES.md
index ff7700d..34ab979 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -160,10 +160,10 @@ foreach (var participant in participants.participants) // This is the better way
*Note: It is not possible to list only the Deleted Accounts. Those will be automatically removed by Telegram from your group after a while*
-## Fetch all messages (history) from a chat
+## Fetch all messages (history) from a chat/user
```csharp
var chats = await client.Messages_GetAllChats();
-InputPeer peer = chats.chats[1234567890]; // the chat we want
+InputPeer peer = chats.chats[1234567890]; // the chat (or User) we want
for (int offset_id = 0; ;)
{
var messages = await client.Messages_GetHistory(peer, offset_id);
@@ -180,6 +180,7 @@ for (int offset_id = 0; ;)
}
```
Notes:
+- `peer` can also be a User, obtained through methods like [`Messages_GetAllDialogs`](#list-dialogs)
- To stop at a specific msg ID, use Messages_GetHistory `min_id` argument. For example, `min_id: dialog.read_inbox_max_id`
- To mark the message history as read, use: `await client.ReadHistory(peer);`
diff --git a/FAQ.md b/FAQ.md
index 42b6f8e..c879365 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -202,7 +202,7 @@ If Telegram servers decide to shutdown this secondary connection, it's not an is
This should be transparent and pending API calls should automatically be resent upon reconnection.
You can choose to increase `MaxAutoReconnects` if it happens too often because your Internet connection is unstable.
-3) If you reach `MaxAutoReconnects` disconnections, then the **OnUpdate** event handler will receive a `ReactorError` object to notify you of the problem.
+3) If you reach `MaxAutoReconnects` disconnections, then the **OnUpdate** event handler will receive a `ReactorError` object to notify you of the problem,
and pending API calls throw the network IOException.
In this case, the recommended action would be to dispose the client and recreate one
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index a62ef21..977e840 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -114,17 +114,17 @@ namespace TL
/// Object defines a contact from the user's phone book. See Derived classes:
public abstract class InputContact : IObject { }
- /// Phone contact. The client_id is just an arbitrary contact ID: it should be set, for example, to an incremental number when using Contacts_ImportContacts, in order to retry importing only the contacts that weren't imported successfully. See
+ /// Phone contact. See
[TLDef(0xF392B7F4)]
public class InputPhoneContact : InputContact
{
- /// User identifier on the client
+ /// An arbitrary 64-bit integer: it should be set, for example, to an incremental number when using Contacts_ImportContacts, in order to retry importing only the contacts that weren't imported successfully, according to the client_ids returned in .retry_contacts.
public long client_id;
/// Phone number
public string phone;
- /// Contact's first name
+ /// Contact's first name
public string first_name;
- /// Contact's last name
+ /// Contact's last name
public string last_name;
}
From c646cac7385fbfdc3d4fec361831a1d5bbb540c1 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Wed, 8 Mar 2023 20:47:10 +0100
Subject: [PATCH 016/304] API Layer 154: bot app/webview stuff, modifying
stickers...
---
EXAMPLES.md | 2 +-
README.md | 2 +-
src/TL.Schema.cs | 141 ++++++++++++++++++++++-----
src/TL.SchemaFuncs.cs | 194 ++++++++++++++++++++++++++++++++++---
src/TL.Table.cs | 25 +++--
src/WTelegramClient.csproj | 2 +-
6 files changed, 317 insertions(+), 49 deletions(-)
diff --git a/EXAMPLES.md b/EXAMPLES.md
index 34ab979..ae0f20e 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -301,7 +301,7 @@ await client.SendMediaAsync(InputPeer.Self, null, inputFile);
// • Send a random dice/game-of-chance effect from the list of available "dices", see https://core.telegram.org/api/dice
var appConfig = await client.Help_GetAppConfig();
-var emojies_send_dice = appConfig["emojies_send_dice"] as string[];
+var emojies_send_dice = appConfig.config["emojies_send_dice"] as string[];
var dice_emoji = emojies_send_dice[new Random().Next(emojies_send_dice.Length)];
var diceMsg = await client.SendMessageAsync(InputPeer.Self, null, new InputMediaDice { emoticon = dice_emoji });
Console.WriteLine("Dice result:" + ((MessageMediaDice)diceMsg.media).value);
diff --git a/README.md b/README.md
index 26656db..b80b190 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[](https://corefork.telegram.org/methods)
+[](https://corefork.telegram.org/methods)
[](https://www.nuget.org/packages/WTelegramClient/)
[](https://dev.azure.com/wiz0u/WTelegramClient/_build?definitionId=7)
[](http://t.me/WTelegramBot?start=donate)
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index 977e840..bd9cfd1 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -2056,11 +2056,22 @@ namespace TL
public string message;
}
/// The domain name of the website on which the user has logged in. More about Telegram Login » See
- [TLDef(0xABE9AFFE)]
+ [TLDef(0xC516D679)]
public class MessageActionBotAllowed : MessageAction
{
+ public Flags flags;
/// The domain name of the website on which the user has logged in.
- public string domain;
+ [IfFlag(0)] public string domain;
+ [IfFlag(2)] public BotApp app;
+
+ [Flags] public enum Flags : uint
+ {
+ /// Field has a value
+ has_domain = 0x1,
+ attach_menu = 0x2,
+ /// Field has a value
+ has_app = 0x4,
+ }
}
/// Secure telegram passport values were received See
[TLDef(0x1B287353)]
@@ -2215,9 +2226,6 @@ namespace TL
{
public PhotoBase photo;
}
- /// See
- [TLDef(0xE7E75F97)]
- public class MessageActionAttachMenuBotAllowed : MessageAction { }
/// See
[TLDef(0xFE77345D)]
public class MessageActionRequestedPeer : MessageAction
@@ -4862,7 +4870,7 @@ namespace TL
}
/// Current configuration See
- [TLDef(0x232566AC)]
+ [TLDef(0xCC1A241E)]
public class Config : IObject
{
/// Flags, see TL conditional fields
@@ -4901,8 +4909,6 @@ namespace TL
public int push_chat_period_ms;
/// Not for client use
public int push_chat_limit;
- /// Maximum count of saved gifs
- public int saved_gifs_limit;
/// Only messages with age smaller than the one specified can be edited
public int edit_time_limit;
/// Only channel/supergroup messages with age smaller than the specified can be deleted
@@ -4913,16 +4919,10 @@ namespace TL
public int rating_e_decay;
/// Maximum number of recent stickers
public int stickers_recent_limit;
- /// Maximum number of faved stickers
- public int stickers_faved_limit;
/// Indicates that round videos (video notes) and voice messages sent in channels and older than the specified period must be marked as read
public int channels_read_media_period;
/// Temporary passport sessions
[IfFlag(0)] public int tmp_sessions;
- /// Maximum count of pinned dialogs
- public int pinned_dialogs_count_max;
- /// Maximum count of dialogs per folder
- public int pinned_infolder_count_max;
/// Maximum allowed outgoing ring time in VoIP calls: if the user we're calling doesn't reply within the specified time (in milliseconds), we should hang up the call
public int call_receive_timeout_ms;
/// Maximum allowed incoming ring time in VoIP calls: if the current user doesn't reply within the specified time (in milliseconds), the call will be automatically refused
@@ -4957,21 +4957,18 @@ namespace TL
[IfFlag(2)] public int base_lang_pack_version;
/// Default message reaction
[IfFlag(15)] public Reaction reactions_default;
+ [IfFlag(16)] public string autologin_token;
[Flags] public enum Flags : uint
{
/// Field has a value
has_tmp_sessions = 0x1,
- /// Whether phone calls can be used
- phonecalls_enabled = 0x2,
/// Field has a value
has_suggested_lang_code = 0x4,
/// Whether the client should use P2P by default for phone calls with contacts
default_p2p_contacts = 0x8,
/// Whether the client should preload featured stickers
preload_featured_stickers = 0x10,
- /// Whether the client should ignore phone entities
- ignore_phone_entities = 0x20,
/// Whether incoming private messages can be deleted for both participants
revoke_pm_inbox = 0x40,
/// Field has a value
@@ -4986,12 +4983,12 @@ namespace TL
has_img_search_username = 0x800,
/// Field has a value
has_static_maps_provider = 0x1000,
- /// Whether pfs was used
- pfs_enabled = 0x2000,
/// Whether to forcefully connect using IPv6 , even if the client knows that IPv4 is available.
force_try_ipv6 = 0x4000,
/// Field has a value
has_reactions_default = 0x8000,
+ /// Field has a value
+ has_autologin_token = 0x10000,
}
}
@@ -7720,7 +7717,7 @@ namespace TL
}
/// Result of a query to an inline bot See
- [TLDef(0x947CA848)]
+ [TLDef(0xE021F2F6)]
public class Messages_BotResults : IObject
{
/// Flags, see TL conditional fields
@@ -7731,6 +7728,7 @@ namespace TL
[IfFlag(1)] public string next_offset;
/// Whether the bot requested the user to message them in private
[IfFlag(2)] public InlineBotSwitchPM switch_pm;
+ [IfFlag(3)] public InlineBotWebView switch_webview;
/// The results
public BotInlineResultBase[] results;
/// Caching validity of the results
@@ -7746,6 +7744,8 @@ namespace TL
has_next_offset = 0x2,
/// Field has a value
has_switch_pm = 0x4,
+ /// Field has a value
+ has_switch_webview = 0x8,
}
}
@@ -9293,7 +9293,7 @@ namespace TL
}
/// Sticker in a stickerset See
- [TLDef(0xFFA0A496)]
+ [TLDef(0x32DA9E9C)]
public class InputStickerSetItem : IObject
{
/// Flags, see TL conditional fields
@@ -9304,11 +9304,14 @@ namespace TL
public string emoji;
/// Coordinates for mask sticker
[IfFlag(0)] public MaskCoords mask_coords;
+ [IfFlag(1)] public string keywords;
[Flags] public enum Flags : uint
{
/// Field has a value
has_mask_coords = 0x1,
+ /// Field has a value
+ has_keywords = 0x2,
}
}
@@ -13124,7 +13127,7 @@ namespace TL
public class Account_ResetPasswordOk : Account_ResetPasswordResult { }
/// A sponsored message. See
- [TLDef(0x3A836DF8)]
+ [TLDef(0xFC25B828)]
public class SponsoredMessage : IObject
{
/// Flags, see TL conditional fields
@@ -13145,6 +13148,8 @@ namespace TL
public string message;
/// Message entities for styled text
[IfFlag(1)] public MessageEntity[] entities;
+ [IfFlag(7)] public string sponsor_info;
+ [IfFlag(8)] public string additional_info;
[Flags] public enum Flags : uint
{
@@ -13161,6 +13166,10 @@ namespace TL
/// Whether the message needs to be labeled as "recommended" instead of "sponsored"
recommended = 0x20,
show_peer_photo = 0x40,
+ /// Field has a value
+ has_sponsor_info = 0x80,
+ /// Field has a value
+ has_additional_info = 0x100,
}
}
@@ -14245,4 +14254,90 @@ namespace TL
/// returns a or for the given Peer
public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats);
}
+
+ /// See
+ /// a value means help.appConfigNotModified
+ [TLDef(0xDD18782E)]
+ public class Help_AppConfig : IObject
+ {
+ public int hash;
+ public JsonObject config;
+ }
+
+ /// See
+ public abstract class InputBotApp : IObject { }
+ /// See
+ [TLDef(0xA920BD7A)]
+ public class InputBotAppID : InputBotApp
+ {
+ public long id;
+ public long access_hash;
+ }
+ /// See
+ [TLDef(0x908C0407)]
+ public class InputBotAppShortName : InputBotApp
+ {
+ public InputUserBase bot_id;
+ public string short_name;
+ }
+
+ /// See
+ /// a value means botAppNotModified
+ [TLDef(0x95FCD1D6)]
+ public class BotApp : IObject
+ {
+ public Flags flags;
+ public long id;
+ public long access_hash;
+ public string short_name;
+ public string title;
+ public string description;
+ public PhotoBase photo;
+ [IfFlag(0)] public DocumentBase document;
+ public long hash;
+
+ [Flags] public enum Flags : uint
+ {
+ has_document = 0x1,
+ }
+ }
+
+ /// See
+ [TLDef(0xEB50ADF5)]
+ public class Messages_BotApp : IObject
+ {
+ public Flags flags;
+ public BotApp app;
+
+ [Flags] public enum Flags : uint
+ {
+ inactive = 0x1,
+ request_write_access = 0x2,
+ }
+ }
+
+ /// See
+ public abstract class AppWebViewResult : IObject { }
+ /// See
+ [TLDef(0x3C1B4F0D)]
+ public class AppWebViewResultUrl : AppWebViewResult
+ {
+ public string url;
+ }
+
+ /// See
+ [TLDef(0xB57295D5)]
+ public class InlineBotWebView : IObject
+ {
+ public string text;
+ public string url;
+ }
+
+ /// See
+ [TLDef(0x4A4FF172)]
+ public class ReadParticipantDate : IObject
+ {
+ public long user_id;
+ public DateTime date;
+ }
}
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index de02856..ac8210d 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -2044,15 +2044,16 @@ namespace TL
/// The maximum amount of time in seconds that the result of the inline query may be cached on the server. Defaults to 300.
/// Pass the offset that a client should send in the next query with the same text to receive more results. Pass an empty string if there are no more results or if you don't support pagination. Offset length can't exceed 64 bytes.
/// If passed, clients will display a button with specified text that switches the user to a private chat with the bot and sends the bot a start message with a certain parameter.
- public static Task Messages_SetInlineBotResults(this Client client, long query_id, InputBotInlineResultBase[] results, DateTime cache_time, string next_offset = null, InlineBotSwitchPM switch_pm = null, bool gallery = false, bool private_ = false)
+ public static Task Messages_SetInlineBotResults(this Client client, long query_id, InputBotInlineResultBase[] results, DateTime cache_time, string next_offset = null, InlineBotSwitchPM switch_pm = null, InlineBotWebView switch_webview = null, bool gallery = false, bool private_ = false)
=> client.Invoke(new Messages_SetInlineBotResults
{
- flags = (Messages_SetInlineBotResults.Flags)((next_offset != null ? 0x4 : 0) | (switch_pm != null ? 0x8 : 0) | (gallery ? 0x1 : 0) | (private_ ? 0x2 : 0)),
+ flags = (Messages_SetInlineBotResults.Flags)((next_offset != null ? 0x4 : 0) | (switch_pm != null ? 0x8 : 0) | (switch_webview != null ? 0x10 : 0) | (gallery ? 0x1 : 0) | (private_ ? 0x2 : 0)),
query_id = query_id,
results = results,
cache_time = cache_time,
next_offset = next_offset,
switch_pm = switch_pm,
+ switch_webview = switch_webview,
});
/// Send a result obtained using Messages_GetInlineBotResults. See Possible codes: 400,403,420,500 (details)
@@ -3076,7 +3077,7 @@ namespace TL
/// Get which users read a specific message: only available for groups and supergroups with less than chat_read_mark_size_threshold members, read receipts will be stored for chat_read_mark_expire_period seconds after the message was sent, see client configuration for more info ». See Possible codes: 400 (details)
/// Dialog
/// Message ID
- public static Task Messages_GetMessageReadParticipants(this Client client, InputPeer peer, int msg_id)
+ public static Task Messages_GetMessageReadParticipants(this Client client, InputPeer peer, int msg_id)
=> client.Invoke(new Messages_GetMessageReadParticipants
{
peer = peer,
@@ -3358,10 +3359,10 @@ namespace TL
/// Web app URL
/// Theme parameters »
/// Short name of the application; 0-64 English letters, digits, and underscores
- public static Task Messages_RequestSimpleWebView(this Client client, InputUserBase bot, string url, string platform, DataJSON theme_params = null)
+ public static Task Messages_RequestSimpleWebView(this Client client, InputUserBase bot, string url, string platform, DataJSON theme_params = null, bool from_switch_webview = false)
=> client.Invoke(new Messages_RequestSimpleWebView
{
- flags = (Messages_RequestSimpleWebView.Flags)(theme_params != null ? 0x1 : 0),
+ flags = (Messages_RequestSimpleWebView.Flags)((theme_params != null ? 0x1 : 0) | (from_switch_webview ? 0x2 : 0)),
bot = bot,
url = url,
theme_params = theme_params,
@@ -3553,6 +3554,26 @@ namespace TL
peer = peer,
});
+ /// See
+ public static Task Messages_GetBotApp(this Client client, InputBotApp app, long hash = default)
+ => client.Invoke(new Messages_GetBotApp
+ {
+ app = app,
+ hash = hash,
+ });
+
+ /// See
+ public static Task Messages_RequestAppWebView(this Client client, InputPeer peer, InputBotApp app, string platform, string start_param = null, DataJSON theme_params = null, bool write_allowed = false)
+ => client.Invoke(new Messages_RequestAppWebView
+ {
+ flags = (Messages_RequestAppWebView.Flags)((start_param != null ? 0x2 : 0) | (theme_params != null ? 0x4 : 0) | (write_allowed ? 0x1 : 0)),
+ peer = peer,
+ app = app,
+ start_param = start_param,
+ theme_params = theme_params,
+ platform = platform,
+ });
+
/// Returns a current state of updates. See [bots: ✓]
public static Task Updates_GetState(this Client client)
=> client.Invoke(new Updates_GetState
@@ -3831,9 +3852,11 @@ namespace TL
});
/// Get app-specific configuration, see client configuration for more info on the result. See
- public static Task Help_GetAppConfig(this Client client)
+ /// a null value means help.appConfigNotModified
+ public static Task Help_GetAppConfig(this Client client, int hash = default)
=> client.Invoke(new Help_GetAppConfig
{
+ hash = hash,
});
/// Saves logs of application on the server. See
@@ -4566,6 +4589,23 @@ namespace TL
admin_rights = admin_rights,
});
+ /// See
+ public static Task Bots_SetBotInfo(this Client client, string lang_code, string about = null, string description = null)
+ => client.Invoke(new Bots_SetBotInfo
+ {
+ flags = (Bots_SetBotInfo.Flags)((about != null ? 0x1 : 0) | (description != null ? 0x2 : 0)),
+ lang_code = lang_code,
+ about = about,
+ description = description,
+ });
+
+ /// See
+ public static Task Bots_GetBotInfo(this Client client, string lang_code)
+ => client.Invoke(new Bots_GetBotInfo
+ {
+ lang_code = lang_code,
+ });
+
/// Get a payment form See Possible codes: 400 (details)
/// Invoice
/// A JSON object with the following keys, containing color theme information (integers, RGB24) to pass to the payment provider, to apply in eventual verification pages:
bg_color - Background color
text_color - Text color
hint_color - Hint text color
link_color - Link color
button_color - Button color
button_text_color - Button text color
@@ -4688,10 +4728,10 @@ namespace TL
/// Stickers
/// Used when importing stickers using the sticker import SDKs, specifies the name of the software that created the stickers
/// a null value means messages.stickerSetNotModified
- public static Task Stickers_CreateStickerSet(this Client client, InputUserBase user_id, string title, string short_name, InputStickerSetItem[] stickers, InputDocument thumb = null, string software = null, bool masks = false, bool animated = false, bool videos = false)
+ public static Task Stickers_CreateStickerSet(this Client client, InputUserBase user_id, string title, string short_name, InputStickerSetItem[] stickers, InputDocument thumb = null, string software = null, bool masks = false, bool animated = false, bool videos = false, bool emojis = false, bool text_color = false)
=> client.Invoke(new Stickers_CreateStickerSet
{
- flags = (Stickers_CreateStickerSet.Flags)((thumb != null ? 0x4 : 0) | (software != null ? 0x8 : 0) | (masks ? 0x1 : 0) | (animated ? 0x2 : 0) | (videos ? 0x10 : 0)),
+ flags = (Stickers_CreateStickerSet.Flags)((thumb != null ? 0x4 : 0) | (software != null ? 0x8 : 0) | (masks ? 0x1 : 0) | (animated ? 0x2 : 0) | (videos ? 0x10 : 0) | (emojis ? 0x20 : 0) | (text_color ? 0x40 : 0)),
user_id = user_id,
title = title,
short_name = short_name,
@@ -4735,11 +4775,13 @@ namespace TL
/// Stickerset
/// Thumbnail
/// a null value means messages.stickerSetNotModified
- public static Task Stickers_SetStickerSetThumb(this Client client, InputStickerSet stickerset, InputDocument thumb)
+ public static Task Stickers_SetStickerSetThumb(this Client client, InputStickerSet stickerset, InputDocument thumb = null, long? thumb_document_id = null)
=> client.Invoke(new Stickers_SetStickerSetThumb
{
+ flags = (Stickers_SetStickerSetThumb.Flags)((thumb != null ? 0x1 : 0) | (thumb_document_id != null ? 0x2 : 0)),
stickerset = stickerset,
thumb = thumb,
+ thumb_document_id = thumb_document_id.GetValueOrDefault(),
});
/// Check whether the given short name is available See Possible codes: 400 (details)
@@ -4758,6 +4800,34 @@ namespace TL
title = title,
});
+ /// See
+ /// a null value means messages.stickerSetNotModified
+ public static Task Stickers_ChangeSticker(this Client client, InputDocument sticker, string emoji = null, MaskCoords mask_coords = null, string keywords = null)
+ => client.Invoke(new Stickers_ChangeSticker
+ {
+ flags = (Stickers_ChangeSticker.Flags)((emoji != null ? 0x1 : 0) | (mask_coords != null ? 0x2 : 0) | (keywords != null ? 0x4 : 0)),
+ sticker = sticker,
+ emoji = emoji,
+ mask_coords = mask_coords,
+ keywords = keywords,
+ });
+
+ /// See
+ /// a null value means messages.stickerSetNotModified
+ public static Task Stickers_RenameStickerSet(this Client client, InputStickerSet stickerset, string title)
+ => client.Invoke(new Stickers_RenameStickerSet
+ {
+ stickerset = stickerset,
+ title = title,
+ });
+
+ /// See
+ public static Task Stickers_DeleteStickerSet(this Client client, InputStickerSet stickerset)
+ => client.Invoke(new Stickers_DeleteStickerSet
+ {
+ stickerset = stickerset,
+ });
+
/// Get phone call configuration to be passed to libtgvoip's shared config See
public static Task Phone_GetCallConfig(this Client client)
=> client.Invoke(new Phone_GetCallConfig
@@ -6861,7 +6931,7 @@ namespace TL.Methods
}
}
- [TLDef(0xEB5EA206)]
+ [TLDef(0xBB12A419)]
public class Messages_SetInlineBotResults : IMethod
{
public Flags flags;
@@ -6870,6 +6940,7 @@ namespace TL.Methods
public DateTime cache_time;
[IfFlag(2)] public string next_offset;
[IfFlag(3)] public InlineBotSwitchPM switch_pm;
+ [IfFlag(4)] public InlineBotWebView switch_webview;
[Flags] public enum Flags : uint
{
@@ -6877,6 +6948,7 @@ namespace TL.Methods
private_ = 0x2,
has_next_offset = 0x4,
has_switch_pm = 0x8,
+ has_switch_webview = 0x10,
}
}
@@ -7765,8 +7837,8 @@ namespace TL.Methods
public string emoticon;
}
- [TLDef(0x2C6F97B7)]
- public class Messages_GetMessageReadParticipants : IMethod
+ [TLDef(0x31C1C44F)]
+ public class Messages_GetMessageReadParticipants : IMethod
{
public InputPeer peer;
public int msg_id;
@@ -8029,6 +8101,7 @@ namespace TL.Methods
[Flags] public enum Flags : uint
{
has_theme_params = 0x1,
+ from_switch_webview = 0x2,
}
}
@@ -8169,6 +8242,31 @@ namespace TL.Methods
}
}
+ [TLDef(0x34FDC5C3)]
+ public class Messages_GetBotApp : IMethod
+ {
+ public InputBotApp app;
+ public long hash;
+ }
+
+ [TLDef(0x8C5A3B3C)]
+ public class Messages_RequestAppWebView : IMethod
+ {
+ public Flags flags;
+ public InputPeer peer;
+ public InputBotApp app;
+ [IfFlag(1)] public string start_param;
+ [IfFlag(2)] public DataJSON theme_params;
+ public string platform;
+
+ [Flags] public enum Flags : uint
+ {
+ write_allowed = 0x1,
+ has_start_param = 0x2,
+ has_theme_params = 0x4,
+ }
+ }
+
[TLDef(0xEDD4882A)]
public class Updates_GetState : IMethod { }
@@ -8393,8 +8491,11 @@ namespace TL.Methods
public string path;
}
- [TLDef(0x98914110)]
- public class Help_GetAppConfig : IMethod { }
+ [TLDef(0x61E3F854)]
+ public class Help_GetAppConfig : IMethod
+ {
+ public int hash;
+ }
[TLDef(0x6F02F748)]
public class Help_SaveAppLog : IMethod
@@ -8975,6 +9076,27 @@ namespace TL.Methods
public ChatAdminRights admin_rights;
}
+ [TLDef(0xA365DF7A)]
+ public class Bots_SetBotInfo : IMethod
+ {
+ public Flags flags;
+ public string lang_code;
+ [IfFlag(0)] public string about;
+ [IfFlag(1)] public string description;
+
+ [Flags] public enum Flags : uint
+ {
+ has_about = 0x1,
+ has_description = 0x2,
+ }
+ }
+
+ [TLDef(0x75EC12E6)]
+ public class Bots_GetBotInfo : IMethod
+ {
+ public string lang_code;
+ }
+
[TLDef(0x37148DBB)]
public class Payments_GetPaymentForm : IMethod
{
@@ -9092,6 +9214,8 @@ namespace TL.Methods
has_thumb = 0x4,
has_software = 0x8,
videos = 0x10,
+ emojis = 0x20,
+ text_color = 0x40,
}
}
@@ -9115,11 +9239,19 @@ namespace TL.Methods
public InputStickerSetItem sticker;
}
- [TLDef(0x9A364E30)]
+ [TLDef(0xA76A5392)]
public class Stickers_SetStickerSetThumb : IMethod
{
+ public Flags flags;
public InputStickerSet stickerset;
- public InputDocument thumb;
+ [IfFlag(0)] public InputDocument thumb;
+ [IfFlag(1)] public long thumb_document_id;
+
+ [Flags] public enum Flags : uint
+ {
+ has_thumb = 0x1,
+ has_thumb_document_id = 0x2,
+ }
}
[TLDef(0x284B3639)]
@@ -9134,6 +9266,36 @@ namespace TL.Methods
public string title;
}
+ [TLDef(0xF5537EBC)]
+ public class Stickers_ChangeSticker : IMethod
+ {
+ public Flags flags;
+ public InputDocument sticker;
+ [IfFlag(0)] public string emoji;
+ [IfFlag(1)] public MaskCoords mask_coords;
+ [IfFlag(2)] public string keywords;
+
+ [Flags] public enum Flags : uint
+ {
+ has_emoji = 0x1,
+ has_mask_coords = 0x2,
+ has_keywords = 0x4,
+ }
+ }
+
+ [TLDef(0x124B1C00)]
+ public class Stickers_RenameStickerSet : IMethod
+ {
+ public InputStickerSet stickerset;
+ public string title;
+ }
+
+ [TLDef(0x87704394)]
+ public class Stickers_DeleteStickerSet : IMethod
+ {
+ public InputStickerSet stickerset;
+ }
+
[TLDef(0x55451FA9)]
public class Phone_GetCallConfig : IMethod { }
diff --git a/src/TL.Table.cs b/src/TL.Table.cs
index f7e6dbe..9cb6716 100644
--- a/src/TL.Table.cs
+++ b/src/TL.Table.cs
@@ -6,7 +6,7 @@ namespace TL
{
public static class Layer
{
- public const int Version = 152; // fetched 03/02/2023 21:46:20
+ public const int Version = 154; // fetched 08/03/2023 19:08:02
internal const int SecretChats = 144;
internal const int MTProto2 = 73;
internal const uint VectorCtor = 0x1CB5C415;
@@ -177,7 +177,7 @@ namespace TL
[0x80E11A7F] = typeof(MessageActionPhoneCall),
[0x4792929B] = typeof(MessageActionScreenshotTaken),
[0xFAE69F56] = typeof(MessageActionCustomAction),
- [0xABE9AFFE] = typeof(MessageActionBotAllowed),
+ [0xC516D679] = typeof(MessageActionBotAllowed),
[0x1B287353] = typeof(MessageActionSecureValuesSentMe),
[0xD95C6154] = typeof(MessageActionSecureValuesSent),
[0xF3F25F76] = typeof(MessageActionContactSignUp),
@@ -194,7 +194,6 @@ namespace TL
[0x0D999256] = typeof(MessageActionTopicCreate),
[0xC0944820] = typeof(MessageActionTopicEdit),
[0x57DE635E] = typeof(MessageActionSuggestProfilePhoto),
- [0xE7E75F97] = typeof(MessageActionAttachMenuBotAllowed),
[0xFE77345D] = typeof(MessageActionRequestedPeer),
[0xD58A08C6] = typeof(Dialog),
[0x71BD134C] = typeof(DialogFolder),
@@ -388,7 +387,7 @@ namespace TL
[0x096A18D5] = typeof(Upload_File),
[0xF18CDA44] = typeof(Upload_FileCdnRedirect),
[0x18B7A10D] = typeof(DcOption),
- [0x232566AC] = typeof(Config),
+ [0xCC1A241E] = typeof(Config),
[0x8E1A1775] = typeof(NearestDc),
[0xCCBBCE30] = typeof(Help_AppUpdate),
[0xC45A6536] = null,//Help_NoAppUpdate
@@ -594,7 +593,7 @@ namespace TL
[0x354A9B09] = typeof(BotInlineMessageMediaInvoice),
[0x11965F3A] = typeof(BotInlineResult),
[0x17DB940B] = typeof(BotInlineMediaResult),
- [0x947CA848] = typeof(Messages_BotResults),
+ [0xE021F2F6] = typeof(Messages_BotResults),
[0x5DAB1AF4] = typeof(ExportedMessageLink),
[0x5F777DCE] = typeof(MessageFwdHeader),
[0x3DBB5986] = typeof(Auth_SentCodeTypeApp),
@@ -709,7 +708,7 @@ namespace TL
[0x8AC32801] = typeof(InputPaymentCredentialsGooglePay),
[0xDB64FD34] = typeof(Account_TmpPassword),
[0xB6213CDF] = typeof(ShippingOption),
- [0xFFA0A496] = typeof(InputStickerSetItem),
+ [0x32DA9E9C] = typeof(InputStickerSetItem),
[0x1E36FDED] = typeof(InputPhoneCall),
[0x5366C915] = typeof(PhoneCallEmpty),
[0xC5226F17] = typeof(PhoneCallWaiting),
@@ -977,7 +976,7 @@ namespace TL
[0xE3779861] = typeof(Account_ResetPasswordFailedWait),
[0xE9EFFC7D] = typeof(Account_ResetPasswordRequestedWait),
[0xE926D63E] = typeof(Account_ResetPasswordOk),
- [0x3A836DF8] = typeof(SponsoredMessage),
+ [0xFC25B828] = typeof(SponsoredMessage),
[0xC9EE1D87] = typeof(Messages_SponsoredMessages),
[0x1839490F] = null,//Messages_SponsoredMessagesEmpty
[0xC9B0539F] = typeof(SearchResultsCalendarPeriod),
@@ -1072,6 +1071,16 @@ namespace TL
[0xC84834CE] = typeof(AutoSaveSettings),
[0x81602D47] = typeof(AutoSaveException),
[0x4C3E069D] = typeof(Account_AutoSaveSettings),
+ [0x7CDE641D] = null,//Help_AppConfigNotModified
+ [0xDD18782E] = typeof(Help_AppConfig),
+ [0xA920BD7A] = typeof(InputBotAppID),
+ [0x908C0407] = typeof(InputBotAppShortName),
+ [0x5DA674B7] = null,//BotAppNotModified
+ [0x95FCD1D6] = typeof(BotApp),
+ [0xEB50ADF5] = typeof(Messages_BotApp),
+ [0x3C1B4F0D] = typeof(AppWebViewResultUrl),
+ [0xB57295D5] = typeof(InlineBotWebView),
+ [0x4A4FF172] = typeof(ReadParticipantDate),
// from TL.Secret:
[0x6ABD9782] = typeof(Layer143.DecryptedMessageMediaDocument),
[0x91CC4674] = typeof(Layer73.DecryptedMessage),
@@ -1190,6 +1199,8 @@ namespace TL
// from TL.Secret:
[typeof(EmojiList)] = 0x481EADFA, //emojiListNotModified
[typeof(Messages_EmojiGroups)] = 0x6FB4AD87, //messages.emojiGroupsNotModified
+ [typeof(Help_AppConfig)] = 0x7CDE641D, //help.appConfigNotModified
+ [typeof(BotApp)] = 0x5DA674B7, //botAppNotModified
[typeof(DecryptedMessageMedia)] = 0x089F5C4A, //decryptedMessageMediaEmpty
};
}
diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj
index f65b2bf..889d922 100644
--- a/src/WTelegramClient.csproj
+++ b/src/WTelegramClient.csproj
@@ -13,7 +13,7 @@
WTelegramClient
0.0.0
Wizou
- Telegram Client API (MTProto) library written 100% in C# and .NET Standard | Latest API layer: 152
Release Notes:
$(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))
+ Telegram Client API (MTProto) library written 100% in C# and .NET Standard | Latest API layer: 154
Release Notes:
$(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))
Copyright © Olivier Marcoux 2021-2023
MIT
https://github.com/wiz0u/WTelegramClient
From b63829393e4acffe30eae21a5b083e914d9dd7d8 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Thu, 9 Mar 2023 22:32:57 +0100
Subject: [PATCH 017/304] Don't raise ReactorError for alt DCs
---
.github/dev.yml | 2 +-
src/Client.cs | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index e53e55a..d4810da 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -2,7 +2,7 @@ pr: none
trigger:
- master
-name: 3.3.1-dev.$(Rev:r)
+name: 3.3.2-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/src/Client.cs b/src/Client.cs
index edf2018..3bcfc31 100644
--- a/src/Client.cs
+++ b/src/Client.cs
@@ -347,7 +347,8 @@ namespace WTelegram
}
catch
{
- RaiseUpdate(reactorError);
+ if (IsMainDC)
+ RaiseUpdate(reactorError);
lock (_pendingRpcs) // abort all pending requests
{
foreach (var rpc in _pendingRpcs.Values)
From fd9177f8059de6748454da2a30d62a46b21b198c Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Thu, 9 Mar 2023 22:41:07 +0100
Subject: [PATCH 018/304] API Layer 155: timestamp of reactions
---
README.md | 2 +-
src/TL.Schema.cs | 9 ++++++++-
src/TL.Table.cs | 5 +++--
src/WTelegramClient.csproj | 2 +-
4 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index b80b190..d60fb32 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[](https://corefork.telegram.org/methods)
+[](https://corefork.telegram.org/methods)
[](https://www.nuget.org/packages/WTelegramClient/)
[](https://dev.azure.com/wiz0u/WTelegramClient/_build?definitionId=7)
[](http://t.me/WTelegramBot?start=donate)
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index bd9cfd1..7e3fd02 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -4449,6 +4449,12 @@ namespace TL
/// See
[TLDef(0xEC05B097)]
public class UpdateAutoSaveSettings : Update { }
+ /// See
+ [TLDef(0xCCF08AD6)]
+ public class UpdateGroupInvitePrivacyForbidden : Update
+ {
+ public long user_id;
+ }
/// Updates state. See
[TLDef(0xA56C2A3E)]
@@ -13442,13 +13448,14 @@ namespace TL
}
/// How a certain peer reacted to the message See
- [TLDef(0xB156FE9C)]
+ [TLDef(0x8C79B63C)]
public class MessagePeerReaction : IObject
{
/// Flags, see TL conditional fields
public Flags flags;
/// Peer that reacted to the message
public Peer peer_id;
+ public DateTime date;
/// Reaction emoji
public Reaction reaction;
diff --git a/src/TL.Table.cs b/src/TL.Table.cs
index 9cb6716..57e224f 100644
--- a/src/TL.Table.cs
+++ b/src/TL.Table.cs
@@ -6,7 +6,7 @@ namespace TL
{
public static class Layer
{
- public const int Version = 154; // fetched 08/03/2023 19:08:02
+ public const int Version = 155; // fetched 09/03/2023 20:45:49
internal const int SecretChats = 144;
internal const int MTProto2 = 73;
internal const uint VectorCtor = 0x1CB5C415;
@@ -369,6 +369,7 @@ namespace TL
[0xFE198602] = typeof(UpdateChannelPinnedTopics),
[0x20529438] = typeof(UpdateUser),
[0xEC05B097] = typeof(UpdateAutoSaveSettings),
+ [0xCCF08AD6] = typeof(UpdateGroupInvitePrivacyForbidden),
[0xA56C2A3E] = typeof(Updates_State),
[0x5D75A138] = typeof(Updates_DifferenceEmpty),
[0x00F49CA0] = typeof(Updates_Difference),
@@ -993,7 +994,7 @@ namespace TL
[0xC077EC01] = typeof(AvailableReaction),
[0x9F071957] = null,//Messages_AvailableReactionsNotModified
[0x768E3AAD] = typeof(Messages_AvailableReactions),
- [0xB156FE9C] = typeof(MessagePeerReaction),
+ [0x8C79B63C] = typeof(MessagePeerReaction),
[0x80EB48AF] = typeof(GroupCallStreamChannel),
[0xD0E482B2] = typeof(Phone_GroupCallStreamChannels),
[0x2DBF3432] = typeof(Phone_GroupCallStreamRtmpUrl),
diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj
index 889d922..68efad0 100644
--- a/src/WTelegramClient.csproj
+++ b/src/WTelegramClient.csproj
@@ -13,7 +13,7 @@
WTelegramClient
0.0.0
Wizou
- Telegram Client API (MTProto) library written 100% in C# and .NET Standard | Latest API layer: 154
Release Notes:
$(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))
+ Telegram Client API (MTProto) library written 100% in C# and .NET Standard | Latest API layer: 155
Release Notes:
$(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))
Copyright © Olivier Marcoux 2021-2023
MIT
https://github.com/wiz0u/WTelegramClient
From 2f3106fe693220676fdf8249fa0cc39bcd07fcd2 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Thu, 16 Mar 2023 13:43:18 +0100
Subject: [PATCH 019/304] MainUsername property on IPeerInfo
---
.github/FUNDING.yml | 3 +-
.github/dev.yml | 2 +-
EXAMPLES.md | 3 +-
README.md | 4 +-
src/TL.Helpers.cs | 10 ++-
src/TL.Schema.cs | 68 +++++++++++++++---
src/TL.SchemaFuncs.cs | 160 +++++++++++++++++++++---------------------
src/TL.Table.cs | 2 +-
8 files changed, 153 insertions(+), 99 deletions(-)
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index cf80d38..1accf5e 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1 +1,2 @@
-custom: ["http://t.me/WTelegramBot?start=donate"]
+github: wiz0u
+custom: ["https://www.buymeacoffee.com/wizou", "http://t.me/WTelegramBot?start=donate"]
diff --git a/.github/dev.yml b/.github/dev.yml
index d4810da..6b18a3e 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -2,7 +2,7 @@ pr: none
trigger:
- master
-name: 3.3.2-dev.$(Rev:r)
+name: 3.3.3-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/EXAMPLES.md b/EXAMPLES.md
index ae0f20e..4bb75c8 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -374,8 +374,9 @@ var chatInvite = await client.Messages_CheckChatInvite("HASH"); // optional: get
await client.Messages_ImportChatInvite("HASH"); // join the channel/group
// Note: This works also with HASH invite links from public channel/group
```
-Note: `CheckChatInvite` can return [3 different types of invitation object](https://corefork.telegram.org/type/ChatInvite)
+`CheckChatInvite` can return [3 different types of invitation object](https://corefork.telegram.org/type/ChatInvite)
+You can also use helper methods `AnalyzeInviteLink` and `GetMessageByLink` to more easily fetch information from links.
## Add/Invite/Remove someone in a chat
```csharp
diff --git a/README.md b/README.md
index d60fb32..8a524db 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
[](https://corefork.telegram.org/methods)
[](https://www.nuget.org/packages/WTelegramClient/)
[](https://dev.azure.com/wiz0u/WTelegramClient/_build?definitionId=7)
-[](http://t.me/WTelegramBot?start=donate)
+[](https://www.buymeacoffee.com/wizou)
## _Telegram Client API library written 100% in C# and .NET_
@@ -195,4 +195,4 @@ as well as the [API Terms of Service](https://core.telegram.org/api/terms) or yo
If you read all this ReadMe, the [Frequently Asked Questions](https://wiz0u.github.io/WTelegramClient/FAQ),
the [Examples codes](https://wiz0u.github.io/WTelegramClient/EXAMPLES) and still have questions, feedback is welcome in our Telegram group [@WTelegramClient](https://t.me/WTelegramClient)
-If you like this library, please [consider a donation](http://t.me/WTelegramBot?start=donate) ❤ This will help the project keep going.
+If you like this library, you can [buy me a coffee](https://www.buymeacoffee.com/wizou) ❤ This will help the project keep going.
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index 1acaff5..1b7b952 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -12,6 +12,7 @@ namespace TL
{
long ID { get; }
bool IsActive { get; }
+ string MainUsername { get; }
InputPeer ToInputPeer();
}
@@ -142,6 +143,7 @@ namespace TL
{
public abstract long ID { get; }
public abstract bool IsActive { get; }
+ public abstract string MainUsername { get; }
public abstract InputPeer ToInputPeer();
protected abstract InputUser ToInputUser();
public static implicit operator InputPeer(UserBase user) => user?.ToInputPeer();
@@ -151,6 +153,7 @@ namespace TL
{
public override long ID => id;
public override bool IsActive => false;
+ public override string MainUsername => null;
public override string ToString() => null;
public override InputPeer ToInputPeer() => null;
protected override InputUser ToInputUser() => null;
@@ -159,13 +162,13 @@ namespace TL
{
public override long ID => id;
public override bool IsActive => (flags & Flags.deleted) == 0;
- public bool IsBot => (flags & Flags.bot) != 0;
- public string MainUsername => username ?? usernames?.FirstOrDefault(u => u.flags.HasFlag(Username.Flags.active))?.username;
+ public override string MainUsername => username ?? usernames?.FirstOrDefault(u => u.flags.HasFlag(Username.Flags.active))?.username;
public override string ToString() => MainUsername is string uname ? '@' + uname : last_name == null ? first_name : $"{first_name} {last_name}";
public override InputPeer ToInputPeer() => new InputPeerUser(id, access_hash);
protected override InputUser ToInputUser() => new(id, access_hash);
/// An estimation of the number of days ago the user was last seen (Online=0, Recently=1, LastWeek=5, LastMonth=20, LongTimeAgo=150)
public TimeSpan LastSeenAgo => status?.LastSeenAgo ?? TimeSpan.FromDays(150);
+ public bool IsBot => (flags & Flags.bot) != 0;
}
/// a null value means userStatusEmpty = last seen a long time ago, more than a month (or blocked/deleted users)
@@ -183,6 +186,7 @@ namespace TL
{
/// Is this chat among current user active chats?
public abstract bool IsActive { get; }
+ public virtual string MainUsername => null;
public abstract ChatPhoto Photo { get; }
/// returns true if you're banned of any of these rights
public abstract bool IsBanned(ChatBannedRights.Flags flags = 0);
@@ -216,7 +220,7 @@ namespace TL
partial class Channel
{
public override bool IsActive => (flags & Flags.left) == 0;
- public string MainUsername => username ?? usernames?.FirstOrDefault(u => u.flags.HasFlag(Username.Flags.active))?.username;
+ public override string MainUsername => username ?? usernames?.FirstOrDefault(u => u.flags.HasFlag(Username.Flags.active))?.username;
public override ChatPhoto Photo => photo;
public override bool IsBanned(ChatBannedRights.Flags flags = 0) => ((banned_rights?.flags ?? 0) & flags) != 0 || ((default_banned_rights?.flags ?? 0) & flags) != 0;
public override InputPeer ToInputPeer() => new InputPeerChannel(id, access_hash);
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index 7e3fd02..c3c7207 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -118,13 +118,13 @@ namespace TL
[TLDef(0xF392B7F4)]
public class InputPhoneContact : InputContact
{
- /// An arbitrary 64-bit integer: it should be set, for example, to an incremental number when using Contacts_ImportContacts, in order to retry importing only the contacts that weren't imported successfully, according to the client_ids returned in .retry_contacts.
+ /// An arbitrary 64-bit integer: it should be set, for example, to an incremental number when using Contacts_ImportContacts, in order to retry importing only the contacts that weren't imported successfully, according to the client_ids returned in .retry_contacts.
public long client_id;
/// Phone number
public string phone;
- /// Contact's first name
+ /// Contact's first name
public string first_name;
- /// Contact's last name
+ /// Contact's last name
public string last_name;
}
@@ -2059,6 +2059,7 @@ namespace TL
[TLDef(0xC516D679)]
public class MessageActionBotAllowed : MessageAction
{
+ /// Flags, see TL conditional fields
public Flags flags;
/// The domain name of the website on which the user has logged in.
[IfFlag(0)] public string domain;
@@ -2133,6 +2134,7 @@ namespace TL
[TLDef(0x3C134D7B)]
public class MessageActionSetMessagesTTL : MessageAction
{
+ /// Flags, see TL conditional fields
public Flags flags;
/// New Time-To-Live
public int period;
@@ -2192,6 +2194,7 @@ namespace TL
[TLDef(0x0D999256)]
public class MessageActionTopicCreate : MessageAction
{
+ /// Flags, see TL conditional fields
public Flags flags;
public string title;
public int icon_color;
@@ -2199,6 +2202,7 @@ namespace TL
[Flags] public enum Flags : uint
{
+ /// Field has a value
has_icon_emoji_id = 0x1,
}
}
@@ -2206,6 +2210,7 @@ namespace TL
[TLDef(0xC0944820)]
public class MessageActionTopicEdit : MessageAction
{
+ /// Flags, see TL conditional fields
public Flags flags;
[IfFlag(0)] public string title;
[IfFlag(1)] public long icon_emoji_id;
@@ -2214,9 +2219,13 @@ namespace TL
[Flags] public enum Flags : uint
{
+ /// Field has a value
has_title = 0x1,
+ /// Field has a value
has_icon_emoji_id = 0x2,
+ /// Field has a value
has_closed = 0x4,
+ /// Field has a value
has_hidden = 0x8,
}
}
@@ -3190,7 +3199,7 @@ namespace TL
[TLDef(0x1BB00451)]
public class InputMessagesFilterPinned : MessagesFilter { }
- /// Object contains info on events occurred. See Derived classes: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
+ /// Object contains info on events occurred. See Derived classes: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
public abstract class Update : IObject { }
/// New message in a private chat or in a basic group. See
[TLDef(0x1F2B0AFD)]
@@ -3682,6 +3691,7 @@ namespace TL
[TLDef(0x1B49EC6D)]
public class UpdateDraftMessage : Update
{
+ /// Flags, see TL conditional fields
public Flags flags;
/// The peer to which the draft is associated
public Peer peer;
@@ -3840,6 +3850,7 @@ namespace TL
[TLDef(0xEA29055D)]
public class UpdateChannelReadMessagesContents : Update
{
+ /// Flags, see TL conditional fields
public Flags flags;
/// Channel/supergroup ID
public long channel_id;
@@ -4315,6 +4326,7 @@ namespace TL
[TLDef(0x5E1B3CB8)]
public class UpdateMessageReactions : Update
{
+ /// Flags, see TL conditional fields
public Flags flags;
/// Peer
public Peer peer;
@@ -4418,6 +4430,7 @@ namespace TL
[TLDef(0x192EFBE3)]
public class UpdateChannelPinnedTopic : Update
{
+ /// Flags, see TL conditional fields
public Flags flags;
public long channel_id;
public int topic_id;
@@ -4431,12 +4444,14 @@ namespace TL
[TLDef(0xFE198602)]
public class UpdateChannelPinnedTopics : Update
{
+ /// Flags, see TL conditional fields
public Flags flags;
public long channel_id;
[IfFlag(0)] public int[] order;
[Flags] public enum Flags : uint
{
+ /// Field has a value
has_order = 0x1,
}
}
@@ -7907,6 +7922,7 @@ namespace TL
[TLDef(0xE57B1432)]
public class Auth_SentCodeTypeFirebaseSms : Auth_SentCodeTypeSms
{
+ /// Flags, see TL conditional fields
public Flags flags;
[IfFlag(0)] public byte[] nonce;
[IfFlag(1)] public string receipt;
@@ -7914,7 +7930,9 @@ namespace TL
[Flags] public enum Flags : uint
{
+ /// Field has a value
has_nonce = 0x1,
+ /// Field has a value
has_receipt = 0x2,
}
}
@@ -10137,13 +10155,16 @@ namespace TL
[TLDef(0x5D8D353B)]
public class ChannelAdminLogEventActionPinTopic : ChannelAdminLogEventAction
{
+ /// Flags, see TL conditional fields
public Flags flags;
[IfFlag(0)] public ForumTopicBase prev_topic;
[IfFlag(1)] public ForumTopicBase new_topic;
[Flags] public enum Flags : uint
{
+ /// Field has a value
has_prev_topic = 0x1,
+ /// Field has a value
has_new_topic = 0x2,
}
}
@@ -13184,6 +13205,7 @@ namespace TL
[TLDef(0xC9EE1D87)]
public class Messages_SponsoredMessages : IObject, IPeerResolver
{
+ /// Flags, see TL conditional fields
public Flags flags;
[IfFlag(0)] public int posts_between;
/// Sponsored messages
@@ -13997,12 +14019,13 @@ namespace TL
}
}
- /// See
+ /// See Derived classes:
public abstract class MessageExtendedMediaBase : IObject { }
/// See
[TLDef(0xAD628CC8)]
public class MessageExtendedMediaPreview : MessageExtendedMediaBase
{
+ /// Flags, see TL conditional fields
public Flags flags;
[IfFlag(0)] public int w;
[IfFlag(0)] public int h;
@@ -14011,8 +14034,11 @@ namespace TL
[Flags] public enum Flags : uint
{
+ /// Field has a value
has_w = 0x1,
+ /// Field has a value
has_thumb = 0x2,
+ /// Field has a value
has_video_duration = 0x4,
}
}
@@ -14035,6 +14061,7 @@ namespace TL
[TLDef(0xB4073647)]
public class Username : IObject
{
+ /// Flags, see TL conditional fields
public Flags flags;
public string username;
@@ -14045,7 +14072,7 @@ namespace TL
}
}
- /// See
+ /// See Derived classes:
public abstract class ForumTopicBase : IObject
{
public virtual int ID { get; }
@@ -14062,6 +14089,7 @@ namespace TL
[TLDef(0x71701DA9)]
public class ForumTopic : ForumTopicBase
{
+ /// Flags, see TL conditional fields
public Flags flags;
public int id;
public DateTime date;
@@ -14080,10 +14108,12 @@ namespace TL
[Flags] public enum Flags : uint
{
+ /// Field has a value
has_icon_emoji_id = 0x1,
my = 0x2,
closed = 0x4,
pinned = 0x8,
+ /// Field has a value
has_draft = 0x10,
short_ = 0x20,
hidden = 0x40,
@@ -14096,6 +14126,7 @@ namespace TL
[TLDef(0x367617D3)]
public class Messages_ForumTopics : IObject, IPeerResolver
{
+ /// Flags, see TL conditional fields
public Flags flags;
public int count;
public ForumTopicBase[] topics;
@@ -14127,19 +14158,22 @@ namespace TL
public DateTime expires;
}
- /// See
+ /// See Derived classes:
public abstract class RequestPeerType : IObject { }
/// See
[TLDef(0x5F3B8A00)]
public class RequestPeerTypeUser : RequestPeerType
{
+ /// Flags, see TL conditional fields
public Flags flags;
[IfFlag(0)] public bool bot;
[IfFlag(1)] public bool premium;
[Flags] public enum Flags : uint
{
+ /// Field has a value
has_bot = 0x1,
+ /// Field has a value
has_premium = 0x2,
}
}
@@ -14147,6 +14181,7 @@ namespace TL
[TLDef(0xC9F06E1B)]
public class RequestPeerTypeChat : RequestPeerType
{
+ /// Flags, see TL conditional fields
public Flags flags;
[IfFlag(3)] public bool has_username;
[IfFlag(4)] public bool forum;
@@ -14156,9 +14191,13 @@ namespace TL
[Flags] public enum Flags : uint
{
creator = 0x1,
+ /// Field has a value
has_user_admin_rights = 0x2,
+ /// Field has a value
has_bot_admin_rights = 0x4,
+ /// Field has a value
has_has_username = 0x8,
+ /// Field has a value
has_forum = 0x10,
bot_participant = 0x20,
}
@@ -14167,6 +14206,7 @@ namespace TL
[TLDef(0x339BEF6C)]
public class RequestPeerTypeBroadcast : RequestPeerType
{
+ /// Flags, see TL conditional fields
public Flags flags;
[IfFlag(3)] public bool has_username;
[IfFlag(1)] public ChatAdminRights user_admin_rights;
@@ -14175,8 +14215,11 @@ namespace TL
[Flags] public enum Flags : uint
{
creator = 0x1,
+ /// Field has a value
has_user_admin_rights = 0x2,
+ /// Field has a value
has_bot_admin_rights = 0x4,
+ /// Field has a value
has_has_username = 0x8,
}
}
@@ -14216,7 +14259,7 @@ namespace TL
public MessageEntity[] entities;
}
- /// Translated text, or no result See Derived classes: ,
+ /// Translated text, or no result See Derived classes:
public abstract class Messages_TranslatedText : IObject { }
/// See
[TLDef(0x33DB32F8)]
@@ -14229,6 +14272,7 @@ namespace TL
[TLDef(0xC84834CE)]
public class AutoSaveSettings : IObject
{
+ /// Flags, see TL conditional fields
public Flags flags;
[IfFlag(2)] public long video_max_size;
@@ -14236,6 +14280,7 @@ namespace TL
{
photos = 0x1,
videos = 0x2,
+ /// Field has a value
has_video_max_size = 0x4,
}
}
@@ -14271,7 +14316,7 @@ namespace TL
public JsonObject config;
}
- /// See
+ /// See Derived classes:
public abstract class InputBotApp : IObject { }
/// See
[TLDef(0xA920BD7A)]
@@ -14293,6 +14338,7 @@ namespace TL
[TLDef(0x95FCD1D6)]
public class BotApp : IObject
{
+ /// Flags, see TL conditional fields
public Flags flags;
public long id;
public long access_hash;
@@ -14305,6 +14351,7 @@ namespace TL
[Flags] public enum Flags : uint
{
+ /// Field has a value
has_document = 0x1,
}
}
@@ -14313,6 +14360,7 @@ namespace TL
[TLDef(0xEB50ADF5)]
public class Messages_BotApp : IObject
{
+ /// Flags, see TL conditional fields
public Flags flags;
public BotApp app;
@@ -14323,7 +14371,7 @@ namespace TL
}
}
- /// See
+ /// See Derived classes:
public abstract class AppWebViewResult : IObject { }
/// See
[TLDef(0x3C1B4F0D)]
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index ac8210d..fdaa088 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -54,7 +54,7 @@ namespace TL
query = query,
});
- /// Invoke the specified query using the specified API layer See Possible codes: 400,403 (details)
+ /// Invoke the specified query using the specified API layer See Possible codes: 400,403,406 (details)
/// The layer to use
/// The query
public static Task InvokeWithLayer(this Client client, int layer, IMethod query)
@@ -286,7 +286,7 @@ namespace TL
code = code,
});
- /// See
+ /// See [bots: ✓]
public static Task Auth_ImportWebTokenAuthorization(this Client client, int api_id, string api_hash, string web_auth_token)
=> client.Invoke(new Auth_ImportWebTokenAuthorization
{
@@ -295,7 +295,7 @@ namespace TL
web_auth_token = web_auth_token,
});
- /// See
+ /// See [bots: ✓]
public static Task Auth_RequestFirebaseSms(this Client client, string phone_number, string phone_code_hash, string safety_net_token = null, string ios_push_secret = null)
=> client.Invoke(new Auth_RequestFirebaseSms
{
@@ -921,7 +921,7 @@ namespace TL
{
});
- /// Get info about multiple wallpapers See
+ /// Get info about multiple wallpapers See Possible codes: 400 (details)
/// Wallpapers to fetch info about
public static Task Account_GetMultiWallPapers(this Client client, params InputWallPaperBase[] wallpapers)
=> client.Invoke(new Account_GetMultiWallPapers
@@ -1062,14 +1062,14 @@ namespace TL
{
});
- /// See
+ /// See [bots: ✓]
public static Task Account_ReorderUsernames(this Client client, params string[] order)
=> client.Invoke(new Account_ReorderUsernames
{
order = order,
});
- /// See
+ /// See [bots: ✓]
public static Task Account_ToggleUsername(this Client client, string username, bool active)
=> client.Invoke(new Account_ToggleUsername
{
@@ -1077,7 +1077,7 @@ namespace TL
active = active,
});
- /// See
+ /// See [bots: ✓]
/// a null value means emojiListNotModified
public static Task Account_GetDefaultProfilePhotoEmojis(this Client client, long hash = default)
=> client.Invoke(new Account_GetDefaultProfilePhotoEmojis
@@ -1085,7 +1085,7 @@ namespace TL
hash = hash,
});
- /// See
+ /// See [bots: ✓]
/// a null value means emojiListNotModified
public static Task Account_GetDefaultGroupPhotoEmojis(this Client client, long hash = default)
=> client.Invoke(new Account_GetDefaultGroupPhotoEmojis
@@ -1093,13 +1093,13 @@ namespace TL
hash = hash,
});
- /// See
+ /// See [bots: ✓]
public static Task Account_GetAutoSaveSettings(this Client client)
=> client.Invoke(new Account_GetAutoSaveSettings
{
});
- /// See
+ /// See [bots: ✓]
public static Task Account_SaveAutoSaveSettings(this Client client, AutoSaveSettings settings, InputPeer peer = null, bool users = false, bool chats = false, bool broadcasts = false)
=> client.Invoke(new Account_SaveAutoSaveSettings
{
@@ -1108,7 +1108,7 @@ namespace TL
settings = settings,
});
- /// See
+ /// See [bots: ✓]
public static Task Account_DeleteAutoSaveExceptions(this Client client)
=> client.Invoke(new Account_DeleteAutoSaveExceptions
{
@@ -1339,13 +1339,13 @@ namespace TL
phone = phone,
});
- /// See