From d916342f1cc4d8a88e9f1f0dc46c897e03705148 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Fri, 21 Oct 2022 19:54:12 +0200
Subject: [PATCH 001/336] Program_SecretChats timerstamp name for saved media
---
.github/dev.yml | 2 +-
Examples/Program_SecretChats.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index adf45c2..04417b8 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -2,7 +2,7 @@ pr: none
trigger:
- master
-name: 3.0.1-dev.$(Rev:r)
+name: 3.0.2-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/Examples/Program_SecretChats.cs b/Examples/Program_SecretChats.cs
index 14412f3..c204af8 100644
--- a/Examples/Program_SecretChats.cs
+++ b/Examples/Program_SecretChats.cs
@@ -92,7 +92,7 @@ Type a command, or a message to send to the active secret chat:");
if (msg.Media != null && unem.message is EncryptedMessage { file: EncryptedFile ef })
{
int slash = msg.Media.MimeType?.IndexOf('/') ?? 0; // quick & dirty conversion from MIME type to file extension
- var filename = slash > 0 ? $"media.{msg.Media.MimeType[(slash + 1)..]}" : "media.bin";
+ var filename = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.{(slash > 0 ? msg.Media.MimeType[(slash + 1)..] : "bin")}";
Console.WriteLine($"{unem.message.ChatId}> {msg.Message} [attached file downloaded to {filename}]");
using var output = File.Create(filename);
await Secrets.DownloadFile(ef, msg.Media, output);
From 7e9d010392170d8f6ae4e1b21204673004d7442d Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Mon, 24 Oct 2022 11:51:33 +0200
Subject: [PATCH 002/336] documentation
---
EXAMPLES.md | 18 +++++++++++++++---
FAQ.md | 19 +++++++++++--------
2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/EXAMPLES.md b/EXAMPLES.md
index 65dd40d..841f5c5 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -28,7 +28,7 @@ var resolved = await client.Contacts_ResolveUsername("MyEch0_Bot"); // username
await client.SendMessageAsync(resolved, "/start");
```
*Note: This also works if the @username points to a channel/group, but you must already have joined that channel before sending a message to it.
-If the username is invalid/unused, the API call raises an exception.*
+If the username is invalid/unused, the API call raises an RpcException.*
### Send a message to someone by phone number
@@ -134,7 +134,7 @@ but the old `Chat` will be marked with flag [deactivated] and should not be used
### List all dialogs (chats/groups/channels/user chat) we are currently in
```csharp
var dialogs = await client.Messages_GetAllDialogs();
-foreach (var dialog in dialogs.dialogs)
+foreach (Dialog dialog in dialogs.dialogs)
switch (dialogs.UserOrChat(dialog))
{
case User user when user.IsActive: Console.WriteLine("User " + user); break;
@@ -218,6 +218,18 @@ var channel = (Channel)chats.chats[1234567890]; // the channel we want
var participants = await client.Channels_GetAllParticipants(channel);
```
+If you only need to list the channel owner/admins, you can use specific filter:
+```csharp
+var participants = await client.Channels_GetParticipants(channel, filter: new ChannelParticipantsAdmins());
+foreach (var participant in participants.participants) // This is the correct way to enumerate the result
+{
+ var user = participants.users[participant.UserID];
+ if (participant is ChannelParticipantCreator cpc) Console.WriteLine($"{user} is the owner '{cpc.rank}'");
+ else if (participant is ChannelParticipantAdmin cpa) Console.WriteLine($"{user} is admin '{cpa.rank}'");
+}
+```
+*Note: It is not possible to list only the Deleted Accounts. Those will be automatically removed by Telegram from your group after a while*
+
### Join a channel/group by their public name or invite link
* For a public channel/group `@channelname`
@@ -286,7 +298,7 @@ for (int offset_id = 0; ;)
offset_id = messages.Messages[^1].ID;
}
```
-
+*Note: If you want to stop at a specific msg ID, use Messages_GetHistory `min_id` argument. For example, `min_id: dialog.read_inbox_max_id`*
### Monitor all Telegram events happening for the user
diff --git a/FAQ.md b/FAQ.md
index f9b762c..a22152a 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -140,12 +140,13 @@ Some additional advices from me:
5. Avoid repetitive polling or repetitive sequence of actions/requests: Save the initial results of your queries, and update those results when you're informed of a change through `OnUpdate` events.
6. If a phone number is brand new, it will be closely monitored by Telegram for abuse, and it can even already be considered a bad user due to bad behavior from the previous owner of that phone number (which may happens often with VoIP or other easy-to-buy-online numbers, so expect fast ban)
-7. You may want to use your new phone number account with an official Telegram client and act like a normal user for some time (some weeks/months), before using it for automation with WTelegramClient.
-8. When creating a new API ID/Hash, I recommend you use your own phone number with long history of normal Telegram usage, rather than a brand new phone number with short history.
+7. Don't buy fake users/session accounts from Internet and don't extract api_id/hash/authkey/sessions from official clients, this is [specifically forbidden by API TOS](https://core.telegram.org/api/terms#2-transparency).
+8. You may want to use your new phone number account with an official Telegram client and act like a normal user for some time (some weeks/months), before using it for automation with WTelegramClient.
+9. When creating a new API ID/Hash, I recommend you use your own phone number with long history of normal Telegram usage, rather than a brand new phone number with short history.
In particular, DON'T create an API ID/Hash for every phone numbers you will control. One API ID/Hash represents your application, which can be used to control several user accounts.
-9. If you actually do use the library to spam, scam, or other stuff annoying to everybody, GTFO and don't cry that you got banned using WTelegramClient. Some people don't seem to realize by themselves that what they plan to do with the library is actually negative for the community and are surprised that they got caught.
+10. If you actually do use the library to spam, scam, or other stuff annoying to everybody, GTFO and don't cry that you got banned using WTelegramClient. Some people don't seem to realize by themselves that what they plan to do with the library is actually negative for the community and are surprised that they got caught.
We don't support such use of the library, and will not help people asking for support if we suspect them of mass-user manipulation.
-10. If your client displays Telegram channels to your users, you have to support and display [official sponsored messages](https://core.telegram.org/api/sponsored-messages).
+11. If your client displays Telegram channels to your users, you have to support and display [official sponsored messages](https://core.telegram.org/api/sponsored-messages).
#### 9. Why the error `CHAT_ID_INVALID`?
@@ -154,7 +155,7 @@ Most chat groups you see are likely of type `Channel`, not `Chat`.
This difference is important to understand. Please [read about the Terminology in ReadMe](README.md#terminology).
You typically get the error `CHAT_ID_INVALID` when you try to call API methods designed specifically for a `Chat`, with the ID of a `Channel`.
-All API methods taking a `long api_id` as a direct method parameter are for Chats and cannot be used with Channels.
+All API methods taking a `long chat_id` as a direct method parameter are for Chats and cannot be used with Channels.
There is probably another method achieving the same result but specifically designed for Channels, and it will have a similar name, but beginning with `Channels_` ...
@@ -164,12 +165,12 @@ That object must be created with both fields `channel_id` and `access_hash` corr
#### 10. `chats.chats[id]` fails. My chats list is empty or does not contain the chat id.
-There can be several reasons why `chats.chats[id]` raise an error:
-- The user account you're currently logged-in as has not joined this particular chat.
+There can be several reasons why `chats.chats` doesn't contain the chat you expect:
+- The currently logged-in user account has not joined this particular chat.
API method [Messages_GetAllChats](https://corefork.telegram.org/method/messages.getAllChats) will only return those chat groups/channels the user is in, not all Telegram chat groups.
- You're trying to use a Bot API (or TDLib) numerical ID, like -1001234567890
Telegram Client API don't use these kind of IDs for chats. Remove the -100 prefix and try again with the rest (1234567890).
-- You're trying to use a user ID instead of a chat ID.
+- You're searching for a user instead of a chat ID.
Private messages with a user are not called "chats". See [Terminology in ReadMe](README.md#terminology).
To obtain the list of users (as well as chats and channels) the logged-in user is currenly engaged in a discussion with, you should [use the API method Messages_GetAllDialogs](EXAMPLES.md#list-dialogs)
- the `chats.chats` dictionary is empty.
@@ -203,6 +204,8 @@ In this case, the recommended action would be to dispose the client and recreate
you might also get Connection shutdown because your client couldn't send Pings to Telegram in the allotted time.
In this case, you can use the `PingInterval` property to increase the delay between pings *(for example 300 seconds instead of 60)*.
+5) If you're using an MTProxy, some of them are known to be quite unstable. You may want to try switching to another MTProxy that is more stable.
+
#### 12. How to migrate from TLSharp? How to sign-in/sign-up/register account properly?
From 517fab89bb247a25494b717bd5aad05f44596e3d Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Tue, 25 Oct 2022 10:34:53 +0200
Subject: [PATCH 003/336] ReadHistory helper
---
EXAMPLES.md | 4 +++-
FAQ.md | 33 +++++++++++++++++++++++++++++++++
README.md | 3 ++-
src/Client.Helpers.cs | 9 +++++++++
src/TL.Schema.cs | 2 +-
src/TL.SchemaFuncs.cs | 2 +-
6 files changed, 49 insertions(+), 4 deletions(-)
diff --git a/EXAMPLES.md b/EXAMPLES.md
index 841f5c5..eb91e4b 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -298,7 +298,9 @@ for (int offset_id = 0; ;)
offset_id = messages.Messages[^1].ID;
}
```
-*Note: If you want to stop at a specific msg ID, use Messages_GetHistory `min_id` argument. For example, `min_id: dialog.read_inbox_max_id`*
+Notes:
+- 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);`
### Monitor all Telegram events happening for the user
diff --git a/FAQ.md b/FAQ.md
index a22152a..5e3dea8 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -163,6 +163,7 @@ However, note that those Channel-compatible methods will require an `InputChanne
That object must be created with both fields `channel_id` and `access_hash` correctly filled. You can read more about this in [FAQ #4](#access-hash).
+
#### 10. `chats.chats[id]` fails. My chats list is empty or does not contain the chat id.
There can be several reasons why `chats.chats` doesn't contain the chat you expect:
@@ -259,6 +260,38 @@ If those missing messages are never obtained during the session, incoming messag
- As recommended, new encryption keys are negotiated every 100 sent/received messages or after one week.
If remote client doesn't complete this negotiation before reaching 200 messages, the Secret Chat is aborted.
+
+#### 15. The example codes don't compile on my machine
+
+The snippets of example codes found in the [ReadMe](README.md) or [Examples](EXAMPLES.md) pages were written for .NET 5 / C# 9 minimum.
+If you're having compiler problem on code constructs such as `using`, `foreach`, `[^1]` or about "Deconstruct",
+that typically means you're still using an obsolete version of .NET (Framework 4.x or Core)
+
+Here are the recommended actions to fix your problem:
+- Create a new project for .NET 6+ (in Visual Studio 2019 or more recent):
+ - Select File > New > Project
+ - Search for "C# Console"
+ - Select the **Console App**, but NOT Console App (.NET Framework) !
+ - On the framework selection page, choose .NET 6.0 or more recent
+ - Now you can start developing for WTelegramClient 🙂
+- If you don't want to target a recent version of .NET, you can upgrade your existing project to use the latest version of the C# language:
+ - Close Visual Studio
+ - Edit your *.csproj file **with Notepad**
+ - Within the first ``, add the following line:
+ `latest`
+ - Save, close Notepad and reopen your project in Visual Studio
+ - If you still have issues on some `foreach` constructs, add this class somewhere in your project:
+ ```csharp
+ static class Extensions
+ {
+ public static void Deconstruct(this KeyValuePair tuple, out T1 key, out T2 value)
+ {
+ key = tuple.Key;
+ value = tuple.Value;
+ }
+ }
+ ```
+
## Troubleshooting guide
diff --git a/README.md b/README.md
index e25529a..e8a0773 100644
--- a/README.md
+++ b/README.md
@@ -151,7 +151,8 @@ await client.SendMessageAsync(target, "Hello, World");
```
➡️ You can find lots of useful code snippets in [EXAMPLES.md](https://github.com/wiz0u/WTelegramClient/blob/master/EXAMPLES.md)
-and in the [Examples subdirectory](https://github.com/wiz0u/WTelegramClient/tree/master/Examples).
+and in the [Examples subdirectory](https://github.com/wiz0u/WTelegramClient/tree/master/Examples).
+➡️ Check [the FAQ](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#compile) if example codes doesn't compile correctly on your machine, or other troubleshooting.
# Terminology in Telegram Client API
diff --git a/src/Client.Helpers.cs b/src/Client.Helpers.cs
index db97629..980d9f1 100644
--- a/src/Client.Helpers.cs
+++ b/src/Client.Helpers.cs
@@ -657,6 +657,15 @@ namespace WTelegram
public Task DeleteMessages(InputPeer peer, params int[] id)
=> peer is InputPeerChannel channel ? this.Channels_DeleteMessages(channel, id) : this.Messages_DeleteMessages(id);
+
+ /// Marks message history as read. See
and Possible codes: 400 (details)
+ /// Target user, channel or group
+ /// 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 switch
+ {
+ InputPeerChannel channel => await this.Channels_ReadHistory(channel, max_id),
+ _ => (await this.Messages_ReadHistory(peer, max_id)) != null
+ };
#endregion
}
}
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index cc61da5..d012742 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -6560,7 +6560,7 @@ namespace TL
/// Message entity representing a spoiler See
[TLDef(0x32CA960F)]
public class MessageEntitySpoiler : MessageEntity { }
- /// Represents a custom emoji See
+ /// Represents a custom emoji.
Note that this entity must wrap exactly one regular emoji (the one contained in .alt) in the related text, otherwise the server will ignore it. See
[TLDef(0xC8CF05F8, inheritBefore = true)]
public class MessageEntityCustomEmoji : MessageEntity
{
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index af4a1a7..5fca2b0 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -3056,7 +3056,7 @@ namespace TL
/// React to message See Possible codes: 400,403 (details)
/// Whether a bigger and longer reaction should be shown
- /// Add this reaction to the recent reactions list
+ /// Add this reaction to the recent reactions list ».
/// Peer
/// Message ID to react to
/// Reaction (a UTF8 emoji)
From cc9cf16f8adc08e18ea6d9718945258fec6b1de7 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Tue, 25 Oct 2022 20:07:43 +0200
Subject: [PATCH 004/336] ToInputChatPhoto helper
---
FAQ.md | 2 ++
src/SecretChats.cs | 8 ++------
src/TL.Helpers.cs | 9 +++++++++
3 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/FAQ.md b/FAQ.md
index 5e3dea8..0b4d1c5 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -292,6 +292,8 @@ Here are the recommended actions to fix your problem:
}
```
+Also, remember to add a `using TL;` at the top of your files to have access to all the Telegram API methods.
+
## Troubleshooting guide
diff --git a/src/SecretChats.cs b/src/SecretChats.cs
index 701619f..8065b5f 100644
--- a/src/SecretChats.cs
+++ b/src/SecretChats.cs
@@ -588,12 +588,8 @@ namespace WTelegram
fingerprint ^= fingerprint >> 32;
using var ige = new AES_IGE_Stream(stream, aes_key, aes_iv, true);
- return await client.UploadFileAsync(ige, null, progress) switch
- {
- InputFile ifl => new InputEncryptedFileUploaded { id = ifl.id, parts = ifl.parts, md5_checksum = ifl.md5_checksum, key_fingerprint = (int)fingerprint },
- InputFileBig ifb => new InputEncryptedFileBigUploaded { id = ifb.id, parts = ifb.parts, key_fingerprint = (int)fingerprint },
- _ => null
- };
+ var inputFile = await client.UploadFileAsync(ige, null, progress);
+ return inputFile.ToInputEncryptedFile((int)fingerprint);
}
/// Download and decrypt an encrypted file from Telegram Secret Chat into the outputStream
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index aad124b..529ec5d 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.IO;
using System.Linq;
using System.Text;
using System.Web;
@@ -57,6 +58,14 @@ namespace TL
{
public abstract InputEncryptedFileBase ToInputEncryptedFile(int key_fingerprint);
public abstract InputSecureFileBase ToInputSecureFile(byte[] file_hash, byte[] secret);
+ /// for a profile photo. for auto-detection
for a profile video. The video MUST be square and 10 seconds max
+ public InputChatUploadedPhoto ToInputChatPhoto(bool? isSquareVideo10s = null)
+ {
+ if (isSquareVideo10s ?? Path.GetExtension(Name)?.ToLowerInvariant() is ".mp4")
+ return new InputChatUploadedPhoto { video = this, flags = InputChatUploadedPhoto.Flags.has_video };
+ else
+ return new InputChatUploadedPhoto { file = this, flags = InputChatUploadedPhoto.Flags.has_file };
+ }
}
partial class InputFile
{
From 1a3cde42417f441b72d6680314d44be33fe05223 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Wed, 26 Oct 2022 14:26:22 +0200
Subject: [PATCH 005/336] Replaced *Default & *None structures with null
---
FAQ.md | 19 ++++++++++---------
src/TL.Helpers.cs | 2 +-
src/TL.Schema.cs | 44 +++++++++++++++----------------------------
src/TL.SchemaFuncs.cs | 11 +++++++----
src/TL.Table.cs | 18 ++++++++++++------
5 files changed, 45 insertions(+), 49 deletions(-)
diff --git a/FAQ.md b/FAQ.md
index 0b4d1c5..6e4e747 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -139,8 +139,8 @@ Here are some advices from [another similar library](https://github.com/gotd/td/
Some additional advices from me:
5. Avoid repetitive polling or repetitive sequence of actions/requests: Save the initial results of your queries, and update those results when you're informed of a change through `OnUpdate` events.
-6. If a phone number is brand new, it will be closely monitored by Telegram for abuse, and it can even already be considered a bad user due to bad behavior from the previous owner of that phone number (which may happens often with VoIP or other easy-to-buy-online numbers, so expect fast ban)
-7. Don't buy fake users/session accounts from Internet and don't extract api_id/hash/authkey/sessions from official clients, this is [specifically forbidden by API TOS](https://core.telegram.org/api/terms#2-transparency).
+6. Don't buy fake user accounts/sessions and don't extract api_id/hash/authkey/sessions from official clients, this is [specifically forbidden by API TOS](https://core.telegram.org/api/terms#2-transparency). You must use your own api_id and create your own sessions associated with it.
+7. If a phone number is brand new, it will be closely monitored by Telegram for abuse, and it can even already be considered a bad user due to bad behavior from the previous owner of that phone number (which may happens often with VoIP or other easy-to-buy-online numbers, so expect fast ban)
8. You may want to use your new phone number account with an official Telegram client and act like a normal user for some time (some weeks/months), before using it for automation with WTelegramClient.
9. When creating a new API ID/Hash, I recommend you use your own phone number with long history of normal Telegram usage, rather than a brand new phone number with short history.
In particular, DON'T create an API ID/Hash for every phone numbers you will control. One API ID/Hash represents your application, which can be used to control several user accounts.
@@ -164,23 +164,24 @@ That object must be created with both fields `channel_id` and `access_hash` corr
-#### 10. `chats.chats[id]` fails. My chats list is empty or does not contain the chat id.
+#### 10. `chats.chats[id]` fails. My chats list is empty or does not contain the chat I'm looking for.
There can be several reasons why `chats.chats` doesn't contain the chat you expect:
-- The currently logged-in user account has not joined this particular chat.
-API method [Messages_GetAllChats](https://corefork.telegram.org/method/messages.getAllChats) will only return those chat groups/channels the user is in, not all Telegram chat groups.
-- You're trying to use a Bot API (or TDLib) numerical ID, like -1001234567890
-Telegram Client API don't use these kind of IDs for chats. Remove the -100 prefix and try again with the rest (1234567890).
- You're searching for a user instead of a chat ID.
Private messages with a user are not called "chats". See [Terminology in ReadMe](README.md#terminology).
-To obtain the list of users (as well as chats and channels) the logged-in user is currenly engaged in a discussion with, you should [use the API method Messages_GetAllDialogs](EXAMPLES.md#list-dialogs)
+To obtain the list of users (as well as chats and channels) the logged-in user is currenly engaged in a discussion with, you should [use the API method `Messages_GetAllDialogs`](EXAMPLES.md#list-dialogs)
+- The currently logged-in user account has not joined this particular chat.
+API method [`Messages_GetAllChats`](https://corefork.telegram.org/method/messages.getAllChats) will only return those chat groups/channels the user is in, not all Telegram chat groups.
+If you're looking for other Telegram groups/channels/users, try API methods [`Contacts_ResolveUsername`](EXAMPLES.md#msg-by-name) or `Contacts_Search`
+- You're trying to use a Bot API (or TDLib) numerical ID, like -1001234567890
+Telegram Client API don't use these kind of IDs for chats. Remove the -100 prefix and try again with the rest (1234567890).
- the `chats.chats` dictionary is empty.
This is the case if you are logged-in as a brand new user account (that hasn't join any chat groups/channels)
or if you are connected to a Test DC (a Telegram datacenter server for tests) instead of Production DC
([read FAQ #6](#wrong-server) for more)
To help determine if `chats.chats` is empty or does not contain a certain chat, you should [dump the chat list to the screen](EXAMPLES.md#list-chats)
-or simply use a debugger: Place a breakpoint after the Messages_GetAllChats call, run the program up to there, and use a Watch pane to display the content of the chats.chats dictionary.
+or simply use a debugger: Place a breakpoint after the `Messages_GetAllChats` call, run the program up to there, and use a Watch pane to display the content of the chats.chats dictionary.
#### 11. I get "Connection shut down" errors in my logs
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index 529ec5d..0e8f82e 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -58,7 +58,7 @@ namespace TL
{
public abstract InputEncryptedFileBase ToInputEncryptedFile(int key_fingerprint);
public abstract InputSecureFileBase ToInputSecureFile(byte[] file_hash, byte[] secret);
- /// for a profile photo. for auto-detection
for a profile video. The video MUST be square and 10 seconds max
+ /// for a profile photo. for auto-detection
for a profile video. The video MUST be square, 10 seconds max, larger than 160x160
public InputChatUploadedPhoto ToInputChatPhoto(bool? isSquareVideo10s = null)
{
if (isSquareVideo10s ?? Path.GetExtension(Name)?.ToLowerInvariant() is ".mp4")
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index d012742..95f1d61 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -3870,7 +3870,7 @@ namespace TL
/// Folder ID
public int id;
/// Folder info
- [IfFlag(0)] public DialogFilterBase filter;
+ [IfFlag(0)] public DialogFilter filter;
[Flags] public enum Flags : uint
{
@@ -6306,7 +6306,7 @@ namespace TL
public class KeyboardButtonBuy : KeyboardButton
{
}
- /// Button to request a user to authorize via URL using Seamless Telegram Login. When the user clicks on such a button, messages.requestUrlAuth should be called, providing the button_id and the ID of the container message. The returned object will contain more details about the authorization request (request_write_access if the bot would like to send messages to the user along with the username of the bot which will be used for user authorization). Finally, the user can choose to call messages.acceptUrlAuth to get a with the URL to open instead of the url of this constructor, or a , in which case the url of this constructor must be opened, instead. If the user refuses the authorization request but still wants to open the link, the url of this constructor must be used. See
+ /// Button to request a user to authorize via URL using Seamless Telegram Login. When the user clicks on such a button, messages.requestUrlAuth should be called, providing the button_id and the ID of the container message. The returned object will contain more details about the authorization request (request_write_access if the bot would like to send messages to the user along with the username of the bot which will be used for user authorization). Finally, the user can choose to call messages.acceptUrlAuth to get a with the URL to open instead of the url of this constructor, or a , in which case the url of this constructor must be opened, instead. If the user refuses the authorization request but still wants to open the link, the url of this constructor must be used. See
[TLDef(0x10B78D29)]
public class KeyboardButtonUrlAuth : KeyboardButtonBase
{
@@ -11332,7 +11332,8 @@ namespace TL
}
}
- /// URL authorization result Derived classes: , , See
+ /// URL authorization result Derived classes: , See
+ /// a null value means urlAuthResultDefault
public abstract class UrlAuthResult : IObject { }
/// Details about the authorization request, for more info click here » See
[TLDef(0x92D33A0E)]
@@ -11358,9 +11359,6 @@ namespace TL
/// The URL name of the website on which the user has logged in.
public string url;
}
- /// Details about an accepted authorization request, for more info click here » See
- [TLDef(0xA9D6DB1F)]
- public class UrlAuthResultDefault : UrlAuthResult { }
/// Geographical location of supergroup (geogroups) See
/// a null value means channelLocationEmpty
@@ -11742,11 +11740,10 @@ namespace TL
public BankCardOpenUrl[] open_urls;
}
- /// Dialog filter (folder ») Derived classes: , See
- public abstract class DialogFilterBase : IObject { }
/// Dialog filter AKA folder See
+ /// a null value means dialogFilterDefault
[TLDef(0x7438F7E8)]
- public class DialogFilter : DialogFilterBase
+ public class DialogFilter : IObject
{
/// Flags, see TL conditional fields
public Flags flags;
@@ -11785,16 +11782,13 @@ namespace TL
has_emoticon = 0x2000000,
}
}
- /// Used only when reordering folders to indicate the default (all chats) folder. See
- [TLDef(0x363293AE)]
- public class DialogFilterDefault : DialogFilterBase { }
/// Suggested folders See
[TLDef(0x77744D4A)]
public class DialogFilterSuggested : IObject
{
/// Folder info
- public DialogFilterBase filter;
+ public DialogFilter filter;
/// Folder description
public string description;
}
@@ -12705,11 +12699,9 @@ namespace TL
public string short_name;
}
- /// Represents a scope where the bot commands, specified using bots.setBotCommands will be valid. Derived classes: , , , , , , See
+ /// Represents a scope where the bot commands, specified using bots.setBotCommands will be valid. Derived classes: , , , , , See
+ /// a null value means botCommandScopeDefault
public abstract class BotCommandScope : IObject { }
- /// The commands will be valid in all dialogs See
- [TLDef(0x2F6CB2AB)]
- public class BotCommandScopeDefault : BotCommandScope { }
/// The specified bot commands will only be valid in all private chats with users. See
[TLDef(0x3C4F04D8)]
public class BotCommandScopeUsers : BotCommandScope { }
@@ -13234,11 +13226,9 @@ namespace TL
}
}
- /// Indicates the action to execute when pressing the in-UI menu button for bots Derived classes: , , See
+ /// Indicates the action to execute when pressing the in-UI menu button for bots Derived classes: , See
+ /// a null value means botMenuButtonDefault
public abstract class BotMenuButtonBase : IObject { }
- /// Placeholder bot menu button never returned to users: see the docs for more info. See
- [TLDef(0x7533A588)]
- public class BotMenuButtonDefault : BotMenuButtonBase { }
/// Bot menu button that opens the bot command list when clicked. See
[TLDef(0x4258C205)]
public class BotMenuButtonCommands : BotMenuButtonBase { }
@@ -13263,11 +13253,9 @@ namespace TL
public DocumentBase[] ringtones;
}
- /// Represents a notification sound Derived classes: , , , See
+ /// Represents a notification sound Derived classes: , , See
+ /// a null value means notificationSoundDefault
public abstract class NotificationSound : IObject { }
- /// Indicates the default notification sound should be used See
- [TLDef(0x97E8BEBE)]
- public class NotificationSoundDefault : NotificationSound { }
/// No notification sound should be used See
[TLDef(0x6F0C34DF)]
public class NotificationSoundNone : NotificationSound { }
@@ -13483,11 +13471,9 @@ namespace TL
public long document_id;
}
- /// Available chat reactions Derived classes: , , See
+ /// Available chat reactions Derived classes: , See
+ /// a null value means chatReactionsNone
public abstract class ChatReactions : IObject { }
- /// No reactions are allowed See
- [TLDef(0xEAFC32BC)]
- public class ChatReactionsNone : ChatReactions { }
/// All reactions or all non-custom reactions are allowed See
[TLDef(0x52928BCA)]
public class ChatReactionsAll : ChatReactions
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index 5fca2b0..c0b70d1 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -2587,6 +2587,7 @@ namespace TL
/// The message
/// The ID of the button with the authorization request
/// URL used for link URL authorization, click here for more info »
+ /// a null value means urlAuthResultDefault
public static Task Messages_RequestUrlAuth(this Client client, InputPeer peer = null, int? msg_id = null, int? button_id = null, string url = null)
=> client.Invoke(new Messages_RequestUrlAuth
{
@@ -2603,6 +2604,7 @@ namespace TL
/// Message ID of the message with the login button
/// ID of the login button
/// URL used for link URL authorization, click here for more info »
+ /// a null value means urlAuthResultDefault
public static Task Messages_AcceptUrlAuth(this Client client, bool write_allowed = false, InputPeer peer = null, int? msg_id = null, int? button_id = null, string url = null)
=> client.Invoke(new Messages_AcceptUrlAuth
{
@@ -2691,7 +2693,7 @@ namespace TL
});
/// Get folders See
- public static Task Messages_GetDialogFilters(this Client client)
+ public static Task Messages_GetDialogFilters(this Client client)
=> client.Invoke(new Messages_GetDialogFilters
{
});
@@ -2705,7 +2707,7 @@ namespace TL
/// Update folder See Possible codes: 400 (details)
/// Folder ID
/// Folder info
- public static Task Messages_UpdateDialogFilter(this Client client, int id, DialogFilterBase filter = null)
+ public static Task Messages_UpdateDialogFilter(this Client client, int id, DialogFilter filter = null)
=> client.Invoke(new Messages_UpdateDialogFilter
{
flags = (Messages_UpdateDialogFilter.Flags)(filter != null ? 0x1 : 0),
@@ -4229,6 +4231,7 @@ namespace TL
/// Gets the menu button action for a given user or for all users, previously set using bots.setBotMenuButton; users can see this information in the . See [bots: ✓] Possible codes: 400 (details)
/// User ID or empty for the default menu button.
+ /// a null value means botMenuButtonDefault
public static Task Bots_GetBotMenuButton(this Client client, InputUserBase user_id)
=> client.Invoke(new Bots_GetBotMenuButton
{
@@ -7106,7 +7109,7 @@ namespace TL.Methods
}
[TLDef(0xF19ED96D)]
- public class Messages_GetDialogFilters : IMethod { }
+ public class Messages_GetDialogFilters : IMethod { }
[TLDef(0xA29CD42C)]
public class Messages_GetSuggestedDialogFilters : IMethod { }
@@ -7116,7 +7119,7 @@ namespace TL.Methods
{
public Flags flags;
public int id;
- [IfFlag(0)] public DialogFilterBase filter;
+ [IfFlag(0)] public DialogFilter filter;
[Flags] public enum Flags : uint
{
diff --git a/src/TL.Table.cs b/src/TL.Table.cs
index 27ecbc9..0ae1e3c 100644
--- a/src/TL.Table.cs
+++ b/src/TL.Table.cs
@@ -865,7 +865,7 @@ namespace TL
[0xE844EBFF] = typeof(Messages_SearchCounter),
[0x92D33A0E] = typeof(UrlAuthResultRequest),
[0x8F8C0E4E] = typeof(UrlAuthResultAccepted),
- [0xA9D6DB1F] = typeof(UrlAuthResultDefault),
+ [0xA9D6DB1F] = null,//UrlAuthResultDefault
[0xBFB5AD8B] = null,//ChannelLocationEmpty
[0x209B82DB] = typeof(ChannelLocation),
[0xCA461B5D] = typeof(PeerLocated),
@@ -891,7 +891,7 @@ namespace TL
[0xF568028A] = typeof(BankCardOpenUrl),
[0x3E24E573] = typeof(Payments_BankCardData),
[0x7438F7E8] = typeof(DialogFilter),
- [0x363293AE] = typeof(DialogFilterDefault),
+ [0x363293AE] = null,//DialogFilterDefault
[0x77744D4A] = typeof(DialogFilterSuggested),
[0xB637EDAF] = typeof(StatsDateRangeDays),
[0xCB43ACDE] = typeof(StatsAbsValueAndPrev),
@@ -942,7 +942,7 @@ namespace TL
[0xDCB118B7] = typeof(GroupCallParticipantVideoSourceGroup),
[0x67753AC8] = typeof(GroupCallParticipantVideo),
[0x85FEA03F] = typeof(Stickers_SuggestedShortName),
- [0x2F6CB2AB] = typeof(BotCommandScopeDefault),
+ [0x2F6CB2AB] = null,//BotCommandScopeDefault
[0x3C4F04D8] = typeof(BotCommandScopeUsers),
[0x6FE1A881] = typeof(BotCommandScopeChats),
[0xB9AA606A] = typeof(BotCommandScopeChatAdmins),
@@ -983,12 +983,12 @@ namespace TL
[0x0C14557C] = typeof(WebViewResultUrl),
[0x882F76BB] = typeof(SimpleWebViewResultUrl),
[0x0C94511C] = typeof(WebViewMessageSent),
- [0x7533A588] = typeof(BotMenuButtonDefault),
+ [0x7533A588] = null,//BotMenuButtonDefault
[0x4258C205] = typeof(BotMenuButtonCommands),
[0xC7B57CE6] = typeof(BotMenuButton),
[0xFBF6E8B1] = null,//Account_SavedRingtonesNotModified
[0xC1E92CC5] = typeof(Account_SavedRingtones),
- [0x97E8BEBE] = typeof(NotificationSoundDefault),
+ [0x97E8BEBE] = null,//NotificationSoundDefault
[0x6F0C34DF] = typeof(NotificationSoundNone),
[0x830B9AE4] = typeof(NotificationSoundLocal),
[0xFF6C8049] = typeof(NotificationSoundRingtone),
@@ -1011,7 +1011,7 @@ namespace TL
[0x79F5D419] = null,//ReactionEmpty
[0x1B2286B8] = typeof(ReactionEmoji),
[0x8935FC73] = typeof(ReactionCustomEmoji),
- [0xEAFC32BC] = typeof(ChatReactionsNone),
+ [0xEAFC32BC] = null,//ChatReactionsNone
[0x52928BCA] = typeof(ChatReactionsAll),
[0x661D4037] = typeof(ChatReactionsSome),
[0xB06FDBDF] = null,//Messages_ReactionsNotModified
@@ -1125,15 +1125,21 @@ namespace TL
[typeof(Help_PassportConfig)] = 0xBFB9F457, //help.passportConfigNotModified
[typeof(Help_UserInfo)] = 0xF3AE2EED, //help.userInfoEmpty
[typeof(Account_WallPapers)] = 0x1C199183, //account.wallPapersNotModified
+ [typeof(UrlAuthResult)] = 0xA9D6DB1F, //urlAuthResultDefault
[typeof(ChannelLocation)] = 0xBFB5AD8B, //channelLocationEmpty
[typeof(Account_Themes)] = 0xF41EB622, //account.themesNotModified
+ [typeof(DialogFilter)] = 0x363293AE, //dialogFilterDefault
[typeof(Help_CountriesList)] = 0x93CC1F32, //help.countriesListNotModified
+ [typeof(BotCommandScope)] = 0x2F6CB2AB, //botCommandScopeDefault
[typeof(Messages_AvailableReactions)] = 0x9F071957, //messages.availableReactionsNotModified
[typeof(AttachMenuBots)] = 0xF1D88A5C, //attachMenuBotsNotModified
+ [typeof(BotMenuButtonBase)] = 0x7533A588, //botMenuButtonDefault
[typeof(Account_SavedRingtones)] = 0xFBF6E8B1, //account.savedRingtonesNotModified
+ [typeof(NotificationSound)] = 0x97E8BEBE, //notificationSoundDefault
[typeof(EmojiStatus)] = 0x2DE11AAE, //emojiStatusEmpty
[typeof(Account_EmojiStatuses)] = 0xD08CE645, //account.emojiStatusesNotModified
[typeof(Reaction)] = 0x79F5D419, //reactionEmpty
+ [typeof(ChatReactions)] = 0xEAFC32BC, //chatReactionsNone
[typeof(Messages_Reactions)] = 0xB06FDBDF, //messages.reactionsNotModified
// from TL.Secret:
[typeof(DecryptedMessageMedia)] = 0x089F5C4A, //decryptedMessageMediaEmpty
From 49969e46cf5ec4e37cd1b8683723386ea19be399 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Wed, 26 Oct 2022 15:14:29 +0200
Subject: [PATCH 006/336] xmldoc
---
src/TL.Schema.cs | 344 +++++++++++++++++++++++------------------------
src/TL.Secret.cs | 2 +-
src/TL.Table.cs | 2 -
3 files changed, 173 insertions(+), 175 deletions(-)
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index 95f1d61..df0ec23 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -27,12 +27,12 @@ namespace TL
}
/// Corresponds to an arbitrary empty object. See
- /// a null value means null
+ /// a value means null
[TLDef(0x56730BCC)]
public class Null : IObject { }
- /// Peer Derived classes: , , , , , See
- /// a null value means inputPeerEmpty
+ /// Peer See Derived classes: , , , , ,
+ /// a value means inputPeerEmpty
public abstract partial class InputPeer : IObject { }
/// Defines the current user. See
[TLDef(0x7DA07EC9)]
@@ -85,8 +85,8 @@ namespace TL
public long channel_id;
}
- /// Defines a user for subsequent interaction. Derived classes: , , See
- /// a null value means inputUserEmpty
+ /// Defines a user for subsequent interaction. See Derived classes: , ,
+ /// a value means inputUserEmpty
public abstract partial class InputUserBase : IObject { }
/// Defines the current user. See
[TLDef(0xF7C1B13F)]
@@ -112,7 +112,7 @@ namespace TL
public long user_id;
}
- /// Object defines a contact from the user's phone book. Derived classes: See
+ /// 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
[TLDef(0xF392B7F4)]
@@ -128,7 +128,7 @@ namespace TL
public string last_name;
}
- /// Defines a file uploaded by the client. Derived classes: , See
+ /// Defines a file uploaded by the client. See Derived classes: ,
public abstract partial class InputFileBase : IObject
{
/// Random file identifier created by the client
@@ -177,8 +177,8 @@ namespace TL
public override string Name => name;
}
- /// Defines media content of a message. Derived classes: , , , , , , , , , , , , , See
- /// a null value means inputMediaEmpty
+ /// Defines media content of a message. See Derived classes: , , , , , , , , , , , , ,
+ /// a value means inputMediaEmpty
public abstract class InputMedia : IObject { }
/// Photo See
[TLDef(0x1E287D04)]
@@ -442,8 +442,8 @@ namespace TL
public string emoticon;
}
- /// Defines a new group profile photo. Derived classes: , See
- /// a null value means inputChatPhotoEmpty
+ /// Defines a new group profile photo. See Derived classes: ,
+ /// a value means inputChatPhotoEmpty
public abstract class InputChatPhotoBase : IObject { }
/// New photo to be set as group profile photo. See
[TLDef(0xC642724E)]
@@ -477,7 +477,7 @@ namespace TL
}
/// Defines a GeoPoint by its coordinates. See
- /// a null value means inputGeoPointEmpty
+ /// a value means inputGeoPointEmpty
[TLDef(0x48222FAF)]
public class InputGeoPoint : IObject
{
@@ -498,7 +498,7 @@ namespace TL
}
/// Defines a photo for further interaction. See
- /// a null value means inputPhotoEmpty
+ /// a value means inputPhotoEmpty
[TLDef(0x3BB3B94A)]
public partial class InputPhoto : IObject
{
@@ -510,7 +510,7 @@ namespace TL
public byte[] file_reference;
}
- /// Defines the location of a file for download. Derived classes: , , , , , , , , , See
+ /// Defines the location of a file for download. See Derived classes: , , , , , , , , ,
public abstract class InputFileLocationBase : IObject { }
/// DEPRECATED location of a photo See
[TLDef(0xDFDAABE1)]
@@ -639,7 +639,7 @@ namespace TL
}
}
- /// Chat partner or group. Derived classes: , , See
+ /// Chat partner or group. See Derived classes: , ,
public abstract partial class Peer : IObject { }
/// Chat partner See
[TLDef(0x59511722)]
@@ -688,7 +688,7 @@ namespace TL
webp = 0x1081464C,
}
- /// Object defines a user. Derived classes: , See
+ /// Object defines a user. See Derived classes: ,
public abstract partial class UserBase : IObject { }
/// Empty constructor, non-existent user. See
[TLDef(0xD3BC4B7A)]
@@ -792,7 +792,7 @@ namespace TL
}
/// User profile photo. See
- /// a null value means userProfilePhotoEmpty
+ /// a value means userProfilePhotoEmpty
[TLDef(0x82D1F706)]
public class UserProfilePhoto : IObject
{
@@ -814,8 +814,8 @@ namespace TL
}
}
- /// User online status Derived classes: , , , , See
- /// a null value means userStatusEmpty
+ /// User online status See Derived classes: , , , ,
+ /// a value means userStatusEmpty
public abstract partial class UserStatus : IObject { }
/// Online status of the user. See
[TLDef(0xEDB93949)]
@@ -841,7 +841,7 @@ namespace TL
[TLDef(0x77EBC742)]
public partial class UserStatusLastMonth : UserStatus { }
- /// Object defines a group. Derived classes: , , , , See
+ /// Object defines a group. See Derived classes: , , , ,
public abstract partial class ChatBase : IObject
{
/// ID of the group
@@ -1044,7 +1044,7 @@ namespace TL
public override string Title => title;
}
- /// Full info about a channel, supergroup, gigagroup or basic group. Derived classes: , See
+ /// Full info about a channel, supergroup, gigagroup or basic group. See Derived classes: ,
public abstract partial class ChatFullBase : IObject
{
/// ID of the chat
@@ -1361,7 +1361,7 @@ namespace TL
public override ChatReactions AvailableReactions => available_reactions;
}
- /// Details of a group member. Derived classes: , , See
+ /// Details of a group member. See Derived classes: , ,
public abstract partial class ChatParticipantBase : IObject
{
/// Member user ID
@@ -1397,7 +1397,7 @@ namespace TL
{
}
- /// Object contains info on group members. Derived classes: , See
+ /// Object contains info on group members. See Derived classes: ,
public abstract partial class ChatParticipantsBase : IObject
{
/// Group ID
@@ -1439,7 +1439,7 @@ namespace TL
}
/// Group profile photo. See
- /// a null value means chatPhotoEmpty
+ /// a value means chatPhotoEmpty
[TLDef(0x1C6E1C11)]
public class ChatPhoto : IObject
{
@@ -1461,7 +1461,7 @@ namespace TL
}
}
- /// Object describing a message. Derived classes: , , See
+ /// Object describing a message. See Derived classes: , ,
public abstract class MessageBase : IObject
{
/// ID of the message
@@ -1670,8 +1670,8 @@ namespace TL
public override int TtlPeriod => ttl_period;
}
- /// Media Derived classes: , , , , , , , , , , , See
- /// a null value means messageMediaEmpty
+ /// Media See Derived classes: , , , , , , , , , , ,
+ /// a value means messageMediaEmpty
public abstract partial class MessageMedia : IObject { }
/// Attached photo. See
[TLDef(0x695150D7)]
@@ -1847,8 +1847,8 @@ namespace TL
public string emoticon;
}
- /// Object describing actions connected to a service message. Derived classes: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , See
- /// a null value means messageActionEmpty
+ /// Object describing actions connected to a service message. See Derived classes: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
+ /// a value means messageActionEmpty
public abstract class MessageAction : IObject { }
/// Group created See
[TLDef(0xBD47CBAD)]
@@ -2137,7 +2137,7 @@ namespace TL
public int months;
}
- /// Chat info. Derived classes: , See
+ /// Chat info. See Derived classes: ,
public abstract class DialogBase : IObject
{
/// The chat
@@ -2226,7 +2226,7 @@ namespace TL
public override int TopMessage => top_message;
}
- /// Object describes a photo. Derived classes: , See
+ /// Object describes a photo. See Derived classes: ,
public abstract partial class PhotoBase : IObject { }
/// Empty constructor, non-existent photo See
[TLDef(0x2331B22D)]
@@ -2265,7 +2265,7 @@ namespace TL
}
}
- /// Location of a certain size of a picture Derived classes: , , , , , See
+ /// Location of a certain size of a picture See Derived classes: , , , , ,
public abstract partial class PhotoSizeBase : IObject
{
/// Thumbnail type (see. )
@@ -2355,7 +2355,7 @@ namespace TL
}
/// GeoPoint. See
- /// a null value means geoPointEmpty
+ /// a value means geoPointEmpty
[TLDef(0xB2A2F663)]
public partial class GeoPoint : IObject
{
@@ -2401,7 +2401,7 @@ namespace TL
}
}
- /// Object contains info on user authorization. Derived classes: , See
+ /// Object contains info on user authorization. See Derived classes: ,
public abstract class Auth_AuthorizationBase : IObject { }
/// Contains user authorization info. See
[TLDef(0x33FB7BB8)]
@@ -2450,7 +2450,7 @@ namespace TL
public byte[] bytes;
}
- /// Object defines the set of users and/or groups that generate notifications. Derived classes: , , , See
+ /// Object defines the set of users and/or groups that generate notifications. See Derived classes: , , ,
public abstract class InputNotifyPeerBase : IObject { }
/// Notifications generated by a certain user or group. See
[TLDef(0xB8BC5B0C)]
@@ -2573,7 +2573,7 @@ namespace TL
}
}
- /// Object contains info on a wallpaper. Derived classes: , See
+ /// Object contains info on a wallpaper. See Derived classes: ,
public abstract class WallPaperBase : IObject
{
/// Identifier
@@ -2778,7 +2778,7 @@ namespace TL
}
/// The current user's contact list and info on users. See
- /// a null value means contacts.contactsNotModified
+ /// a value means contacts.contactsNotModified
[TLDef(0xEAE87E42)]
public class Contacts_Contacts : IObject
{
@@ -2825,7 +2825,7 @@ namespace TL
public int count;
}
- /// Object contains a list of chats with messages and auxiliary data. Derived classes: , , See
+ /// Object contains a list of chats with messages and auxiliary data. See Derived classes: , ,
public abstract partial class Messages_DialogsBase : IObject, IPeerResolver
{
/// List of chats
@@ -2872,7 +2872,7 @@ namespace TL
public override IPeerInfo UserOrChat(Peer peer) => null;
}
- /// Object contains information on list of messages with auxiliary data. Derived classes: , , , See
+ /// Object contains information on list of messages with auxiliary data. See Derived classes: , , ,
public abstract partial class Messages_MessagesBase : IObject, IPeerResolver
{
/// List of messages
@@ -3002,8 +3002,8 @@ namespace TL
public int offset;
}
- /// Object describes message filter. Derived classes: , , , , , , , , , , , , , , , See
- /// a null value means inputMessagesFilterEmpty
+ /// Object describes message filter. See Derived classes: , , , , , , , , , , , , , , ,
+ /// a value means inputMessagesFilterEmpty
public abstract class MessagesFilter : IObject { }
/// Filter for messages containing photos. See
[TLDef(0x9609A51C)]
@@ -3064,7 +3064,7 @@ namespace TL
[TLDef(0x1BB00451)]
public class InputMessagesFilterPinned : MessagesFilter { }
- /// Object contains info on events occurred. Derived classes: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , See
+ /// 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)]
@@ -4303,7 +4303,7 @@ namespace TL
public int unread_count;
}
- /// Occurred changes. Derived classes: , , , See
+ /// Occurred changes. See Derived classes: , , ,
public abstract partial class Updates_DifferenceBase : IObject, IPeerResolver
{
/// List of new messages
@@ -4392,7 +4392,7 @@ namespace TL
public override IPeerInfo UserOrChat(Peer peer) => null;
}
- /// Object which is perceived by the client without a call on its part when an event occurs. Derived classes: , , , , , , See
+ /// Object which is perceived by the client without a call on its part when an event occurs. See Derived classes: , , , , , ,
public abstract partial class UpdatesBase : IObject, IPeerResolver
{
/// date
@@ -4643,7 +4643,7 @@ namespace TL
public Dictionary users;
}
- /// Contains info on file. Derived classes: , See
+ /// Contains info on file. See Derived classes: ,
public abstract class Upload_FileBase : IObject { }
/// File content. See
[TLDef(0x096A18D5)]
@@ -4853,7 +4853,7 @@ namespace TL
}
/// An update is available for the application. See
- /// a null value means help.noAppUpdate
+ /// a value means help.noAppUpdate
[TLDef(0xCCBBCE30)]
public class Help_AppUpdate : IObject
{
@@ -4895,7 +4895,7 @@ namespace TL
public string message;
}
- /// Object contains info on an encrypted chat. Derived classes: , , , , See
+ /// Object contains info on an encrypted chat. See Derived classes: , , , ,
public abstract class EncryptedChatBase : IObject
{
/// Chat ID
@@ -5011,7 +5011,7 @@ namespace TL
}
/// Encrypted file. See
- /// a null value means encryptedFileEmpty
+ /// a value means encryptedFileEmpty
[TLDef(0xA8008CD8)]
public partial class EncryptedFile : IObject
{
@@ -5027,8 +5027,8 @@ namespace TL
public int key_fingerprint;
}
- /// Object sets encrypted file for attachment Derived classes: , , See
- /// a null value means inputEncryptedFileEmpty
+ /// Object sets encrypted file for attachment See Derived classes: , ,
+ /// a value means inputEncryptedFileEmpty
public abstract class InputEncryptedFileBase : IObject
{
/// Random file ID created by client
@@ -5077,7 +5077,7 @@ namespace TL
public override long ID => id;
}
- /// Object contains encrypted message. Derived classes: , See
+ /// Object contains encrypted message. See Derived classes: ,
public abstract class EncryptedMessageBase : IObject
{
/// Random message ID, assigned by the author of message
@@ -5136,7 +5136,7 @@ namespace TL
public override byte[] Bytes => bytes;
}
- /// Contains Diffie-Hellman key generation protocol parameters. Derived classes: , See
+ /// Contains Diffie-Hellman key generation protocol parameters. See Derived classes: ,
public abstract class Messages_DhConfigBase : IObject { }
/// Configuring parameters did not change. See
[TLDef(0xC0E24635)]
@@ -5175,7 +5175,7 @@ namespace TL
}
/// Defines a document for subsequent interaction. See
- /// a null value means inputDocumentEmpty
+ /// a value means inputDocumentEmpty
[TLDef(0x1ABFB575)]
public partial class InputDocument : IObject
{
@@ -5187,7 +5187,7 @@ namespace TL
public byte[] file_reference;
}
- /// A document. Derived classes: , See
+ /// A document. See Derived classes: ,
public abstract partial class DocumentBase : IObject { }
/// Empty constructor, document doesn't exist. See
[TLDef(0x36F8C871)]
@@ -5242,7 +5242,7 @@ namespace TL
public UserBase user;
}
- /// Object defines the set of users and/or groups that generate notifications. Derived classes: , , , See
+ /// Object defines the set of users and/or groups that generate notifications. See Derived classes: , , ,
public abstract class NotifyPeerBase : IObject { }
/// Notifications generated by a certain user or group. See
[TLDef(0x9FD40BD8)]
@@ -5261,7 +5261,7 @@ namespace TL
[TLDef(0xD612E8EF)]
public class NotifyBroadcasts : NotifyPeerBase { }
- /// User actions. Use this to provide users with detailed info about their chat partner's actions: typing or sending attachments of all kinds. Derived classes: , , , , , , , , , , , , , , , , , See
+ /// User actions. Use this to provide users with detailed info about their chat partner's actions: typing or sending attachments of all kinds. See Derived classes: , , , , , , , , , , , , , , , , ,
public abstract partial class SendMessageAction : IObject { }
/// User is typing. See
[TLDef(0x16BF744E)]
@@ -5416,7 +5416,7 @@ namespace TL
VoiceMessages = 0x0697F414,
}
- /// Privacy rule Derived classes: , , , , , , , See
+ /// Privacy rule See Derived classes: , , , , , , ,
public abstract class InputPrivacyRule : IObject { }
/// Allow only contacts See
[TLDef(0x0D09E07B)]
@@ -5459,7 +5459,7 @@ namespace TL
public long[] chats;
}
- /// Privacy rule Derived classes: , , , , , , , See
+ /// Privacy rule See Derived classes: , , , , , , ,
public abstract class PrivacyRule : IObject { }
/// Allow all contacts See
[TLDef(0xFFFE1BAC)]
@@ -5524,7 +5524,7 @@ namespace TL
public int days;
}
- /// Various possible attributes of a document (used to define if it's a sticker, a GIF, a video, a mask sticker, an image, an audio, and so on) Derived classes: , , , , , , , See
+ /// Various possible attributes of a document (used to define if it's a sticker, a GIF, a video, a mask sticker, an image, an audio, and so on) See Derived classes: , , , , , , ,
public abstract class DocumentAttribute : IObject { }
/// Defines the width and height of an image uploaded as document See
[TLDef(0x6C37C15C)]
@@ -5636,7 +5636,7 @@ namespace TL
}
/// Found stickers See
- /// a null value means messages.stickersNotModified
+ /// a value means messages.stickersNotModified
[TLDef(0x30A6EC7E)]
public class Messages_Stickers : IObject
{
@@ -5657,7 +5657,7 @@ namespace TL
}
/// Info about all installed stickers See
- /// a null value means messages.allStickersNotModified
+ /// a value means messages.allStickersNotModified
[TLDef(0xCDBBCEBB)]
public class Messages_AllStickers : IObject
{
@@ -5677,7 +5677,7 @@ namespace TL
public int pts_count;
}
- /// Instant View webpage preview Derived classes: , , , See
+ /// Instant View webpage preview See Derived classes: , , ,
public abstract class WebPageBase : IObject
{
/// Preview ID
@@ -5963,7 +5963,7 @@ namespace TL
public int flags;
}
- /// Exported chat invite Derived classes: , See
+ /// Exported chat invite See Derived classes: ,
public abstract class ExportedChatInvite : IObject { }
/// Exported chat invite See
[TLDef(0x0AB4A819)]
@@ -6016,7 +6016,7 @@ namespace TL
[TLDef(0xED107AB7)]
public class ChatInvitePublicJoinRequests : ExportedChatInvite { }
- /// Chat invite Derived classes: , , See
+ /// Chat invite See Derived classes: , ,
public abstract class ChatInviteBase : IObject { }
/// The user has already joined this chat See
[TLDef(0x5A686D7C)]
@@ -6070,8 +6070,8 @@ namespace TL
public DateTime expires;
}
- /// Represents a stickerset Derived classes: , , , , , , , See
- /// a null value means inputStickerSetEmpty
+ /// Represents a stickerset See Derived classes: , , , , , , ,
+ /// a value means inputStickerSetEmpty
public abstract partial class InputStickerSet : IObject { }
/// Stickerset by ID See
[TLDef(0x9DE7A269)]
@@ -6165,7 +6165,7 @@ namespace TL
}
/// Stickerset and stickers inside it See
- /// a null value means messages.stickerSetNotModified
+ /// a value means messages.stickerSetNotModified
[TLDef(0xB60A24A6)]
public class Messages_StickerSet : IObject
{
@@ -6223,7 +6223,7 @@ namespace TL
}
}
- /// Bot or inline keyboard buttons Derived classes: , , , , , , , , , , , , , , See
+ /// Bot or inline keyboard buttons See Derived classes: , , , , , , , , , , , , , ,
public abstract class KeyboardButtonBase : IObject
{
/// Button text
@@ -6411,7 +6411,7 @@ namespace TL
public KeyboardButtonBase[] buttons;
}
- /// Reply markup for bot and inline keyboards Derived classes: , , , See
+ /// Reply markup for bot and inline keyboards See Derived classes: , , ,
public abstract class ReplyMarkup : IObject { }
/// Hide sent bot keyboard See
[TLDef(0xA03E5B85)]
@@ -6476,7 +6476,7 @@ namespace TL
public KeyboardButtonRow[] rows;
}
- /// Message entities, representing styled text in a message Derived classes: , , , , , , , , , , , , , , , , , , , , See
+ /// Message entities, representing styled text in a message See Derived classes: , , , , , , , , , , , , , , , , , , , ,
public abstract class MessageEntity : IObject
{
/// Offset of message entity within message (in UTF-16 code units)
@@ -6568,8 +6568,8 @@ namespace TL
public long document_id;
}
- /// Represents a channel Derived classes: , See
- /// a null value means inputChannelEmpty
+ /// Represents a channel See Derived classes: ,
+ /// a value means inputChannelEmpty
public abstract class InputChannelBase : IObject
{
/// Channel ID
@@ -6626,7 +6626,7 @@ namespace TL
public int max_id;
}
- /// Contains the difference (new messages) between our local channel state and the remote state Derived classes: , , See
+ /// Contains the difference (new messages) between our local channel state and the remote state See Derived classes: , ,
public abstract partial class Updates_ChannelDifferenceBase : IObject, IPeerResolver
{
/// returns a or for the given Peer
@@ -6711,7 +6711,7 @@ namespace TL
}
/// Filter for getting only certain types of channel messages See
- /// a null value means channelMessagesFilterEmpty
+ /// a value means channelMessagesFilterEmpty
[TLDef(0xCD77D957)]
public class ChannelMessagesFilter : IObject
{
@@ -6727,7 +6727,7 @@ namespace TL
}
}
- /// Channel participant Derived classes: , , , , , See
+ /// Channel participant See Derived classes: , , , , ,
public abstract partial class ChannelParticipantBase : IObject { }
/// Channel/supergroup participant See
[TLDef(0xC00C07C0)]
@@ -6834,7 +6834,7 @@ namespace TL
public Peer peer;
}
- /// Filter for fetching channel participants Derived classes: , , , , , , , See
+ /// Filter for fetching channel participants See Derived classes: , , , , , , ,
public abstract class ChannelParticipantsFilter : IObject { }
/// Fetch only recent participants See
[TLDef(0xDE3F3C79)]
@@ -6894,7 +6894,7 @@ namespace TL
}
/// Represents multiple channel participants See
- /// a null value means channels.channelParticipantsNotModified
+ /// a value means channels.channelParticipantsNotModified
[TLDef(0x9AB0FEAF)]
public class Channels_ChannelParticipants : IObject, IPeerResolver
{
@@ -6949,7 +6949,7 @@ namespace TL
}
/// Saved gifs See
- /// a null value means messages.savedGifsNotModified
+ /// a value means messages.savedGifsNotModified
[TLDef(0x84A02A0D)]
public class Messages_SavedGifs : IObject
{
@@ -6959,7 +6959,7 @@ namespace TL
public DocumentBase[] gifs;
}
- /// Represents a sent inline message from the perspective of a bot Derived classes: , , , , , , See
+ /// Represents a sent inline message from the perspective of a bot See Derived classes: , , , , , ,
public abstract class InputBotInlineMessage : IObject { }
/// A media See
[TLDef(0x3380C786)]
@@ -7131,7 +7131,7 @@ namespace TL
}
}
- /// Inline bot result Derived classes: , , , See
+ /// Inline bot result See Derived classes: , , ,
public abstract class InputBotInlineResultBase : IObject
{
/// ID of result
@@ -7248,7 +7248,7 @@ namespace TL
public override InputBotInlineMessage SendMessage => send_message;
}
- /// Inline message Derived classes: , , , , , See
+ /// Inline message See Derived classes: , , , , ,
public abstract class BotInlineMessage : IObject { }
/// Send whatever media is attached to the See
[TLDef(0x764CF810)]
@@ -7405,7 +7405,7 @@ namespace TL
}
}
- /// Results of an inline query Derived classes: , See
+ /// Results of an inline query See Derived classes: ,
public abstract class BotInlineResultBase : IObject
{
/// Result ID
@@ -7607,7 +7607,7 @@ namespace TL
MissedCall = 0xD61AD6EE,
}
- /// Type of the verification code that was sent Derived classes: , , , , , , See
+ /// Type of the verification code that was sent See Derived classes: , , , , , ,
public abstract class Auth_SentCodeType : IObject { }
/// The code was sent through the telegram app See
[TLDef(0x3DBB5986)]
@@ -7725,7 +7725,7 @@ namespace TL
}
}
- /// Represents a sent inline message from the perspective of a bot Derived classes: , See
+ /// Represents a sent inline message from the perspective of a bot See Derived classes: ,
public abstract class InputBotInlineMessageIDBase : IObject
{
/// DC ID to use when working with this inline message
@@ -7839,8 +7839,8 @@ namespace TL
public TopPeer[] peers;
}
- /// Top peers Derived classes: , See
- /// a null value means contacts.topPeersNotModified
+ /// Top peers See Derived classes: ,
+ /// a value means contacts.topPeersNotModified
public abstract class Contacts_TopPeersBase : IObject { }
/// Top peers See
[TLDef(0x70B772A8)]
@@ -7859,7 +7859,7 @@ namespace TL
[TLDef(0xB52C939D)]
public class Contacts_TopPeersDisabled : Contacts_TopPeersBase { }
- /// Represents a message draft. Derived classes: , See
+ /// Represents a message draft. See Derived classes: ,
public abstract class DraftMessageBase : IObject { }
/// Empty draft See
[TLDef(0x1B0C841A)]
@@ -7902,7 +7902,7 @@ namespace TL
}
}
- /// Featured stickers Derived classes: , See
+ /// Featured stickers See Derived classes: ,
public abstract class Messages_FeaturedStickersBase : IObject { }
/// Featured stickers haven't changed See
[TLDef(0xC6DC0C66)]
@@ -7934,7 +7934,7 @@ namespace TL
}
/// Recently used stickers See
- /// a null value means messages.recentStickersNotModified
+ /// a value means messages.recentStickersNotModified
[TLDef(0x88D37C56)]
public class Messages_RecentStickers : IObject
{
@@ -7958,7 +7958,7 @@ namespace TL
public StickerSetCoveredBase[] sets;
}
- /// Result of stickerset installation process Derived classes: , See
+ /// Result of stickerset installation process See Derived classes: ,
public abstract class Messages_StickerSetInstallResult : IObject { }
/// The stickerset was installed successfully See
[TLDef(0x38641628)]
@@ -7971,7 +7971,7 @@ namespace TL
public StickerSetCoveredBase[] sets;
}
- /// Stickerset preview Derived classes: , , See
+ /// Stickerset preview See Derived classes: , ,
public abstract class StickerSetCoveredBase : IObject
{
/// Stickerset
@@ -8030,7 +8030,7 @@ namespace TL
public double zoom;
}
- /// Represents a media with attached stickers Derived classes: , See
+ /// Represents a media with attached stickers See Derived classes: ,
public abstract class InputStickeredMedia : IObject { }
/// A photo with stickers attached See
[TLDef(0x4A992157)]
@@ -8075,7 +8075,7 @@ namespace TL
}
}
- /// A game to send Derived classes: , See
+ /// A game to send See Derived classes: ,
public abstract class InputGame : IObject { }
/// Indicates an already sent game See
[TLDef(0x032C3E77)]
@@ -8118,8 +8118,8 @@ namespace TL
public Dictionary users;
}
- /// Rich text Derived classes: , , , , , , , , , , , , , , See
- /// a null value means textEmpty
+ /// Rich text See Derived classes: , , , , , , , , , , , , , ,
+ /// a value means textEmpty
public abstract class RichText : IObject { }
/// Plain text See
[TLDef(0x744694E0)]
@@ -8241,7 +8241,7 @@ namespace TL
public string name;
}
- /// Represents an instant view page element Derived classes: , , , , , , , , , , , , , , , , , , , , , , , , , , , , See
+ /// Represents an instant view page element See Derived classes: , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
public abstract class PageBlock : IObject { }
/// Unsupported IV element See
[TLDef(0x13567E8A)]
@@ -8680,7 +8680,7 @@ namespace TL
}
}
- /// Saved payment credentials Derived classes: See
+ /// Saved payment credentials See Derived classes:
public abstract class PaymentSavedCredentials : IObject { }
/// Saved credit card See
[TLDef(0xCDC27A1F)]
@@ -8692,7 +8692,7 @@ namespace TL
public string title;
}
- /// Remote document Derived classes: , See
+ /// Remote document See Derived classes: ,
public abstract class WebDocumentBase : IObject
{
/// Document URL
@@ -8765,7 +8765,7 @@ namespace TL
public DocumentAttribute[] attributes;
}
- /// Location of remote file Derived classes: , , See
+ /// Location of remote file See Derived classes: , ,
public abstract class InputWebFileLocationBase : IObject { }
/// Location of a remote HTTP(s) file See
[TLDef(0xC239D686)]
@@ -8907,7 +8907,7 @@ namespace TL
}
}
- /// Payment result Derived classes: , See
+ /// Payment result See Derived classes: ,
public abstract class Payments_PaymentResultBase : IObject { }
/// Payment result See
[TLDef(0x4E5F810D)]
@@ -8990,7 +8990,7 @@ namespace TL
}
}
- /// Payment credentials Derived classes: , , , See
+ /// Payment credentials See Derived classes: , , ,
public abstract class InputPaymentCredentialsBase : IObject { }
/// Saved payment credentials See
[TLDef(0xC10EB2CF)]
@@ -9083,7 +9083,7 @@ namespace TL
public long access_hash;
}
- /// Phone call Derived classes: , , , , , See
+ /// Phone call See Derived classes: , , , , ,
public abstract class PhoneCallBase : IObject
{
/// Call ID
@@ -9260,7 +9260,7 @@ namespace TL
public override long ID => id;
}
- /// Phone call connection Derived classes: , See
+ /// Phone call connection See Derived classes: ,
public abstract class PhoneConnectionBase : IObject
{
/// Endpoint ID
@@ -9373,7 +9373,7 @@ namespace TL
public Dictionary users;
}
- /// Represents the download status of a CDN file Derived classes: , See
+ /// Represents the download status of a CDN file See Derived classes: ,
public abstract class Upload_CdnFileBase : IObject { }
/// The file was cleared from the temporary RAM cache of the CDN and has to be re-uploaded. See
[TLDef(0xEEA8E46E)]
@@ -9408,7 +9408,7 @@ namespace TL
public CdnPublicKey[] public_keys;
}
- /// Language pack string Derived classes: , , See
+ /// Language pack string See Derived classes: , ,
public abstract class LangPackStringBase : IObject
{
/// Language key
@@ -9525,7 +9525,7 @@ namespace TL
}
}
- /// Channel admin log event Derived classes: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , See
+ /// Channel admin log event See Derived classes: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
public abstract class ChannelAdminLogEventAction : IObject { }
/// Channel/supergroup title was changed See
[TLDef(0xE6DFB825)]
@@ -9889,7 +9889,7 @@ namespace TL
}
/// Favorited stickers See
- /// a null value means messages.favedStickersNotModified
+ /// a value means messages.favedStickersNotModified
[TLDef(0x2CB51097)]
public class Messages_FavedStickers : IObject
{
@@ -9901,7 +9901,7 @@ namespace TL
public DocumentBase[] stickers;
}
- /// Recent t.me urls Derived classes: , , , , See
+ /// Recent t.me urls See Derived classes: , , , ,
public abstract class RecentMeUrl : IObject
{
/// URL
@@ -10009,7 +10009,7 @@ namespace TL
public Dictionary users;
}
- /// A message Derived classes: , , , See
+ /// A message See Derived classes: , , ,
public abstract partial class InputMessage : IObject { }
/// Message by ID See
[TLDef(0xA676A322)]
@@ -10038,7 +10038,7 @@ namespace TL
public long query_id;
}
- /// Peer, or all peers in a certain folder Derived classes: , See
+ /// Peer, or all peers in a certain folder See Derived classes: ,
public abstract partial class InputDialogPeerBase : IObject { }
/// A peer See
[TLDef(0xFCAAFEB7)]
@@ -10055,7 +10055,7 @@ namespace TL
public int folder_id;
}
- /// Peer, or all peers in a folder Derived classes: , See
+ /// Peer, or all peers in a folder See Derived classes: ,
public abstract class DialogPeerBase : IObject { }
/// Peer See
[TLDef(0xE56DBF05)]
@@ -10073,7 +10073,7 @@ namespace TL
}
/// Found stickersets See
- /// a null value means messages.foundStickerSetsNotModified
+ /// a value means messages.foundStickerSetsNotModified
[TLDef(0x8AF09DD2)]
public class Messages_FoundStickerSets : IObject
{
@@ -10105,7 +10105,7 @@ namespace TL
public int port;
}
- /// Update of Telegram's terms of service Derived classes: , See
+ /// Update of Telegram's terms of service See Derived classes: ,
public abstract class Help_TermsOfServiceUpdateBase : IObject { }
/// No changes were made to telegram's terms of service See
[TLDef(0xE3309F7F)]
@@ -10124,7 +10124,7 @@ namespace TL
public Help_TermsOfService terms_of_service;
}
- /// Secure passport file, for more info see the passport docs » Derived classes: , See
+ /// Secure passport file, for more info see the passport docs » See Derived classes: ,
public abstract class InputSecureFileBase : IObject
{
/// Secure file ID
@@ -10162,7 +10162,7 @@ namespace TL
}
/// Secure passport file, for more info see the passport docs » See
- /// a null value means secureFileEmpty
+ /// a value means secureFileEmpty
[TLDef(0x7D09C27E)]
public partial class SecureFile : IObject
{
@@ -10194,7 +10194,7 @@ namespace TL
public byte[] secret;
}
- /// Plaintext verified passport data. Derived classes: , See
+ /// Plaintext verified passport data. See Derived classes: ,
public abstract class SecurePlainData : IObject { }
/// Phone number to use in telegram passport: it must be verified, first ». See
[TLDef(0x7D6099DD)]
@@ -10338,7 +10338,7 @@ namespace TL
public byte[] hash;
}
- /// Secure value error Derived classes: , , , , , , , , See
+ /// Secure value error See Derived classes: , , , , , , , ,
public abstract class SecureValueErrorBase : IObject
{
/// The section of the user's Telegram Passport which has the error, one of , , , , ,
@@ -10518,7 +10518,7 @@ namespace TL
}
/// Deep link info, see the here for more details See
- /// a null value means help.deepLinkInfoEmpty
+ /// a value means help.deepLinkInfoEmpty
[TLDef(0x6A4EE832)]
public class Help_DeepLinkInfo : IObject
{
@@ -10538,7 +10538,7 @@ namespace TL
}
}
- /// Saved contact Derived classes: See
+ /// Saved contact See Derived classes:
public abstract class SavedContact : IObject { }
/// Saved contact See
[TLDef(0x1142BD56)]
@@ -10562,8 +10562,8 @@ namespace TL
public long id;
}
- /// Key derivation function to use when generating the password hash for SRP two-factor authorization Derived classes: See
- /// a null value means passwordKdfAlgoUnknown
+ /// Key derivation function to use when generating the password hash for SRP two-factor authorization See Derived classes:
+ /// a value means passwordKdfAlgoUnknown
public abstract class PasswordKdfAlgo : IObject { }
/// This key derivation algorithm defines that SRP 2FA login must be used See
[TLDef(0x3A912D4A)]
@@ -10579,8 +10579,8 @@ namespace TL
public byte[] p;
}
- /// KDF algorithm to use for computing telegram passport hash Derived classes: , See
- /// a null value means securePasswordKdfAlgoUnknown
+ /// KDF algorithm to use for computing telegram passport hash See Derived classes: ,
+ /// a value means securePasswordKdfAlgoUnknown
public abstract class SecurePasswordKdfAlgo : IObject
{
/// Salt
@@ -10606,7 +10606,7 @@ namespace TL
}
/// Constructor for checking the validity of a 2FA SRP password (see SRP) See
- /// a null value means inputCheckPasswordEmpty
+ /// a value means inputCheckPasswordEmpty
[TLDef(0xD27FF082)]
public class InputCheckPasswordSRP : IObject
{
@@ -10618,7 +10618,7 @@ namespace TL
public byte[] M1;
}
- /// Required secure file type Derived classes: , See
+ /// Required secure file type See Derived classes: ,
public abstract class SecureRequiredTypeBase : IObject { }
/// Required type See
[TLDef(0x829D99DA)]
@@ -10648,7 +10648,7 @@ namespace TL
}
/// Telegram passport configuration See
- /// a null value means help.passportConfigNotModified
+ /// a value means help.passportConfigNotModified
[TLDef(0xA098D6AF)]
public class Help_PassportConfig : IObject
{
@@ -10682,7 +10682,7 @@ namespace TL
public JSONValue value;
}
- /// JSON value Derived classes: , , , , , See
+ /// JSON value See Derived classes: , , , , ,
public abstract partial class JSONValue : IObject { }
/// null JSON value See
[TLDef(0x3F6D7B68)]
@@ -10775,7 +10775,7 @@ namespace TL
public RichText credit;
}
- /// Item in block list Derived classes: , See
+ /// Item in block list See Derived classes: ,
public abstract class PageListItem : IObject { }
/// List item See
[TLDef(0xB92FB6CD)]
@@ -10792,7 +10792,7 @@ namespace TL
public PageBlock[] blocks;
}
- /// Represents an instant view ordered list Derived classes: , See
+ /// Represents an instant view ordered list See Derived classes: ,
public abstract class PageListOrderedItem : IObject
{
/// Number of element within ordered list
@@ -10888,7 +10888,7 @@ namespace TL
}
/// Internal use See
- /// a null value means help.userInfoEmpty
+ /// a value means help.userInfoEmpty
[TLDef(0x01EB3758)]
public class Help_UserInfo : IObject
{
@@ -11086,7 +11086,7 @@ namespace TL
}
}
- /// Wallpaper Derived classes: , , See
+ /// Wallpaper See Derived classes: , ,
public abstract class InputWallPaperBase : IObject { }
/// Wallpaper See
[TLDef(0xE630B979)]
@@ -11113,7 +11113,7 @@ namespace TL
}
/// Installed wallpapers See
- /// a null value means account.wallPapersNotModified
+ /// a value means account.wallPapersNotModified
[TLDef(0xCDC3858C)]
public class Account_WallPapers : IObject
{
@@ -11332,8 +11332,8 @@ namespace TL
}
}
- /// URL authorization result Derived classes: , See
- /// a null value means urlAuthResultDefault
+ /// URL authorization result See Derived classes: ,
+ /// a value means urlAuthResultDefault
public abstract class UrlAuthResult : IObject { }
/// Details about the authorization request, for more info click here » See
[TLDef(0x92D33A0E)]
@@ -11361,7 +11361,7 @@ namespace TL
}
/// Geographical location of supergroup (geogroups) See
- /// a null value means channelLocationEmpty
+ /// a value means channelLocationEmpty
[TLDef(0x209B82DB)]
public class ChannelLocation : IObject
{
@@ -11371,7 +11371,7 @@ namespace TL
public string address;
}
- /// Geolocated peer Derived classes: , See
+ /// Geolocated peer See Derived classes: ,
public abstract class PeerLocatedBase : IObject
{
/// Validity period of current data
@@ -11414,7 +11414,7 @@ namespace TL
public string text;
}
- /// Cloud theme Derived classes: , See
+ /// Cloud theme See Derived classes: ,
public abstract class InputThemeBase : IObject { }
/// Theme See
[TLDef(0x3C5693E9)]
@@ -11476,7 +11476,7 @@ namespace TL
}
/// Installed themes See
- /// a null value means account.themesNotModified
+ /// a value means account.themesNotModified
[TLDef(0x9A3D8C6D)]
public class Account_Themes : IObject
{
@@ -11486,7 +11486,7 @@ namespace TL
public Theme[] themes;
}
- /// Login token (for QR code login) Derived classes: , , See
+ /// Login token (for QR code login) See Derived classes: , ,
public abstract class Auth_LoginTokenBase : IObject { }
/// Login token (for QR code login) See
[TLDef(0x629F1980)]
@@ -11621,7 +11621,7 @@ namespace TL
}
}
- /// Webpage attributes Derived classes: See
+ /// Webpage attributes See Derived classes:
public abstract class WebPageAttribute : IObject { }
/// Page theme See
[TLDef(0x54B56617)]
@@ -11643,7 +11643,7 @@ namespace TL
}
}
- /// How a user voted in a poll Derived classes: , , See
+ /// How a user voted in a poll See Derived classes: , ,
public abstract class MessageUserVoteBase : IObject
{
/// User ID
@@ -11741,7 +11741,7 @@ namespace TL
}
/// Dialog filter AKA folder See
- /// a null value means dialogFilterDefault
+ /// a value means dialogFilterDefault
[TLDef(0x7438F7E8)]
public class DialogFilter : IObject
{
@@ -11823,7 +11823,7 @@ namespace TL
public double total;
}
- /// Channel statistics graph Derived classes: , , See
+ /// Channel statistics graph See Derived classes: , ,
public abstract class StatsGraphBase : IObject { }
/// This channel statistics graph must be generated asynchronously using stats.loadAsyncGraph to reduce server load See
[TLDef(0x4A27EB2D)]
@@ -11905,7 +11905,7 @@ namespace TL
public MessageInteractionCounters[] recent_message_interactions;
}
- /// Info about pinned MTProxy or Public Service Announcement peers. Derived classes: , See
+ /// Info about pinned MTProxy or Public Service Announcement peers. See Derived classes: ,
public abstract class Help_PromoDataBase : IObject { }
/// No PSA/MTProxy info is available See
[TLDef(0x98F6AC75)]
@@ -12109,7 +12109,7 @@ namespace TL
}
/// Name, ISO code, localized name and phone codes/patterns of all available countries See
- /// a null value means help.countriesListNotModified
+ /// a value means help.countriesListNotModified
[TLDef(0x87D0759E)]
public class Help_CountriesList : IObject
{
@@ -12264,7 +12264,7 @@ namespace TL
public StatsGraphBase views_graph;
}
- /// A group call Derived classes: , See
+ /// A group call See Derived classes: ,
public abstract class GroupCallBase : IObject
{
/// Group call ID
@@ -12556,7 +12556,7 @@ namespace TL
public Dictionary users;
}
- /// Contains info about a chat invite, and eventually a pointer to the newest chat invite. Derived classes: , See
+ /// Contains info about a chat invite, and eventually a pointer to the newest chat invite. See Derived classes: ,
public abstract class Messages_ExportedChatInviteBase : IObject
{
/// Info about the chat invite
@@ -12699,8 +12699,8 @@ namespace TL
public string short_name;
}
- /// Represents a scope where the bot commands, specified using bots.setBotCommands will be valid. Derived classes: , , , , , See
- /// a null value means botCommandScopeDefault
+ /// Represents a scope where the bot commands, specified using bots.setBotCommands will be valid. See Derived classes: , , , , ,
+ /// a value means botCommandScopeDefault
public abstract class BotCommandScope : IObject { }
/// The specified bot commands will only be valid in all private chats with users. See
[TLDef(0x3C4F04D8)]
@@ -12729,7 +12729,7 @@ namespace TL
public InputUserBase user_id;
}
- /// Result of an account.resetPassword request. Derived classes: , , See
+ /// Result of an account.resetPassword request. See Derived classes: , ,
public abstract class Account_ResetPasswordResult : IObject { }
/// You recently requested a password reset that was canceled, please wait until the specified date before requesting another reset. See
[TLDef(0xE3779861)]
@@ -12851,7 +12851,7 @@ namespace TL
public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats);
}
- /// Information about a message in a specific position Derived classes: See
+ /// Information about a message in a specific position See Derived classes:
public abstract class SearchResultsPosition : IObject { }
/// Information about a message in a specific position See
[TLDef(0x7F648B67)]
@@ -13038,7 +13038,7 @@ namespace TL
}
/// Animations and metadata associated with message reactions » See
- /// a null value means messages.availableReactionsNotModified
+ /// a value means messages.availableReactionsNotModified
[TLDef(0x768E3AAD)]
public class Messages_AvailableReactions : IObject
{
@@ -13048,7 +13048,7 @@ namespace TL
public AvailableReaction[] reactions;
}
- /// Translated text, or no result Derived classes: , See
+ /// Translated text, or no result See Derived classes: ,
public abstract class Messages_TranslatedText : IObject { }
/// No translation is available See
[TLDef(0x67CA4737)]
@@ -13166,7 +13166,7 @@ namespace TL
}
/// Represents a list of bot web apps that can be launched from the attachment menu » See
- /// a null value means attachMenuBotsNotModified
+ /// a value means attachMenuBotsNotModified
[TLDef(0x3C4301C0)]
public class AttachMenuBots : IObject
{
@@ -13188,7 +13188,7 @@ namespace TL
public Dictionary users;
}
- /// Contains the webview URL with appropriate theme and user info parameters added Derived classes: See
+ /// Contains the webview URL with appropriate theme and user info parameters added See Derived classes:
public abstract class WebViewResult : IObject { }
/// Contains the webview URL with appropriate theme and user info parameters added See
[TLDef(0x0C14557C)]
@@ -13200,7 +13200,7 @@ namespace TL
public string url;
}
- /// Contains the webview URL with appropriate theme parameters added Derived classes: See
+ /// Contains the webview URL with appropriate theme parameters added See Derived classes:
public abstract class SimpleWebViewResult : IObject { }
/// Contains the webview URL with appropriate theme parameters added See
[TLDef(0x882F76BB)]
@@ -13226,8 +13226,8 @@ namespace TL
}
}
- /// Indicates the action to execute when pressing the in-UI menu button for bots Derived classes: , See
- /// a null value means botMenuButtonDefault
+ /// Indicates the action to execute when pressing the in-UI menu button for bots See Derived classes: ,
+ /// a value means botMenuButtonDefault
public abstract class BotMenuButtonBase : IObject { }
/// Bot menu button that opens the bot command list when clicked. See
[TLDef(0x4258C205)]
@@ -13243,7 +13243,7 @@ namespace TL
}
/// A list of saved notification sounds See
- /// a null value means account.savedRingtonesNotModified
+ /// a value means account.savedRingtonesNotModified
[TLDef(0xC1E92CC5)]
public class Account_SavedRingtones : IObject
{
@@ -13253,8 +13253,8 @@ namespace TL
public DocumentBase[] ringtones;
}
- /// Represents a notification sound Derived classes: , , See
- /// a null value means notificationSoundDefault
+ /// Represents a notification sound See Derived classes: , ,
+ /// a value means notificationSoundDefault
public abstract class NotificationSound : IObject { }
/// No notification sound should be used See
[TLDef(0x6F0C34DF)]
@@ -13302,7 +13302,7 @@ namespace TL
Broadcast = 0x7BFBDEFC,
}
- /// An invoice Derived classes: , See
+ /// An invoice See Derived classes: ,
public abstract class InputInvoice : IObject { }
/// An invoice contained in a message. See
[TLDef(0xC5B56859)]
@@ -13365,7 +13365,7 @@ namespace TL
public Dictionary users;
}
- /// Info about a Telegram Premium purchase Derived classes: , See
+ /// Info about a Telegram Premium purchase See Derived classes: ,
public abstract class InputStorePaymentPurpose : IObject { }
/// Info about a Telegram Premium purchase See
[TLDef(0xA6751E66)]
@@ -13427,7 +13427,7 @@ namespace TL
}
/// An emoji status See
- /// a null value means emojiStatusEmpty
+ /// a value means emojiStatusEmpty
[TLDef(0x929B619D)]
public class EmojiStatus : IObject
{
@@ -13443,7 +13443,7 @@ namespace TL
}
/// A list of emoji statuses See
- /// a null value means account.emojiStatusesNotModified
+ /// a value means account.emojiStatusesNotModified
[TLDef(0x90C467D1)]
public class Account_EmojiStatuses : IObject
{
@@ -13453,8 +13453,8 @@ namespace TL
public EmojiStatus[] statuses;
}
- /// Message reaction Derived classes: , See
- /// a null value means reactionEmpty
+ /// Message reaction See Derived classes: ,
+ /// a value means reactionEmpty
public abstract class Reaction : IObject { }
/// Normal emoji message reaction See
[TLDef(0x1B2286B8)]
@@ -13471,8 +13471,8 @@ namespace TL
public long document_id;
}
- /// Available chat reactions Derived classes: , See
- /// a null value means chatReactionsNone
+ /// Available chat reactions See Derived classes: ,
+ /// a value means chatReactionsNone
public abstract class ChatReactions : IObject { }
/// All reactions or all non-custom reactions are allowed See
[TLDef(0x52928BCA)]
@@ -13496,7 +13496,7 @@ namespace TL
}
/// List of message reactions See
- /// a null value means messages.reactionsNotModified
+ /// a value means messages.reactionsNotModified
[TLDef(0xEAFDF716)]
public class Messages_Reactions : IObject
{
@@ -13506,7 +13506,7 @@ namespace TL
public Reaction[] reactions;
}
- /// Email verification purpose Derived classes: , , See
+ /// Email verification purpose See Derived classes: , ,
public abstract class EmailVerifyPurpose : IObject { }
/// Email verification purpose: setup login email See
[TLDef(0x4345BE73)]
@@ -13524,7 +13524,7 @@ namespace TL
[TLDef(0xBBF51685)]
public class EmailVerifyPurposePassport : EmailVerifyPurpose { }
- /// Email verification code or token Derived classes: , , See
+ /// Email verification code or token See Derived classes: , ,
public abstract class EmailVerification : IObject { }
/// Email verification code See
[TLDef(0x922E55A9)]
diff --git a/src/TL.Secret.cs b/src/TL.Secret.cs
index 125f06b..8c810c8 100644
--- a/src/TL.Secret.cs
+++ b/src/TL.Secret.cs
@@ -28,7 +28,7 @@ namespace TL
}
/// Object describes media contents of an encrypted message. See
- /// a null value means decryptedMessageMediaEmpty
+ /// a value means decryptedMessageMediaEmpty
public abstract class DecryptedMessageMedia : IObject
{
public virtual string MimeType { get; }
diff --git a/src/TL.Table.cs b/src/TL.Table.cs
index 0ae1e3c..3682f20 100644
--- a/src/TL.Table.cs
+++ b/src/TL.Table.cs
@@ -1078,7 +1078,6 @@ namespace TL
[0x36B091DE] = typeof(Layer45.DecryptedMessage),
[0x204D3878] = typeof(Layer17.DecryptedMessage),
[0x1F814F1F] = typeof(Layer8.DecryptedMessage),
- // The End
};
internal readonly static Dictionary Nullables = new()
@@ -1143,7 +1142,6 @@ namespace TL
[typeof(Messages_Reactions)] = 0xB06FDBDF, //messages.reactionsNotModified
// from TL.Secret:
[typeof(DecryptedMessageMedia)] = 0x089F5C4A, //decryptedMessageMediaEmpty
- // The End
};
}
}
From d64c5c0c1e57e57a03149e3af3cd092489e9387f Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Wed, 26 Oct 2022 17:33:06 +0200
Subject: [PATCH 007/336] closes #103: files incorrectly padded to nearest 16
bytes
---
EXAMPLES.md | 2 +-
src/Client.Helpers.cs | 2 +-
src/Encryption.cs | 5 +++--
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/EXAMPLES.md b/EXAMPLES.md
index eb91e4b..e57d7fb 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -177,7 +177,7 @@ var uploadedFile = await client.UploadFileAsync(@"C:\Pictures\flower.jpg");
// Photo 3 specified by external url:
const string photoUrl = "https://picsum.photos/310/200.jpg";
-var inputMedias = new InputMedia[]
+var inputMedias = new List
{
photoFromTelegram, // PhotoBase has implicit conversion to InputMediaPhoto
new InputMediaUploadedPhoto { file = uploadedFile },
diff --git a/src/Client.Helpers.cs b/src/Client.Helpers.cs
index 980d9f1..b809f94 100644
--- a/src/Client.Helpers.cs
+++ b/src/Client.Helpers.cs
@@ -86,7 +86,7 @@ namespace WTelegram
bool abort = false;
for (long bytesLeft = length; !abort && bytesLeft != 0; file_part++)
{
- var bytes = new byte[(Math.Min(FilePartSize, bytesLeft) + 15) & ~15];
+ var bytes = new byte[Math.Min(FilePartSize, bytesLeft)];
read = await stream.FullReadAsync(bytes, bytes.Length, default);
await _parallelTransfers.WaitAsync();
bytesLeft -= read;
diff --git a/src/Encryption.cs b/src/Encryption.cs
index 72bf6fe..450e35f 100644
--- a/src/Encryption.cs
+++ b/src/Encryption.cs
@@ -539,6 +539,7 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB
else { prevBytes = new byte[32]; Array.Copy(iv, 0, prevBytes, 16, 16); Array.Copy(iv, 16, prevBytes, 0, 16); }
}
+ public override long Length => base.Length + 15 & ~15;
public override bool CanSeek => false;
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
@@ -549,7 +550,7 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB
Process(buffer, offset, count);
if (ContentLength.HasValue && _innerStream.Position == _innerStream.Length)
return count - (int)(_innerStream.Position - ContentLength.Value);
- return count;
+ return count + 15 & ~15;
}
public override void Write(byte[] buffer, int offset, int count)
@@ -562,7 +563,7 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB
public void Process(byte[] buffer, int offset, int count)
{
- count = (count + 15) & ~15;
+ count = count + 15 & ~15;
var span = MemoryMarshal.Cast(buffer.AsSpan(offset, count));
var prev = MemoryMarshal.Cast(prevBytes);
for (offset = 0, count /= 8; offset < count;)
From b902b33558228f90a7b2cb2db1feeca2903b0b1c Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Tue, 1 Nov 2022 18:44:01 +0100
Subject: [PATCH 008/336] updated docs (and reordered Examples.md)
---
EXAMPLES.md | 484 +++++++++++++++++++++---------------------
README.md | 2 +-
src/Client.cs | 37 ++--
src/TL.Schema.cs | 22 +-
src/TL.SchemaFuncs.cs | 4 +-
src/TL.Secret.cs | 4 +-
6 files changed, 277 insertions(+), 276 deletions(-)
diff --git a/EXAMPLES.md b/EXAMPLES.md
index e57d7fb..59bf859 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -21,6 +21,29 @@ and avoid calling the same methods (like `Messages_GetAllChats`) repetitively.
ℹ️ WTelegramClient covers 100% of Telegram Client API, much more than the examples below: check the [full API methods list](https://corefork.telegram.org/methods)!
More examples can also be found in the [Examples folder](Examples) and in answers to [StackOverflow questions](https://stackoverflow.com/questions/tagged/wtelegramclient).
+
+### Change logging settings
+By default, WTelegramClient logs are displayed on the Console screen.
+If you are not in a Console app or don't want the logs on screen, you can redirect them as you prefer:
+
+```csharp
+// • Log to file in replacement of default Console screen logging, using this static variable:
+static StreamWriter WTelegramLogs = new StreamWriter("WTelegram.log", true, Encoding.UTF8) { AutoFlush = true };
+...
+WTelegram.Helpers.Log = (lvl, str) => WTelegramLogs.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [{"TDIWE!"[lvl]}] {str}");
+
+// • Log to VS Output debugging pane in addition (+=) to the default Console screen logging:
+WTelegram.Helpers.Log += (lvl, str) => System.Diagnostics.Debug.WriteLine(str);
+
+// • In ASP.NET service, you will typically send logs to an ILogger:
+WTelegram.Helpers.Log = (lvl, str) => _logger.Log((LogLevel)lvl, str);
+
+// • Disable logging (THIS IS NOT RECOMMENDED as you won't be able to diagnose any upcoming problem):
+WTelegram.Helpers.Log = (lvl, str) => { };
+```
+
+The `lvl` argument correspond to standard [LogLevel values](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel#fields)
+
### Send a message to someone by @username
```csharp
@@ -30,15 +53,6 @@ await client.SendMessageAsync(resolved, "/start");
*Note: This also works if the @username points to a channel/group, but you must already have joined that channel before sending a message to it.
If the username is invalid/unused, the API call raises an RpcException.*
-
-### Send a message to someone by phone number
-```csharp
-var contacts = await client.Contacts_ImportContacts(new[] { new InputPhoneContact { phone = "+PHONENUMBER" } });
-if (contacts.imported.Length > 0)
- await client.SendMessageAsync(contacts.users[contacts.imported[0].user_id], "Hello!");
-```
-*Note: To prevent spam, Telegram may restrict your ability to add new phone numbers.*
-
### Convert message to/from HTML or Markdown, and send it to ourself (Saved Messages)
@@ -63,6 +77,196 @@ 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))*
+
+### List all dialogs (chats/groups/channels/user chat) we are currently in
+```csharp
+var dialogs = await client.Messages_GetAllDialogs();
+foreach (Dialog dialog in dialogs.dialogs)
+{
+ switch (dialogs.UserOrChat(dialog))
+ {
+ case User user when user.IsActive: Console.WriteLine("User " + user); break;
+ case ChatBase chat when chat.IsActive: Console.WriteLine(chat); break;
+ }
+ //var latestMsg = dialogs.messages.FirstOrDefault(m => m.Peer.ID == dialog.Peer.ID && m.ID == dialog.TopMessage);
+}
+```
+
+*Note: the lists returned by Messages_GetAllDialogs contains the `access_hash` for those chats and users.*
+See also the `Main` method in [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
+
+
+### List all chats (groups/channels NOT users) that we joined and send a message to one
+```csharp
+var chats = await client.Messages_GetAllChats();
+foreach (var (id, chat) in chats.chats)
+ if (chat.IsActive)
+ Console.WriteLine($"{id} : {chat}");
+Console.Write("Choose a chat ID to send a message to: ");
+long chatId = long.Parse(Console.ReadLine());
+await client.SendMessageAsync(chats.chats[chatId], "Hello, World");
+```
+Notes:
+- This list does not include discussions with other users. For this, you need to use [Messages_GetAllDialogs](#list-dialogs).
+- The list returned by Messages_GetAllChats contains the `access_hash` for those chats. Read [FAQ #4](FAQ.md#access-hash) about this.
+- If a basic chat group has been migrated to a supergroup, you may find both the old `Chat` and a `Channel` with different IDs in the `chats.chats` result,
+but the old `Chat` will be marked with flag [deactivated] and should not be used anymore. See [Terminology in ReadMe](README.md#terminology).
+- You can find a longer version of this method call in [Examples/Program_GetAllChats.cs](Examples/Program_GetAllChats.cs)
+
+
+### List the members from a chat
+For a basic Chat: *(see Terminology in [ReadMe](README.md#terminology))*
+```csharp
+var chatFull = await client.Messages_GetFullChat(1234567890); // the chat we want
+foreach (var (id, user) in chatFull.users)
+ Console.WriteLine(user);
+```
+
+For a Channel/Group:
+```csharp
+var chats = await client.Messages_GetAllChats();
+var channel = (Channel)chats.chats[1234567890]; // the channel we want
+for (int offset = 0; ;)
+{
+ var participants = await client.Channels_GetParticipants(channel, null, offset);
+ foreach (var (id, user) in participants.users)
+ Console.WriteLine(user);
+ offset += participants.participants.Length;
+ if (offset >= participants.count || participants.participants.Length == 0) break;
+}
+```
+
+For big Channel/Group, Telegram servers might limit the number of members you can obtain with the normal above method.
+In this case, you can use the following helper method, but it can take several minutes to complete:
+```csharp
+var chats = await client.Messages_GetAllChats();
+var channel = (Channel)chats.chats[1234567890]; // the channel we want
+var participants = await client.Channels_GetAllParticipants(channel);
+```
+
+You can use specific filters, for example to list only the channel owner/admins:
+```csharp
+var participants = await client.Channels_GetParticipants(channel, filter: new ChannelParticipantsAdmins());
+foreach (var participant in participants.participants) // This is the correct way to enumerate the result
+{
+ var user = participants.users[participant.UserID];
+ if (participant is ChannelParticipantCreator cpc) Console.WriteLine($"{user} is the owner '{cpc.rank}'");
+ else if (participant is ChannelParticipantAdmin cpa) Console.WriteLine($"{user} is admin '{cpa.rank}'");
+}
+```
+*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
+```csharp
+var chats = await client.Messages_GetAllChats();
+InputPeer peer = chats.chats[1234567890]; // the chat we want
+for (int offset_id = 0; ;)
+{
+ var messages = await client.Messages_GetHistory(peer, offset_id);
+ if (messages.Messages.Length == 0) break;
+ foreach (var msgBase in messages.Messages)
+ {
+ var from = messages.UserOrChat(msgBase.From ?? msgBase.Peer); // from can be User/Chat/Channel
+ if (msgBase is Message msg)
+ Console.WriteLine($"{from}> {msg.message} {msg.media}");
+ else if (msgBase is MessageService ms)
+ Console.WriteLine($"{from} [{ms.action.GetType().Name[13..]}]");
+ }
+ offset_id = messages.Messages[^1].ID;
+}
+```
+Notes:
+- 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);`
+
+
+### Monitor all Telegram events happening for the user
+
+This is done through the `client.OnUpdate` callback event.
+Your event handler implementation can either return `Task.CompletedTask` or be an `async Task` method.
+
+See [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
+
+
+### Monitor new messages being posted in chats in real-time
+
+You have to handle `client.OnUpdate` events containing an `UpdateNewMessage`.
+
+See the `DisplayMessage` method in [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
+
+You can filter specific chats the message are posted in, by looking at the `Message.peer_id` field.
+
+
+### Downloading photos, medias, files
+
+This is done using the helper method `client.DownloadFileAsync(file, outputStream)`
+that simplifies the download of a photo/document/file once you get a reference to its location *(through updates or API calls)*.
+
+See [Examples/Program_DownloadSavedMedia.cs](Examples/Program_DownloadSavedMedia.cs) that download all media files you forward to yourself (Saved Messages)
+
+
+### Upload a media file and post it with caption to a chat
+```csharp
+const int ChatId = 1234567890; // the chat we want
+const string Filepath = @"C:\...\photo.jpg";
+
+var chats = await client.Messages_GetAllChats();
+InputPeer peer = chats.chats[ChatId];
+var inputFile = await client.UploadFileAsync(Filepath);
+await client.SendMediaAsync(peer, "Here is the photo", inputFile);
+```
+
+
+### Send a grouped media album using photos from various sources
+```csharp
+// Photo 1 already on Telegram: latest photo found in the user's Saved Messages
+var history = await client.Messages_GetHistory(InputPeer.Self);
+PhotoBase photoFromTelegram = history.Messages.OfType().Select(m => m.media).OfType().First().photo;
+// Photo 2 uploaded now from our computer:
+var uploadedFile = await client.UploadFileAsync(@"C:\Pictures\flower.jpg");
+// Photo 3 specified by external url:
+const string photoUrl = "https://picsum.photos/310/200.jpg";
+
+var inputMedias = new List
+{
+ photoFromTelegram, // PhotoBase has implicit conversion to InputMediaPhoto
+ new InputMediaUploadedPhoto { file = uploadedFile },
+ new InputMediaPhotoExternal() { url = photoUrl },
+};
+await client.SendAlbumAsync(InputPeer.Self, inputMedias, "My first album");
+```
+*Note: Don't mix Photos and file Documents in your album, it doesn't work well*
+
+
+### Forward or copy a message to another chat
+```csharp
+// Determine which chats and message to forward/copy
+var chats = await client.Messages_GetAllChats();
+var from_chat = chats.chats[1234567890]; // source chat
+var to_chat = chats.chats[1234567891]; // destination chat
+var history = await client.Messages_GetHistory(from_chat, limit: 1);
+var msg = history.Messages[0] as Message; // last message of source chat
+
+// • Forward the message (only the source message id is necessary)
+await client.Messages_ForwardMessages(from_chat, new[] { msg.ID }, new[] { WTelegram.Helpers.RandomLong() }, to_chat);
+
+// • Copy the message without the "Forwarded" header (only the source message id is necessary)
+await client.Messages_ForwardMessages(from_chat, new[] { msg.ID }, new[] { WTelegram.Helpers.RandomLong() }, to_chat, drop_author: true);
+
+// • Alternative solution to copy the message (the full message is needed)
+await client.SendMessageAsync(to_chat, msg.message, msg.media?.ToInputMedia(), entities: msg.entities);
+```
+
+
+### Schedule a message to be sent to a chat
+```csharp
+var chats = await client.Messages_GetAllChats();
+InputPeer peer = chats.chats[1234567890]; // the chat we want
+DateTime when = DateTime.UtcNow.AddMinutes(3);
+await client.SendMessageAsync(peer, "This will be posted in 3 minutes", schedule_date: when);
+```
+
### Fun with stickers, GIFs, dice, and animated emojies
```csharp
@@ -112,123 +316,41 @@ var typing = await client.Messages_SetTyping(InputPeer.Self, new SendMessageEmoj
await Task.Delay(5000);
```
-
-### List all chats (groups/channels NOT users) that we joined and send a message to one
+
+### Fun with custom emojies and reactions on pinned messages
```csharp
-var chats = await client.Messages_GetAllChats();
-foreach (var (id, chat) in chats.chats)
- if (chat.IsActive)
- Console.WriteLine($"{id} : {chat}");
-Console.Write("Choose a chat ID to send a message to: ");
-long chatId = long.Parse(Console.ReadLine());
-await client.SendMessageAsync(chats.chats[chatId], "Hello, World");
-```
-Notes:
-- This list does not include discussions with other users. For this, you need to use [Messages_GetAllDialogs](#list-dialogs).
-- The list returned by Messages_GetAllChats contains the `access_hash` for those chats. Read [FAQ #4](FAQ.md#access-hash) about this.
-- If a basic chat group has been migrated to a supergroup, you may find both the old `Chat` and a `Channel` with different IDs in the `chats.chats` result,
-but the old `Chat` will be marked with flag [deactivated] and should not be used anymore. See [Terminology in ReadMe](README.md#terminology).
-- You can find a longer version of this method call in [Examples/Program_GetAllChats.cs](Examples/Program_GetAllChats.cs)
+// • Sending a message with custom emojies in Markdown to ourself:
+var text = "Vicksy says Hi! [👋](emoji?id=5190875290439525089)";
+var entities = client.MarkdownToEntities(ref text, premium: true);
+await client.SendMessageAsync(InputPeer.Self, text, entities: entities);
+// also available in HTML: 👋
-
-### List all dialogs (chats/groups/channels/user chat) we are currently in
-```csharp
-var dialogs = await client.Messages_GetAllDialogs();
-foreach (Dialog dialog in dialogs.dialogs)
- switch (dialogs.UserOrChat(dialog))
- {
- case User user when user.IsActive: Console.WriteLine("User " + user); break;
- case ChatBase chat when chat.IsActive: Console.WriteLine(chat); break;
- }
-```
-
-*Note: the lists returned by Messages_GetAllDialogs contains the `access_hash` for those chats and users.*
-See also the `Main` method in [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
-
-
-### Schedule a message to be sent to a chat
-```csharp
-var chats = await client.Messages_GetAllChats();
-InputPeer peer = chats.chats[1234567890]; // the chat we want
-DateTime when = DateTime.UtcNow.AddMinutes(3);
-await client.SendMessageAsync(peer, "This will be posted in 3 minutes", schedule_date: when);
-```
-
-
-### Upload a media file and post it with caption to a chat
-```csharp
-const int ChatId = 1234567890; // the chat we want
-const string Filepath = @"C:\...\photo.jpg";
+// • Fetch all available standard emoji reactions
+var all_emoji = await client.Messages_GetAvailableReactions();
var chats = await client.Messages_GetAllChats();
-InputPeer peer = chats.chats[ChatId];
-var inputFile = await client.UploadFileAsync(Filepath);
-await client.SendMediaAsync(peer, "Here is the photo", inputFile);
-```
+var chat = chats.chats[1234567890]; // the chat we want
-
-### Send a grouped media album using photos from various sources
-```csharp
-// Photo 1 already on Telegram: latest photo found in the user's Saved Messages
-var history = await client.Messages_GetHistory(InputPeer.Self);
-PhotoBase photoFromTelegram = history.Messages.OfType().Select(m => m.media).OfType().First().photo;
-// Photo 2 uploaded now from our computer:
-var uploadedFile = await client.UploadFileAsync(@"C:\Pictures\flower.jpg");
-// Photo 3 specified by external url:
-const string photoUrl = "https://picsum.photos/310/200.jpg";
-
-var inputMedias = new List
+// • Check reactions available in this chat
+var full = await client.GetFullChat(chat);
+Reaction reaction = full.full_chat.AvailableReactions switch
{
- photoFromTelegram, // PhotoBase has implicit conversion to InputMediaPhoto
- new InputMediaUploadedPhoto { file = uploadedFile },
- new InputMediaPhotoExternal() { url = photoUrl },
+ ChatReactionsSome some => some.reactions[0], // only some reactions are allowed => pick the first
+ ChatReactionsAll all => // all reactions are allowed in this chat
+ all.flags.HasFlag(ChatReactionsAll.Flags.allow_custom) && client.User.flags.HasFlag(TL.User.Flags.premium)
+ ? new ReactionCustomEmoji { document_id = 5190875290439525089 } // we can use custom emoji reactions here
+ : new ReactionEmoji { emoticon = all_emoji.reactions[0].reaction }, // else, pick the first standard emoji reaction
+ _ => null // reactions are not allowed in this chat
};
-await client.SendAlbumAsync(InputPeer.Self, inputMedias, "My first album");
-```
-*Note: Don't mix Photos and file Documents in your album, it doesn't work well*
+if (reaction == null) return;
-
-### Get all members from a chat
-For a basic Chat: *(see Terminology in [ReadMe](README.md#terminology))*
-```csharp
-var chatFull = await client.Messages_GetFullChat(1234567890); // the chat we want
-foreach (var (id, user) in chatFull.users)
- Console.WriteLine(user);
+// • Send the selected reaction on the last 2 pinned messages
+var messages = await client.Messages_Search(chat, limit: 2);
+foreach (var msg in messages.Messages)
+ await client.Messages_SendReaction(chat, msg.ID, reaction: new[] { reaction });
```
+*Note: you can find custom emoji document IDs via API methods like [Messages_GetFeaturedEmojiStickers](https://corefork.telegram.org/method/messages.getFeaturedEmojiStickers) or inspecting incoming messages. Access hash is not required*
-For a Channel/Group:
-```csharp
-var chats = await client.Messages_GetAllChats();
-var channel = (Channel)chats.chats[1234567890]; // the channel we want
-for (int offset = 0; ;)
-{
- var participants = await client.Channels_GetParticipants(channel, null, offset);
- foreach (var (id, user) in participants.users)
- Console.WriteLine(user);
- offset += participants.participants.Length;
- if (offset >= participants.count || participants.participants.Length == 0) break;
-}
-```
-
-For big Channel/Group, Telegram servers might limit the number of members you can obtain with the normal above method.
-In this case, you can use the following helper method, but it can take several minutes to complete:
-```csharp
-var chats = await client.Messages_GetAllChats();
-var channel = (Channel)chats.chats[1234567890]; // the channel we want
-var participants = await client.Channels_GetAllParticipants(channel);
-```
-
-If you only need to list the channel owner/admins, you can use specific filter:
-```csharp
-var participants = await client.Channels_GetParticipants(channel, filter: new ChannelParticipantsAdmins());
-foreach (var participant in participants.participants) // This is the correct way to enumerate the result
-{
- var user = participants.users[participant.UserID];
- if (participant is ChannelParticipantCreator cpc) Console.WriteLine($"{user} is the owner '{cpc.rank}'");
- else if (participant is ChannelParticipantAdmin cpa) Console.WriteLine($"{user} is admin '{cpa.rank}'");
-}
-```
-*Note: It is not possible to list only the Deleted Accounts. Those will be automatically removed by Telegram from your group after a while*
### Join a channel/group by their public name or invite link
@@ -278,46 +400,14 @@ await client.Messages_DeleteExportedChatInvite(chat, invite.link);
await client.DeleteChatUser(chat, user);
```
-
-### Get all messages (history) from a chat
+
+### Send a message to someone by phone number
```csharp
-var chats = await client.Messages_GetAllChats();
-InputPeer peer = chats.chats[1234567890]; // the chat we want
-for (int offset_id = 0; ;)
-{
- var messages = await client.Messages_GetHistory(peer, offset_id);
- if (messages.Messages.Length == 0) break;
- foreach (var msgBase in messages.Messages)
- {
- var from = messages.UserOrChat(msgBase.From ?? msgBase.Peer); // from can be User/Chat/Channel
- if (msgBase is Message msg)
- Console.WriteLine($"{from}> {msg.message} {msg.media}");
- else if (msgBase is MessageService ms)
- Console.WriteLine($"{from} [{ms.action.GetType().Name[13..]}]");
- }
- offset_id = messages.Messages[^1].ID;
-}
+var contacts = await client.Contacts_ImportContacts(new[] { new InputPhoneContact { phone = "+PHONENUMBER" } });
+if (contacts.imported.Length > 0)
+ await client.SendMessageAsync(contacts.users[contacts.imported[0].user_id], "Hello!");
```
-Notes:
-- 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);`
-
-
-### Monitor all Telegram events happening for the user
-
-This is done through the `client.OnUpdate` callback event.
-Your event handler implementation can either return `Task.CompletedTask` or be an `async Task` method.
-
-See [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
-
-
-### Monitor new messages being posted in chats in real-time
-
-You have to handle `client.OnUpdate` events containing an `UpdateNewMessage`.
-
-See the `DisplayMessage` method in [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
-
-You can filter specific chats the message are posted in, by looking at the `Message.peer_id` field.
+*Note: Don't use this method too much. To prevent spam, Telegram may restrict your ability to add new phone numbers.*
### Retrieve the current user's contacts list
@@ -348,14 +438,6 @@ finally
}
```
-
-### Downloading photos, medias, files
-
-This is done using the helper method `client.DownloadFileAsync(file, outputStream)`
-that simplify the download of a photo/document/file once you get a reference to its location *(through updates or API calls)*.
-
-See [Examples/Program_DownloadSavedMedia.cs](Examples/Program_DownloadSavedMedia.cs) that download all media files you forward to yourself (Saved Messages)
-
### Collect Access Hash and save them for later use
@@ -397,29 +479,6 @@ If your Telegram client is already connected to such MTPROTO proxy, you can also
*Note: WTelegramClient always uses transport obfuscation when connecting to Telegram servers, even without MTProxy*
-
-### Change logging settings
-By default, WTelegramClient logs are displayed on the Console screen.
-If you are not in a Console app or don't want the logs on screen, you can redirect them as you prefer:
-
-```csharp
-// • Log to file in replacement of default Console screen logging, using this static variable:
-static StreamWriter WTelegramLogs = new StreamWriter("WTelegram.log", true, Encoding.UTF8) { AutoFlush = true };
-...
-WTelegram.Helpers.Log = (lvl, str) => WTelegramLogs.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [{"TDIWE!"[lvl]}] {str}");
-
-// • Log to VS Output debugging pane in addition (+=) to the default Console screen logging:
-WTelegram.Helpers.Log += (lvl, str) => System.Diagnostics.Debug.WriteLine(str);
-
-// • In ASP.NET service, you will typically send logs to an ILogger:
-WTelegram.Helpers.Log = (lvl, str) => _logger.Log((LogLevel)lvl, str);
-
-// • Disable logging (THIS IS NOT RECOMMENDED as you won't be able to diagnose any upcoming problem):
-WTelegram.Helpers.Log = (lvl, str) => { };
-```
-
-The `lvl` argument correspond to standard [LogLevel values](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel#fields)
-
### Change 2FA password
```csharp
@@ -449,61 +508,6 @@ Use it to pass a custom Stream-derived class that will **read** (first initial c
You can find an example for such custom session store in [Examples/Program_Heroku.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_Heroku.cs#L61)
-
-### Fun with custom emojies and reactions on pinned messages
-```csharp
-// • Sending a message with custom emojies in Markdown to ourself:
-var text = "Vicksy says Hi! [👋](emoji?id=5190875290439525089)";
-var entities = client.MarkdownToEntities(ref text, premium: true);
-await client.SendMessageAsync(InputPeer.Self, text, entities: entities);
-// also available in HTML: 👋
-
-// • Fetch all available standard emoji reactions
-var all_emoji = await client.Messages_GetAvailableReactions();
-
-var chats = await client.Messages_GetAllChats();
-var chat = chats.chats[1234567890]; // the chat we want
-
-// • Check reactions available in this chat
-var full = await client.GetFullChat(chat);
-Reaction reaction = full.full_chat.AvailableReactions switch
-{
- ChatReactionsSome some => some.reactions[0], // only some reactions are allowed => pick the first
- ChatReactionsAll all => // all reactions are allowed in this chat
- all.flags.HasFlag(ChatReactionsAll.Flags.allow_custom) && client.User.flags.HasFlag(TL.User.Flags.premium)
- ? new ReactionCustomEmoji { document_id = 5190875290439525089 } // we can use custom emoji reactions here
- : new ReactionEmoji { emoticon = all_emoji.reactions[0].reaction }, // else, pick the first standard emoji reaction
- _ => null // reactions are not allowed in this chat
-};
-if (reaction == null) return;
-
-// • Send the selected reaction on the last 2 pinned messages
-var messages = await client.Messages_Search(chat, limit: 2);
-foreach (var msg in messages.Messages)
- await client.Messages_SendReaction(chat, msg.ID, reaction: new[] { reaction });
-```
-*Note: you can find custom emoji document IDs via API methods like [Messages_GetFeaturedEmojiStickers](https://corefork.telegram.org/method/messages.getFeaturedEmojiStickers) or inspecting incoming messages. Access hash is not required*
-
-
-### Forward or copy a message to another chat
-```csharp
-// Determine which chats and message to forward/copy
-var chats = await client.Messages_GetAllChats();
-var from_chat = chats.chats[1234567890]; // source chat
-var to_chat = chats.chats[1234567891]; // destination chat
-var history = await client.Messages_GetHistory(from_chat, limit: 1);
-var msg = history.Messages[0] as Message; // last message of source chat
-
-// • Forward the message (only the source message id is necessary)
-await client.Messages_ForwardMessages(from_chat, new[] { msg.ID }, new[] { WTelegram.Helpers.RandomLong() }, to_chat);
-
-// • Copy the message without the "Forwarded" header (only the source message id is necessary)
-await client.Messages_ForwardMessages(from_chat, new[] { msg.ID }, new[] { WTelegram.Helpers.RandomLong() }, to_chat, drop_author: true);
-
-// • Alternative solution to copy the message (the full message is needed)
-await client.SendMessageAsync(to_chat, msg.message, msg.media?.ToInputMedia(), entities: msg.entities);
-```
-
### Send/receive end-to-end encrypted messages & files in Secret Chats
diff --git a/README.md b/README.md
index e8a0773..439e09d 100644
--- a/README.md
+++ b/README.md
@@ -163,7 +163,7 @@ or a [broadcast channel](https://corefork.telegram.org/api/channel#channels) (th
- `Chat` : A private [basic chat group](https://corefork.telegram.org/api/channel#basic-groups) with less than 200 members
(it may be migrated to a supergroup `Channel` with a new ID when it gets bigger or public, in which case the old `Chat` will still exist but will be `deactivated`)
**⚠️ Most chat groups you see are really of type `Channel`, not `Chat`!**
-- chats : In plural or general meaning, it means either `Chat` or `Channel`
+- chats : In plural or general meaning, it means either `Chat` or `Channel` *(therefore, no private user discussions)*
- `Peer` : Either a `Chat`, a `Channel` or a `User`
- Dialog : Status of chat with a `Peer` *(draft, last message, unread count, pinned...)*. It represents each line from your Telegram chat list.
- Access Hash : Telegram requires you to provide a specific `access_hash` for users, channels, and other resources before interacting with them.
diff --git a/src/Client.cs b/src/Client.cs
index de73394..7386ae7 100644
--- a/src/Client.cs
+++ b/src/Client.cs
@@ -322,27 +322,24 @@ namespace WTelegram
if (!IsMainDC && _pendingRpcs.Count <= 1 && ex is ApplicationException { Message: ConnectionShutDown } or IOException { InnerException: SocketException })
if (_pendingRpcs.Values.FirstOrDefault() is not Rpc rpc || rpc.type == typeof(Pong))
_reactorReconnects = 0;
- if (_reactorReconnects != 0)
- {
- await Task.Delay(5000);
- if (_networkStream == null) return; // Dispose has been called in-between
- await ConnectAsync(); // start a new reactor after 5 secs
- lock (_pendingRpcs) // retry all pending requests
- {
- foreach (var rpc in _pendingRpcs.Values)
- rpc.tcs.SetResult(reactorError); // this leads to a retry (see Invoke method)
- _pendingRpcs.Clear();
- _bareRpc = null;
- }
- // TODO: implement an Updates gaps handling system? https://core.telegram.org/api/updates
- if (IsMainDC)
- {
- var updatesState = await this.Updates_GetState(); // this call reenables incoming Updates
- RaiseUpdate(updatesState);
- }
- }
- else
+ if (_reactorReconnects == 0)
throw;
+ await Task.Delay(5000);
+ if (_networkStream == null) return; // Dispose has been called in-between
+ await ConnectAsync(); // start a new reactor after 5 secs
+ lock (_pendingRpcs) // retry all pending requests
+ {
+ foreach (var rpc in _pendingRpcs.Values)
+ rpc.tcs.SetResult(reactorError); // this leads to a retry (see Invoke method)
+ _pendingRpcs.Clear();
+ _bareRpc = null;
+ }
+ // TODO: implement an Updates gaps handling system? https://core.telegram.org/api/updates
+ if (IsMainDC)
+ {
+ var updatesState = await this.Updates_GetState(); // this call reenables incoming Updates
+ RaiseUpdate(updatesState);
+ }
}
catch
{
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index df0ec23..a827e48 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -2268,24 +2268,24 @@ namespace TL
/// Location of a certain size of a picture See Derived classes: , , , , ,
public abstract partial class PhotoSizeBase : IObject
{
- /// Thumbnail type (see. )
+ /// Thumbnail type »
public virtual string Type { get; }
}
/// Empty constructor. Image with this thumbnail is unavailable. See
[TLDef(0x0E17E23C)]
public partial class PhotoSizeEmpty : PhotoSizeBase
{
- /// Thumbnail type (see. )
+ /// Thumbnail type »
public string type;
- /// Thumbnail type (see. )
+ /// Thumbnail type »
public override string Type => type;
}
/// Image description. See
[TLDef(0x75C78E60)]
public partial class PhotoSize : PhotoSizeBase
{
- /// Thumbnail type
+ /// Thumbnail type »
public string type;
/// Image width
public int w;
@@ -2294,7 +2294,7 @@ namespace TL
/// File size
public int size;
- /// Thumbnail type
+ /// Thumbnail type »
public override string Type => type;
}
/// Description of an image and its content. See
@@ -2329,7 +2329,7 @@ namespace TL
[TLDef(0xFA3EFB95)]
public partial class PhotoSizeProgressive : PhotoSizeBase
{
- /// Photosize type
+ /// Photosize type »
public string type;
/// Photo width
public int w;
@@ -2338,7 +2338,7 @@ namespace TL
/// Sizes of progressive JPEG file prefixes, which can be used to preliminarily show the image.
public int[] sizes;
- /// Photosize type
+ /// Photosize type »
public override string Type => type;
}
/// Messages with animated stickers can have a compressed svg (< 300 bytes) to show the outline of the sticker before fetching the actual lottie animation. See
@@ -13151,9 +13151,9 @@ namespace TL
public long bot_id;
/// Attachment menu item name
public string short_name;
- /// List of peer types where this attachment should be shown
+ /// List of dialog types where this attachment menu entry should be shown
public AttachMenuPeerType[] peer_types;
- /// Attachment menu icon
+ /// List of platform-specific static icons and animations to use for the attachment menu button
public AttachMenuBotIcon[] icons;
[Flags] public enum Flags : uint
@@ -13292,9 +13292,9 @@ namespace TL
{
///The bot attachment menu entry is available in the chat with the bot that offers it
SameBotPM = 0x7D6BE90E,
- ///The bot attachment menu entry is available in private chats with other bots
+ ///The bot attachment menu entry is available in private chats with other bots (excluding the bot that offers the current attachment menu)
BotPM = 0xC32BFA1A,
- ///The bot attachment menu entry is available in private chats with other users
+ ///The bot attachment menu entry is available in private chats with other users (not bots)
PM = 0xF146D31F,
///The bot attachment menu entry is available in groups and supergroups
Chat = 0x0509113F,
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index c0b70d1..43f7f50 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -3214,7 +3214,7 @@ namespace TL
/// Bot that owns the web app
/// Web app URL
/// If the web app was opened from the attachment menu using a attachment menu deep link, start_param should contain the data from the startattach parameter.
- /// Theme parameters for the web app
+ /// Theme parameters »
/// Short name of the application; 0-64 English letters, digits, and underscores
/// Whether the inline message that will be sent by the bot on behalf of the user once the web app interaction is terminated should be sent in reply to this message ID.
/// Open the web app as the specified peer, sending the resulting the message as the specified peer.
@@ -3253,7 +3253,7 @@ namespace TL
/// Open a bot web app. See
/// Bot that owns the webapp
/// Web app URL
- /// Theme parameters
+ /// 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)
=> client.Invoke(new Messages_RequestSimpleWebView
diff --git a/src/TL.Secret.cs b/src/TL.Secret.cs
index 8c810c8..1cf43a6 100644
--- a/src/TL.Secret.cs
+++ b/src/TL.Secret.cs
@@ -672,7 +672,7 @@ namespace TL
[TLDef(0x77BFB61B)]
public partial class PhotoSize : PhotoSizeBase
{
- /// Thumbnail type
+ /// Thumbnail type »
public string type;
public FileLocationBase location;
/// Image width
@@ -682,7 +682,7 @@ namespace TL
/// File size
public int size;
- /// Thumbnail type
+ /// Thumbnail type »
public override string Type => type;
}
/// Description of an image and its content. See
From fd42d3e6df61cdea1cb920b048bb92b813f02ba4 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Tue, 1 Nov 2022 19:26:40 +0100
Subject: [PATCH 009/336] Upgrade to layer 148: Topics, Usernames, Sticker
keywords... + support for flags2 has_fields
---
Examples/Program_ListenUpdates.cs | 2 +-
README.md | 2 +-
src/TL.Schema.cs | 275 ++++++++++++++++++++-
src/TL.SchemaFuncs.cs | 385 ++++++++++++++++++++++++++----
src/TL.Table.cs | 39 ++-
src/TL.cs | 16 +-
6 files changed, 648 insertions(+), 71 deletions(-)
diff --git a/Examples/Program_ListenUpdates.cs b/Examples/Program_ListenUpdates.cs
index fd25eb6..920dfd1 100644
--- a/Examples/Program_ListenUpdates.cs
+++ b/Examples/Program_ListenUpdates.cs
@@ -50,7 +50,7 @@ namespace WTelegramClientTest
case UpdateChannelUserTyping ucut2: Console.WriteLine($"{Peer(ucut2.from_id)} is {ucut2.action} in {Chat(ucut2.channel_id)}"); break;
case UpdateChatParticipants { participants: ChatParticipants cp }: Console.WriteLine($"{cp.participants.Length} participants in {Chat(cp.chat_id)}"); break;
case UpdateUserStatus uus: Console.WriteLine($"{User(uus.user_id)} is now {uus.status.GetType().Name[10..]}"); break;
- case UpdateUserName uun: Console.WriteLine($"{User(uun.user_id)} has changed profile name: @{uun.username} {uun.first_name} {uun.last_name}"); break;
+ case UpdateUserName uun: Console.WriteLine($"{User(uun.user_id)} has changed profile name: {uun.first_name} {uun.last_name}"); break;
case UpdateUserPhoto uup: Console.WriteLine($"{User(uup.user_id)} has changed profile photo"); break;
default: Console.WriteLine(update.GetType().Name); break; // there are much more update types than the above cases
}
diff --git a/README.md b/README.md
index 439e09d..16da3f6 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
[](https://www.nuget.org/packages/WTelegramClient/)
[](https://dev.azure.com/wiz0u/WTelegramClient/_build?definitionId=7)
-[](https://corefork.telegram.org/methods)
+[](https://corefork.telegram.org/methods)
[](https://dev.azure.com/wiz0u/WTelegramClient/_artifacts/feed/WTelegramClient/NuGet/WTelegramClient)
[](https://t.me/WTelegramClient)
[](http://t.me/WTelegramBot?start=donate)
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index a827e48..b785fb9 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -698,11 +698,12 @@ namespace TL
public long id;
}
/// Indicates info about a certain user See
- [TLDef(0x5D99ADEE)]
+ [TLDef(0x8F97C628)]
public partial class User : UserBase
{
/// Flags, see TL conditional fields
public Flags flags;
+ public Flags2 flags2;
/// ID of the user
public long id;
/// Access hash of the user
@@ -729,6 +730,7 @@ namespace TL
[IfFlag(22)] public string lang_code;
/// Emoji status
[IfFlag(30)] public EmojiStatus emoji_status;
+ [IfFlag(32)] public Username[] usernames;
[Flags] public enum Flags : uint
{
@@ -789,6 +791,12 @@ namespace TL
/// Field has a value
has_emoji_status = 0x40000000,
}
+
+ [Flags] public enum Flags2 : uint
+ {
+ /// Field has a value
+ has_usernames = 0x1,
+ }
}
/// User profile photo. See
@@ -926,11 +934,12 @@ namespace TL
public override string Title => title;
}
/// Channel/supergroup info See
- [TLDef(0x8261AC61)]
+ [TLDef(0x83259464)]
public partial class Channel : ChatBase
{
/// Flags, see TL conditional fields
public Flags flags;
+ public Flags2 flags2;
/// ID of the channel
public long id;
/// Access hash
@@ -953,6 +962,7 @@ namespace TL
[IfFlag(18)] public ChatBannedRights default_banned_rights;
/// Participant count
[IfFlag(17)] public int participants_count;
+ [IfFlag(32)] public Username[] usernames;
[Flags] public enum Flags : uint
{
@@ -1006,6 +1016,13 @@ namespace TL
join_to_send = 0x10000000,
/// Whether a user's join request will have to be approved by administrators, toggle using channels.toggleJoinToSend
join_request = 0x20000000,
+ forum = 0x40000000,
+ }
+
+ [Flags] public enum Flags2 : uint
+ {
+ /// Field has a value
+ has_usernames = 0x1,
}
/// ID of the channel
@@ -2136,6 +2153,36 @@ namespace TL
/// Duration of the gifted Telegram Premium subscription
public int months;
}
+ /// See
+ [TLDef(0x0D999256)]
+ public class MessageActionTopicCreate : MessageAction
+ {
+ public Flags flags;
+ public string title;
+ public int icon_color;
+ [IfFlag(0)] public long icon_emoji_id;
+
+ [Flags] public enum Flags : uint
+ {
+ has_icon_emoji_id = 0x1,
+ }
+ }
+ /// See
+ [TLDef(0xB18A431C)]
+ public class MessageActionTopicEdit : MessageAction
+ {
+ public Flags flags;
+ [IfFlag(0)] public string title;
+ [IfFlag(1)] public long icon_emoji_id;
+ [IfFlag(2)] public bool closed;
+
+ [Flags] public enum Flags : uint
+ {
+ has_title = 0x1,
+ has_icon_emoji_id = 0x2,
+ has_closed = 0x4,
+ }
+ }
/// Chat info. See Derived classes: ,
public abstract class DialogBase : IObject
@@ -2468,6 +2515,13 @@ namespace TL
/// All channels See
[TLDef(0xB1DB7C7E)]
public class InputNotifyBroadcasts : InputNotifyPeerBase { }
+ /// See
+ [TLDef(0x5C467992)]
+ public class InputNotifyForumTopic : InputNotifyPeerBase
+ {
+ public InputPeer peer;
+ public int top_msg_id;
+ }
/// Notification settings. See
[TLDef(0xDF1F002B)]
@@ -3132,7 +3186,7 @@ namespace TL
public UserStatus status;
}
/// Changes the user's first name, last name and username. See
- [TLDef(0xC3F202E0)]
+ [TLDef(0xA7848924)]
public class UpdateUserName : Update
{
/// User identifier
@@ -3141,8 +3195,7 @@ namespace TL
public string first_name;
/// New last name. Corresponds to the new value of real_last_name field of the .
public string last_name;
- /// New username.
- public string username;
+ public Username[] usernames;
}
/// Change of contact's profile photo. See
[TLDef(0xF227868C)]
@@ -3575,13 +3628,21 @@ namespace TL
public int max_id;
}
/// Notifies a change of a message draft. See
- [TLDef(0xEE2BB969)]
+ [TLDef(0x1B49EC6D)]
public class UpdateDraftMessage : Update
{
+ public Flags flags;
/// The peer to which the draft is associated
public Peer peer;
+ [IfFlag(0)] public int top_msg_id;
/// The draft
public DraftMessageBase draft;
+
+ [Flags] public enum Flags : uint
+ {
+ /// Field has a value
+ has_top_msg_id = 0x1,
+ }
}
/// Some featured stickers were marked as read See
[TLDef(0x571D2742)]
@@ -3725,11 +3786,21 @@ namespace TL
[TLDef(0xE511996D)]
public class UpdateFavedStickers : Update { }
/// The specified channel/supergroup messages were read See
- [TLDef(0x44BDD535, inheritBefore = true)]
- public class UpdateChannelReadMessagesContents : UpdateChannel
+ [TLDef(0xEA29055D)]
+ public class UpdateChannelReadMessagesContents : Update
{
+ public Flags flags;
+ /// Channel/supergroup ID
+ public long channel_id;
+ [IfFlag(0)] public int top_msg_id;
/// IDs of messages that were read
public int[] messages;
+
+ [Flags] public enum Flags : uint
+ {
+ /// Field has a value
+ has_top_msg_id = 0x1,
+ }
}
/// All contacts were deleted See
[TLDef(0x7084A7BE)]
@@ -4190,15 +4261,23 @@ namespace TL
public int qts;
}
/// New message reactions » are available See
- [TLDef(0x154798C3)]
+ [TLDef(0x5E1B3CB8)]
public class UpdateMessageReactions : Update
{
+ public Flags flags;
/// Peer
public Peer peer;
/// Message ID
public int msg_id;
+ [IfFlag(0)] public int top_msg_id;
/// Reactions
public MessageReactions reactions;
+
+ [Flags] public enum Flags : uint
+ {
+ /// Field has a value
+ has_top_msg_id = 0x1,
+ }
}
/// The list of installed attachment menu entries » has changed, use messages.getAttachMenuBots to fetch the updated list. See
[TLDef(0x17B7A20B)]
@@ -4286,6 +4365,19 @@ namespace TL
public int msg_id;
public MessageExtendedMediaBase extended_media;
}
+ /// See
+ [TLDef(0xF694B0AE)]
+ public class UpdateChannelPinnedTopic : Update
+ {
+ public Flags flags;
+ public long channel_id;
+ [IfFlag(0)] public int topic_id;
+
+ [Flags] public enum Flags : uint
+ {
+ has_topic_id = 0x1,
+ }
+ }
/// Updates state. See
[TLDef(0xA56C2A3E)]
@@ -5260,6 +5352,13 @@ namespace TL
/// Channel notification settings See
[TLDef(0xD612E8EF)]
public class NotifyBroadcasts : NotifyPeerBase { }
+ /// See
+ [TLDef(0x226E6308)]
+ public class NotifyForumTopic : NotifyPeerBase
+ {
+ public Peer peer;
+ public int top_msg_id;
+ }
/// User actions. Use this to provide users with detailed info about their chat partner's actions: typing or sending attachments of all kinds. See Derived classes: , , , , , , , , , , , , , , , , ,
public abstract partial class SendMessageAction : IObject { }
@@ -6111,6 +6210,9 @@ namespace TL
/// Default custom emoji status stickerset See
[TLDef(0x29D0F5EE)]
public class InputStickerSetEmojiDefaultStatuses : InputStickerSet { }
+ /// See
+ [TLDef(0x44C1F8E9)]
+ public class InputStickerSetEmojiDefaultTopicIcons : InputStickerSet { }
/// Represents a stickerset (stickerpack) See
[TLDef(0x2DD14EDC)]
@@ -6166,13 +6268,14 @@ namespace TL
/// Stickerset and stickers inside it See
/// a value means messages.stickerSetNotModified
- [TLDef(0xB60A24A6)]
+ [TLDef(0x6E153F16)]
public class Messages_StickerSet : IObject
{
/// The stickerset
public StickerSet set;
/// Emoji info for stickers
public StickerPack[] packs;
+ public StickerKeyword[] keywords;
/// Stickers in stickerset
public DocumentBase[] documents;
}
@@ -8002,13 +8105,14 @@ namespace TL
public override StickerSet Set => set;
}
/// Stickerset preview with all stickers of the stickerset included.
Currently used only for custom emoji stickersets, to avoid a further call to messages.getStickerSet. See
- [TLDef(0x1AED5EE5)]
+ [TLDef(0x40D13C0E)]
public class StickerSetFullCovered : StickerSetCoveredBase
{
/// Stickerset
public StickerSet set;
/// Emoji information about every sticker in the stickerset
public StickerPack[] packs;
+ public StickerKeyword[] keywords;
/// Stickers
public DocumentBase[] documents;
@@ -9803,6 +9907,52 @@ namespace TL
/// New allowed reaction emojis
public ChatReactions new_value;
}
+ /// See
+ [TLDef(0xF04FB3A9)]
+ public class ChannelAdminLogEventActionChangeUsernames : ChannelAdminLogEventAction
+ {
+ public string[] prev_value;
+ public string[] new_value;
+ }
+ /// See
+ [TLDef(0x02CC6383)]
+ public class ChannelAdminLogEventActionToggleForum : ChannelAdminLogEventAction
+ {
+ public bool new_value;
+ }
+ /// See
+ [TLDef(0x58707D28)]
+ public class ChannelAdminLogEventActionCreateTopic : ChannelAdminLogEventAction
+ {
+ public ForumTopicBase topic;
+ }
+ /// See
+ [TLDef(0xF06FE208)]
+ public class ChannelAdminLogEventActionEditTopic : ChannelAdminLogEventAction
+ {
+ public ForumTopicBase prev_topic;
+ public ForumTopicBase new_topic;
+ }
+ /// See
+ [TLDef(0xAE168909)]
+ public class ChannelAdminLogEventActionDeleteTopic : ChannelAdminLogEventAction
+ {
+ public ForumTopicBase topic;
+ }
+ /// See
+ [TLDef(0x5D8D353B)]
+ public class ChannelAdminLogEventActionPinTopic : ChannelAdminLogEventAction
+ {
+ public Flags flags;
+ [IfFlag(0)] public ForumTopicBase prev_topic;
+ [IfFlag(1)] public ForumTopicBase new_topic;
+
+ [Flags] public enum Flags : uint
+ {
+ has_prev_topic = 0x1,
+ has_new_topic = 0x2,
+ }
+ }
/// Admin log event See
[TLDef(0x1FAD68CD)]
@@ -9875,6 +10025,7 @@ namespace TL
invites = 0x8000,
/// A message was posted in a channel
send = 0x10000,
+ forums = 0x20000,
}
}
@@ -11045,6 +11196,7 @@ namespace TL
manage_call = 0x800,
/// Set this flag if none of the other flags are set, but you still want the user to be an admin: if this or any of the other flags are set, the admin can get the chat admin log, get chat statistics, get message statistics in channels, get channel members, see anonymous administrators in supergroups and ignore slow mode.
other = 0x1000,
+ manage_topics = 0x2000,
}
}
@@ -11083,6 +11235,7 @@ namespace TL
invite_users = 0x8000,
/// If set, does not allow any user to pin messages in a supergroup/chat
pin_messages = 0x20000,
+ manage_topics = 0x40000,
}
}
@@ -12211,6 +12364,7 @@ namespace TL
/// Field has a value
has_reply_to_top_id = 0x2,
reply_to_scheduled = 0x4,
+ forum_topic = 0x8,
}
}
@@ -12786,19 +12940,29 @@ namespace TL
has_chat_invite = 0x10,
/// Whether the message needs to be labeled as "recommended" instead of "sponsored"
recommended = 0x20,
+ show_peer_photo = 0x40,
}
}
/// A set of sponsored messages associated to a channel See
- [TLDef(0x65A4C7D5)]
+ /// a value means messages.sponsoredMessagesEmpty
+ [TLDef(0xC9EE1D87)]
public class Messages_SponsoredMessages : IObject, IPeerResolver
{
+ public Flags flags;
+ [IfFlag(0)] public int posts_between;
/// Sponsored messages
public SponsoredMessage[] messages;
/// Chats mentioned in the sponsored messages
public Dictionary chats;
/// Users mentioned in the sponsored messages
public Dictionary users;
+
+ [Flags] public enum Flags : uint
+ {
+ /// Field has a value
+ has_posts_between = 0x1,
+ }
/// returns a or for the given Peer
public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats);
}
@@ -13630,4 +13794,91 @@ namespace TL
{
public MessageMedia media;
}
+
+ /// See
+ [TLDef(0xFCFEB29C)]
+ public class StickerKeyword : IObject
+ {
+ public long document_id;
+ public string[] keyword;
+ }
+
+ /// See
+ [TLDef(0xB4073647)]
+ public class Username : IObject
+ {
+ public Flags flags;
+ public string username;
+
+ [Flags] public enum Flags : uint
+ {
+ editable = 0x1,
+ active = 0x2,
+ }
+ }
+
+ /// See
+ public abstract class ForumTopicBase : IObject
+ {
+ public virtual int ID { get; }
+ }
+ /// See
+ [TLDef(0x023F109B)]
+ public class ForumTopicDeleted : ForumTopicBase
+ {
+ public int id;
+
+ public override int ID => id;
+ }
+ /// See
+ [TLDef(0x71701DA9)]
+ public class ForumTopic : ForumTopicBase
+ {
+ public Flags flags;
+ public int id;
+ public DateTime date;
+ public string title;
+ public int icon_color;
+ [IfFlag(0)] public long icon_emoji_id;
+ public int top_message;
+ public int read_inbox_max_id;
+ public int read_outbox_max_id;
+ public int unread_count;
+ public int unread_mentions_count;
+ public int unread_reactions_count;
+ public Peer from_id;
+ public PeerNotifySettings notify_settings;
+ [IfFlag(4)] public DraftMessageBase draft;
+
+ [Flags] public enum Flags : uint
+ {
+ has_icon_emoji_id = 0x1,
+ my = 0x2,
+ closed = 0x4,
+ pinned = 0x8,
+ has_draft = 0x10,
+ }
+
+ public override int ID => id;
+ }
+
+ /// See
+ [TLDef(0x367617D3)]
+ public class Messages_ForumTopics : IObject, IPeerResolver
+ {
+ public Flags flags;
+ public int count;
+ public ForumTopicBase[] topics;
+ public MessageBase[] messages;
+ public Dictionary chats;
+ public Dictionary users;
+ public int pts;
+
+ [Flags] public enum Flags : uint
+ {
+ order_by_create_date = 0x1,
+ }
+ /// 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 43f7f50..081d365 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -869,13 +869,11 @@ namespace TL
/// Get theme information See Possible codes: 400 (details)
/// Theme format, a string that identifies the theming engines supported by the client
/// Theme
- /// Deprecated: should always be 0
- public static Task Account_GetTheme(this Client client, string format, InputThemeBase theme, long document_id)
+ public static Task Account_GetTheme(this Client client, string format, InputThemeBase theme)
=> client.Invoke(new Account_GetTheme
{
format = format,
theme = theme,
- document_id = document_id,
});
/// Get installed themes See
@@ -1044,6 +1042,21 @@ namespace TL
{
});
+ /// See
+ public static Task Account_ReorderUsernames(this Client client, params string[] order)
+ => client.Invoke(new Account_ReorderUsernames
+ {
+ order = order,
+ });
+
+ /// See
+ public static Task Account_ToggleUsername(this Client client, string username, bool active)
+ => client.Invoke(new Account_ToggleUsername
+ {
+ username = username,
+ active = active,
+ });
+
/// 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)
@@ -1425,12 +1438,13 @@ namespace TL
/// Message entities for sending styled text
/// Scheduled message date for scheduled messages
/// Send this message as the specified peer
- public static Task Messages_SendMessage(this Client client, InputPeer peer, string message, long random_id, bool no_webpage = false, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, int? reply_to_msg_id = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null, InputPeer send_as = null)
+ public static Task Messages_SendMessage(this Client client, InputPeer peer, string message, long random_id, bool no_webpage = false, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, int? reply_to_msg_id = null, int? top_msg_id = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null, InputPeer send_as = null)
=> client.Invoke(new Messages_SendMessage
{
- flags = (Messages_SendMessage.Flags)((no_webpage ? 0x2 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_SendMessage.Flags)((no_webpage ? 0x2 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
peer = peer,
reply_to_msg_id = reply_to_msg_id.GetValueOrDefault(),
+ top_msg_id = top_msg_id.GetValueOrDefault(),
message = message,
random_id = random_id,
reply_markup = reply_markup,
@@ -1454,12 +1468,13 @@ namespace TL
/// Message entities for styled text
/// Scheduled message date for scheduled messages
/// Send this message as the specified peer
- public static Task Messages_SendMedia(this Client client, InputPeer peer, InputMedia media, string message, long random_id, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, int? reply_to_msg_id = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null, InputPeer send_as = null)
+ public static Task Messages_SendMedia(this Client client, InputPeer peer, InputMedia media, string message, long random_id, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, int? reply_to_msg_id = null, int? top_msg_id = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null, InputPeer send_as = null)
=> client.Invoke(new Messages_SendMedia
{
- flags = (Messages_SendMedia.Flags)((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_SendMedia.Flags)((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
peer = peer,
reply_to_msg_id = reply_to_msg_id.GetValueOrDefault(),
+ top_msg_id = top_msg_id.GetValueOrDefault(),
media = media,
message = message,
random_id = random_id,
@@ -1482,14 +1497,15 @@ namespace TL
/// Destination peer
/// Scheduled message date for scheduled messages
/// Forward the messages as the specified peer
- public static Task Messages_ForwardMessages(this Client client, InputPeer from_peer, int[] id, long[] random_id, InputPeer to_peer, bool silent = false, bool background = false, bool with_my_score = false, bool drop_author = false, bool drop_media_captions = false, bool noforwards = false, DateTime? schedule_date = null, InputPeer send_as = null)
+ public static Task Messages_ForwardMessages(this Client client, InputPeer from_peer, int[] id, long[] random_id, InputPeer to_peer, bool silent = false, bool background = false, bool with_my_score = false, bool drop_author = false, bool drop_media_captions = false, bool noforwards = false, int? top_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null)
=> client.Invoke(new Messages_ForwardMessages
{
- flags = (Messages_ForwardMessages.Flags)((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (with_my_score ? 0x100 : 0) | (drop_author ? 0x800 : 0) | (drop_media_captions ? 0x1000 : 0) | (noforwards ? 0x4000 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_ForwardMessages.Flags)((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (with_my_score ? 0x100 : 0) | (drop_author ? 0x800 : 0) | (drop_media_captions ? 0x1000 : 0) | (noforwards ? 0x4000 : 0) | (top_msg_id != null ? 0x200 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
from_peer = from_peer,
id = id,
random_id = random_id,
to_peer = to_peer,
+ top_msg_id = top_msg_id.GetValueOrDefault(),
schedule_date = schedule_date.GetValueOrDefault(),
send_as = send_as,
});
@@ -1979,12 +1995,13 @@ namespace TL
/// Result ID from messages.getInlineBotResults
/// Scheduled message date for scheduled messages
/// Send this message as the specified peer
- public static Task Messages_SendInlineBotResult(this Client client, InputPeer peer, long random_id, long query_id, string id, bool silent = false, bool background = false, bool clear_draft = false, bool hide_via = false, int? reply_to_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null)
+ public static Task Messages_SendInlineBotResult(this Client client, InputPeer peer, long random_id, long query_id, string id, bool silent = false, bool background = false, bool clear_draft = false, bool hide_via = false, int? reply_to_msg_id = null, int? top_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null)
=> client.Invoke(new Messages_SendInlineBotResult
{
- flags = (Messages_SendInlineBotResult.Flags)((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (hide_via ? 0x800 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_SendInlineBotResult.Flags)((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (hide_via ? 0x800 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
peer = peer,
reply_to_msg_id = reply_to_msg_id.GetValueOrDefault(),
+ top_msg_id = top_msg_id.GetValueOrDefault(),
random_id = random_id,
query_id = query_id,
id = id,
@@ -2088,11 +2105,12 @@ namespace TL
/// Destination of the message that should be sent
/// The draft
/// Message entities for styled text
- public static Task Messages_SaveDraft(this Client client, InputPeer peer, string message, bool no_webpage = false, int? reply_to_msg_id = null, MessageEntity[] entities = null)
+ public static Task Messages_SaveDraft(this Client client, InputPeer peer, string message, bool no_webpage = false, int? reply_to_msg_id = null, int? top_msg_id = null, MessageEntity[] entities = null)
=> client.Invoke(new Messages_SaveDraft
{
- flags = (Messages_SaveDraft.Flags)((no_webpage ? 0x2 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (entities != null ? 0x8 : 0)),
+ flags = (Messages_SaveDraft.Flags)((no_webpage ? 0x2 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x4 : 0) | (entities != null ? 0x8 : 0)),
reply_to_msg_id = reply_to_msg_id.GetValueOrDefault(),
+ top_msg_id = top_msg_id.GetValueOrDefault(),
peer = peer,
message = message,
entities = entities,
@@ -2369,10 +2387,12 @@ namespace TL
/// Maximum number of results to return, see pagination
/// Maximum message ID to return, see pagination
/// Minimum message ID to return, see pagination
- public static Task Messages_GetUnreadMentions(this Client client, InputPeer peer, int offset_id = default, int add_offset = default, int limit = int.MaxValue, int max_id = default, int min_id = default)
+ public static Task Messages_GetUnreadMentions(this Client client, InputPeer peer, int offset_id = default, int add_offset = default, int limit = int.MaxValue, int max_id = default, int min_id = default, int? top_msg_id = null)
=> client.Invoke(new Messages_GetUnreadMentions
{
+ flags = (Messages_GetUnreadMentions.Flags)(top_msg_id != null ? 0x1 : 0),
peer = peer,
+ top_msg_id = top_msg_id.GetValueOrDefault(),
offset_id = offset_id,
add_offset = add_offset,
limit = limit,
@@ -2382,10 +2402,12 @@ namespace TL
/// Mark mentions as read See Possible codes: 400 (details)
/// Dialog
- public static Task Messages_ReadMentions(this Client client, InputPeer peer)
+ public static Task Messages_ReadMentions(this Client client, InputPeer peer, int? top_msg_id = null)
=> client.Invoke(new Messages_ReadMentions
{
+ flags = (Messages_ReadMentions.Flags)(top_msg_id != null ? 0x1 : 0),
peer = peer,
+ top_msg_id = top_msg_id.GetValueOrDefault(),
});
/// Get live location history of a certain user See
@@ -2411,12 +2433,13 @@ namespace TL
/// The medias to send: note that they must be separately uploaded using messages.uploadMedia first, using raw inputMediaUploaded* constructors is not supported.
/// Scheduled message date for scheduled messages
/// Send this message as the specified peer
- public static Task Messages_SendMultiMedia(this Client client, InputPeer peer, InputSingleMedia[] multi_media, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, int? reply_to_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null)
+ public static Task Messages_SendMultiMedia(this Client client, InputPeer peer, InputSingleMedia[] multi_media, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, int? reply_to_msg_id = null, int? top_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null)
=> client.Invoke(new Messages_SendMultiMedia
{
- flags = (Messages_SendMultiMedia.Flags)((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_SendMultiMedia.Flags)((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
peer = peer,
reply_to_msg_id = reply_to_msg_id.GetValueOrDefault(),
+ top_msg_id = top_msg_id.GetValueOrDefault(),
multi_media = multi_media,
schedule_date = schedule_date.GetValueOrDefault(),
send_as = send_as,
@@ -2575,10 +2598,12 @@ namespace TL
/// Get the number of results that would be found by a messages.search call with the same parameters See Possible codes: 400 (details)
/// Peer where to search
/// Search filters
- public static Task Messages_GetSearchCounters(this Client client, InputPeer peer, params MessagesFilter[] filters)
+ public static Task Messages_GetSearchCounters(this Client client, InputPeer peer, MessagesFilter[] filters, int? top_msg_id = null)
=> client.Invoke(new Messages_GetSearchCounters
{
+ flags = (Messages_GetSearchCounters.Flags)(top_msg_id != null ? 0x1 : 0),
peer = peer,
+ top_msg_id = top_msg_id.GetValueOrDefault(),
filters = filters,
});
@@ -2783,10 +2808,12 @@ namespace TL
/// Unpin all pinned messages See [bots: ✓] Possible codes: 400 (details)
/// Chat where to unpin
- public static Task Messages_UnpinAllMessages(this Client client, InputPeer peer)
+ public static Task Messages_UnpinAllMessages(this Client client, InputPeer peer, int? top_msg_id = null)
=> client.Invoke(new Messages_UnpinAllMessages
{
+ flags = (Messages_UnpinAllMessages.Flags)(top_msg_id != null ? 0x1 : 0),
peer = peer,
+ top_msg_id = top_msg_id.GetValueOrDefault(),
});
/// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Delete a chat See Possible codes: 400 (details)
@@ -3149,10 +3176,12 @@ namespace TL
/// Maximum number of results to return, see pagination
/// Only return reactions for messages up until this message ID
/// Only return reactions for messages starting from this message ID
- public static Task Messages_GetUnreadReactions(this Client client, InputPeer peer, int offset_id = default, int add_offset = default, int limit = int.MaxValue, int max_id = default, int min_id = default)
+ public static Task Messages_GetUnreadReactions(this Client client, InputPeer peer, int offset_id = default, int add_offset = default, int limit = int.MaxValue, int max_id = default, int min_id = default, int? top_msg_id = null)
=> client.Invoke(new Messages_GetUnreadReactions
{
+ flags = (Messages_GetUnreadReactions.Flags)(top_msg_id != null ? 0x1 : 0),
peer = peer,
+ top_msg_id = top_msg_id.GetValueOrDefault(),
offset_id = offset_id,
add_offset = add_offset,
limit = limit,
@@ -3162,10 +3191,12 @@ namespace TL
/// Mark message reactions » as read See Possible codes: 400 (details)
/// Peer
- public static Task Messages_ReadReactions(this Client client, InputPeer peer)
+ public static Task Messages_ReadReactions(this Client client, InputPeer peer, int? top_msg_id = null)
=> client.Invoke(new Messages_ReadReactions
{
+ flags = (Messages_ReadReactions.Flags)(top_msg_id != null ? 0x1 : 0),
peer = peer,
+ top_msg_id = top_msg_id.GetValueOrDefault(),
});
/// View and search recently sent media.
This method does not support pagination. See
@@ -3218,10 +3249,10 @@ namespace TL
/// Short name of the application; 0-64 English letters, digits, and underscores
/// Whether the inline message that will be sent by the bot on behalf of the user once the web app interaction is terminated should be sent in reply to this message ID.
/// Open the web app as the specified peer, sending the resulting the message as the specified peer.
- public static Task Messages_RequestWebView(this Client client, InputPeer peer, InputUserBase bot, string platform, bool from_bot_menu = false, bool silent = false, string url = null, string start_param = null, DataJSON theme_params = null, int? reply_to_msg_id = null, InputPeer send_as = null)
+ public static Task Messages_RequestWebView(this Client client, InputPeer peer, InputUserBase bot, string platform, bool from_bot_menu = false, bool silent = false, string url = null, string start_param = null, DataJSON theme_params = null, int? reply_to_msg_id = null, int? top_msg_id = null, InputPeer send_as = null)
=> client.Invoke(new Messages_RequestWebView
{
- flags = (Messages_RequestWebView.Flags)((from_bot_menu ? 0x10 : 0) | (silent ? 0x20 : 0) | (url != null ? 0x2 : 0) | (start_param != null ? 0x8 : 0) | (theme_params != null ? 0x4 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_RequestWebView.Flags)((from_bot_menu ? 0x10 : 0) | (silent ? 0x20 : 0) | (url != null ? 0x2 : 0) | (start_param != null ? 0x8 : 0) | (theme_params != null ? 0x4 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (send_as != null ? 0x2000 : 0)),
peer = peer,
bot = bot,
url = url,
@@ -3229,6 +3260,7 @@ namespace TL
theme_params = theme_params,
platform = platform,
reply_to_msg_id = reply_to_msg_id.GetValueOrDefault(),
+ top_msg_id = top_msg_id.GetValueOrDefault(),
send_as = send_as,
});
@@ -3239,14 +3271,15 @@ namespace TL
/// Web app interaction ID obtained from messages.requestWebView
/// Whether the inline message that will be sent by the bot on behalf of the user once the web app interaction is terminated should be sent in reply to this message ID.
/// Open the web app as the specified peer
- public static Task Messages_ProlongWebView(this Client client, InputPeer peer, InputUserBase bot, long query_id, bool silent = false, int? reply_to_msg_id = null, InputPeer send_as = null)
+ public static Task Messages_ProlongWebView(this Client client, InputPeer peer, InputUserBase bot, long query_id, bool silent = false, int? reply_to_msg_id = null, int? top_msg_id = null, InputPeer send_as = null)
=> client.Invoke(new Messages_ProlongWebView
{
- flags = (Messages_ProlongWebView.Flags)((silent ? 0x20 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_ProlongWebView.Flags)((silent ? 0x20 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (send_as != null ? 0x2000 : 0)),
peer = peer,
bot = bot,
query_id = query_id,
reply_to_msg_id = reply_to_msg_id.GetValueOrDefault(),
+ top_msg_id = top_msg_id.GetValueOrDefault(),
send_as = send_as,
});
@@ -4123,6 +4156,7 @@ namespace TL
/// Get a list of sponsored messages See Possible codes: 400 (details)
/// Peer
+ /// a null value means messages.sponsoredMessagesEmpty
public static Task Channels_GetSponsoredMessages(this Client client, InputChannelBase channel)
=> client.Invoke(new Channels_GetSponsoredMessages
{
@@ -4167,6 +4201,101 @@ namespace TL
enabled = enabled,
});
+ /// See
+ public static Task Channels_ReorderUsernames(this Client client, InputChannelBase channel, params string[] order)
+ => client.Invoke(new Channels_ReorderUsernames
+ {
+ channel = channel,
+ order = order,
+ });
+
+ /// See
+ public static Task Channels_ToggleUsername(this Client client, InputChannelBase channel, string username, bool active)
+ => client.Invoke(new Channels_ToggleUsername
+ {
+ channel = channel,
+ username = username,
+ active = active,
+ });
+
+ /// See
+ public static Task Channels_DeactivateAllUsernames(this Client client, InputChannelBase channel)
+ => client.Invoke(new Channels_DeactivateAllUsernames
+ {
+ channel = channel,
+ });
+
+ /// See
+ public static Task Channels_ToggleForum(this Client client, InputChannelBase channel, bool enabled)
+ => client.Invoke(new Channels_ToggleForum
+ {
+ channel = channel,
+ enabled = enabled,
+ });
+
+ /// See
+ public static Task Channels_CreateForumTopic(this Client client, InputChannelBase channel, string title, long random_id, int? icon_color = null, long? icon_emoji_id = null, InputPeer send_as = null)
+ => client.Invoke(new Channels_CreateForumTopic
+ {
+ flags = (Channels_CreateForumTopic.Flags)((icon_color != null ? 0x1 : 0) | (icon_emoji_id != null ? 0x8 : 0) | (send_as != null ? 0x4 : 0)),
+ channel = channel,
+ title = title,
+ icon_color = icon_color.GetValueOrDefault(),
+ icon_emoji_id = icon_emoji_id.GetValueOrDefault(),
+ random_id = random_id,
+ send_as = send_as,
+ });
+
+ /// 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)
+ => client.Invoke(new Channels_GetForumTopics
+ {
+ flags = (Channels_GetForumTopics.Flags)(q != null ? 0x1 : 0),
+ channel = channel,
+ q = q,
+ offset_date = offset_date,
+ offset_id = offset_id,
+ offset_topic = offset_topic,
+ limit = limit,
+ });
+
+ /// See
+ public static Task Channels_GetForumTopicsByID(this Client client, InputChannelBase channel, params int[] topics)
+ => client.Invoke(new Channels_GetForumTopicsByID
+ {
+ channel = channel,
+ topics = topics,
+ });
+
+ /// See
+ public static Task Channels_EditForumTopic(this Client client, InputChannelBase channel, int topic_id, string title = null, long? icon_emoji_id = null, bool? closed = default)
+ => client.Invoke(new Channels_EditForumTopic
+ {
+ flags = (Channels_EditForumTopic.Flags)((title != null ? 0x1 : 0) | (icon_emoji_id != null ? 0x2 : 0) | (closed != default ? 0x4 : 0)),
+ channel = channel,
+ topic_id = topic_id,
+ title = title,
+ icon_emoji_id = icon_emoji_id.GetValueOrDefault(),
+ closed = closed.GetValueOrDefault(),
+ });
+
+ /// See
+ public static Task Channels_UpdatePinnedForumTopic(this Client client, InputChannelBase channel, int topic_id, bool pinned)
+ => client.Invoke(new Channels_UpdatePinnedForumTopic
+ {
+ channel = channel,
+ topic_id = topic_id,
+ pinned = pinned,
+ });
+
+ /// See
+ public static Task Channels_DeleteTopicHistory(this Client client, InputChannelBase channel, int top_msg_id)
+ => client.Invoke(new Channels_DeleteTopicHistory
+ {
+ channel = channel,
+ top_msg_id = top_msg_id,
+ });
+
/// Sends a custom request; for bots only See [bots: ✓] Possible codes: 400,403 (details)
/// The method name
/// JSON-serialized method parameters
@@ -5592,12 +5721,11 @@ namespace TL.Methods
}
}
- [TLDef(0x8D9D742B)]
+ [TLDef(0x3A5869EC)]
public class Account_GetTheme : IMethod
{
public string format;
public InputThemeBase theme;
- public long document_id;
}
[TLDef(0x7206E458)]
@@ -5720,6 +5848,19 @@ namespace TL.Methods
[TLDef(0x18201AAE)]
public class Account_ClearRecentEmojiStatuses : IMethod { }
+ [TLDef(0xEF500EAB)]
+ public class Account_ReorderUsernames : IMethod
+ {
+ public string[] order;
+ }
+
+ [TLDef(0x58D6B376)]
+ public class Account_ToggleUsername : IMethod
+ {
+ public string username;
+ public bool active;
+ }
+
[TLDef(0x0D91A548)]
public class Users_GetUsers : IMethod
{
@@ -6018,12 +6159,13 @@ namespace TL.Methods
}
}
- [TLDef(0x0D9D75A4)]
+ [TLDef(0x1CC20387)]
public class Messages_SendMessage : IMethod
{
public Flags flags;
public InputPeer peer;
[IfFlag(0)] public int reply_to_msg_id;
+ [IfFlag(9)] public int top_msg_id;
public string message;
public long random_id;
[IfFlag(2)] public ReplyMarkup reply_markup;
@@ -6040,6 +6182,7 @@ namespace TL.Methods
silent = 0x20,
background = 0x40,
clear_draft = 0x80,
+ has_top_msg_id = 0x200,
has_schedule_date = 0x400,
has_send_as = 0x2000,
noforwards = 0x4000,
@@ -6047,12 +6190,13 @@ namespace TL.Methods
}
}
- [TLDef(0xE25FF8E0)]
+ [TLDef(0x7547C966)]
public class Messages_SendMedia : IMethod
{
public Flags flags;
public InputPeer peer;
[IfFlag(0)] public int reply_to_msg_id;
+ [IfFlag(9)] public int top_msg_id;
public InputMedia media;
public string message;
public long random_id;
@@ -6069,6 +6213,7 @@ namespace TL.Methods
silent = 0x20,
background = 0x40,
clear_draft = 0x80,
+ has_top_msg_id = 0x200,
has_schedule_date = 0x400,
has_send_as = 0x2000,
noforwards = 0x4000,
@@ -6076,7 +6221,7 @@ namespace TL.Methods
}
}
- [TLDef(0xCC30290B)]
+ [TLDef(0xC661BBC4)]
public class Messages_ForwardMessages : IMethod
{
public Flags flags;
@@ -6084,6 +6229,7 @@ namespace TL.Methods
public int[] id;
public long[] random_id;
public InputPeer to_peer;
+ [IfFlag(9)] public int top_msg_id;
[IfFlag(10)] public DateTime schedule_date;
[IfFlag(13)] public InputPeer send_as;
@@ -6092,6 +6238,7 @@ namespace TL.Methods
silent = 0x20,
background = 0x40,
with_my_score = 0x100,
+ has_top_msg_id = 0x200,
has_schedule_date = 0x400,
drop_author = 0x800,
drop_media_captions = 0x1000,
@@ -6476,12 +6623,13 @@ namespace TL.Methods
}
}
- [TLDef(0x7AA11297)]
+ [TLDef(0xD3FBDCCB)]
public class Messages_SendInlineBotResult : IMethod
{
public Flags flags;
public InputPeer peer;
[IfFlag(0)] public int reply_to_msg_id;
+ [IfFlag(9)] public int top_msg_id;
public long random_id;
public long query_id;
public string id;
@@ -6494,6 +6642,7 @@ namespace TL.Methods
silent = 0x20,
background = 0x40,
clear_draft = 0x80,
+ has_top_msg_id = 0x200,
has_schedule_date = 0x400,
hide_via = 0x800,
has_send_as = 0x2000,
@@ -6590,11 +6739,12 @@ namespace TL.Methods
public InputDialogPeerBase[] peers;
}
- [TLDef(0xBC39E14B)]
+ [TLDef(0xB4331E3F)]
public class Messages_SaveDraft : IMethod
{
public Flags flags;
[IfFlag(0)] public int reply_to_msg_id;
+ [IfFlag(2)] public int top_msg_id;
public InputPeer peer;
public string message;
[IfFlag(3)] public MessageEntity[] entities;
@@ -6603,6 +6753,7 @@ namespace TL.Methods
{
has_reply_to_msg_id = 0x1,
no_webpage = 0x2,
+ has_top_msg_id = 0x4,
has_entities = 0x8,
}
}
@@ -6839,21 +6990,35 @@ namespace TL.Methods
public bool unfave;
}
- [TLDef(0x46578472)]
+ [TLDef(0xF107E790)]
public class Messages_GetUnreadMentions : IMethod
{
+ public Flags flags;
public InputPeer peer;
+ [IfFlag(0)] public int top_msg_id;
public int offset_id;
public int add_offset;
public int limit;
public int max_id;
public int min_id;
+
+ [Flags] public enum Flags : uint
+ {
+ has_top_msg_id = 0x1,
+ }
}
- [TLDef(0x0F0189D3)]
+ [TLDef(0x36E5BF4D)]
public class Messages_ReadMentions : IMethod
{
+ public Flags flags;
public InputPeer peer;
+ [IfFlag(0)] public int top_msg_id;
+
+ [Flags] public enum Flags : uint
+ {
+ has_top_msg_id = 0x1,
+ }
}
[TLDef(0x702A40E0)]
@@ -6864,12 +7029,13 @@ namespace TL.Methods
public long hash;
}
- [TLDef(0xF803138F)]
+ [TLDef(0xB6F11A1C)]
public class Messages_SendMultiMedia : IMethod
{
public Flags flags;
public InputPeer peer;
[IfFlag(0)] public int reply_to_msg_id;
+ [IfFlag(9)] public int top_msg_id;
public InputSingleMedia[] multi_media;
[IfFlag(10)] public DateTime schedule_date;
[IfFlag(13)] public InputPeer send_as;
@@ -6880,6 +7046,7 @@ namespace TL.Methods
silent = 0x20,
background = 0x40,
clear_draft = 0x80,
+ has_top_msg_id = 0x200,
has_schedule_date = 0x400,
has_send_as = 0x2000,
noforwards = 0x4000,
@@ -7003,11 +7170,18 @@ namespace TL.Methods
public string lang_code;
}
- [TLDef(0x732EEF00)]
+ [TLDef(0x00AE7CC1)]
public class Messages_GetSearchCounters : IMethod
{
+ public Flags flags;
public InputPeer peer;
+ [IfFlag(0)] public int top_msg_id;
public MessagesFilter[] filters;
+
+ [Flags] public enum Flags : uint
+ {
+ has_top_msg_id = 0x1,
+ }
}
[TLDef(0x198FB446)]
@@ -7170,10 +7344,17 @@ namespace TL.Methods
public int read_max_id;
}
- [TLDef(0xF025BC8B)]
+ [TLDef(0xEE22B9A8)]
public class Messages_UnpinAllMessages : IMethod
{
+ public Flags flags;
public InputPeer peer;
+ [IfFlag(0)] public int top_msg_id;
+
+ [Flags] public enum Flags : uint
+ {
+ has_top_msg_id = 0x1,
+ }
}
[TLDef(0x5BD0EE50)]
@@ -7470,21 +7651,35 @@ namespace TL.Methods
}
}
- [TLDef(0xE85BAE1A)]
+ [TLDef(0x3223495B)]
public class Messages_GetUnreadReactions : IMethod
{
+ public Flags flags;
public InputPeer peer;
+ [IfFlag(0)] public int top_msg_id;
public int offset_id;
public int add_offset;
public int limit;
public int max_id;
public int min_id;
+
+ [Flags] public enum Flags : uint
+ {
+ has_top_msg_id = 0x1,
+ }
}
- [TLDef(0x82E251D7)]
+ [TLDef(0x54AA7F8E)]
public class Messages_ReadReactions : IMethod
{
+ public Flags flags;
public InputPeer peer;
+ [IfFlag(0)] public int top_msg_id;
+
+ [Flags] public enum Flags : uint
+ {
+ has_top_msg_id = 0x1,
+ }
}
[TLDef(0x107E31A0)]
@@ -7514,7 +7709,7 @@ namespace TL.Methods
public bool enabled;
}
- [TLDef(0xFC87A53C)]
+ [TLDef(0x178B480B)]
public class Messages_RequestWebView : IMethod
{
public Flags flags;
@@ -7525,6 +7720,7 @@ namespace TL.Methods
[IfFlag(2)] public DataJSON theme_params;
public string platform;
[IfFlag(0)] public int reply_to_msg_id;
+ [IfFlag(9)] public int top_msg_id;
[IfFlag(13)] public InputPeer send_as;
[Flags] public enum Flags : uint
@@ -7535,11 +7731,12 @@ namespace TL.Methods
has_start_param = 0x8,
from_bot_menu = 0x10,
silent = 0x20,
+ has_top_msg_id = 0x200,
has_send_as = 0x2000,
}
}
- [TLDef(0xEA5FBCCE)]
+ [TLDef(0x7FF34309)]
public class Messages_ProlongWebView : IMethod
{
public Flags flags;
@@ -7547,12 +7744,14 @@ namespace TL.Methods
public InputUserBase bot;
public long query_id;
[IfFlag(0)] public int reply_to_msg_id;
+ [IfFlag(9)] public int top_msg_id;
[IfFlag(13)] public InputPeer send_as;
[Flags] public enum Flags : uint
{
has_reply_to_msg_id = 0x1,
silent = 0x20,
+ has_top_msg_id = 0x200,
has_send_as = 0x2000,
}
}
@@ -8226,6 +8425,110 @@ namespace TL.Methods
public bool enabled;
}
+ [TLDef(0xB45CED1D)]
+ public class Channels_ReorderUsernames : IMethod
+ {
+ public InputChannelBase channel;
+ public string[] order;
+ }
+
+ [TLDef(0x50F24105)]
+ public class Channels_ToggleUsername : IMethod
+ {
+ public InputChannelBase channel;
+ public string username;
+ public bool active;
+ }
+
+ [TLDef(0x0A245DD3)]
+ public class Channels_DeactivateAllUsernames : IMethod
+ {
+ public InputChannelBase channel;
+ }
+
+ [TLDef(0xA4298B29)]
+ public class Channels_ToggleForum : IMethod
+ {
+ public InputChannelBase channel;
+ public bool enabled;
+ }
+
+ [TLDef(0xF40C0224)]
+ public class Channels_CreateForumTopic : IMethod
+ {
+ public Flags flags;
+ public InputChannelBase channel;
+ public string title;
+ [IfFlag(0)] public int icon_color;
+ [IfFlag(3)] public long icon_emoji_id;
+ public long random_id;
+ [IfFlag(2)] public InputPeer send_as;
+
+ [Flags] public enum Flags : uint
+ {
+ has_icon_color = 0x1,
+ has_send_as = 0x4,
+ has_icon_emoji_id = 0x8,
+ }
+ }
+
+ [TLDef(0x0DE560D1)]
+ public class Channels_GetForumTopics : IMethod
+ {
+ public Flags flags;
+ public InputChannelBase channel;
+ [IfFlag(0)] public string q;
+ public DateTime offset_date;
+ public int offset_id;
+ public int offset_topic;
+ public int limit;
+
+ [Flags] public enum Flags : uint
+ {
+ has_q = 0x1,
+ }
+ }
+
+ [TLDef(0xB0831EB9)]
+ public class Channels_GetForumTopicsByID : IMethod
+ {
+ public InputChannelBase channel;
+ public int[] topics;
+ }
+
+ [TLDef(0x6C883E2D)]
+ public class Channels_EditForumTopic : IMethod
+ {
+ public Flags flags;
+ public InputChannelBase channel;
+ public int topic_id;
+ [IfFlag(0)] public string title;
+ [IfFlag(1)] public long icon_emoji_id;
+ [IfFlag(2)] public bool closed;
+
+ [Flags] public enum Flags : uint
+ {
+ has_title = 0x1,
+ has_icon_emoji_id = 0x2,
+ has_closed = 0x4,
+ }
+ }
+
+ [TLDef(0x6C2D9026)]
+ public class Channels_UpdatePinnedForumTopic : IMethod
+ {
+ public InputChannelBase channel;
+ public int topic_id;
+ public bool pinned;
+ }
+
+ [TLDef(0x34435F2D)]
+ public class Channels_DeleteTopicHistory : IMethod
+ {
+ public InputChannelBase channel;
+ public int top_msg_id;
+ }
+
[TLDef(0xAA2769ED)]
public class Bots_SendCustomRequest : IMethod
{
diff --git a/src/TL.Table.cs b/src/TL.Table.cs
index 3682f20..77a69be 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 = 146; // fetched 14/09/2022 16:18:39
+ public const int Version = 148; // fetched 01/11/2022 17:33:23
internal const int SecretChats = 101;
internal const int MTProto2 = 73;
internal const uint VectorCtor = 0x1CB5C415;
@@ -119,7 +119,7 @@ namespace TL
[0x36C6019A] = typeof(PeerChat),
[0xA2A5371E] = typeof(PeerChannel),
[0xD3BC4B7A] = typeof(UserEmpty),
- [0x5D99ADEE] = typeof(User),
+ [0x8F97C628] = typeof(User),
[0x4F11BAE1] = null,//UserProfilePhotoEmpty
[0x82D1F706] = typeof(UserProfilePhoto),
[0x09D05049] = null,//UserStatusEmpty
@@ -131,7 +131,7 @@ namespace TL
[0x29562865] = typeof(ChatEmpty),
[0x41CBF256] = typeof(Chat),
[0x6592A1A7] = typeof(ChatForbidden),
- [0x8261AC61] = typeof(Channel),
+ [0x83259464] = typeof(Channel),
[0x17D493D5] = typeof(ChannelForbidden),
[0xC9D31138] = typeof(ChatFull),
[0xF2355507] = typeof(ChannelFull),
@@ -191,6 +191,8 @@ namespace TL
[0x47DD8079] = typeof(MessageActionWebViewDataSentMe),
[0xB4C38CB5] = typeof(MessageActionWebViewDataSent),
[0xABA0F5C6] = typeof(MessageActionGiftPremium),
+ [0x0D999256] = typeof(MessageActionTopicCreate),
+ [0xB18A431C] = typeof(MessageActionTopicEdit),
[0xA8EDD0F5] = typeof(Dialog),
[0x71BD134C] = typeof(DialogFolder),
[0x2331B22D] = typeof(PhotoEmpty),
@@ -211,6 +213,7 @@ namespace TL
[0x193B4417] = typeof(InputNotifyUsers),
[0x4A95E84E] = typeof(InputNotifyChats),
[0xB1DB7C7E] = typeof(InputNotifyBroadcasts),
+ [0x5C467992] = typeof(InputNotifyForumTopic),
[0xDF1F002B] = typeof(InputPeerNotifySettings),
[0xA83B0426] = typeof(PeerNotifySettings),
[0xA518110D] = typeof(PeerSettings),
@@ -260,7 +263,7 @@ namespace TL
[0x83487AF0] = typeof(UpdateChatUserTyping),
[0x07761198] = typeof(UpdateChatParticipants),
[0xE5BDF8DE] = typeof(UpdateUserStatus),
- [0xC3F202E0] = typeof(UpdateUserName),
+ [0xA7848924] = typeof(UpdateUserName),
[0xF227868C] = typeof(UpdateUserPhoto),
[0x12BCBD9A] = typeof(UpdateNewEncryptedMessage),
[0x1710F156] = typeof(UpdateEncryptedChatTyping),
@@ -295,7 +298,7 @@ namespace TL
[0xE40370A3] = typeof(UpdateEditMessage),
[0x691E9052] = typeof(UpdateInlineBotCallbackQuery),
[0xB75F99A9] = typeof(UpdateReadChannelOutbox),
- [0xEE2BB969] = typeof(UpdateDraftMessage),
+ [0x1B49EC6D] = typeof(UpdateDraftMessage),
[0x571D2742] = typeof(UpdateReadFeaturedStickers),
[0x9A422C20] = typeof(UpdateRecentStickers),
[0xA229DD06] = typeof(UpdateConfig),
@@ -311,7 +314,7 @@ namespace TL
[0x46560264] = typeof(UpdateLangPackTooLong),
[0x56022F4D] = typeof(UpdateLangPack),
[0xE511996D] = typeof(UpdateFavedStickers),
- [0x44BDD535] = typeof(UpdateChannelReadMessagesContents),
+ [0xEA29055D] = typeof(UpdateChannelReadMessagesContents),
[0x7084A7BE] = typeof(UpdateContactsReset),
[0xB23FC698] = typeof(UpdateChannelAvailableMessages),
[0xE16459C3] = typeof(UpdateDialogUnreadMark),
@@ -348,7 +351,7 @@ namespace TL
[0x4D712F2E] = typeof(UpdateBotCommands),
[0x7063C3DB] = typeof(UpdatePendingJoinRequests),
[0x11DFA986] = typeof(UpdateBotChatInviteRequester),
- [0x154798C3] = typeof(UpdateMessageReactions),
+ [0x5E1B3CB8] = typeof(UpdateMessageReactions),
[0x17B7A20B] = typeof(UpdateAttachMenuBots),
[0x1592B79D] = typeof(UpdateWebViewResultSent),
[0x14B85813] = typeof(UpdateBotMenuButton),
@@ -360,6 +363,7 @@ namespace TL
[0x6F7863F4] = typeof(UpdateRecentReactions),
[0x86FCCF85] = typeof(UpdateMoveStickerSetToTop),
[0x5A73A98C] = typeof(UpdateMessageExtendedMedia),
+ [0xF694B0AE] = typeof(UpdateChannelPinnedTopic),
[0xA56C2A3E] = typeof(Updates_State),
[0x5D75A138] = typeof(Updates_DifferenceEmpty),
[0x00F49CA0] = typeof(Updates_Difference),
@@ -410,6 +414,7 @@ namespace TL
[0xB4C83B4C] = typeof(NotifyUsers),
[0xC007CEC3] = typeof(NotifyChats),
[0xD612E8EF] = typeof(NotifyBroadcasts),
+ [0x226E6308] = typeof(NotifyForumTopic),
[0x16BF744E] = typeof(SendMessageTypingAction),
[0xFD5EC8F5] = typeof(SendMessageCancelAction),
[0xA187D66F] = typeof(SendMessageRecordVideoAction),
@@ -486,8 +491,9 @@ namespace TL
[0xC88B3B02] = typeof(InputStickerSetPremiumGifts),
[0x04C4D4CE] = typeof(InputStickerSetEmojiGenericAnimations),
[0x29D0F5EE] = typeof(InputStickerSetEmojiDefaultStatuses),
+ [0x44C1F8E9] = typeof(InputStickerSetEmojiDefaultTopicIcons),
[0x2DD14EDC] = typeof(StickerSet),
- [0xB60A24A6] = typeof(Messages_StickerSet),
+ [0x6E153F16] = typeof(Messages_StickerSet),
[0xD3F924EB] = null,//Messages_StickerSetNotModified
[0xC27AC8C7] = typeof(BotCommand),
[0x8F300B57] = typeof(BotInfo),
@@ -613,7 +619,7 @@ namespace TL
[0x35E410A8] = typeof(Messages_StickerSetInstallResultArchive),
[0x6410A5D2] = typeof(StickerSetCovered),
[0x3407E51B] = typeof(StickerSetMultiCovered),
- [0x1AED5EE5] = typeof(StickerSetFullCovered),
+ [0x40D13C0E] = typeof(StickerSetFullCovered),
[0xAED6DBB2] = typeof(MaskCoords),
[0x4A992157] = typeof(InputStickeredMediaPhoto),
[0x0438865B] = typeof(InputStickeredMediaDocument),
@@ -750,6 +756,12 @@ namespace TL
[0xCB2AC766] = typeof(ChannelAdminLogEventActionToggleNoForwards),
[0x278F2868] = typeof(ChannelAdminLogEventActionSendMessage),
[0xBE4E0EF8] = typeof(ChannelAdminLogEventActionChangeAvailableReactions),
+ [0xF04FB3A9] = typeof(ChannelAdminLogEventActionChangeUsernames),
+ [0x02CC6383] = typeof(ChannelAdminLogEventActionToggleForum),
+ [0x58707D28] = typeof(ChannelAdminLogEventActionCreateTopic),
+ [0xF06FE208] = typeof(ChannelAdminLogEventActionEditTopic),
+ [0xAE168909] = typeof(ChannelAdminLogEventActionDeleteTopic),
+ [0x5D8D353B] = typeof(ChannelAdminLogEventActionPinTopic),
[0x1FAD68CD] = typeof(ChannelAdminLogEvent),
[0xED8AF74D] = typeof(Channels_AdminLogResults),
[0xEA107AE4] = typeof(ChannelAdminLogEventsFilter),
@@ -953,7 +965,8 @@ namespace TL
[0xE9EFFC7D] = typeof(Account_ResetPasswordRequestedWait),
[0xE926D63E] = typeof(Account_ResetPasswordOk),
[0x3A836DF8] = typeof(SponsoredMessage),
- [0x65A4C7D5] = typeof(Messages_SponsoredMessages),
+ [0xC9EE1D87] = typeof(Messages_SponsoredMessages),
+ [0x1839490F] = null,//Messages_SponsoredMessagesEmpty
[0xC9B0539F] = typeof(SearchResultsCalendarPeriod),
[0x147EE23C] = typeof(Messages_SearchResultsCalendar),
[0x7F648B67] = typeof(SearchResultPosition),
@@ -1028,6 +1041,11 @@ namespace TL
[0xB81C7034] = typeof(SendAsPeer),
[0xAD628CC8] = typeof(MessageExtendedMediaPreview),
[0xEE479C64] = typeof(MessageExtendedMedia),
+ [0xFCFEB29C] = typeof(StickerKeyword),
+ [0xB4073647] = typeof(Username),
+ [0x023F109B] = typeof(ForumTopicDeleted),
+ [0x71701DA9] = typeof(ForumTopic),
+ [0x367617D3] = typeof(Messages_ForumTopics),
// from TL.Secret:
[0xBB718624] = typeof(Layer66.SendMessageUploadRoundAction),
[0xE50511D8] = typeof(Layer45.DecryptedMessageMediaWebPage),
@@ -1130,6 +1148,7 @@ namespace TL
[typeof(DialogFilter)] = 0x363293AE, //dialogFilterDefault
[typeof(Help_CountriesList)] = 0x93CC1F32, //help.countriesListNotModified
[typeof(BotCommandScope)] = 0x2F6CB2AB, //botCommandScopeDefault
+ [typeof(Messages_SponsoredMessages)] = 0x1839490F, //messages.sponsoredMessagesEmpty
[typeof(Messages_AvailableReactions)] = 0x9F071957, //messages.availableReactionsNotModified
[typeof(AttachMenuBots)] = 0xF1D88A5C, //attachMenuBotsNotModified
[typeof(BotMenuButtonBase)] = 0x7533A588, //botMenuButtonDefault
diff --git a/src/TL.cs b/src/TL.cs
index 6daf747..c7b1767 100644
--- a/src/TL.cs
+++ b/src/TL.cs
@@ -59,14 +59,16 @@ namespace TL
writer.Write(ctorNb);
IEnumerable fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
if (tlDef.inheritBefore) fields = fields.GroupBy(f => f.DeclaringType).Reverse().SelectMany(g => g);
- uint flags = 0;
+ ulong flags = 0;
IfFlagAttribute ifFlag;
foreach (var field in fields)
{
- if (((ifFlag = field.GetCustomAttribute()) != null) && (flags & (1U << ifFlag.Bit)) == 0) continue;
+ if (((ifFlag = field.GetCustomAttribute()) != null) && (flags & (1UL << ifFlag.Bit)) == 0) continue;
object value = field.GetValue(obj);
writer.WriteTLValue(value, field.FieldType);
- if (field.FieldType.IsEnum && field.Name == "flags") flags = (uint)value;
+ if (field.FieldType.IsEnum)
+ if (field.Name == "flags") flags = (uint)value;
+ else if (field.Name == "flags2") flags |= (ulong)(uint)value << 32;
}
}
@@ -83,14 +85,16 @@ namespace TL
var obj = Activator.CreateInstance(type, true);
IEnumerable fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
if (tlDef.inheritBefore) fields = fields.GroupBy(f => f.DeclaringType).Reverse().SelectMany(g => g);
- uint flags = 0;
+ ulong flags = 0;
IfFlagAttribute ifFlag;
foreach (var field in fields)
{
- if (((ifFlag = field.GetCustomAttribute()) != null) && (flags & (1U << ifFlag.Bit)) == 0) continue;
+ if (((ifFlag = field.GetCustomAttribute()) != null) && (flags & (1UL << ifFlag.Bit)) == 0) continue;
object value = reader.ReadTLValue(field.FieldType);
field.SetValue(obj, value);
- if (field.FieldType.IsEnum && field.Name == "flags") flags = (uint)value;
+ if (field.FieldType.IsEnum)
+ if (field.Name == "flags") flags = (uint)value;
+ else if (field.Name == "flags2") flags |= (ulong)(uint)value << 32;
if (reader.Client?.CollectAccessHash == true) reader.Client.CollectField(field, obj, value);
}
return (IObject)obj;
From d9b137d41cae87b347dc3e05598ae2b4a839f546 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Sat, 5 Nov 2022 23:01:38 +0100
Subject: [PATCH 010/336] added User.MainUsername to help with multiple
usernames
---
.github/dev.yml | 2 +-
EXAMPLES.md | 18 +++++++++---------
src/TL.Helpers.cs | 1 +
src/TL.Schema.cs | 2 +-
src/TL.SchemaFuncs.cs | 6 +++---
5 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index 04417b8..ddfdabc 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -2,7 +2,7 @@ pr: none
trigger:
- master
-name: 3.0.2-dev.$(Rev:r)
+name: 3.0.4-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/EXAMPLES.md b/EXAMPLES.md
index 59bf859..35a535c 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -7,7 +7,7 @@ using System.Linq;
using TL;
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
-var myself = await client.LoginUserIfNeeded();
+await client.LoginUserIfNeeded();
```
In this case, environment variables are used for configuration so make sure to
@@ -58,7 +58,7 @@ If the username is invalid/unused, the API call raises an RpcException.*
### Convert message to/from HTML or Markdown, and send it to ourself (Saved Messages)
```csharp
// HTML-formatted text:
-var text = $"Hello dear {HtmlText.Escape(myself.first_name)}\n" +
+var text = $"Hello dear {HtmlText.Escape(client.User.first_name)}\n" +
"Enjoy this userbot written with WTelegramClient";
var entities = client.HtmlToEntities(ref text);
var sent = await client.SendMessageAsync(InputPeer.Self, text, entities: entities);
@@ -67,7 +67,7 @@ text = client.EntitiesToHtml(sent.message, sent.entities);
```
```csharp
// Markdown-style text:
-var text2 = $"Hello __dear *{Markdown.Escape(myself.first_name)}*__\n" +
+var text2 = $"Hello __dear *{Markdown.Escape(client.User.first_name)}*__\n" +
"Enjoy this `userbot` written with [WTelegramClient](https://github.com/wiz0u/WTelegramClient)";
var entities2 = client.MarkdownToEntities(ref text2);
var sent2 = await client.SendMessageAsync(InputPeer.Self, text2, entities: entities2);
@@ -147,7 +147,7 @@ var participants = await client.Channels_GetAllParticipants(channel);
You can use specific filters, for example to list only the channel owner/admins:
```csharp
var participants = await client.Channels_GetParticipants(channel, filter: new ChannelParticipantsAdmins());
-foreach (var participant in participants.participants) // This is the correct way to enumerate the result
+foreach (var participant in participants.participants) // This is the better way to enumerate the result
{
var user = participants.users[participant.UserID];
if (participant is ChannelParticipantCreator cpc) Console.WriteLine($"{user} is the owner '{cpc.rank}'");
@@ -232,7 +232,7 @@ var inputMedias = new List
{
photoFromTelegram, // PhotoBase has implicit conversion to InputMediaPhoto
new InputMediaUploadedPhoto { file = uploadedFile },
- new InputMediaPhotoExternal() { url = photoUrl },
+ new InputMediaPhotoExternal { url = photoUrl },
};
await client.SendAlbumAsync(InputPeer.Self, inputMedias, "My first album");
```
@@ -349,7 +349,7 @@ var messages = await client.Messages_Search(chat, lim
foreach (var msg in messages.Messages)
await client.Messages_SendReaction(chat, msg.ID, reaction: new[] { reaction });
```
-*Note: you can find custom emoji document IDs via API methods like [Messages_GetFeaturedEmojiStickers](https://corefork.telegram.org/method/messages.getFeaturedEmojiStickers) or inspecting incoming messages. Access hash is not required*
+*Note: you can find custom emoji document IDs via API methods like [Messages_GetFeaturedEmojiStickers](https://corefork.telegram.org/methods#working-with-custom-animated-emojis) or inspecting incoming messages. Access hash is not required*
@@ -407,7 +407,7 @@ var contacts = await client.Contacts_ImportContacts(new[] { new InputPhoneContac
if (contacts.imported.Length > 0)
await client.SendMessageAsync(contacts.users[contacts.imported[0].user_id], "Hello!");
```
-*Note: Don't use this method too much. To prevent spam, Telegram may restrict your ability to add new phone numbers.*
+*Note: Don't use this method too much. To prevent spam, Telegram may restrict your ability to add new phone numbers or ban your account.*
### Retrieve the current user's contacts list
@@ -457,7 +457,7 @@ client.TcpHandler = async (address, port) =>
var proxy = new Socks5ProxyClient(ProxyHost, ProxyPort, ProxyUsername, ProxyPassword);
return proxy.CreateConnection(address, port);
};
-var myself = await client.LoginUserIfNeeded();
+await client.LoginUserIfNeeded();
```
or with [xNetStandard](https://www.nuget.org/packages/xNetStandard/):
```csharp
@@ -472,7 +472,7 @@ MTProxy (MTProto proxy) can be used to prevent ISP blocking Telegram servers, th
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
client.MTProxyUrl = "http://t.me/proxy?server=...&port=...&secret=...";
-var myself = await client.LoginUserIfNeeded();
+await client.LoginUserIfNeeded();
```
You can find a list of working MTProxies in channels like [@ProxyMTProto](https://t.me/ProxyMTProto) or [@MTProxyT](https://t.me/MTProxyT) *(right-click the "Connect" buttons)*
If your Telegram client is already connected to such MTPROTO proxy, you can also export its URL by clicking on the shield button  and then **⋮** > **Share**
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index 0e8f82e..3bf8380 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -129,6 +129,7 @@ namespace TL
{
public override long ID => id;
public override bool IsActive => (flags & Flags.deleted) == 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 InputPeer ToInputPeer() => new InputPeerUser(id, access_hash);
protected override InputUser ToInputUser() => new(id, access_hash);
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index b785fb9..eb74e8c 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -3207,7 +3207,7 @@ namespace TL
public DateTime date;
/// New profile photo
public UserProfilePhoto photo;
- /// (), if one of the previously used photos is set a profile photo.
+ /// (), if one of the previously used photos is set a profile photo.
public bool previous;
}
/// New encrypted message. See
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index 081d365..5eb402f 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -290,7 +290,7 @@ namespace TL
/// Avoid receiving (silent and invisible background) notifications. Useful to save battery.
/// Device token type, see PUSH updates for the possible values.
/// Device token, see PUSH updates for the possible values.
- /// If is transmitted, a sandbox-certificate will be used during transmission.
+ /// If is transmitted, a sandbox-certificate will be used during transmission.
/// For FCM and APNS VoIP, optional encryption key used to encrypt push notifications
/// List of user identifiers of other users currently using the client
public static Task Account_RegisterDevice(this Client client, int token_type, string token, bool app_sandbox, byte[] secret, long[] other_uids, bool no_muted = false)
@@ -354,7 +354,7 @@ namespace TL
});
/// Updates online user status. See Possible codes: 403 (details)
- /// If is transmitted, user status will change to .
+ /// If is transmitted, user status will change to .
public static Task Account_UpdateStatus(this Client client, bool offline)
=> client.Invoke(new Account_UpdateStatus
{
@@ -1656,7 +1656,7 @@ namespace TL
/// Send typing event by the current user to a secret chat. See Possible codes: 400 (details)
/// Secret chat ID
- /// Typing.
Possible values:
, if the user started typing and more than 5 seconds have passed since the last request
, if the user stopped typing
+ /// Typing.
Possible values:
, if the user started typing and more than 5 seconds have passed since the last request
, if the user stopped typing
public static Task Messages_SetEncryptedTyping(this Client client, InputEncryptedChat peer, bool typing)
=> client.Invoke(new Messages_SetEncryptedTyping
{
From 8fa00a8cc6daf7599485ac7c56b560ac6c0adb31 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Tue, 8 Nov 2022 17:06:16 +0100
Subject: [PATCH 011/336] Support for bare methods in session
---
EXAMPLES.md | 2 +-
Examples/Program_ListenUpdates.cs | 2 +-
FAQ.md | 6 +++---
src/Client.cs | 13 +++++++++----
4 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/EXAMPLES.md b/EXAMPLES.md
index 35a535c..d8fc6dc 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -448,7 +448,7 @@ This is done by activating the experimental `client.CollectAccessHash` system.
See [Examples/Program_CollectAccessHash.cs](Examples/Program_CollectAccessHash.cs) for how to enable it, and save/restore them for later use.
-### Use a proxy to connect to Telegram
+### Use a proxy or MTProxy to connect to Telegram
SOCKS/HTTPS proxies can be used through the `client.TcpHandler` delegate and a proxy library like [StarkSoftProxy](https://www.nuget.org/packages/StarkSoftProxy/):
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
diff --git a/Examples/Program_ListenUpdates.cs b/Examples/Program_ListenUpdates.cs
index 920dfd1..e463eef 100644
--- a/Examples/Program_ListenUpdates.cs
+++ b/Examples/Program_ListenUpdates.cs
@@ -52,7 +52,7 @@ namespace WTelegramClientTest
case UpdateUserStatus uus: Console.WriteLine($"{User(uus.user_id)} is now {uus.status.GetType().Name[10..]}"); break;
case UpdateUserName uun: Console.WriteLine($"{User(uun.user_id)} has changed profile name: {uun.first_name} {uun.last_name}"); break;
case UpdateUserPhoto uup: Console.WriteLine($"{User(uup.user_id)} has changed profile photo"); break;
- default: Console.WriteLine(update.GetType().Name); break; // there are much more update types than the above cases
+ default: Console.WriteLine(update.GetType().Name); break; // there are much more update types than the above example cases
}
}
diff --git a/FAQ.md b/FAQ.md
index 6e4e747..188d5dd 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -48,7 +48,7 @@ calling `client.Login(...)` as the user provides the requested configuration ele
You can download such full example apps [for WinForms](https://github.com/wiz0u/WTelegramClient/raw/master/Examples/WinForms_app.zip) and [for ASP.NET](https://github.com/wiz0u/WTelegramClient/raw/master/Examples/ASPnet_webapp.zip)
-#### 4. Where to get the access_hash? Why the error `CHANNEL_INVALID` or `USER_ID_INVALID`?
+#### 4. How to use IDs? Where to get the 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)
@@ -206,7 +206,7 @@ In this case, the recommended action would be to dispose the client and recreate
you might also get Connection shutdown because your client couldn't send Pings to Telegram in the allotted time.
In this case, you can use the `PingInterval` property to increase the delay between pings *(for example 300 seconds instead of 60)*.
-5) If you're using an MTProxy, some of them are known to be quite unstable. You may want to try switching to another MTProxy that is more stable.
+5) If you're using an [MTProxy](EXAMPLES.md#proxy), some of them are known to be quite unstable. You may want to try switching to another MTProxy that is more stable.
#### 12. How to migrate from TLSharp? How to sign-in/sign-up/register account properly?
@@ -233,7 +233,7 @@ In particular, it will detect and handle automatically and properly the various
* Request to resend the verification code through alternate ways like SMS (if your Config answer an empty "verification_code" initially)
* Transient failures, slowness to respond, wrong code/password, checks for encryption key safety, etc..
-Contrary to TLSharp, WTelegramClient supports MTProto v2.0 (more secured), transport obfuscation, protocol security checks, MTProto Proxy, real-time updates, multiple DC connections, API documentation in Intellisense...
+Contrary to TLSharp, WTelegramClient supports MTProto v2.0 (more secured), transport obfuscation, protocol security checks, MTProto [Proxy](EXAMPLES.md#proxy), real-time updates, multiple DC connections, API documentation in Intellisense...
#### 13. How to host my userbot online?
diff --git a/src/Client.cs b/src/Client.cs
index 7386ae7..27b4c8a 100644
--- a/src/Client.cs
+++ b/src/Client.cs
@@ -578,11 +578,16 @@ namespace WTelegram
if (_bareRpc != null)
{
var rpc = PullPendingRequest(_bareRpc.msgId);
- if ((rpc?.type.IsAssignableFrom(obj.GetType())) != true)
+ if ((rpc?.type.IsAssignableFrom(obj.GetType())) == true)
+ {
+ _bareRpc = null;
+ rpc.tcs.SetResult(obj);
+ return;
+ }
+ else if (_dcSession.AuthKeyID == 0)
throw new ApplicationException($"Received a {obj.GetType()} incompatible with expected bare {rpc?.type}");
- _bareRpc = null;
- rpc.tcs.SetResult(obj);
- return;
+ lock (_pendingRpcs)
+ _pendingRpcs[_bareRpc.msgId] = _bareRpc;
}
switch (obj)
{
From a038be87af41f9799a65bce870d55e7dd57d9ada Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Fri, 11 Nov 2022 00:33:29 +0100
Subject: [PATCH 012/336] Improved Secret Chats: Support layer 144 : big
documents, silent (layer not yet supported by other clients) List of
ISecretChat with detailed properties Fix PFS issue losing a message...
---
.github/dev.yml | 2 +-
.github/release.yml | 2 +-
Examples/Program_SecretChats.cs | 31 +--
FAQ.md | 2 +-
src/Encryption.cs | 2 +-
src/SecretChats.cs | 93 ++++----
src/TL.Schema.cs | 2 +-
src/TL.Secret.cs | 411 ++++++++++++++++++--------------
src/TL.Table.cs | 56 ++---
9 files changed, 326 insertions(+), 275 deletions(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index ddfdabc..02d8f36 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -2,7 +2,7 @@ pr: none
trigger:
- master
-name: 3.0.4-dev.$(Rev:r)
+name: 3.1.1-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/.github/release.yml b/.github/release.yml
index 9a0e1a8..250e994 100644
--- a/.github/release.yml
+++ b/.github/release.yml
@@ -1,7 +1,7 @@
pr: none
trigger: none
-name: 3.0.$(Rev:r)
+name: 3.1.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/Examples/Program_SecretChats.cs b/Examples/Program_SecretChats.cs
index c204af8..4b0edf0 100644
--- a/Examples/Program_SecretChats.cs
+++ b/Examples/Program_SecretChats.cs
@@ -4,23 +4,24 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using TL;
+using WTelegram;
namespace WTelegramClientTest
{
static class Program_SecretChats
{
- static WTelegram.Client Client;
- static WTelegram.SecretChats Secrets;
- static InputEncryptedChat ActiveChat; // the secret chat currently selected
+ static Client Client;
+ static SecretChats Secrets;
+ static ISecretChat ActiveChat; // the secret chat currently selected
static readonly Dictionary Users = new();
static readonly Dictionary Chats = new();
// go to Project Properties > Debug > Environment variables and add at least these: api_id, api_hash, phone_number
static async Task Main()
{
- WTelegram.Helpers.Log = (l, s) => System.Diagnostics.Debug.WriteLine(s);
- Client = new WTelegram.Client(Environment.GetEnvironmentVariable);
- Secrets = new WTelegram.SecretChats(Client, "Secrets.bin");
+ Helpers.Log = (l, s) => System.Diagnostics.Debug.WriteLine(s);
+ Client = new Client(Environment.GetEnvironmentVariable);
+ Secrets = new SecretChats(Client, "Secrets.bin");
AppDomain.CurrentDomain.ProcessExit += (s, e) => { Secrets.Dispose(); Client.Dispose(); };
SelectActiveChat();
@@ -46,9 +47,9 @@ Type a command, or a message to send to the active secret chat:");
var line = Console.ReadLine();
if (line.StartsWith('/'))
{
- if (line == "/discard delete") { await Secrets.Discard(ActiveChat, true); SelectActiveChat(); }
- else if (line == "/discard") { await Secrets.Discard(ActiveChat, false); SelectActiveChat(); }
- else if (line == "/read") await Client.Messages_ReadEncryptedHistory(ActiveChat, DateTime.UtcNow);
+ if (line == "/discard delete") { await Secrets.Discard(ActiveChat.ChatId, true); SelectActiveChat(); }
+ else if (line == "/discard") { await Secrets.Discard(ActiveChat.ChatId, false); SelectActiveChat(); }
+ else if (line == "/read") await Client.Messages_ReadEncryptedHistory(ActiveChat.Peer, DateTime.UtcNow);
else if (line == "/users") foreach (var user in Users.Values) Console.WriteLine($"{user.id,-10} {user}");
else if (line.StartsWith("/select ")) SelectActiveChat(int.Parse(line[8..]));
else if (line.StartsWith("/request "))
@@ -58,15 +59,15 @@ Type a command, or a message to send to the active secret chat:");
Console.WriteLine("User not found");
else if (line.StartsWith("/photo "))
{
- var media = new TL.Layer45.DecryptedMessageMediaPhoto { caption = line[7..] };
+ var media = new TL.Layer46.DecryptedMessageMediaPhoto { caption = line[7..] };
var file = await Secrets.UploadFile(File.OpenRead(line[7..]), media);
- var sent = await Secrets.SendMessage(ActiveChat, new TL.Layer73.DecryptedMessage { random_id = WTelegram.Helpers.RandomLong(),
+ var sent = await Secrets.SendMessage(ActiveChat.ChatId, new TL.Layer73.DecryptedMessage { random_id = Helpers.RandomLong(),
media = media, flags = TL.Layer73.DecryptedMessage.Flags.has_media }, file: file);
}
else Console.WriteLine("Unrecognized command");
}
else if (ActiveChat == null) Console.WriteLine("No active secret chat");
- else await Secrets.SendMessage(ActiveChat, new TL.Layer73.DecryptedMessage { message = line, random_id = WTelegram.Helpers.RandomLong() });
+ else await Secrets.SendMessage(ActiveChat.ChatId, new TL.Layer73.DecryptedMessage { message = line, random_id = Helpers.RandomLong() });
}
catch (Exception ex)
{
@@ -86,7 +87,7 @@ Type a command, or a message to send to the active secret chat:");
await Secrets.HandleUpdate(ue);
break;
case UpdateNewEncryptedMessage unem: // Encrypted message or service message:
- if (unem.message.ChatId != ActiveChat?.chat_id) SelectActiveChat(unem.message.ChatId);
+ if (unem.message.ChatId != ActiveChat?.ChatId) SelectActiveChat(unem.message.ChatId);
foreach (var msg in Secrets.DecryptMessage(unem.message))
{
if (msg.Media != null && unem.message is EncryptedMessage { file: EncryptedFile ef })
@@ -110,8 +111,8 @@ Type a command, or a message to send to the active secret chat:");
private static void SelectActiveChat(int newActiveChat = 0)
{
- ActiveChat = Secrets.Peers.FirstOrDefault(sc => newActiveChat == 0 || sc.chat_id == newActiveChat);
- Console.WriteLine("Active secret chat ID: " + ActiveChat?.chat_id);
+ ActiveChat = Secrets.Chats.FirstOrDefault(sc => newActiveChat == 0 || sc.ChatId == newActiveChat);
+ Console.WriteLine("Active secret chat ID: " + ActiveChat?.ChatId);
}
}
}
diff --git a/FAQ.md b/FAQ.md
index 188d5dd..9a1c8d8 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -140,7 +140,7 @@ Some additional advices from me:
5. Avoid repetitive polling or repetitive sequence of actions/requests: Save the initial results of your queries, and update those results when you're informed of a change through `OnUpdate` events.
6. Don't buy fake user accounts/sessions and don't extract api_id/hash/authkey/sessions from official clients, this is [specifically forbidden by API TOS](https://core.telegram.org/api/terms#2-transparency). You must use your own api_id and create your own sessions associated with it.
-7. If a phone number is brand new, it will be closely monitored by Telegram for abuse, and it can even already be considered a bad user due to bad behavior from the previous owner of that phone number (which may happens often with VoIP or other easy-to-buy-online numbers, so expect fast ban)
+7. If a phone number is brand new, it will be closely monitored by Telegram for abuse, and it can even already be considered a bad user due to bad behavior from the previous owner of that phone number (which may happen often with VoIP or other easy-to-buy-online numbers, so expect fast ban)
8. You may want to use your new phone number account with an official Telegram client and act like a normal user for some time (some weeks/months), before using it for automation with WTelegramClient.
9. When creating a new API ID/Hash, I recommend you use your own phone number with long history of normal Telegram usage, rather than a brand new phone number with short history.
In particular, DON'T create an API ID/Hash for every phone numbers you will control. One API ID/Hash represents your application, which can be used to control several user accounts.
diff --git a/src/Encryption.cs b/src/Encryption.cs
index 450e35f..a3a3eaf 100644
--- a/src/Encryption.cs
+++ b/src/Encryption.cs
@@ -531,7 +531,7 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB
private readonly ICryptoTransform aesCrypto;
private readonly byte[] prevBytes;
- public AES_IGE_Stream(Stream stream, int size, byte[] key, byte[] iv) : this(stream, key, iv, false) { ContentLength = size; }
+ public AES_IGE_Stream(Stream stream, long size, byte[] key, byte[] iv) : this(stream, key, iv, false) { ContentLength = size; }
public AES_IGE_Stream(Stream stream, byte[] key, byte[] iv, bool encrypt) : base(stream)
{
aesCrypto = encrypt ? Encryption.AesECB.CreateEncryptor(key, null) : Encryption.AesECB.CreateDecryptor(key, null);
diff --git a/src/SecretChats.cs b/src/SecretChats.cs
index 8065b5f..b857422 100644
--- a/src/SecretChats.cs
+++ b/src/SecretChats.cs
@@ -13,6 +13,14 @@ using static WTelegram.Encryption;
namespace WTelegram
{
+ public interface ISecretChat
+ {
+ int ChatId { get; }
+ long RemoteUserId { get; }
+ InputEncryptedChat Peer { get; }
+ int RemoteLayer { get; }
+ }
+
public sealed class SecretChats : IDisposable
{
public event Action OnChanged;
@@ -28,7 +36,7 @@ namespace WTelegram
private const int ThresholdPFS = 100;
[TLDef(0xFEFEFEFE)]
- internal class SecretChat : IObject
+ internal class SecretChat : IObject, ISecretChat
{
[Flags] public enum Flags : uint { requestChat = 1, renewKey = 2, acceptKey = 4, originator = 8, commitKey = 16 }
public Flags flags;
@@ -43,8 +51,12 @@ namespace WTelegram
public long exchange_id;
public int ChatId => peer.chat_id;
+ public long RemoteUserId => participant_id;
+ public InputEncryptedChat Peer => peer;
+ public int RemoteLayer => remoteLayer;
+
internal long key_fingerprint;
- internal SortedList pendingMsgs = new();
+ internal SortedList pendingMsgs = new();
internal void Discarded() // clear out fields for more security
{
Array.Clear(authKey, 0, authKey.Length);
@@ -67,13 +79,7 @@ namespace WTelegram
}
public void Dispose() { OnChanged?.Invoke(); storage?.Dispose(); sha256.Dispose(); sha1.Dispose(); }
- public List Peers => chats.Values.Select(sc => sc.peer).ToList();
-
- /// Return secret chats with the given remote user ID
- /// remote user ID
- /// List of matching secret chat ids/access_hash
- public List FindChatsByParticipant(long participant_id)
- => chats.Where(kvp => kvp.Value.participant_id == participant_id).Select(kvp => kvp.Value.peer).ToList();
+ public List Chats => chats.Values.ToList();
public bool IsChatActive(int chat_id) => !(chats.GetValueOrDefault(chat_id)?.flags.HasFlag(SecretChat.Flags.requestChat) ?? true);
@@ -253,16 +259,16 @@ namespace WTelegram
private async Task SendNotifyLayer(SecretChat chat)
{
- await SendMessage(chat.ChatId, new TL.Layer17.DecryptedMessageService { random_id = Helpers.RandomLong(),
- action = new TL.Layer17.DecryptedMessageActionNotifyLayer { layer = Layer.SecretChats } });
+ await SendMessage(chat.ChatId, new TL.Layer23.DecryptedMessageService { random_id = Helpers.RandomLong(),
+ action = new TL.Layer23.DecryptedMessageActionNotifyLayer { layer = Layer.SecretChats } });
if (chat.remoteLayer < Layer.MTProto2) chat.remoteLayer = Layer.MTProto2;
}
/// Encrypt and send a message on a secret chat
- /// You would typically pass an instance of or that you created and filled
+ /// You would typically pass an instance of or that you created and filled
///
Remember to fill random_id with , and the flags field if necessary
/// Secret Chat ID
- /// The pre-filled DecryptedMessage or DecryptedMessageService to send
+ /// The pre-filled DecryptedMessage or DecryptedMessageService to send
/// Send encrypted message without a notification
/// Optional file attachment. See method UploadFile
/// Confirmation of sent message
@@ -271,7 +277,7 @@ namespace WTelegram
if (!chats.TryGetValue(chatId, out var chat)) throw new ApplicationException("Secret chat not found");
try
{
- var dml = new TL.Layer17.DecryptedMessageLayer
+ var dml = new TL.Layer23.DecryptedMessageLayer
{
layer = Math.Min(chat.remoteLayer, Layer.SecretChats),
random_bytes = new byte[15],
@@ -290,7 +296,7 @@ namespace WTelegram
}
}
- private async Task SendMessage(SecretChat chat, TL.Layer17.DecryptedMessageLayer dml, bool silent = false, InputEncryptedFileBase file = null)
+ private async Task SendMessage(SecretChat chat, TL.Layer23.DecryptedMessageLayer dml, bool silent = false, InputEncryptedFileBase file = null)
{
RNG.GetBytes(dml.random_bytes);
int x = 8 - (int)(chat.flags & SecretChat.Flags.originator);
@@ -321,7 +327,7 @@ namespace WTelegram
CheckPFS(chat);
if (file != null)
return await client.Messages_SendEncryptedFile(chat.peer, dml.message.RandomId, data, file, silent);
- else if (dml.message is TL.Layer17.DecryptedMessageService or TL.Layer8.DecryptedMessageService)
+ else if (dml.message is TL.Layer23.DecryptedMessageService or TL.Layer8.DecryptedMessageService)
return await client.Messages_SendEncryptedService(chat.peer, dml.message.RandomId, data);
else
return await client.Messages_SendEncrypted(chat.peer, dml.message.RandomId, data, silent);
@@ -360,7 +366,7 @@ namespace WTelegram
/// Decrypt an encrypted message obtained in
/// Encrypted
/// If messages are missing or received in wrong order, automatically request to resend missing messages
- /// An array of DecryptedMessage or DecryptedMessageService from various TL.LayerXX namespaces.
+ /// An array of DecryptedMessage or DecryptedMessageService from various TL.LayerXX namespaces.
/// You can use the generic properties to access their fields
/// May return an empty array if msg was already previously received or is not the next message in sequence.
///
May return multiple messages if missing messages are finally received (using = true)
@@ -371,7 +377,7 @@ namespace WTelegram
try
{
var obj = Decrypt(chat, msg.Bytes, msg.Bytes.Length);
- if (obj is not TL.Layer17.DecryptedMessageLayer dml) throw new ApplicationException("Decrypted object is not DecryptedMessageLayer");
+ if (obj is not TL.Layer23.DecryptedMessageLayer dml) throw new ApplicationException("Decrypted object is not DecryptedMessageLayer");
if (dml.random_bytes.Length < 15) throw new ApplicationException("Not enough random_bytes");
if (((dml.out_seq_no ^ dml.in_seq_no) & 1) != 1 || ((dml.out_seq_no ^ chat.in_seq_no) & 1) != 0) throw new ApplicationException("Invalid seq_no parities");
if (dml.layer > chat.remoteLayer) chat.remoteLayer = dml.layer;
@@ -384,8 +390,8 @@ namespace WTelegram
if (lastPending == 0) lastPending = chat.in_seq_no;
chat.pendingMsgs[dml.out_seq_no] = dml;
if (dml.out_seq_no > lastPending + 2) // send request to resend missing gap asynchronously
- _ = SendMessage(chat.ChatId, new TL.Layer17.DecryptedMessageService { random_id = Helpers.RandomLong(),
- action = new TL.Layer17.DecryptedMessageActionResend { start_seq_no = lastPending + 2, end_seq_no = dml.out_seq_no - 2 } });
+ _ = SendMessage(chat.ChatId, new TL.Layer23.DecryptedMessageService { random_id = Helpers.RandomLong(),
+ action = new TL.Layer23.DecryptedMessageActionResend { start_seq_no = lastPending + 2, end_seq_no = dml.out_seq_no - 2 } });
return Array.Empty();
}
chat.in_seq_no = dml.out_seq_no;
@@ -423,13 +429,13 @@ namespace WTelegram
{
switch (action)
{
- case TL.Layer17.DecryptedMessageActionNotifyLayer dmanl:
+ case TL.Layer23.DecryptedMessageActionNotifyLayer dmanl:
chat.remoteLayer = dmanl.layer;
return true;
- case TL.Layer17.DecryptedMessageActionResend resend:
+ case TL.Layer23.DecryptedMessageActionResend resend:
Helpers.Log(1, $"SC{(short)chat.ChatId:X4}> Resend {resend.start_seq_no}-{resend.end_seq_no}");
- var msgSvc = new TL.Layer17.DecryptedMessageService { action = new TL.Layer20.DecryptedMessageActionNoop() };
- var dml = new TL.Layer17.DecryptedMessageLayer
+ var msgSvc = new TL.Layer23.DecryptedMessageService { action = new TL.Layer23.DecryptedMessageActionNoop() };
+ var dml = new TL.Layer23.DecryptedMessageLayer
{
layer = Math.Min(chat.remoteLayer, Layer.SecretChats),
random_bytes = new byte[15],
@@ -442,13 +448,13 @@ namespace WTelegram
_ = SendMessage(chat, dml);
}
return true;
- case TL.Layer20.DecryptedMessageActionNoop:
+ case TL.Layer23.DecryptedMessageActionNoop:
Helpers.Log(1, $"SC{(short)chat.ChatId:X4}> Noop");
return true;
- case TL.Layer20.DecryptedMessageActionRequestKey:
- case TL.Layer20.DecryptedMessageActionAcceptKey:
- case TL.Layer20.DecryptedMessageActionCommitKey:
- case TL.Layer20.DecryptedMessageActionAbortKey:
+ case TL.Layer23.DecryptedMessageActionRequestKey:
+ case TL.Layer23.DecryptedMessageActionAcceptKey:
+ case TL.Layer23.DecryptedMessageActionCommitKey:
+ case TL.Layer23.DecryptedMessageActionAbortKey:
Helpers.Log(1, $"SC{(short)chat.ChatId:X4}> PFS {action.GetType().Name[22..]}");
HandlePFS(chat, action);
return true;
@@ -465,16 +471,17 @@ namespace WTelegram
else { Helpers.Log(4, "SC{(short)chat.ChatId:X4}> PFS Failure"); _ = Discard(chat.ChatId); return; }
try
{
+ chat.flags |= SecretChat.Flags.renewKey;
Helpers.Log(1, $"SC{(short)chat.ChatId:X4}> PFS RenewKey");
+ await Task.Delay(100);
chat.salt = new byte[256];
RNG.GetBytes(chat.salt);
var a = BigEndianInteger(chat.salt);
var g_a = BigInteger.ModPow(dh.g, a, dh_prime);
CheckGoodGaAndGb(g_a, dh_prime);
- chat.flags |= SecretChat.Flags.renewKey;
chat.exchange_id = Helpers.RandomLong();
- await SendMessage(chat.ChatId, new TL.Layer17.DecryptedMessageService { random_id = Helpers.RandomLong(),
- action = new TL.Layer20.DecryptedMessageActionRequestKey { exchange_id = chat.exchange_id, g_a = g_a.To256Bytes() } });
+ await SendMessage(chat.ChatId, new TL.Layer23.DecryptedMessageService { random_id = Helpers.RandomLong(),
+ action = new TL.Layer23.DecryptedMessageActionRequestKey { exchange_id = chat.exchange_id, g_a = g_a.To256Bytes() } });
}
catch (Exception ex)
{
@@ -489,7 +496,7 @@ namespace WTelegram
{
switch (action)
{
- case TL.Layer20.DecryptedMessageActionRequestKey request:
+ case TL.Layer23.DecryptedMessageActionRequestKey request:
switch (chat.flags & (SecretChat.Flags.requestChat | SecretChat.Flags.renewKey | SecretChat.Flags.acceptKey))
{
case SecretChat.Flags.renewKey: // Concurrent Re-Keying
@@ -517,10 +524,10 @@ namespace WTelegram
chat.salt = gab.To256Bytes();
chat.exchange_id = request.exchange_id;
var key_fingerprint = BinaryPrimitives.ReadInt64LittleEndian(sha1.ComputeHash(chat.salt).AsSpan(12));
- await SendMessage(chat.ChatId, new TL.Layer17.DecryptedMessageService { random_id = Helpers.RandomLong(),
- action = new TL.Layer20.DecryptedMessageActionAcceptKey { exchange_id = request.exchange_id, g_b = g_b.To256Bytes(), key_fingerprint = key_fingerprint } });
+ await SendMessage(chat.ChatId, new TL.Layer23.DecryptedMessageService { random_id = Helpers.RandomLong(),
+ action = new TL.Layer23.DecryptedMessageActionAcceptKey { exchange_id = request.exchange_id, g_b = g_b.To256Bytes(), key_fingerprint = key_fingerprint } });
break;
- case TL.Layer20.DecryptedMessageActionAcceptKey accept:
+ case TL.Layer23.DecryptedMessageActionAcceptKey accept:
if ((chat.flags & (SecretChat.Flags.requestChat | SecretChat.Flags.renewKey | SecretChat.Flags.acceptKey)) != SecretChat.Flags.renewKey)
throw new ApplicationException("Invalid AcceptKey");
if (accept.exchange_id != chat.exchange_id)
@@ -533,13 +540,13 @@ namespace WTelegram
key_fingerprint = BinaryPrimitives.ReadInt64LittleEndian(sha1.ComputeHash(authKey).AsSpan(12));
if (accept.key_fingerprint != key_fingerprint)
throw new ApplicationException("AcceptKey: key_fingerprint mismatch");
- _ = SendMessage(chat.ChatId, new TL.Layer17.DecryptedMessageService { random_id = Helpers.RandomLong(),
- action = new TL.Layer20.DecryptedMessageActionCommitKey { exchange_id = accept.exchange_id, key_fingerprint = accept.key_fingerprint } });
+ _ = SendMessage(chat.ChatId, new TL.Layer23.DecryptedMessageService { random_id = Helpers.RandomLong(),
+ action = new TL.Layer23.DecryptedMessageActionCommitKey { exchange_id = accept.exchange_id, key_fingerprint = accept.key_fingerprint } });
chat.salt = chat.authKey; // A may only discard the previous key after a message encrypted with the new key has been received.
SetAuthKey(chat, authKey);
chat.flags = chat.flags & ~SecretChat.Flags.renewKey | SecretChat.Flags.commitKey;
break;
- case TL.Layer20.DecryptedMessageActionCommitKey commit:
+ case TL.Layer23.DecryptedMessageActionCommitKey commit:
if ((chat.flags & (SecretChat.Flags.requestChat | SecretChat.Flags.renewKey | SecretChat.Flags.acceptKey)) != SecretChat.Flags.acceptKey)
throw new ApplicationException("Invalid RequestKey");
key_fingerprint = BinaryPrimitives.ReadInt64LittleEndian(sha1.ComputeHash(chat.salt).AsSpan(12));
@@ -549,10 +556,10 @@ namespace WTelegram
authKey = chat.authKey;
SetAuthKey(chat, chat.salt);
Array.Clear(authKey, 0, authKey.Length); // the old key must be securely discarded
- await SendMessage(chat.ChatId, new TL.Layer17.DecryptedMessageService { random_id = Helpers.RandomLong(),
- action = new TL.Layer20.DecryptedMessageActionNoop() });
+ await SendMessage(chat.ChatId, new TL.Layer23.DecryptedMessageService { random_id = Helpers.RandomLong(),
+ action = new TL.Layer23.DecryptedMessageActionNoop() });
break;
- case TL.Layer20.DecryptedMessageActionAbortKey abort:
+ case TL.Layer23.DecryptedMessageActionAbortKey abort:
if ((chat.flags & (SecretChat.Flags.renewKey | SecretChat.Flags.acceptKey)) == 0 ||
chat.flags.HasFlag(SecretChat.Flags.commitKey) || abort.exchange_id != chat.exchange_id)
return;
@@ -579,7 +586,7 @@ namespace WTelegram
byte[] aes_key = new byte[32], aes_iv = new byte[32];
RNG.GetBytes(aes_key);
RNG.GetBytes(aes_iv);
- media.SizeKeyIV = (checked((int)stream.Length), aes_key, aes_iv);
+ media.SizeKeyIV = (stream.Length, aes_key, aes_iv);
using var md5 = MD5.Create();
md5.TransformBlock(aes_key, 0, 32, null, 0);
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index eb74e8c..a9026f8 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -13179,7 +13179,7 @@ namespace TL
public DocumentBase static_icon;
/// The animated sticker to show when the user opens the reaction dropdown
public DocumentBase appear_animation;
- /// The animated sticker to show when the user selects this reaction
+ /// The animated sticker to show when the user hovers over the reaction
public DocumentBase select_animation;
/// The animated sticker to show when the reaction is chosen and activated
public DocumentBase activate_animation;
diff --git a/src/TL.Secret.cs b/src/TL.Secret.cs
index 1cf43a6..1253e9b 100644
--- a/src/TL.Secret.cs
+++ b/src/TL.Secret.cs
@@ -32,7 +32,7 @@ namespace TL
public abstract class DecryptedMessageMedia : IObject
{
public virtual string MimeType { get; }
- internal virtual (int size, byte[] key, byte[] iv) SizeKeyIV { get => default; set => throw new ApplicationException("Incompatible DecryptedMessageMedia"); }
+ internal virtual (long size, byte[] key, byte[] iv) SizeKeyIV { get => default; set => throw new ApplicationException("Incompatible DecryptedMessageMedia"); }
}
/// Object describes the action to which a service message is linked. See
@@ -110,7 +110,7 @@ namespace TL
public byte[] iv;
public override string MimeType => "image/jpeg";
- internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
+ internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// Video attached to an encrypted message. See
[TLDef(0x4CEE6EF3)]
@@ -135,7 +135,7 @@ namespace TL
/// Initialization vector
public byte[] iv;
- internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
+ internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// GeoPoint attached to an encrypted message. See
[TLDef(0x35480A59)]
@@ -182,7 +182,7 @@ namespace TL
/// File MIME-type
public override string MimeType => mime_type;
- internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
+ internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// Audio file attached to a secret chat message. See
[TLDef(0x6080758F)]
@@ -197,7 +197,7 @@ namespace TL
/// Initialization vector
public byte[] iv;
- internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
+ internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// Setting of a message lifetime after reading. See
@@ -233,8 +233,43 @@ namespace TL
public class DecryptedMessageActionFlushHistory : DecryptedMessageAction { }
}
- namespace Layer17
+ namespace Layer23
{
+ /// Image description. See
+ [TLDef(0x77BFB61B)]
+ public partial class PhotoSize : PhotoSizeBase
+ {
+ /// Thumbnail type »
+ public string type;
+ public FileLocationBase location;
+ /// Image width
+ public int w;
+ /// Image height
+ public int h;
+ /// File size
+ public int size;
+
+ /// Thumbnail type »
+ public override string Type => type;
+ }
+ /// Description of an image and its content. See
+ [TLDef(0xE9A734FA)]
+ public partial class PhotoCachedSize : PhotoSizeBase
+ {
+ /// Thumbnail type
+ public string type;
+ public FileLocationBase location;
+ /// Image width
+ public int w;
+ /// Image height
+ public int h;
+ /// Binary data, file content
+ public byte[] bytes;
+
+ /// Thumbnail type
+ public override string Type => type;
+ }
+
/// User is uploading a video. See
[TLDef(0x92042FF7)]
public class SendMessageUploadVideoAction : SendMessageAction { }
@@ -248,6 +283,28 @@ namespace TL
[TLDef(0x8FAEE98E)]
public class SendMessageUploadDocumentAction : SendMessageAction { }
+ /// Defines a sticker See
+ [TLDef(0xFB0A5727)]
+ public class DocumentAttributeSticker : DocumentAttribute { }
+ /// Defines a video See
+ [TLDef(0x5910CCCB)]
+ public class DocumentAttributeVideo : DocumentAttribute
+ {
+ /// Duration in seconds
+ public int duration;
+ /// Video width
+ public int w;
+ /// Video height
+ public int h;
+ }
+ /// Represents an audio file See
+ [TLDef(0x051448E5)]
+ public class DocumentAttributeAudio : DocumentAttribute
+ {
+ /// Duration in seconds
+ public int duration;
+ }
+
/// Contents of an encrypted message. See
[TLDef(0x204D3878)]
public class DecryptedMessage : DecryptedMessageBase
@@ -313,7 +370,7 @@ namespace TL
/// MIME-type of the video file
Parameter added in Layer 17.
public override string MimeType => mime_type;
- internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
+ internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// Audio file attached to a secret chat message. See
[TLDef(0x57E0A9CB)]
@@ -333,7 +390,31 @@ namespace TL
/// MIME-type of the audio file
Parameter added in Layer 13.
public override string MimeType => mime_type;
- internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
+ internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
+ }
+ /// Non-e2e documented forwarded from non-secret chat See
+ [TLDef(0xFA95B0DD)]
+ public class DecryptedMessageMediaExternalDocument : DecryptedMessageMedia
+ {
+ /// Document ID
+ public long id;
+ /// access hash
+ public long access_hash;
+ /// Date
+ public DateTime date;
+ /// Mime type
+ public string mime_type;
+ /// Size
+ public int size;
+ /// Thumbnail
+ public PhotoSizeBase thumb;
+ /// DC ID
+ public int dc_id;
+ /// Attributes for media types
+ public DocumentAttribute[] attributes;
+
+ /// Mime type
+ public override string MimeType => mime_type;
}
/// Request for the other party in a Secret Chat to automatically resend a contiguous range of previously sent messages, as explained in Sequence number is Secret Chats. See
@@ -359,6 +440,45 @@ namespace TL
/// Type of action
public SendMessageAction action;
}
+ /// Request rekeying, see rekeying process See
+ [TLDef(0xF3C9611B)]
+ public class DecryptedMessageActionRequestKey : DecryptedMessageAction
+ {
+ /// Exchange ID
+ public long exchange_id;
+ /// g_a, see rekeying process
+ public byte[] g_a;
+ }
+ /// Accept new key See
+ [TLDef(0x6FE1735B)]
+ public class DecryptedMessageActionAcceptKey : DecryptedMessageAction
+ {
+ /// Exchange ID
+ public long exchange_id;
+ /// B parameter, see rekeying process
+ public byte[] g_b;
+ /// Key fingerprint, see rekeying process
+ public long key_fingerprint;
+ }
+ /// Abort rekeying See
+ [TLDef(0xDD05EC6B)]
+ public class DecryptedMessageActionAbortKey : DecryptedMessageAction
+ {
+ /// Exchange ID
+ public long exchange_id;
+ }
+ /// Commit new key, see rekeying process See
+ [TLDef(0xEC2E0B9B)]
+ public class DecryptedMessageActionCommitKey : DecryptedMessageAction
+ {
+ /// Exchange ID, see rekeying process
+ public long exchange_id;
+ /// Key fingerprint, see rekeying process
+ public long key_fingerprint;
+ }
+ /// NOOP action See
+ [TLDef(0xA82FDD63)]
+ public class DecryptedMessageActionNoop : DecryptedMessageAction { }
/// Sets the layer number for the contents of an encrypted message. See
[TLDef(0x1BE31789)]
@@ -375,19 +495,49 @@ namespace TL
/// The content of message itself
public DecryptedMessageBase message;
}
+
+ /// File is currently unavailable. See
+ [TLDef(0x7C596B46)]
+ public class FileLocationUnavailable : FileLocationBase
+ {
+ /// Server volume
+ public long volume_id;
+ /// File ID
+ public int local_id;
+ /// Checksum to access the file
+ public long secret;
+
+ /// Server volume
+ public override long VolumeId => volume_id;
+ /// File ID
+ public override int LocalId => local_id;
+ /// Checksum to access the file
+ public override long Secret => secret;
+ }
+ /// File location. See
+ [TLDef(0x53D69076)]
+ public class FileLocation : FileLocationBase
+ {
+ /// Number of the data center holding the file
+ public int dc_id;
+ /// Server volume
+ public long volume_id;
+ /// File ID
+ public int local_id;
+ /// Checksum to access the file
+ public long secret;
+
+ /// Server volume
+ public override long VolumeId => volume_id;
+ /// File ID
+ public override int LocalId => local_id;
+ /// Checksum to access the file
+ public override long Secret => secret;
+ }
}
namespace Layer45
{
- /// Defines a sticker See
- [TLDef(0x3A556302)]
- public class DocumentAttributeSticker : DocumentAttribute
- {
- /// Alternative emoji representation of sticker
- public string alt;
- /// Associated stickerset
- public InputStickerSet stickerset;
- }
/// Represents an audio file See
[TLDef(0xDED218E0)]
public class DocumentAttributeAudio : DocumentAttribute
@@ -399,6 +549,27 @@ namespace TL
/// Performer
public string performer;
}
+ }
+
+ namespace Layer46
+ {
+ /// Defines a sticker See
+ [TLDef(0x3A556302)]
+ public class DocumentAttributeSticker : DocumentAttribute
+ {
+ /// Alternative emoji representation of sticker
+ public string alt;
+ /// Associated stickerset
+ public InputStickerSet stickerset;
+ }
+
+ /// Message entity representing a user mention: for creating a mention use . See
+ [TLDef(0x352DCA58, inheritBefore = true)]
+ public class MessageEntityMentionName : MessageEntityMention
+ {
+ /// Identifier of the user that was mentioned
+ public int user_id;
+ }
/// Contents of an encrypted message. See
[TLDef(0x36B091DE)]
@@ -475,7 +646,7 @@ namespace TL
public string caption;
public override string MimeType => "image/jpeg";
- internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
+ internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// Video attached to an encrypted message. See
[TLDef(0x970C8C0E)]
@@ -507,7 +678,7 @@ namespace TL
/// MIME-type of the video file
Parameter added in Layer 17.
public override string MimeType => mime_type;
- internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
+ internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// Document attached to a message in a secret chat. See
[TLDef(0x7AFE8AE2)]
@@ -535,7 +706,7 @@ namespace TL
/// File MIME-type
public override string MimeType => mime_type;
- internal override (int, byte[], byte[]) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
+ internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = (checked((int)value.size), value.key, value.iv); }
}
/// Venue See
[TLDef(0x8A0DF56F)]
@@ -563,6 +734,13 @@ namespace TL
}
}
+ namespace Layer66
+ {
+ /// User is uploading a round video See
+ [TLDef(0xBB718624)]
+ public class SendMessageUploadRoundAction : SendMessageAction { }
+ }
+
namespace Layer73
{
/// Contents of an encrypted message. See
@@ -592,6 +770,8 @@ namespace TL
{
/// Field has a value
has_reply_to_random_id = 0x8,
+ /// Whether this is a silent message (no notification triggered)
+ silent = 0x20,
/// Field has a value
has_entities = 0x80,
/// Field has a value
@@ -623,180 +803,41 @@ namespace TL
}
}
- namespace Layer20
+ namespace Layer101
+ { }
+
+ namespace Layer143
{
- /// Request rekeying, see rekeying process See
- [TLDef(0xF3C9611B)]
- public class DecryptedMessageActionRequestKey : DecryptedMessageAction
+ /// Document attached to a message in a secret chat. See
+ [TLDef(0x6ABD9782)]
+ public class DecryptedMessageMediaDocument : DecryptedMessageMedia
{
- /// Exchange ID
- public long exchange_id;
- /// g_a, see rekeying process
- public byte[] g_a;
- }
- /// Accept new key See
- [TLDef(0x6FE1735B)]
- public class DecryptedMessageActionAcceptKey : DecryptedMessageAction
- {
- /// Exchange ID
- public long exchange_id;
- /// B parameter, see rekeying process
- public byte[] g_b;
- /// Key fingerprint, see rekeying process
- public long key_fingerprint;
- }
- /// Abort rekeying See
- [TLDef(0xDD05EC6B)]
- public class DecryptedMessageActionAbortKey : DecryptedMessageAction
- {
- /// Exchange ID
- public long exchange_id;
- }
- /// Commit new key, see rekeying process See
- [TLDef(0xEC2E0B9B)]
- public class DecryptedMessageActionCommitKey : DecryptedMessageAction
- {
- /// Exchange ID, see rekeying process
- public long exchange_id;
- /// Key fingerprint, see rekeying process
- public long key_fingerprint;
- }
- /// NOOP action See
- [TLDef(0xA82FDD63)]
- public class DecryptedMessageActionNoop : DecryptedMessageAction { }
- }
-
- namespace Layer23
- {
- /// Image description. See
- [TLDef(0x77BFB61B)]
- public partial class PhotoSize : PhotoSizeBase
- {
- /// Thumbnail type »
- public string type;
- public FileLocationBase location;
- /// Image width
- public int w;
- /// Image height
- public int h;
- /// File size
- public int size;
-
- /// Thumbnail type »
- public override string Type => type;
- }
- /// Description of an image and its content. See
- [TLDef(0xE9A734FA)]
- public partial class PhotoCachedSize : PhotoSizeBase
- {
- /// Thumbnail type
- public string type;
- public FileLocationBase location;
- /// Image width
- public int w;
- /// Image height
- public int h;
- /// Binary data, file content
- public byte[] bytes;
-
- /// Thumbnail type
- public override string Type => type;
- }
-
- /// Defines a sticker See
- [TLDef(0xFB0A5727)]
- public class DocumentAttributeSticker : DocumentAttribute { }
- /// Defines a video See
- [TLDef(0x5910CCCB)]
- public class DocumentAttributeVideo : DocumentAttribute
- {
- /// Duration in seconds
- public int duration;
- /// Video width
- public int w;
- /// Video height
- public int h;
- }
- /// Represents an audio file See
- [TLDef(0x051448E5)]
- public class DocumentAttributeAudio : DocumentAttribute
- {
- /// Duration in seconds
- public int duration;
- }
-
- /// Non-e2e documented forwarded from non-secret chat See
- [TLDef(0xFA95B0DD)]
- public class DecryptedMessageMediaExternalDocument : DecryptedMessageMedia
- {
- /// Document ID
- public long id;
- /// access hash
- public long access_hash;
- /// Date
- public DateTime date;
- /// Mime type
+ /// Thumbnail-file contents (JPEG-file, quality 55, set in a 90x90 square)
+ public byte[] thumb;
+ /// Thumbnail width
+ public int thumb_w;
+ /// Thumbnail height
+ public int thumb_h;
+ /// File MIME-type
public string mime_type;
- /// Size
- public int size;
- /// Thumbnail
- public PhotoSizeBase thumb;
- /// DC ID
- public int dc_id;
- /// Attributes for media types
+ /// Document size ( on layer <143, on layer >=143)
+ public long size;
+ /// Key to decrypt the attached document file
+ public byte[] key;
+ /// Initialization
+ public byte[] iv;
+ /// Document attributes for media types
public DocumentAttribute[] attributes;
+ /// Caption
+ public string caption;
- /// Mime type
+ /// File MIME-type
public override string MimeType => mime_type;
- }
- /// File is currently unavailable. See
- [TLDef(0x7C596B46)]
- public class FileLocationUnavailable : FileLocationBase
- {
- /// Server volume
- public long volume_id;
- /// File ID
- public int local_id;
- /// Checksum to access the file
- public long secret;
-
- /// Server volume
- public override long VolumeId => volume_id;
- /// File ID
- public override int LocalId => local_id;
- /// Checksum to access the file
- public override long Secret => secret;
- }
- /// File location. See
- [TLDef(0x53D69076)]
- public class FileLocation : FileLocationBase
- {
- /// Number of the data center holding the file
- public int dc_id;
- /// Server volume
- public long volume_id;
- /// File ID
- public int local_id;
- /// Checksum to access the file
- public long secret;
-
- /// Server volume
- public override long VolumeId => volume_id;
- /// File ID
- public override int LocalId => local_id;
- /// Checksum to access the file
- public override long Secret => secret;
+ internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; }
}
}
- namespace Layer66
- {
- /// User is uploading a round video See
- [TLDef(0xBB718624)]
- public class SendMessageUploadRoundAction : SendMessageAction { }
- }
-
- namespace Layer46
+ namespace Layer144
{ }
}
diff --git a/src/TL.Table.cs b/src/TL.Table.cs
index 77a69be..50a3c11 100644
--- a/src/TL.Table.cs
+++ b/src/TL.Table.cs
@@ -7,7 +7,7 @@ namespace TL
public static class Layer
{
public const int Version = 148; // fetched 01/11/2022 17:33:23
- internal const int SecretChats = 101;
+ internal const int SecretChats = 144;
internal const int MTProto2 = 73;
internal const uint VectorCtor = 0x1CB5C415;
internal const uint NullCtor = 0x56730BCC;
@@ -1047,54 +1047,56 @@ namespace TL
[0x71701DA9] = typeof(ForumTopic),
[0x367617D3] = typeof(Messages_ForumTopics),
// from TL.Secret:
+ [0x6ABD9782] = typeof(Layer143.DecryptedMessageMediaDocument),
+ [0x91CC4674] = typeof(Layer73.DecryptedMessage),
[0xBB718624] = typeof(Layer66.SendMessageUploadRoundAction),
- [0xE50511D8] = typeof(Layer45.DecryptedMessageMediaWebPage),
- [0x8A0DF56F] = typeof(Layer45.DecryptedMessageMediaVenue),
+ [0xE50511D8] = typeof(Layer46.DecryptedMessageMediaWebPage),
+ [0x8A0DF56F] = typeof(Layer46.DecryptedMessageMediaVenue),
+ [0x352DCA58] = typeof(Layer46.MessageEntityMentionName),
+ [0x3A556302] = typeof(Layer46.DocumentAttributeSticker),
+ [0x7AFE8AE2] = typeof(Layer46.DecryptedMessageMediaDocument),
+ [0x970C8C0E] = typeof(Layer46.DecryptedMessageMediaVideo),
+ [0xF1FA8D78] = typeof(Layer46.DecryptedMessageMediaPhoto),
+ [0x36B091DE] = typeof(Layer46.DecryptedMessage),
+ [0xDED218E0] = typeof(Layer45.DocumentAttributeAudio),
[0xFA95B0DD] = typeof(Layer23.DecryptedMessageMediaExternalDocument),
[0x53D69076] = typeof(Layer23.FileLocation),
[0x7C596B46] = typeof(Layer23.FileLocationUnavailable),
[0xE9A734FA] = typeof(Layer23.PhotoCachedSize),
[0x77BFB61B] = typeof(Layer23.PhotoSize),
- [0xDED218E0] = typeof(Layer45.DocumentAttributeAudio),
[0x051448E5] = typeof(Layer23.DocumentAttributeAudio),
[0x5910CCCB] = typeof(Layer23.DocumentAttributeVideo),
- [0x3A556302] = typeof(Layer45.DocumentAttributeSticker),
[0xFB0A5727] = typeof(Layer23.DocumentAttributeSticker),
- [0xA82FDD63] = typeof(Layer20.DecryptedMessageActionNoop),
- [0xEC2E0B9B] = typeof(Layer20.DecryptedMessageActionCommitKey),
- [0xDD05EC6B] = typeof(Layer20.DecryptedMessageActionAbortKey),
- [0x6FE1735B] = typeof(Layer20.DecryptedMessageActionAcceptKey),
- [0xF3C9611B] = typeof(Layer20.DecryptedMessageActionRequestKey),
- [0xCCB27641] = typeof(Layer17.DecryptedMessageActionTyping),
- [0xF3048883] = typeof(Layer17.DecryptedMessageActionNotifyLayer),
- [0x511110B0] = typeof(Layer17.DecryptedMessageActionResend),
- [0x8FAEE98E] = typeof(Layer17.SendMessageUploadDocumentAction),
- [0x990A3C1A] = typeof(Layer17.SendMessageUploadPhotoAction),
- [0xE6AC8A6F] = typeof(Layer17.SendMessageUploadAudioAction),
- [0x92042FF7] = typeof(Layer17.SendMessageUploadVideoAction),
- [0x1BE31789] = typeof(Layer17.DecryptedMessageLayer),
+ [0xA82FDD63] = typeof(Layer23.DecryptedMessageActionNoop),
+ [0xEC2E0B9B] = typeof(Layer23.DecryptedMessageActionCommitKey),
+ [0xDD05EC6B] = typeof(Layer23.DecryptedMessageActionAbortKey),
+ [0x6FE1735B] = typeof(Layer23.DecryptedMessageActionAcceptKey),
+ [0xF3C9611B] = typeof(Layer23.DecryptedMessageActionRequestKey),
+ [0xCCB27641] = typeof(Layer23.DecryptedMessageActionTyping),
+ [0xF3048883] = typeof(Layer23.DecryptedMessageActionNotifyLayer),
+ [0x511110B0] = typeof(Layer23.DecryptedMessageActionResend),
+ [0x8FAEE98E] = typeof(Layer23.SendMessageUploadDocumentAction),
+ [0x990A3C1A] = typeof(Layer23.SendMessageUploadPhotoAction),
+ [0xE6AC8A6F] = typeof(Layer23.SendMessageUploadAudioAction),
+ [0x92042FF7] = typeof(Layer23.SendMessageUploadVideoAction),
+ [0x1BE31789] = typeof(Layer23.DecryptedMessageLayer),
+ [0x57E0A9CB] = typeof(Layer23.DecryptedMessageMediaAudio),
+ [0x524A415D] = typeof(Layer23.DecryptedMessageMediaVideo),
+ [0x73164160] = typeof(Layer23.DecryptedMessageService),
+ [0x204D3878] = typeof(Layer23.DecryptedMessage),
[0x6719E45C] = typeof(Layer8.DecryptedMessageActionFlushHistory),
[0x8AC1F475] = typeof(Layer8.DecryptedMessageActionScreenshotMessages),
[0x65614304] = typeof(Layer8.DecryptedMessageActionDeleteMessages),
[0x0C4F40BE] = typeof(Layer8.DecryptedMessageActionReadMessages),
- [0x57E0A9CB] = typeof(Layer17.DecryptedMessageMediaAudio),
[0x6080758F] = typeof(Layer8.DecryptedMessageMediaAudio),
- [0x7AFE8AE2] = typeof(Layer45.DecryptedMessageMediaDocument),
[0xB095434B] = typeof(Layer8.DecryptedMessageMediaDocument),
[0xA1733AEC] = typeof(Layer8.DecryptedMessageActionSetMessageTTL),
[0x588A0A97] = typeof(Layer8.DecryptedMessageMediaContact),
[0x35480A59] = typeof(Layer8.DecryptedMessageMediaGeoPoint),
- [0x970C8C0E] = typeof(Layer45.DecryptedMessageMediaVideo),
- [0x524A415D] = typeof(Layer17.DecryptedMessageMediaVideo),
[0x4CEE6EF3] = typeof(Layer8.DecryptedMessageMediaVideo),
- [0xF1FA8D78] = typeof(Layer45.DecryptedMessageMediaPhoto),
[0x32798A8C] = typeof(Layer8.DecryptedMessageMediaPhoto),
[0x089F5C4A] = null,//Layer8.DecryptedMessageMediaEmpty
- [0x73164160] = typeof(Layer17.DecryptedMessageService),
[0xAA48327D] = typeof(Layer8.DecryptedMessageService),
- [0x91CC4674] = typeof(Layer73.DecryptedMessage),
- [0x36B091DE] = typeof(Layer45.DecryptedMessage),
- [0x204D3878] = typeof(Layer17.DecryptedMessage),
[0x1F814F1F] = typeof(Layer8.DecryptedMessage),
};
From 6b3fcdb967a4bdc255382d64e33e54be528c7d01 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Fri, 11 Nov 2022 01:47:37 +0100
Subject: [PATCH 013/336] Trying to add ReleaseNotes in nuget package
---
.github/dev.yml | 2 +-
.github/release.yml | 2 +-
src/WTelegramClient.csproj | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index 02d8f36..cd20498 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -25,7 +25,7 @@ steps:
includesymbols: true
versioningScheme: 'byEnvVar'
versionEnvVar: 'Build.BuildNumber'
- buildProperties: 'NoWarn="0419;1573;1591";Version=$(Build.BuildNumber);ContinuousIntegrationBuild=true'
+ buildProperties: 'NoWarn="0419;1573;1591";Version=$(Build.BuildNumber);ContinuousIntegrationBuild=true;ReleaseNotes="$(ReleaseNotes)"'
# buildProperties: 'NoWarn="0419;1573;1591";AllowedOutputExtensionsInPackageBuildOutputFolder=".dll;.xml;.pdb"'
- task: NuGetCommand@2
diff --git a/.github/release.yml b/.github/release.yml
index 250e994..180eb0e 100644
--- a/.github/release.yml
+++ b/.github/release.yml
@@ -31,7 +31,7 @@ stages:
includesymbols: true
versioningScheme: 'byEnvVar'
versionEnvVar: 'Build.BuildNumber'
- buildProperties: 'NoWarn="0419;1573;1591";Version=$(Build.BuildNumber);ContinuousIntegrationBuild=true'
+ buildProperties: 'NoWarn="0419;1573;1591";Version=$(Build.BuildNumber);ContinuousIntegrationBuild=true;ReleaseNotes="$(ReleaseNotes)"'
- task: NuGetCommand@2
inputs:
diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj
index 1356ff0..8fce696 100644
--- a/src/WTelegramClient.csproj
+++ b/src/WTelegramClient.csproj
@@ -23,6 +23,7 @@
git
Telegram;Client;Api;UserBot;MTProto;TLSharp;OpenTl
README.md
+ $(ReleaseNotes.Replace('|',$([System.Environment]::NewLine)))
IDE0079;0419;1573;1591;NETSDK1138
TRACE;OBFUSCATION
From ba523f7d21c7273d1b35bafcba3ff73ccafcafe5 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Sat, 12 Nov 2022 19:40:34 +0100
Subject: [PATCH 014/336] Releasing 3.1.1
---
README.md | 20 ++++++++++----------
src/WTelegramClient.csproj | 6 +++---
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/README.md b/README.md
index 16da3f6..436378c 100644
--- a/README.md
+++ b/README.md
@@ -96,15 +96,15 @@ await DoLogin("+12025550156"); // user's phone_number
async Task DoLogin(string loginInfo) // (add this method to your code)
{
- while (client.User == null)
- switch (await client.Login(loginInfo)) // returns which config info is needed to continue login
- {
- case "verification_code": Console.Write("Code: "); loginInfo = Console.ReadLine(); break;
- case "name": loginInfo = "John Doe"; break; // if sign-up is required (first_name last_name)
- case "password": loginInfo = "secret!"; break; // if user has enabled 2FA
- default: loginInfo = null; break;
- }
- Console.WriteLine($"We are logged-in as {client.User} (id {client.User.id})");
+ while (client.User == null)
+ switch (await client.Login(loginInfo)) // returns which config is needed to continue login
+ {
+ case "verification_code": Console.Write("Code: "); loginInfo = Console.ReadLine(); break;
+ case "name": loginInfo = "John Doe"; break; // if sign-up is required (first/last_name)
+ case "password": loginInfo = "secret!"; break; // if user has enabled 2FA
+ default: loginInfo = null; break;
+ }
+ Console.WriteLine($"We are logged-in as {client.User} (id {client.User.id})");
}
```
@@ -134,7 +134,7 @@ 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} with {basicChat.participants_count} members");
+ Console.WriteLine($"{id}: Basic chat: {basicChat.title}");
break;
case Channel group when group.IsGroup:
Console.WriteLine($"{id}: Group {group.username}: {group.title}");
diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj
index 8fce696..5ff24ba 100644
--- a/src/WTelegramClient.csproj
+++ b/src/WTelegramClient.csproj
@@ -23,7 +23,7 @@
git
Telegram;Client;Api;UserBot;MTProto;TLSharp;OpenTl
README.md
- $(ReleaseNotes.Replace('|',$([System.Environment]::NewLine)))
+ $(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))
IDE0079;0419;1573;1591;NETSDK1138
TRACE;OBFUSCATION
@@ -42,9 +42,9 @@
-
+
From fe5773ce290357daf0121daa6bdfb76b121f06e0 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Sat, 12 Nov 2022 20:02:46 +0100
Subject: [PATCH 015/336] Add release notes in Description too
---
.github/dev.yml | 2 +-
src/WTelegramClient.csproj | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index cd20498..4352170 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -2,7 +2,7 @@ pr: none
trigger:
- master
-name: 3.1.1-dev.$(Rev:r)
+name: 3.1.2-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj
index 5ff24ba..51eaaab 100644
--- a/src/WTelegramClient.csproj
+++ b/src/WTelegramClient.csproj
@@ -13,7 +13,7 @@
WTelegramClient
0.0.0
Wizou
- Telegram Client API library written 100% in C# and .NET Standard | Latest MTProto & Telegram API layer version
+ Telegram Client API library written 100% in C# and .NET Standard | Latest MTProto & Telegram API layer version
Release Notes:
$(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))
Copyright © Olivier Marcoux 2021-2022
MIT
https://github.com/wiz0u/WTelegramClient
From 61510465d218519c891a1b83128512827edf4d91 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Sun, 13 Nov 2022 00:25:56 +0100
Subject: [PATCH 016/336] =?UTF-8?q?Fix=20immediate=20crash=20=F0=9F=A4=A6?=
=?UTF-8?q?=F0=9F=8F=BB=E2=80=8D=E2=99=82=EF=B8=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Client.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Client.cs b/src/Client.cs
index 27b4c8a..e9506ae 100644
--- a/src/Client.cs
+++ b/src/Client.cs
@@ -104,7 +104,7 @@ namespace WTelegram
_dcSession ??= new() { Id = Helpers.RandomLong() };
_dcSession.Client = this;
var version = Assembly.GetExecutingAssembly().GetCustomAttribute().InformationalVersion;
- Helpers.Log(1, $"WTelegramClient {version[..version.IndexOf('+')]} running under {System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription}");
+ Helpers.Log(1, $"WTelegramClient {version} running under {System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription}");
}
private Client(Client cloneOf, Session.DCSession dcSession)
From 2047154d2651e5cc730e475b3aabdff8aad12e27 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Tue, 15 Nov 2022 16:20:00 +0100
Subject: [PATCH 017/336] doc
---
.github/dev.yml | 2 +-
README.md | 4 ++--
src/Client.Helpers.cs | 5 +++--
src/Client.cs | 2 +-
4 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index 4352170..d26fff4 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -2,7 +2,7 @@ pr: none
trigger:
- master
-name: 3.1.2-dev.$(Rev:r)
+name: 3.1.3-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/README.md b/README.md
index 436378c..b4369aa 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
-[](https://www.nuget.org/packages/WTelegramClient/)
+[](https://www.nuget.org/packages/WTelegramClient/)
[](https://dev.azure.com/wiz0u/WTelegramClient/_build?definitionId=7)
[](https://corefork.telegram.org/methods)
[](https://dev.azure.com/wiz0u/WTelegramClient/_artifacts/feed/WTelegramClient/NuGet/WTelegramClient)
-[](https://t.me/WTelegramClient)
+[](https://t.me/WTelegramClient)
[](http://t.me/WTelegramBot?start=donate)
## _Telegram Client API library written 100% in C# and .NET Standard_
diff --git a/src/Client.Helpers.cs b/src/Client.Helpers.cs
index b809f94..3ef85f2 100644
--- a/src/Client.Helpers.cs
+++ b/src/Client.Helpers.cs
@@ -16,7 +16,7 @@ namespace WTelegram
partial class Client
{
#region Collect Access Hash system
- /// Enable the collection of id/access_hash pairs (experimental)
+ /// Enable the collection of id/access_hash pairs (experimental)
See
public bool CollectAccessHash { get; set; }
public IEnumerable> AllAccessHashesFor() where T : IObject => _accessHashes.GetValueOrDefault(typeof(T));
private readonly Dictionary> _accessHashes = new();
@@ -25,10 +25,11 @@ namespace WTelegram
/// 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
+ /// 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;
}
diff --git a/src/Client.cs b/src/Client.cs
index e9506ae..891764a 100644
--- a/src/Client.cs
+++ b/src/Client.cs
@@ -49,7 +49,7 @@ namespace WTelegram
public bool Disconnected => _tcpClient != null && !(_tcpClient.Client?.Connected ?? false);
/// ID of the current logged-in user or 0
public long UserId => _session.UserId;
- /// Info about the current logged-in user
+ /// Info about the current logged-in user. This is filled after a successful (re)login
public User User { get; private set; }
private Func _config;
From adf61349119617177f91cc72416e7dcbcfdc1fc3 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Sat, 19 Nov 2022 02:03:48 +0100
Subject: [PATCH 018/336] Doc/Rationalize user/chat generic helpers
---
README.md | 11 ++++++-----
src/Client.Helpers.cs | 45 +++++++++++++++++++++++++++++++++----------
2 files changed, 41 insertions(+), 15 deletions(-)
diff --git a/README.md b/README.md
index b4369aa..28e6757 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ All the Telegram Client APIs (MTProto) are supported so you can do everything th
This ReadMe is a **quick but important tutorial** to learn the fundamentals about this library. Please read it all.
->⚠️ This library relies on asynchronous C# programming (`async/await`) so make sure you are familiar with this advanced topic before proceeding.
+>⚠️ This library requires understanding advanced C# techniques such as **asynchronous programming** or **subclass pattern matching**...
>If you are a beginner in C#, starting a project based on this library might not be a great idea.
# How to use
@@ -85,7 +85,7 @@ Another simple approach is to pass `Environment.GetEnvironmentVariable` as the c
*(undefined variables get the default `null` behavior)*.
Finally, if you want to redirect the library logs to your logger instead of the Console, you can install a delegate in the `WTelegram.Helpers.Log` static property.
-Its `int` argument is the log severity, compatible with the [LogLevel enum](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel)
+Its `int` argument is the log severity, compatible with the [LogLevel enum](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel).
# Alternative simplified configuration & login
Since version 3.0.0, a new approach to login/configuration has been added. Some people might find it easier to deal with:
@@ -185,7 +185,8 @@ Required API parameters/fields can sometimes be set to 0 or `null` when unused (
I've added several useful converters, implicit cast or helper properties to various API objects so that they are more easy to manipulate.
-Beyond the TL async methods, the Client class offers a few other methods to simplify the sending/receiving of files, medias or messages.
+Beyond the TL async methods, the Client class offers a few other methods to simplify the sending/receiving of files, medias or messages,
+as well as generic handling of chats/channels.
This library works best with **.NET 5.0+** (faster, no dependencies) and is also available for **.NET Standard 2.0** (.NET Framework 4.6.1+ & .NET Core 2.0+) and **Xamarin/Mono.Android**
@@ -200,10 +201,10 @@ This library can be used for any Telegram scenarios including:
It has been tested in a Console app, [in Windows Forms](https://github.com/wiz0u/WTelegramClient/raw/master/Examples/WinForms_app.zip),
[in ASP.NET webservice](https://github.com/wiz0u/WTelegramClient/raw/master/Examples/ASPnet_webapp.zip), and in Xamarin/Android.
-Please don't use this library for Spam or Scam. Respect Telegram [Terms of Service](https://telegram.org/tos)
+Don't use this library for Spam or Scam. Respect Telegram [Terms of Service](https://telegram.org/tos)
as well as the [API Terms of Service](https://core.telegram.org/api/terms) or you might get banned from Telegram servers.
Developers feedback is welcome in the Telegram support group [@WTelegramClient](https://t.me/WTelegramClient)
You can also check our [📖 Frequently Asked Questions](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md) for more help and troubleshooting guide.
-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, please [consider a donation](http://t.me/WTelegramBot?start=donate) ❤ This will help the project keep going.
diff --git a/src/Client.Helpers.cs b/src/Client.Helpers.cs
index 3ef85f2..6fe1510 100644
--- a/src/Client.Helpers.cs
+++ b/src/Client.Helpers.cs
@@ -580,13 +580,19 @@ namespace WTelegram
}
private const string OnlyChatChannel = "This method works on Chat & Channel only";
- public Task AddChatUser(InputPeer peer, InputUserBase user, int fwd_limit = int.MaxValue) => peer switch
+ /// Generic helper: Adds a single user to a Chat or Channel See
and Possible codes: 400,403
+ /// Chat/Channel
+ /// User to be added
+ public Task AddChatUser(InputPeer peer, InputUserBase user) => peer switch
{
- InputPeerChat chat => this.Messages_AddChatUser(chat.chat_id, user, fwd_limit),
+ InputPeerChat chat => this.Messages_AddChatUser(chat.chat_id, user, int.MaxValue),
InputPeerChannel channel => this.Channels_InviteToChannel(channel, new[] { user }),
_ => throw new ArgumentException(OnlyChatChannel),
};
+ /// Generic helper: Kick a user from a Chat or Channel [bots: ✓] See
and Possible codes: 400,403
+ /// Chat/Channel
+ /// User to be removed
public Task DeleteChatUser(InputPeer peer, InputUser user) => peer switch
{
InputPeerChat chat => this.Messages_DeleteChatUser(chat.chat_id, user, true),
@@ -594,6 +600,8 @@ namespace WTelegram
_ => throw new ArgumentException(OnlyChatChannel),
};
+ /// Generic helper: Leave a Chat or Channel [bots: ✓] See
and Possible codes: 400,403
+ /// Chat/Channel to leave
public Task LeaveChat(InputPeer peer) => peer switch
{
InputPeerChat chat => this.Messages_DeleteChatUser(chat.chat_id, InputUser.Self, true),
@@ -601,6 +609,10 @@ namespace WTelegram
_ => throw new ArgumentException(OnlyChatChannel),
};
+ /// Generic helper: Make a user admin in a Chat or Channel See
and [bots: ✓] Possible codes: 400,403,406
+ /// Chat/Channel
+ /// The user to make admin
+ /// Whether to make them admin
public async Task EditChatAdmin(InputPeer peer, InputUserBase user, bool is_admin)
{
switch (peer)
@@ -617,6 +629,9 @@ namespace WTelegram
}
}
+ /// Generic helper: Change the photo of a Chat or Channel [bots: ✓] See
and Possible codes: 400,403
+ /// Chat/Channel
+ /// New photo
public Task EditChatPhoto(InputPeer peer, InputChatPhotoBase photo) => peer switch
{
InputPeerChat chat => this.Messages_EditChatPhoto(chat.chat_id, photo),
@@ -624,6 +639,9 @@ namespace WTelegram
_ => throw new ArgumentException(OnlyChatChannel),
};
+ /// Generic helper: Edit the name of a Chat or Channel [bots: ✓] See
and Possible codes: 400,403
+ /// Chat/Channel
+ /// New name
public Task EditChatTitle(InputPeer peer, string title) => peer switch
{
InputPeerChat chat => this.Messages_EditChatTitle(chat.chat_id, title),
@@ -631,6 +649,8 @@ namespace WTelegram
_ => throw new ArgumentException(OnlyChatChannel),
};
+ /// Get full info about a Chat or Channel [bots: ✓] See
and Possible codes: 400,403,406
+ /// Chat/Channel
public Task GetFullChat(InputPeer peer) => peer switch
{
InputPeerChat chat => this.Messages_GetFullChat(chat.chat_id),
@@ -638,6 +658,8 @@ namespace WTelegram
_ => throw new ArgumentException(OnlyChatChannel),
};
+ /// Generic helper: Delete a Chat or Channel See
and Possible codes: 400,403,406
+ /// Chat/Channel to delete
public async Task DeleteChat(InputPeer peer)
{
switch (peer)
@@ -653,20 +675,23 @@ namespace WTelegram
}
}
+ /// Generic helper: Get individual messages by IDs [bots: ✓] See
and Possible codes: 400
+ /// User/Chat/Channel
+ /// IDs of messages to get
public Task GetMessages(InputPeer peer, params InputMessage[] id)
=> peer is InputPeerChannel channel ? this.Channels_GetMessages(channel, id) : this.Messages_GetMessages(id);
+ /// Generic helper: Delete messages by IDs [bots: ✓]
Messages are deleted for all participants See
and Possible codes: 400,403
+ /// User/Chat/Channel
+ /// IDs of messages to delete
public Task DeleteMessages(InputPeer peer, params int[] id)
- => peer is InputPeerChannel channel ? this.Channels_DeleteMessages(channel, id) : this.Messages_DeleteMessages(id);
+ => peer is InputPeerChannel channel ? this.Channels_DeleteMessages(channel, id) : this.Messages_DeleteMessages(id, true);
- /// Marks message history as read. See
and Possible codes: 400 (details)
- /// Target user, channel or group
+ /// Generic helper: Marks message history as read. See
and Possible codes: 400
+ /// User/Chat/Channel
/// 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 switch
- {
- InputPeerChannel channel => await this.Channels_ReadHistory(channel, max_id),
- _ => (await this.Messages_ReadHistory(peer, max_id)) != null
- };
+ 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;
#endregion
}
}
From fd593b429ae37c702580676788159a81c2eb546f Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Sun, 20 Nov 2022 17:15:57 +0100
Subject: [PATCH 019/336] InputPeer.ID & MessageBase.ToString helpers. Publish
pre-releases on nuget now
---
.github/dev.yml | 8 ++++----
EXAMPLES.md | 8 +++++---
FAQ.md | 18 +++++++++---------
README.md | 2 +-
src/TL.Helpers.cs | 37 ++++++++++++++++++++++++++++++-------
src/TL.Schema.cs | 12 ++++++------
src/WTelegramClient.csproj | 3 ++-
7 files changed, 57 insertions(+), 31 deletions(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index d26fff4..994f6ad 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -25,14 +25,14 @@ steps:
includesymbols: true
versioningScheme: 'byEnvVar'
versionEnvVar: 'Build.BuildNumber'
- buildProperties: 'NoWarn="0419;1573;1591";Version=$(Build.BuildNumber);ContinuousIntegrationBuild=true;ReleaseNotes="$(ReleaseNotes)"'
+ buildProperties: 'NoWarn="0419;1573;1591";Version=$(Build.BuildNumber);ContinuousIntegrationBuild=true;ReleaseNotes="$(Build.SourceVersionMessage)"'
# buildProperties: 'NoWarn="0419;1573;1591";AllowedOutputExtensionsInPackageBuildOutputFolder=".dll;.xml;.pdb"'
- task: NuGetCommand@2
inputs:
command: 'push'
- packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.*upkg'
+ packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg'
publishPackageMetadata: true
- nuGetFeedType: 'internal'
- publishVstsFeed: 'WTelegramClient/WTelegramClient'
+ nuGetFeedType: 'external'
+ publishFeedCredentials: 'nuget.org'
diff --git a/EXAMPLES.md b/EXAMPLES.md
index d8fc6dc..1e26e97 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -88,12 +88,14 @@ foreach (Dialog dialog in dialogs.dialogs)
case User user when user.IsActive: Console.WriteLine("User " + user); break;
case ChatBase chat when chat.IsActive: Console.WriteLine(chat); break;
}
- //var latestMsg = dialogs.messages.FirstOrDefault(m => m.Peer.ID == dialog.Peer.ID && m.ID == dialog.TopMessage);
+ //var latestMsg = dialogs.messages.FirstOrDefault(m => m.Peer.ID == dialog.Peer.ID && m.ID == dialog.TopMessage);
}
```
-*Note: the lists returned by Messages_GetAllDialogs contains the `access_hash` for those chats and users.*
-See also the `Main` method in [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
+Notes:
+- The lists returned by Messages_GetAllDialogs contains the `access_hash` for those chats and users.
+- See also the `Main` method in [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
+- To retrieve the dialog information about a specific [peer](README.md#terminology), use `client.Messages_GetPeerDialogs(inputPeer)`
### List all chats (groups/channels NOT users) that we joined and send a message to one
diff --git a/FAQ.md b/FAQ.md
index 9a1c8d8..fcb3789 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -283,15 +283,15 @@ Here are the recommended actions to fix your problem:
- Save, close Notepad and reopen your project in Visual Studio
- If you still have issues on some `foreach` constructs, add this class somewhere in your project:
```csharp
- static class Extensions
- {
- public static void Deconstruct(this KeyValuePair tuple, out T1 key, out T2 value)
- {
- key = tuple.Key;
- value = tuple.Value;
- }
- }
- ```
+ static class Extensions
+ {
+ public static void Deconstruct(this KeyValuePair tuple, out T1 key, out T2 value)
+ {
+ key = tuple.Key;
+ value = tuple.Value;
+ }
+ }
+ ```
Also, remember to add a `using TL;` at the top of your files to have access to all the Telegram API methods.
diff --git a/README.md b/README.md
index 28e6757..d173cc5 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
[](https://www.nuget.org/packages/WTelegramClient/)
[](https://dev.azure.com/wiz0u/WTelegramClient/_build?definitionId=7)
[](https://corefork.telegram.org/methods)
-[](https://dev.azure.com/wiz0u/WTelegramClient/_artifacts/feed/WTelegramClient/NuGet/WTelegramClient)
+[](https://dev.azure.com/wiz0u/WTelegramClient/_artifacts/feed/WTelegramClient/NuGet/WTelegramClient)
[](https://t.me/WTelegramClient)
[](http://t.me/WTelegramBot?start=donate)
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index 3bf8380..506b52d 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -15,29 +15,48 @@ namespace TL
InputPeer ToInputPeer();
}
- partial class InputPeer { public static InputPeerSelf Self => new(); }
+ partial class InputPeer
+ {
+ public static readonly InputPeerSelf Self = new();
+ public abstract long ID { get; }
+ }
+ partial class InputPeerSelf
+ {
+ public override long ID => 0;
+ }
partial class InputPeerChat
{
/// ⚠ Only for small private Chat. Chat groups of type Channel must use InputPeerChannel. See Terminology in README
/// Chat identifier
public InputPeerChat(long chat_id) => this.chat_id = chat_id;
internal InputPeerChat() { }
+ public override long ID => chat_id;
}
partial class InputPeerUser
{
/// User identifier
- /// ⚠ REQUIRED FIELD. See FAQ for how to obtain it
access_hash value from the constructor
+ /// ⚠ REQUIRED FIELD. See FAQ for how to obtain it
access_hash value from the structure
public InputPeerUser(long user_id, long access_hash) { this.user_id = user_id; this.access_hash = access_hash; }
internal InputPeerUser() { }
public static implicit operator InputUser(InputPeerUser user) => new(user.user_id, user.access_hash);
+ public override long ID => user_id;
}
partial class InputPeerChannel
{
/// Channel identifier
- /// ⚠ REQUIRED FIELD. See FAQ for how to obtain it
access_hash value from the constructor
+ /// ⚠ REQUIRED FIELD. See FAQ for how to obtain it
access_hash value from the structure
public InputPeerChannel(long channel_id, long access_hash) { this.channel_id = channel_id; this.access_hash = access_hash; }
internal InputPeerChannel() { }
public static implicit operator InputChannel(InputPeerChannel channel) => new(channel.channel_id, channel.access_hash);
+ public override long ID => channel_id;
+ }
+ partial class InputPeerUserFromMessage
+ {
+ public override long ID => user_id;
+ }
+ partial class InputPeerChannelFromMessage
+ {
+ public override long ID => channel_id;
}
partial class InputUserBase { public abstract long? UserId { get; } }
@@ -48,7 +67,7 @@ namespace TL
public override long? UserId => user_id;
public static InputUserSelf Self => new();
/// User identifier
- /// ⚠ REQUIRED FIELD. See FAQ for how to obtain it
access_hash value from the constructor
+ /// ⚠ REQUIRED FIELD. See FAQ for how to obtain it
access_hash value from the structure
public InputUser(long user_id, long access_hash) { this.user_id = user_id; this.access_hash = access_hash; }
internal InputUser() { }
public static implicit operator InputPeerUser(InputUser user) => new(user.user_id, user.access_hash);
@@ -138,8 +157,8 @@ namespace TL
}
- /// a null value means userStatusEmpty = last seen a long time ago, more than a month (this is also always shown to blocked users)
- partial class UserStatus { /// An estimation of the number of days ago the user was last seen (online=0, recently=1, lastWeek=5, lastMonth=20)
= null means a long time ago, more than a month (this is also always shown to blocked users)
+ /// a null value means userStatusEmpty = last seen a long time ago, more than a month (this is also always shown for blocked/deleted users)
+ partial class UserStatus { /// An estimation of the number of days ago the user was last seen (online=0, recently=1, lastWeek=5, lastMonth=20)
= null means a long time ago, more than a month (this is also always shown for blocked/deleted users)
public abstract TimeSpan LastSeenAgo { get; } }
partial class UserStatusOnline { public override TimeSpan LastSeenAgo => TimeSpan.Zero; }
partial class UserStatusOffline { public override TimeSpan LastSeenAgo => DateTime.UtcNow - new DateTime((was_online + 62135596800L) * 10000000, DateTimeKind.Utc); }
@@ -218,6 +237,10 @@ namespace TL
partial class ChatParticipantsForbidden { public override ChatParticipantBase[] Participants => Array.Empty(); }
partial class ChatParticipants { public override ChatParticipantBase[] Participants => participants; }
+ partial class MessageEmpty { public override string ToString() => "(no message)"; }
+ partial class Message { public override string ToString() => $"{(from_id ?? peer_id)?.ID}> {message} {media}"; }
+ partial class MessageService { public override string ToString() => $"{(from_id ?? peer_id)?.ID} [{action.GetType().Name[13..]}]"; }
+
partial class MessageMedia { ///Use this helper method to send a copy of the media without downloading it
///Quiz poll may need to be voted before obtaining the correct answers. Dice will not replicate same value. TTL ignored
May return for Invoice and other unsupported media types
public virtual InputMedia ToInputMedia() => null; }
@@ -463,7 +486,7 @@ namespace TL
partial class InputChannel
{
/// Channel identifier
- /// ⚠ REQUIRED FIELD. See FAQ for how to obtain it
access_hash value from the constructor
+ /// ⚠ REQUIRED FIELD. See FAQ for how to obtain it
access_hash value from the structure
public InputChannel(long channel_id, long access_hash) { this.channel_id = channel_id; this.access_hash = access_hash; }
internal InputChannel() { }
public static implicit operator InputPeerChannel(InputChannel channel) => new(channel.channel_id, channel.access_hash);
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index a9026f8..4d66f08 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -36,7 +36,7 @@ namespace TL
public abstract partial class InputPeer : IObject { }
/// Defines the current user. See
[TLDef(0x7DA07EC9)]
- public class InputPeerSelf : InputPeer { }
+ public partial class InputPeerSelf : InputPeer { }
/// Defines a chat for further interaction. See
[TLDef(0x35A95CB9)]
public partial class InputPeerChat : InputPeer
@@ -64,7 +64,7 @@ namespace TL
}
/// Defines a min user that was seen in a certain message of a certain chat. See
[TLDef(0xA87B0A1C)]
- public class InputPeerUserFromMessage : InputPeer
+ public partial class InputPeerUserFromMessage : InputPeer
{
/// The chat where the user was seen
public InputPeer peer;
@@ -75,7 +75,7 @@ namespace TL
}
/// Defines a min channel that was seen in a certain message of a certain chat. See
[TLDef(0xBD2A0840)]
- public class InputPeerChannelFromMessage : InputPeer
+ public partial class InputPeerChannelFromMessage : InputPeer
{
/// The chat where the channel's message was seen
public InputPeer peer;
@@ -1496,7 +1496,7 @@ namespace TL
}
/// Empty constructor, non-existent message. See
[TLDef(0x90A6CA84)]
- public class MessageEmpty : MessageBase
+ public partial class MessageEmpty : MessageBase
{
/// Flags, see TL conditional fields
public Flags flags;
@@ -1518,7 +1518,7 @@ namespace TL
}
/// A message See
[TLDef(0x38116EE0)]
- public class Message : MessageBase
+ public partial class Message : MessageBase
{
/// Flags, see TL conditional fields
public Flags flags;
@@ -1632,7 +1632,7 @@ namespace TL
}
/// Indicates a service message See
[TLDef(0x2B085862)]
- public class MessageService : MessageBase
+ public partial class MessageService : MessageBase
{
/// Flags, see TL conditional fields
public Flags flags;
diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj
index 51eaaab..eccde27 100644
--- a/src/WTelegramClient.csproj
+++ b/src/WTelegramClient.csproj
@@ -42,7 +42,8 @@
-
From 11238550d313c90130dfb519f512a0de876b3e91 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Wed, 23 Nov 2022 14:18:07 +0100
Subject: [PATCH 020/336] Upgrade to layer 149: More Topics stuff
---
EXAMPLES.md | 2 +-
FAQ.md | 23 +++++++++++++----------
README.md | 8 +++-----
src/TL.Schema.cs | 23 +++++++++++++++++++----
src/TL.SchemaFuncs.cs | 22 ++++++++++++++++++++++
src/TL.Table.cs | 7 ++++---
6 files changed, 62 insertions(+), 23 deletions(-)
diff --git a/EXAMPLES.md b/EXAMPLES.md
index 1e26e97..c777b70 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -47,7 +47,7 @@ The `lvl` argument correspond to standard [LogLevel values](https://learn.micros
### Send a message to someone by @username
```csharp
-var resolved = await client.Contacts_ResolveUsername("MyEch0_Bot"); // username without the @
+var resolved = await client.Contacts_ResolveUsername("JsonDumpBot"); // username without the @
await client.SendMessageAsync(resolved, "/start");
```
*Note: This also works if the @username points to a channel/group, but you must already have joined that channel before sending a message to it.
diff --git a/FAQ.md b/FAQ.md
index fcb3789..b703c0b 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -72,13 +72,11 @@ You can then retrieve it with `client.GetAccessHashFor
-#### 5. I need to test a feature that has been developed but not yet released in WTelegramClient nuget
+#### 5. I need to test a feature that has been recently developed but seems not available in my program
-The developmental versions of the library are available through Azure DevOps as part of the Continuous Integration builds after each Github commit.
+The developmental versions of the library are now available as **pre-release** on Nuget (with `-dev` in the version number)
-You can access these versions for testing in your program by going to our [private nuget feeds](https://dev.azure.com/wiz0u/WTelegramClient/_artifacts/feed/WTelegramClient/NuGet/WTelegramClient),
-click on button "Connect to feed" and follow the steps to setup your dev environment.
-After that, you should be able to see/install the pre-release versions in your Nuget package manager and install them in your application. *(make sure you enable the **pre-release** checkbox)*
+So make sure you tick the checkbox "Include prerelease" in Nuget manager and/or navigate to the Versions list then select the highest `x.x.x-dev.x` version to install in your program.
#### 6. Telegram asks me to signup (firstname, lastname) even for an existing account
@@ -307,14 +305,19 @@ So you can either:
- Build your code in RELEASE mode
- Modify your config callback to reply to "server_address" with the IP address of Telegram production servers (as found on your API development tools)
-2) Did you call `LoginUserIfNeeded()`?
-If you don't authenticate as a user (or bot), you have access to a very limited subset of Telegram APIs
+2) Did you call `Login` or `LoginUserIfNeeded` succesfully?
+If you don't complete authentication as a user (or bot), you have access to a very limited subset of Telegram APIs.
+Make sure your calls succeed and don't throw an exception.
3) Did you use `await` with every Client methods?
-This library is completely Task-based. You should learn, understand and use the [asynchronous model of C# programming](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/) before proceeding further.
+This library is completely Task-based. You should learn, understand and use the [asynchronous model of C# programming](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/) before proceeding further.
+Using `.Result` or `.Wait()` can lead to deadlocks.
4) Is your program ending immediately instead of waiting for Updates?
-Your program must be running/waiting continuously in order for the background Task to receive and process the Updates. So make sure your main program doesn't end immediately. For a console program, this is typical done by waiting for a key or some close event.
+Your program must be running/waiting continuously in order for the background Task to receive and process the Updates.
+So make sure your main program doesn't end immediately or dispose the client too soon (via `using`?).
+For a console program, this is typical done by waiting for a key or some close event.
5) Is every Telegram API call rejected? (typically with an exception message like `AUTH_RESTART`)
-The user authentification might have failed at some point (or the user revoked the authorization). It is therefore necessary to go through the authentification again. This can be done by deleting the WTelegram.session file, or at runtime by calling `client.Reset()`
+The user authentification might have failed at some point (or the user revoked the authorization).
+It is therefore necessary to go through the authentification again. This can be done by deleting the WTelegram.session file, or at runtime by calling `client.Reset()`
diff --git a/README.md b/README.md
index d173cc5..1db4148 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,6 @@
[](https://www.nuget.org/packages/WTelegramClient/)
[](https://dev.azure.com/wiz0u/WTelegramClient/_build?definitionId=7)
-[](https://corefork.telegram.org/methods)
-[](https://dev.azure.com/wiz0u/WTelegramClient/_artifacts/feed/WTelegramClient/NuGet/WTelegramClient)
-[](https://t.me/WTelegramClient)
+[](https://corefork.telegram.org/methods)
[](http://t.me/WTelegramBot?start=donate)
## _Telegram Client API library written 100% in C# and .NET Standard_
@@ -204,7 +202,7 @@ It has been tested in a Console app, [in Windows Forms](https://github.com/wiz0u
Don't use this library for Spam or Scam. Respect Telegram [Terms of Service](https://telegram.org/tos)
as well as the [API Terms of Service](https://core.telegram.org/api/terms) or you might get banned from Telegram servers.
-Developers feedback is welcome in the Telegram support group [@WTelegramClient](https://t.me/WTelegramClient)
-You can also check our [📖 Frequently Asked Questions](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md) for more help and troubleshooting guide.
+If you read all this ReadMe, the [Frequently Asked Questions](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md),
+the [Examples codes](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md) 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.
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index 4d66f08..b7fab60 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -2974,7 +2974,7 @@ namespace TL
}
}
/// Channel messages See
- [TLDef(0x64479808)]
+ [TLDef(0xC776BA4E)]
public partial class Messages_ChannelMessages : Messages_MessagesBase, IPeerResolver
{
/// Flags, see TL conditional fields
@@ -2987,6 +2987,7 @@ namespace TL
[IfFlag(2)] public int offset_id_offset;
/// Found messages
public MessageBase[] messages;
+ public ForumTopicBase[] topics;
/// Chats
public Dictionary chats;
/// Users
@@ -4366,16 +4367,29 @@ namespace TL
public MessageExtendedMediaBase extended_media;
}
/// See
- [TLDef(0xF694B0AE)]
+ [TLDef(0x192EFBE3)]
public class UpdateChannelPinnedTopic : Update
{
public Flags flags;
public long channel_id;
- [IfFlag(0)] public int topic_id;
+ public int topic_id;
[Flags] public enum Flags : uint
{
- has_topic_id = 0x1,
+ pinned = 0x1,
+ }
+ }
+ /// See
+ [TLDef(0xFE198602)]
+ public class UpdateChannelPinnedTopics : Update
+ {
+ public Flags flags;
+ public long channel_id;
+ [IfFlag(0)] public int[] order;
+
+ [Flags] public enum Flags : uint
+ {
+ has_order = 0x1,
}
}
@@ -13857,6 +13871,7 @@ namespace TL
closed = 0x4,
pinned = 0x8,
has_draft = 0x10,
+ short = 0x20,
}
public override int ID => id;
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index 5eb402f..b2d4701 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -4296,6 +4296,15 @@ namespace TL
top_msg_id = top_msg_id,
});
+ /// See
+ public static Task Channels_ReorderPinnedForumTopics(this Client client, InputChannelBase channel, int[] order, bool force = false)
+ => client.Invoke(new Channels_ReorderPinnedForumTopics
+ {
+ flags = (Channels_ReorderPinnedForumTopics.Flags)(force ? 0x1 : 0),
+ channel = channel,
+ order = order,
+ });
+
/// Sends a custom request; for bots only See [bots: ✓] Possible codes: 400,403 (details)
/// The method name
/// JSON-serialized method parameters
@@ -8529,6 +8538,19 @@ namespace TL.Methods
public int top_msg_id;
}
+ [TLDef(0x2950A18F)]
+ public class Channels_ReorderPinnedForumTopics : IMethod
+ {
+ public Flags flags;
+ public InputChannelBase channel;
+ public int[] order;
+
+ [Flags] public enum Flags : uint
+ {
+ force = 0x1,
+ }
+ }
+
[TLDef(0xAA2769ED)]
public class Bots_SendCustomRequest : IMethod
{
diff --git a/src/TL.Table.cs b/src/TL.Table.cs
index 50a3c11..d991db7 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 = 148; // fetched 01/11/2022 17:33:23
+ public const int Version = 149; // fetched 23/11/2022 13:15:45
internal const int SecretChats = 144;
internal const int MTProto2 = 73;
internal const uint VectorCtor = 0x1CB5C415;
@@ -233,7 +233,7 @@ namespace TL
[0xF0E3E596] = typeof(Messages_DialogsNotModified),
[0x8C718E87] = typeof(Messages_Messages),
[0x3A54685E] = typeof(Messages_MessagesSlice),
- [0x64479808] = typeof(Messages_ChannelMessages),
+ [0xC776BA4E] = typeof(Messages_ChannelMessages),
[0x74535F21] = typeof(Messages_MessagesNotModified),
[0x64FF9FD5] = typeof(Messages_Chats),
[0x9CD81144] = typeof(Messages_ChatsSlice),
@@ -363,7 +363,8 @@ namespace TL
[0x6F7863F4] = typeof(UpdateRecentReactions),
[0x86FCCF85] = typeof(UpdateMoveStickerSetToTop),
[0x5A73A98C] = typeof(UpdateMessageExtendedMedia),
- [0xF694B0AE] = typeof(UpdateChannelPinnedTopic),
+ [0x192EFBE3] = typeof(UpdateChannelPinnedTopic),
+ [0xFE198602] = typeof(UpdateChannelPinnedTopics),
[0xA56C2A3E] = typeof(Updates_State),
[0x5D75A138] = typeof(Updates_DifferenceEmpty),
[0x00F49CA0] = typeof(Updates_Difference),
From 898523346b06cd396aeac4b72bec250f42cea6ed Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Wed, 23 Nov 2022 14:28:25 +0100
Subject: [PATCH 021/336] build fix | Upgrade to layer 149: More Topics stuff
---
src/TL.Schema.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index b7fab60..8a7851b 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -13871,7 +13871,7 @@ namespace TL
closed = 0x4,
pinned = 0x8,
has_draft = 0x10,
- short = 0x20,
+ short_ = 0x20,
}
public override int ID => id;
From a8d6656c0548f0cdc337e51de0efec79e36b7b2c Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Sat, 26 Nov 2022 14:16:52 +0100
Subject: [PATCH 022/336] Using Github pages. Added User.IsBot helper
---
.github/dev.yml | 2 +-
EXAMPLES.md | 2 +-
FAQ.md | 4 ++--
README.md | 26 +++++++++++------------
src/TL.Helpers.cs | 17 ++++++++-------
src/TL.Schema.cs | 48 +++++++++++++++++++++----------------------
src/TL.SchemaFuncs.cs | 38 +++++++++++++++++-----------------
7 files changed, 68 insertions(+), 69 deletions(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index 994f6ad..31ee239 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -2,7 +2,7 @@ pr: none
trigger:
- master
-name: 3.1.3-dev.$(Rev:r)
+name: 3.1.4-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/EXAMPLES.md b/EXAMPLES.md
index c777b70..2fcc816 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -379,7 +379,7 @@ await client.Messages_ImportChatInvite("HASH"); // join the channel/group
var chats = await client.Messages_GetAllChats();
var chat = chats.chats[1234567890]; // the target chat
```
-After the above code, once you [have obtained](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#access-hash) an `InputUser` or `User`, you can:
+After the above code, once you [have obtained](FAQ.md#access-hash) an `InputUser` or `User`, you can:
```csharp
// • Directly add the user to a Chat/Channel/group:
await client.AddChatUser(chat, user);
diff --git a/FAQ.md b/FAQ.md
index b703c0b..36f03c5 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -45,7 +45,7 @@ and when the user has provided the verification_code through your app, you "set"
Another solution is to use the [alternative login method](README.md#alternative-simplified-configuration--login),
calling `client.Login(...)` as the user provides the requested configuration elements.
-You can download such full example apps [for WinForms](https://github.com/wiz0u/WTelegramClient/raw/master/Examples/WinForms_app.zip) and [for ASP.NET](https://github.com/wiz0u/WTelegramClient/raw/master/Examples/ASPnet_webapp.zip)
+You can download such full example apps [for WinForms](Examples/WinForms_app.zip) and [for ASP.NET](Examples/ASPnet_webapp.zip)
#### 4. How to use IDs? Where to get the access_hash? Why the error `CHANNEL_INVALID` or `USER_ID_INVALID`?
@@ -301,7 +301,7 @@ Here is a list of common issues and how to fix them so that your program work co
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)).
So you can either:
- - **Recommended:** Use the [official Nuget package](https://www.nuget.org/packages/WTelegramClient) or the [private nuget feed of development builds](https://dev.azure.com/wiz0u/WTelegramClient/_artifacts/feed/WTelegramClient/NuGet/WTelegramClient)
+ - **Recommended:** Use the [official Nuget package](https://www.nuget.org/packages/WTelegramClient)
- Build your code in RELEASE mode
- Modify your config callback to reply to "server_address" with the IP address of Telegram production servers (as found on your API development tools)
diff --git a/README.md b/README.md
index 1db4148..88d7368 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
+[](https://corefork.telegram.org/methods)
[](https://www.nuget.org/packages/WTelegramClient/)
[](https://dev.azure.com/wiz0u/WTelegramClient/_build?definitionId=7)
-[](https://corefork.telegram.org/methods)
[](http://t.me/WTelegramBot?start=donate)
## _Telegram Client API library written 100% in C# and .NET Standard_
@@ -76,7 +76,7 @@ There are other configuration items that are queried to your method but returnin
Those shown above are the only ones that have no default values and should be provided by your method.
Returning `null` for verification_code or password will show a prompt for console apps, or an error otherwise
-*(see [FAQ #3](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#GUI) for WinForms)*
+*(see [FAQ #3](https://wiz0u.github.io/WTelegramClient/FAQ#GUI) for WinForms)*
Returning `""` for verification_code requests the resending of the code through another system (SMS or Call).
Another simple approach is to pass `Environment.GetEnvironmentVariable` as the config callback and define the configuration items as environment variables
@@ -108,7 +108,7 @@ async Task DoLogin(string loginInfo) // (add this method to your code)
With this method, you can choose in some cases to interrupt the login loop via a `return` instead of `break`, and resume it later
by calling `DoLogin(requestedCode)` again once you've obtained the requested code/password/etc...
-See [WinForms example](https://github.com/wiz0u/WTelegramClient/raw/master/Examples/WinForms_app.zip) and [ASP.NET example](https://github.com/wiz0u/WTelegramClient/raw/master/Examples/ASPnet_webapp.zip)
+See [WinForms example](https://wiz0u.github.io/WTelegramClient/Examples/WinForms_app.zip) and [ASP.NET example](https://wiz0u.github.io/WTelegramClient/Examples/ASPnet_webapp.zip)
# Example of API call
@@ -148,9 +148,9 @@ Console.WriteLine($"Sending a message in chat {chatId}: {target.Title}");
await client.SendMessageAsync(target, "Hello, World");
```
-➡️ You can find lots of useful code snippets in [EXAMPLES.md](https://github.com/wiz0u/WTelegramClient/blob/master/EXAMPLES.md)
+➡️ 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).
-➡️ Check [the FAQ](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#compile) if example codes doesn't compile correctly on your machine, or other troubleshooting.
+➡️ Check [the FAQ](https://wiz0u.github.io/WTelegramClient/FAQ#compile) if example codes doesn't compile correctly on your machine, or other troubleshooting.
# Terminology in Telegram Client API
@@ -165,14 +165,14 @@ or a [broadcast channel](https://corefork.telegram.org/api/channel#channels) (th
- `Peer` : Either a `Chat`, a `Channel` or a `User`
- Dialog : Status of chat with a `Peer` *(draft, last message, unread count, pinned...)*. It represents each line from your Telegram chat list.
- Access Hash : Telegram requires you to provide a specific `access_hash` for users, channels, and other resources before interacting with them.
-See [FAQ #4](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#access-hash) to learn more about it.
+See [FAQ #4](https://wiz0u.github.io/WTelegramClient/FAQ#access-hash) to learn more about it.
- DC (DataCenter) : There are a few datacenters depending on where in the world the user (or an uploaded media file) is from.
- Session or Authorization : Pairing between a device and a phone number. You can have several active sessions for the same phone number.
# Other things to know
The Client class also offers an `OnUpdate` event that is triggered when Telegram servers sends Updates (like new messages or status), independently of your API requests.
-See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs)
+See [Examples/Program_ListenUpdates.cs](https://wiz0u.github.io/WTelegramClient/Examples/Program_ListenUpdates.cs)
An invalid API request can result in a `RpcException` being raised, reflecting the [error code and status text](https://revgram.github.io/errors.html) of the problem.
@@ -191,18 +191,18 @@ This library works best with **.NET 5.0+** (faster, no dependencies) and is also
# Library uses and limitations
This library can be used for any Telegram scenarios including:
- Sequential or parallel automated steps based on API requests/responses
-- Real-time [monitoring](https://github.com/wiz0u/WTelegramClient/blob/master/EXAMPLES.md#updates) of incoming Updates/Messages
+- Real-time [monitoring](https://wiz0u.github.io/WTelegramClient/EXAMPLES#updates) of incoming Updates/Messages
- Download/upload of files/media
-- Exchange end-to-end encrypted messages/files in [Secret Chats](https://github.com/wiz0u/WTelegramClient/blob/master/EXAMPLES.md#e2e)
+- Exchange end-to-end encrypted messages/files in [Secret Chats](https://wiz0u.github.io/WTelegramClient/EXAMPLES#e2e)
- Building a full-featured interactive client
-It has been tested in a Console app, [in Windows Forms](https://github.com/wiz0u/WTelegramClient/raw/master/Examples/WinForms_app.zip),
-[in ASP.NET webservice](https://github.com/wiz0u/WTelegramClient/raw/master/Examples/ASPnet_webapp.zip), and in Xamarin/Android.
+It has been tested in a Console app, [in Windows Forms](https://wiz0u.github.io/WTelegramClient/Examples/WinForms_app.zip),
+[in ASP.NET webservice](https://wiz0u.github.io/WTelegramClient/Examples/ASPnet_webapp.zip), and in Xamarin/Android.
Don't use this library for Spam or Scam. Respect Telegram [Terms of Service](https://telegram.org/tos)
as well as the [API Terms of Service](https://core.telegram.org/api/terms) or you might get banned from Telegram servers.
-If you read all this ReadMe, the [Frequently Asked Questions](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md),
-the [Examples codes](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md) and still have questions, feedback is welcome in our Telegram group [@WTelegramClient](https://t.me/WTelegramClient)
+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.
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index 506b52d..baa60d3 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -148,6 +148,7 @@ 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 ToString() => username != null ? '@' + username : last_name == null ? first_name : $"{first_name} {last_name}";
public override InputPeer ToInputPeer() => new InputPeerUser(id, access_hash);
@@ -156,18 +157,16 @@ namespace TL
public TimeSpan LastSeenAgo => status?.LastSeenAgo ?? TimeSpan.FromDays(150);
}
-
- /// a null value means userStatusEmpty = last seen a long time ago, more than a month (this is also always shown for blocked/deleted users)
- partial class UserStatus { /// An estimation of the number of days ago the user was last seen (online=0, recently=1, lastWeek=5, lastMonth=20)
= null means a long time ago, more than a month (this is also always shown for blocked/deleted users)
- public abstract TimeSpan LastSeenAgo { get; } }
- partial class UserStatusOnline { public override TimeSpan LastSeenAgo => TimeSpan.Zero; }
- partial class UserStatusOffline { public override TimeSpan LastSeenAgo => DateTime.UtcNow - new DateTime((was_online + 62135596800L) * 10000000, DateTimeKind.Utc); }
+ /// a null value means userStatusEmpty = last seen a long time ago, more than a month (or blocked/deleted users)
+ partial class UserStatus { internal abstract TimeSpan LastSeenAgo { get; } }
+ partial class UserStatusOnline { internal override TimeSpan LastSeenAgo => TimeSpan.Zero; }
+ partial class UserStatusOffline { internal override TimeSpan LastSeenAgo => DateTime.UtcNow - new DateTime((was_online + 62135596800L) * 10000000, DateTimeKind.Utc); }
/// covers anything between 1 second and 2-3 days
- partial class UserStatusRecently { public override TimeSpan LastSeenAgo => TimeSpan.FromDays(1); }
+ partial class UserStatusRecently { internal override TimeSpan LastSeenAgo => TimeSpan.FromDays(1); }
/// between 2-3 and seven days
- partial class UserStatusLastWeek { public override TimeSpan LastSeenAgo => TimeSpan.FromDays(5); }
+ partial class UserStatusLastWeek { internal override TimeSpan LastSeenAgo => TimeSpan.FromDays(5); }
/// between 6-7 days and a month
- partial class UserStatusLastMonth { public override TimeSpan LastSeenAgo => TimeSpan.FromDays(20); }
+ partial class UserStatusLastMonth { internal override TimeSpan LastSeenAgo => TimeSpan.FromDays(20); }
partial class ChatBase : IPeerInfo
{
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index 8a7851b..1177959 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -50,7 +50,7 @@ namespace TL
{
/// User identifier
public long user_id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
access_hash value from the
+ /// ⚠ REQUIRED FIELD. See how to obtain it
access_hash value from the
public long access_hash;
}
/// Defines a channel for further interaction. See
@@ -59,7 +59,7 @@ namespace TL
{
/// Channel identifier
public long channel_id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
access_hash value from the
+ /// ⚠ REQUIRED FIELD. See how to obtain it
access_hash value from the
public long access_hash;
}
/// Defines a min user that was seen in a certain message of a certain chat. See
@@ -97,7 +97,7 @@ namespace TL
{
/// User identifier
public long user_id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
access_hash value from the
+ /// ⚠ REQUIRED FIELD. See how to obtain it
access_hash value from the
public long access_hash;
}
/// Defines a min user that was seen in a certain message of a certain chat. See
@@ -504,7 +504,7 @@ namespace TL
{
/// Photo identifier
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
access_hash value from the
+ /// ⚠ REQUIRED FIELD. See how to obtain it
access_hash value from the
public long access_hash;
/// File reference
public byte[] file_reference;
@@ -531,7 +531,7 @@ namespace TL
{
/// File ID, id parameter value from
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Checksum, access_hash parameter value from
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Checksum, access_hash parameter value from
public long access_hash;
}
/// Document location (video, voice, audio, basically every type except photo) See
@@ -540,7 +540,7 @@ namespace TL
{
/// Document ID
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
access_hash parameter from the
+ /// ⚠ REQUIRED FIELD. See how to obtain it
access_hash parameter from the
public long access_hash;
/// File reference
public byte[] file_reference;
@@ -553,7 +553,7 @@ namespace TL
{
/// File ID, id parameter value from
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Checksum, access_hash parameter value from
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Checksum, access_hash parameter value from
public long access_hash;
}
/// Empty constructor for takeout See
@@ -565,7 +565,7 @@ namespace TL
{
/// Photo ID, obtained from the object
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Photo's access hash, obtained from the object
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Photo's access hash, obtained from the object
public long access_hash;
/// File reference
public byte[] file_reference;
@@ -578,7 +578,7 @@ namespace TL
{
/// Photo ID
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash
public long access_hash;
/// File reference
public byte[] file_reference;
@@ -5112,7 +5112,7 @@ namespace TL
{
/// Chat ID
public int chat_id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Checking sum from constructor , or
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Checking sum from constructor , or
public long access_hash;
}
@@ -5162,7 +5162,7 @@ namespace TL
{
/// File ID, value of id parameter from
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Checking sum, value of access_hash parameter from
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Checking sum, value of access_hash parameter from
public long access_hash;
/// File ID, value of id parameter from
@@ -5287,7 +5287,7 @@ namespace TL
{
/// Document ID
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
access_hash parameter from the
+ /// ⚠ REQUIRED FIELD. See how to obtain it
access_hash parameter from the
public long access_hash;
/// File reference
public byte[] file_reference;
@@ -6192,7 +6192,7 @@ namespace TL
{
/// ID
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash
public long access_hash;
}
/// Stickerset by short name, from a stickerset deep link » See
@@ -6698,7 +6698,7 @@ namespace TL
{
/// Channel ID
public long channel_id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash taken from the
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash taken from the
public long access_hash;
/// Channel ID
@@ -7858,7 +7858,7 @@ namespace TL
public int dc_id;
/// ID of message, contains both the (32-bit, legacy) owner ID and the message ID, used only for Bot API backwards compatibility with 32-bit user ID.
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash of message
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash of message
public long access_hash;
/// DC ID to use when working with this inline message
@@ -7876,7 +7876,7 @@ namespace TL
public long owner_id;
/// ID of message
public int id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash of message
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash of message
public long access_hash;
/// DC ID to use when working with this inline message
@@ -8201,7 +8201,7 @@ namespace TL
{
/// game ID from constructor
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
access hash from constructor
+ /// ⚠ REQUIRED FIELD. See how to obtain it
access hash from constructor
public long access_hash;
}
/// Game by short name See
@@ -8891,7 +8891,7 @@ namespace TL
{
/// HTTP URL of file
public string url;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash
public long access_hash;
}
/// Used to download a server-generated image with the map preview from a , see the webfile docs for more info ». See
@@ -8900,7 +8900,7 @@ namespace TL
{
/// Generated from the lat, long and accuracy_radius parameters of the
public InputGeoPoint geo_point;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash of the
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash of the
public long access_hash;
/// Map width in pixels before applying scale; 16-1024
public int w;
@@ -9197,7 +9197,7 @@ namespace TL
{
/// Call ID
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash
public long access_hash;
}
@@ -10319,7 +10319,7 @@ namespace TL
{
/// Secure file ID
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Secure file access hash
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Secure file access hash
public long access_hash;
/// Secure file ID
@@ -11261,7 +11261,7 @@ namespace TL
{
/// Wallpaper ID
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash
public long access_hash;
}
/// Wallpaper by slug (a unique ID, obtained from a wallpaper link ») See
@@ -11589,7 +11589,7 @@ namespace TL
{
/// ID
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Access hash
public long access_hash;
}
/// Theme by theme ID See
@@ -12525,7 +12525,7 @@ namespace TL
{
/// Group call ID
public long id;
- /// ⚠ REQUIRED FIELD. See how to obtain it
Group call access hash
+ /// ⚠ REQUIRED FIELD. See how to obtain it
Group call access hash
public long access_hash;
}
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index b2d4701..93ac53c 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -97,7 +97,7 @@ namespace TL
/// Application identifier (see App configuration)
/// Application secret hash (see App configuration)
/// Settings for the code type to send
- [Obsolete("Use LoginUserIfNeeded instead of this method. See https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#tlsharp")]
+ [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)
=> client.Invoke(new Auth_SendCode
{
@@ -112,7 +112,7 @@ namespace TL
/// SMS-message ID
/// New user first name
/// New user last name
- [Obsolete("Use LoginUserIfNeeded instead of this method. See https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#tlsharp")]
+ [Obsolete("Use LoginUserIfNeeded instead of this method. See https://wiz0u.github.io/WTelegramClient/FAQ#tlsharp")]
public static Task Auth_SignUp(this Client client, string phone_number, string phone_code_hash, string first_name, string last_name)
=> client.Invoke(new Auth_SignUp
{
@@ -127,7 +127,7 @@ namespace TL
/// SMS-message ID, obtained from auth.sendCode
/// Valid numerical code from the SMS-message
/// Email verification code or token
- [Obsolete("Use LoginUserIfNeeded instead of this method. See https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#tlsharp")]
+ [Obsolete("Use LoginUserIfNeeded instead of this method. See https://wiz0u.github.io/WTelegramClient/FAQ#tlsharp")]
public static Task Auth_SignIn(this Client client, string phone_number, string phone_code_hash, string phone_code = null, EmailVerification email_verification = null)
=> client.Invoke(new Auth_SignIn
{
@@ -223,7 +223,7 @@ namespace TL
/// Resend the login code via another medium, the phone code type is determined by the return value of the previous auth.sendCode/auth.resendCode: see login for more info. See Possible codes: 400,406 (details)
/// The phone number
/// The phone code hash obtained from auth.sendCode
- [Obsolete("Use LoginUserIfNeeded instead of this method. See https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#tlsharp")]
+ [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)
=> client.Invoke(new Auth_ResendCode
{
@@ -234,7 +234,7 @@ namespace TL
/// Cancel the login verification code See Possible codes: 400,406 (details)
/// Phone number
/// Phone code hash from auth.sendCode
- [Obsolete("Use LoginUserIfNeeded instead of this method. See https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#tlsharp")]
+ [Obsolete("Use LoginUserIfNeeded instead of this method. See https://wiz0u.github.io/WTelegramClient/FAQ#tlsharp")]
public static Task Auth_CancelCode(this Client client, string phone_number, string phone_code_hash)
=> client.Invoke(new Auth_CancelCode
{
@@ -1282,7 +1282,7 @@ namespace TL
phone = phone,
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Returns the list of messages by their IDs. See [bots: ✓]
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Returns the list of messages by their IDs. See [bots: ✓]
/// Message ID list
public static Task Messages_GetMessages(this Client client, params InputMessage[] id)
=> client.Invoke(new Messages_GetMessages
@@ -1392,7 +1392,7 @@ namespace TL
max_date = max_date.GetValueOrDefault(),
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Deletes messages by their identifiers. See [bots: ✓] Possible codes: 400,403 (details)
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Deletes messages by their identifiers. See [bots: ✓] Possible codes: 400,403 (details)
/// Whether to delete messages for all participants of the chat
/// Message ID list
public static Task Messages_DeleteMessages(this Client client, int[] id, bool revoke = false)
@@ -1402,7 +1402,7 @@ namespace TL
id = id,
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Confirms receipt of messages by a client, cancels PUSH-notification sending. See
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Confirms receipt of messages by a client, cancels PUSH-notification sending. See
/// Maximum message ID available in a client.
public static Task Messages_ReceivedMessages(this Client client, int max_id = default)
=> client.Invoke(new Messages_ReceivedMessages
@@ -1540,7 +1540,7 @@ namespace TL
message = message,
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Returns chat basic info on their IDs. See [bots: ✓] Possible codes: 400 (details)
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Returns chat basic info on their IDs. See [bots: ✓] Possible codes: 400 (details)
/// List of chat IDs
public static Task Messages_GetChats(this Client client, params long[] id)
=> client.Invoke(new Messages_GetChats
@@ -1548,7 +1548,7 @@ namespace TL
id = id,
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Get full info about a basic group. See [bots: ✓] Possible codes: 400 (details)
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Get full info about a basic group. See [bots: ✓] Possible codes: 400 (details)
/// Basic group ID.
public static Task Messages_GetFullChat(this Client client, long chat_id)
=> client.Invoke(new Messages_GetFullChat
@@ -1556,7 +1556,7 @@ namespace TL
chat_id = chat_id,
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Changes chat name and sends a service message on it. See [bots: ✓] Possible codes: 400 (details)
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Changes chat name and sends a service message on it. See [bots: ✓] Possible codes: 400 (details)
/// Chat ID
/// New chat name, different from the old one
public static Task Messages_EditChatTitle(this Client client, long chat_id, string title)
@@ -1566,7 +1566,7 @@ namespace TL
title = title,
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Changes chat photo and sends a service message on it See [bots: ✓] Possible codes: 400 (details)
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Changes chat photo and sends a service message on it See [bots: ✓] Possible codes: 400 (details)
/// Chat ID
/// Photo to be set
public static Task Messages_EditChatPhoto(this Client client, long chat_id, InputChatPhotoBase photo)
@@ -1576,7 +1576,7 @@ namespace TL
photo = photo,
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Adds a user to a chat and sends a service message on it. See Possible codes: 400,403 (details)
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Adds a user to a chat and sends a service message on it. See Possible codes: 400,403 (details)
/// Chat ID
/// User ID to be added
/// Number of last messages to be forwarded
@@ -1588,7 +1588,7 @@ namespace TL
fwd_limit = fwd_limit,
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Deletes a user from a chat and sends a service message on it. See [bots: ✓] Possible codes: 400 (details)
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Deletes a user from a chat and sends a service message on it. See [bots: ✓] Possible codes: 400 (details)
/// Remove the entire chat history of the specified user in this chat.
/// Chat ID
/// User ID to be deleted
@@ -1732,7 +1732,7 @@ namespace TL
peer = peer,
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Notifies the sender about the recipient having listened a voice message or watched a video. See
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Notifies the sender about the recipient having listened a voice message or watched a video. See
/// Message ID list
public static Task Messages_ReadMessageContents(this Client client, params int[] id)
=> client.Invoke(new Messages_ReadMessageContents
@@ -1860,7 +1860,7 @@ namespace TL
increment = increment,
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Make a user admin in a basic group. See Possible codes: 400 (details)
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Make a user admin in a basic group. See Possible codes: 400 (details)
/// The ID of the group
/// The user to make admin
/// Whether to make them admin
@@ -1872,7 +1872,7 @@ namespace TL
is_admin = is_admin,
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Turn a basic group into a supergroup See Possible codes: 400,403 (details)
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Turn a basic group into a supergroup See Possible codes: 400,403 (details)
/// Basic group to migrate
public static Task Messages_MigrateChat(this Client client, long chat_id)
=> client.Invoke(new Messages_MigrateChat
@@ -2816,7 +2816,7 @@ namespace TL
top_msg_id = top_msg_id.GetValueOrDefault(),
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Delete a chat See Possible codes: 400 (details)
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Delete a chat See Possible codes: 400 (details)
/// Chat ID
public static Task Messages_DeleteChat(this Client client, long chat_id)
=> client.Invoke(new Messages_DeleteChat
@@ -3298,7 +3298,7 @@ namespace TL
platform = platform,
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Terminate webview interaction started with messages.requestWebView, sending the specified message to the chat on behalf of the user. See [bots: ✓] Possible codes: 400 (details)
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Terminate webview interaction started with messages.requestWebView, sending the specified message to the chat on behalf of the user. See [bots: ✓] Possible codes: 400 (details)
/// Webview interaction ID obtained from messages.requestWebView
/// Message to send
public static Task Messages_SendWebViewResultMessage(this Client client, string bot_query_id, InputBotInlineResultBase result)
From bd629e7384406951e6dc07518cf2cf962a7deb7a Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Sat, 26 Nov 2022 15:16:04 +0100
Subject: [PATCH 023/336] doc updates
---
EXAMPLES.md | 57 +++++++++++++++++++++++++++--------------------------
FAQ.md | 36 +++++++++++++++++----------------
2 files changed, 48 insertions(+), 45 deletions(-)
diff --git a/EXAMPLES.md b/EXAMPLES.md
index 2fcc816..88bf1de 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -1,4 +1,4 @@
-## Example programs using WTelegramClient
+# Example programs using WTelegramClient
For these examples to work as a fully-functional Program.cs, be sure to start with these lines:
```csharp
@@ -18,11 +18,12 @@ Remember that these are just simple example codes that you should adjust to your
In real production code, you might want to properly test the success of each operation or handle exceptions,
and avoid calling the same methods (like `Messages_GetAllChats`) repetitively.
-ℹ️ WTelegramClient covers 100% of Telegram Client API, much more than the examples below: check the [full API methods list](https://corefork.telegram.org/methods)!
-More examples can also be found in the [Examples folder](Examples) and in answers to [StackOverflow questions](https://stackoverflow.com/questions/tagged/wtelegramclient).
+➡️ Use Ctrl-F to search this page for the example matching your needs
+WTelegramClient covers 100% of Telegram Client API, much more than the examples below: check the [full API methods list](https://corefork.telegram.org/methods)!
+More examples can also be found in the [Examples folder](https://github.com/wiz0u/WTelegramClient/tree/master/Examples) and in answers to [StackOverflow questions](https://stackoverflow.com/questions/tagged/wtelegramclient).
-### Change logging settings
+## Change logging settings
By default, WTelegramClient logs are displayed on the Console screen.
If you are not in a Console app or don't want the logs on screen, you can redirect them as you prefer:
@@ -45,7 +46,7 @@ WTelegram.Helpers.Log = (lvl, str) => { };
The `lvl` argument correspond to standard [LogLevel values](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel#fields)
-### Send a message to someone by @username
+## Send a message to someone by @username
```csharp
var resolved = await client.Contacts_ResolveUsername("JsonDumpBot"); // username without the @
await client.SendMessageAsync(resolved, "/start");
@@ -55,7 +56,7 @@ If the username is invalid/unused, the API call raises an RpcException.*
-### Convert message to/from HTML or Markdown, and send it to ourself (Saved Messages)
+## Convert message to/from HTML or Markdown, and send it to ourself (Saved Messages)
```csharp
// HTML-formatted text:
var text = $"Hello dear {HtmlText.Escape(client.User.first_name)}\n" +
@@ -78,7 +79,7 @@ See [HTML formatting style](https://core.telegram.org/bots/api/#html-style) and
*Note: For the `tg://user?id=` notation to work, that user's access hash must have been collected first ([see below](#collect-access-hash))*
-### List all dialogs (chats/groups/channels/user chat) we are currently in
+## List all dialogs (chats/groups/channels/user chat) we are currently in
```csharp
var dialogs = await client.Messages_GetAllDialogs();
foreach (Dialog dialog in dialogs.dialogs)
@@ -98,7 +99,7 @@ Notes:
- To retrieve the dialog information about a specific [peer](README.md#terminology), use `client.Messages_GetPeerDialogs(inputPeer)`
-### List all chats (groups/channels NOT users) that we joined and send a message to one
+## List all chats (groups/channels NOT users) that we joined and send a message to one
```csharp
var chats = await client.Messages_GetAllChats();
foreach (var (id, chat) in chats.chats)
@@ -116,7 +117,7 @@ but the old `Chat` will be marked with flag [deactivated] and should not be used
- You can find a longer version of this method call in [Examples/Program_GetAllChats.cs](Examples/Program_GetAllChats.cs)
-### List the members from a chat
+## List the members from a chat
For a basic Chat: *(see Terminology in [ReadMe](README.md#terminology))*
```csharp
var chatFull = await client.Messages_GetFullChat(1234567890); // the chat we want
@@ -159,7 +160,7 @@ 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
```csharp
var chats = await client.Messages_GetAllChats();
InputPeer peer = chats.chats[1234567890]; // the chat we want
@@ -183,7 +184,7 @@ Notes:
- To mark the message history as read, use: `await client.ReadHistory(peer);`
-### Monitor all Telegram events happening for the user
+## Monitor all Telegram events happening for the user
This is done through the `client.OnUpdate` callback event.
Your event handler implementation can either return `Task.CompletedTask` or be an `async Task` method.
@@ -191,7 +192,7 @@ Your event handler implementation can either return `Task.CompletedTask` or be a
See [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
-### Monitor new messages being posted in chats in real-time
+## Monitor new messages being posted in chats in real-time
You have to handle `client.OnUpdate` events containing an `UpdateNewMessage`.
@@ -200,7 +201,7 @@ See the `DisplayMessage` method in [Examples/Program_ListenUpdates.cs](Examples/
You can filter specific chats the message are posted in, by looking at the `Message.peer_id` field.
-### Downloading photos, medias, files
+## Downloading photos, medias, files
This is done using the helper method `client.DownloadFileAsync(file, outputStream)`
that simplifies the download of a photo/document/file once you get a reference to its location *(through updates or API calls)*.
@@ -208,7 +209,7 @@ that simplifies the download of a photo/document/file once you get a reference t
See [Examples/Program_DownloadSavedMedia.cs](Examples/Program_DownloadSavedMedia.cs) that download all media files you forward to yourself (Saved Messages)
-### Upload a media file and post it with caption to a chat
+## Upload a media file and post it with caption to a chat
```csharp
const int ChatId = 1234567890; // the chat we want
const string Filepath = @"C:\...\photo.jpg";
@@ -220,7 +221,7 @@ await client.SendMediaAsync(peer, "Here is the photo", inputFile);
```
-### Send a grouped media album using photos from various sources
+## Send a grouped media album using photos from various sources
```csharp
// Photo 1 already on Telegram: latest photo found in the user's Saved Messages
var history = await client.Messages_GetHistory(InputPeer.Self);
@@ -241,7 +242,7 @@ await client.SendAlbumAsync(InputPeer.Self, inputMedias, "My first album");
*Note: Don't mix Photos and file Documents in your album, it doesn't work well*
-### Forward or copy a message to another chat
+## Forward or copy a message to another chat
```csharp
// Determine which chats and message to forward/copy
var chats = await client.Messages_GetAllChats();
@@ -261,7 +262,7 @@ await client.SendMessageAsync(to_chat, msg.message, msg.media?.ToInputMedia(), e
```
-### Schedule a message to be sent to a chat
+## Schedule a message to be sent to a chat
```csharp
var chats = await client.Messages_GetAllChats();
InputPeer peer = chats.chats[1234567890]; // the chat we want
@@ -270,7 +271,7 @@ await client.SendMessageAsync(peer, "This will be posted in 3 minutes", schedule
```
-### Fun with stickers, GIFs, dice, and animated emojies
+## Fun with stickers, GIFs, dice, and animated emojies
```csharp
// • List all stickerSets the user has added to his account
var allStickers = await client.Messages_GetAllStickers();
@@ -319,7 +320,7 @@ await Task.Delay(5000);
```
-### Fun with custom emojies and reactions on pinned messages
+## Fun with custom emojies and reactions on pinned messages
```csharp
// • Sending a message with custom emojies in Markdown to ourself:
var text = "Vicksy says Hi! [👋](emoji?id=5190875290439525089)";
@@ -355,7 +356,7 @@ foreach (var msg in messages.Messages)
-### Join a channel/group by their public name or invite link
+## Join a channel/group by their public name or invite link
* For a public channel/group `@channelname`
If you have a link of the form `https://t.me/channelname`, you need to extract the `channelname` from the URL.
You can resolve the channel/group username and join it like this:
@@ -374,7 +375,7 @@ await client.Messages_ImportChatInvite("HASH"); // join the channel/group
```
-### Add/Invite/Remove someone in a chat
+## Add/Invite/Remove someone in a chat
```csharp
var chats = await client.Messages_GetAllChats();
var chat = chats.chats[1234567890]; // the target chat
@@ -403,7 +404,7 @@ await client.DeleteChatUser(chat, user);
```
-### Send a message to someone by phone number
+## Send a message to someone by phone number
```csharp
var contacts = await client.Contacts_ImportContacts(new[] { new InputPhoneContact { phone = "+PHONENUMBER" } });
if (contacts.imported.Length > 0)
@@ -412,7 +413,7 @@ if (contacts.imported.Length > 0)
*Note: Don't use this method too much. To prevent spam, Telegram may restrict your ability to add new phone numbers or ban your account.*
-### Retrieve the current user's contacts list
+## Retrieve the current user's contacts list
There are two different methods. Here is the simpler one:
```csharp
var contacts = await client.Contacts_GetContacts();
@@ -441,7 +442,7 @@ finally
```
-### Collect Access Hash and save them for later use
+## Collect Access Hash and save them for later use
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.
@@ -450,7 +451,7 @@ This is done by activating the experimental `client.CollectAccessHash` system.
See [Examples/Program_CollectAccessHash.cs](Examples/Program_CollectAccessHash.cs) for how to enable it, and save/restore them for later use.
-### Use a proxy or MTProxy to connect to Telegram
+## Use a proxy or MTProxy to connect to Telegram
SOCKS/HTTPS proxies can be used through the `client.TcpHandler` delegate and a proxy library like [StarkSoftProxy](https://www.nuget.org/packages/StarkSoftProxy/):
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
@@ -482,7 +483,7 @@ If your Telegram client is already connected to such MTPROTO proxy, you can also
*Note: WTelegramClient always uses transport obfuscation when connecting to Telegram servers, even without MTProxy*
-### Change 2FA password
+## Change 2FA password
```csharp
const string old_password = "password"; // current password if any (unused otherwise)
const string new_password = "new_password"; // or null to disable 2FA
@@ -500,7 +501,7 @@ await client.Account_UpdatePasswordSettings(password, new Account_PasswordInputS
```
-### Store session data to database or elsewhere, instead of files
+## Store session data to database or elsewhere, instead of files
If you don't want to store session data into files *(for example if your VPS Hosting doesn't allow that)*, or just for easier management,
you can choose to store the session data somewhere else, like in a database.
@@ -511,7 +512,7 @@ Use it to pass a custom Stream-derived class that will **read** (first initial c
You can find an example for such custom session store in [Examples/Program_Heroku.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_Heroku.cs#L61)
-### Send/receive end-to-end encrypted messages & files in Secret Chats
+## Send/receive end-to-end encrypted messages & files in Secret Chats
This can be done easily using the helper class `WTelegram.SecretChats` offering methods to manage/encrypt/decrypt secret chats & encrypted messages/files.
diff --git a/FAQ.md b/FAQ.md
index 36f03c5..2cd38db 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -1,11 +1,13 @@
-## FAQ
+# FAQ
Before asking questions, make sure to **[read through the ReadMe first](README.md)**,
take a look at the [example programs](EXAMPLES.md) or [StackOverflow questions](https://stackoverflow.com/questions/tagged/wtelegramclient),
and refer to the [API method list](https://corefork.telegram.org/methods) for the full range of Telegram services available in this library.
+➡️ Use Ctrl-F to search this page for the information you seek
+
-#### 1. How to remove the Console logs?
+## 1. How to remove the Console logs?
Writing the library logs to the Console is the default behavior of the `WTelegram.Helpers.Log` delegate.
You can change the delegate with the `+=` operator to **also** write them somewhere else, or with the `=` operator to prevent them from being printed to screen and instead write them somewhere (file, logger, ...).
@@ -14,7 +16,7 @@ In any case, it is not recommended to totally ignore those logs because you woul
Read the [example about logging settings](EXAMPLES.md#logging) for how to write logs to a file.
-#### 2. How to handle multiple user accounts
+## 2. How to handle multiple user accounts
The WTelegram.session file contains the authentication keys negociated for the current user.
@@ -32,7 +34,7 @@ Your api_id/api_hash represents your application, and shouldn't change with each
-#### 3. How to use the library in a WinForms, WPF or ASP.NET application
+## 3. How to use the library in a WinForms, WPF or ASP.NET application
The library should work without a problem in such applications.
The difficulty might be in your Config callback when the user must enter the verification code or password, as you can't use `Console.ReadLine` here.
@@ -48,7 +50,7 @@ calling `client.Login(...)` as the user provides the requested configuration ele
You can download such full example apps [for WinForms](Examples/WinForms_app.zip) and [for ASP.NET](Examples/ASPnet_webapp.zip)
-#### 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? Where to get the 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)
@@ -72,14 +74,14 @@ You can then retrieve it with `client.GetAccessHashFor
-#### 5. I need to test a feature that has been recently developed but seems not available in my program
+## 5. I need to test a feature that has been recently developed but seems not available in my program
The developmental versions of the library are now available as **pre-release** on Nuget (with `-dev` in the version number)
So make sure you tick the checkbox "Include prerelease" in Nuget manager and/or navigate to the Versions list then select the highest `x.x.x-dev.x` version to install in your program.
-#### 6. Telegram asks me to signup (firstname, lastname) even for an existing account
+## 6. Telegram asks me to signup (firstname, lastname) even for an existing account
This happens when you connect to Telegram Test servers instead of Production servers.
On these separate test servers, all created accounts and chats are periodically deleted, so you shouldn't use them under normal circumstances.
@@ -96,7 +98,7 @@ If you use the Github source project in an old .NET Framework 4.x or .NET Core x
To fix this, you should also switch to using the [WTelegramClient Nuget package](https://www.nuget.org/packages/WTelegramClient) as it will install the required dependencies for it to work.
-#### 7. I get errors FLOOD_WAIT_X or PEER_FLOOD, PHONE_NUMBER_BANNED, USER_DEACTIVATED_BAN. I can't import phone numbers.
+## 7. I get errors FLOOD_WAIT_X or PEER_FLOOD, PHONE_NUMBER_BANNED, USER_DEACTIVATED_BAN. I can't import phone numbers.
You can get these kind of problems if you abuse Telegram [Terms of Service](https://telegram.org/tos), or the [API Terms of Service](https://core.telegram.org/api/terms), or make excessive requests.
@@ -111,7 +113,7 @@ If you think your phone number was banned from Telegram for a wrong reason, you
In any case, WTelegramClient is not responsible for the bad usage of the library and we are not affiliated to Telegram teams, so there is nothing we can do.
-#### 8. How to NOT get banned from Telegram?
+## 8. How to NOT get banned from Telegram?
**Do not share publicly your app's ID and hash!** They cannot be regenerated and are bound to your Telegram account.
@@ -147,7 +149,7 @@ We don't support such use of the library, and will not help people asking for su
11. If your client displays Telegram channels to your users, you have to support and display [official sponsored messages](https://core.telegram.org/api/sponsored-messages).
-#### 9. Why the error `CHAT_ID_INVALID`?
+## 9. Why the error `CHAT_ID_INVALID`?
Most chat groups you see are likely of type `Channel`, not `Chat`.
This difference is important to understand. Please [read about the Terminology in ReadMe](README.md#terminology).
@@ -162,7 +164,7 @@ That object must be created with both fields `channel_id` and `access_hash` corr
-#### 10. `chats.chats[id]` fails. My chats list is empty or does not contain the chat I'm looking for.
+## 10. `chats.chats[id]` fails. My chats list is empty or does not contain the chat I'm looking for.
There can be several reasons why `chats.chats` doesn't contain the chat you expect:
- You're searching for a user instead of a chat ID.
@@ -182,7 +184,7 @@ To help determine if `chats.chats` is empty or does not contain a certain chat,
or simply use a debugger: Place a breakpoint after the `Messages_GetAllChats` call, run the program up to there, and use a Watch pane to display the content of the chats.chats dictionary.
-#### 11. I get "Connection shut down" errors in my logs
+## 11. I get "Connection shut down" errors in my logs
There are various reasons why you may get this error. Here are the explanation and how to solve it:
@@ -207,7 +209,7 @@ In this case, you can use the `PingInterval` property to increase the delay betw
5) If you're using an [MTProxy](EXAMPLES.md#proxy), some of them are known to be quite unstable. You may want to try switching to another MTProxy that is more stable.
-#### 12. How to migrate from TLSharp? How to sign-in/sign-up/register account properly?
+## 12. How to migrate from TLSharp? How to sign-in/sign-up/register account properly?
First, make sure you read the [ReadMe documentation](README.md) completely, it contains essential information and a quick tutorial to easily understand how to correctly use the library.
@@ -234,7 +236,7 @@ In particular, it will detect and handle automatically and properly the various
Contrary to TLSharp, WTelegramClient supports MTProto v2.0 (more secured), transport obfuscation, protocol security checks, MTProto [Proxy](EXAMPLES.md#proxy), real-time updates, multiple DC connections, API documentation in Intellisense...
-#### 13. How to host my userbot online?
+## 13. How to host my userbot online?
If you need your userbot to run 24/7, you would typically design your userbot as a Console program, compiled for Linux or Windows,
and hosted online on any [VPS Hosting](https://www.google.com/search?q=vps+hosting) (Virtual Private Server).
@@ -244,7 +246,7 @@ There are many cheap VPS Hosting offers available, for example Heroku:
See [Examples/Program_Heroku.cs](Examples/Program_Heroku.cs) for such an implementation and the steps to host/deploy it.
-#### 14. Secret Chats implementation details
+## 14. Secret Chats implementation details
The following choices were made while implementing Secret Chats in WTelegramClient:
- It may not support remote antique Telegram clients *(prior to 2018, still using insecure MTProto 1.0)*
@@ -260,7 +262,7 @@ If those missing messages are never obtained during the session, incoming messag
If remote client doesn't complete this negotiation before reaching 200 messages, the Secret Chat is aborted.
-#### 15. The example codes don't compile on my machine
+## 15. The example codes don't compile on my machine
The snippets of example codes found in the [ReadMe](README.md) or [Examples](EXAMPLES.md) pages were written for .NET 5 / C# 9 minimum.
If you're having compiler problem on code constructs such as `using`, `foreach`, `[^1]` or about "Deconstruct",
@@ -294,7 +296,7 @@ Here are the recommended actions to fix your problem:
Also, remember to add a `using TL;` at the top of your files to have access to all the Telegram API methods.
-## Troubleshooting guide
+# 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?
From 76d75a6035efe73500ad23bead8ea9d7e123b36c Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Sat, 26 Nov 2022 23:10:06 +0100
Subject: [PATCH 024/336] implicit Input* operators for Wallpaper,
EncryptedChat, PhoneCall, Theme, GroupCall
---
src/TL.Helpers.cs | 50 +++++++++++++++++++------
src/TL.Schema.cs | 94 ++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 126 insertions(+), 18 deletions(-)
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index baa60d3..dc68173 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -97,6 +97,17 @@ namespace TL
public override InputSecureFileBase ToInputSecureFile(byte[] file_hash, byte[] secret) => new InputSecureFileUploaded { id = id, parts = parts, file_hash = file_hash, secret = secret };
}
+ partial class InputMediaUploadedDocument
+ {
+ public InputMediaUploadedDocument() { }
+ public InputMediaUploadedDocument(InputFileBase inputFile, string mimeType)
+ {
+ file = inputFile;
+ mime_type = mimeType;
+ if (inputFile.Name is string filename) attributes = new[] { new DocumentAttributeFilename { file_name = filename } };
+ }
+ }
+
partial class InputPhoto
{
public static implicit operator InputMediaPhoto(InputPhoto photo) => new() { id = photo };
@@ -340,17 +351,19 @@ namespace TL
public static implicit operator InputGeoPoint(GeoPoint geo) => new() { lat = geo.lat, lon = geo.lon, accuracy_radius = geo.accuracy_radius, flags = (InputGeoPoint.Flags)geo.flags };
}
- partial class InputMediaUploadedDocument
+ partial class WallPaperBase
{
- public InputMediaUploadedDocument() { }
- public InputMediaUploadedDocument(InputFileBase inputFile, string mimeType)
- {
- file = inputFile;
- mime_type = mimeType;
- if (inputFile.Name is string filename) attributes = new[] { new DocumentAttributeFilename { file_name = filename } };
- }
+ protected abstract InputWallPaperBase ToInputWallPaper();
+ public static implicit operator InputWallPaperBase(WallPaperBase wp) => wp.ToInputWallPaper();
+ }
+ partial class WallPaper
+ {
+ protected override InputWallPaperBase ToInputWallPaper() => new InputWallPaper { id = id, access_hash = access_hash };
+ }
+ partial class WallPaperNoFile
+ {
+ protected override InputWallPaperBase ToInputWallPaper() => new InputWallPaperNoFile { id = id };
}
-
partial class Contacts_Blocked { public IPeerInfo UserOrChat(PeerBlocked peer) => peer.peer_id?.UserOrChat(users, chats); }
partial class Messages_DialogsBase { public IPeerInfo UserOrChat(DialogBase dialog) => UserOrChat(dialog.Peer);
public abstract int TotalCount { get; } }
@@ -416,7 +429,8 @@ namespace TL
}, pts = pts, pts_count = pts_count
} }; }
- partial class InputEncryptedChat { public static implicit operator int(InputEncryptedChat chat) => chat.chat_id; }
+ partial class InputEncryptedChat { public static implicit operator int(InputEncryptedChat chat) => chat.chat_id;
+ public static implicit operator InputEncryptedChat(EncryptedChatBase chat) => new() { chat_id = chat.ID, access_hash = chat.AccessHash }; }
partial class EncryptedFile
{
@@ -554,14 +568,16 @@ namespace TL
partial class Game { public static implicit operator InputGameID(Game game) => new() { id = game.id, access_hash = game.access_hash }; }
partial class WebDocument { public static implicit operator InputWebFileLocation(WebDocument doc) => new() { url = doc.url, access_hash = doc.access_hash }; }
+ partial class PhoneCallBase { public static implicit operator InputPhoneCall(PhoneCallBase call) => new() { id = call.ID, access_hash = call.AccessHash }; }
+
partial class InputMessage
{
- public static implicit operator InputMessage(int id) => new InputMessageID() { id = id };
+ public static implicit operator InputMessage(int id) => new InputMessageID { id = id };
}
partial class InputDialogPeerBase
{
- public static implicit operator InputDialogPeerBase(InputPeer peer) => new InputDialogPeer() { peer = peer };
+ public static implicit operator InputDialogPeerBase(InputPeer peer) => new InputDialogPeer { peer = peer };
}
partial class SecureFile
@@ -632,4 +648,14 @@ namespace TL
return dic;
}
}
+
+ partial class Theme
+ {
+ public static implicit operator InputTheme(Theme theme) => new() { id = theme.id, access_hash = theme.access_hash };
+ }
+
+ partial class GroupCallBase
+ {
+ public static implicit operator InputGroupCall(GroupCallBase call) => new() { id = call.ID, access_hash = call.AccessHash };
+ }
}
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index 1177959..3da5301 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -2628,7 +2628,7 @@ namespace TL
}
/// Object contains info on a wallpaper. See Derived classes: ,
- public abstract class WallPaperBase : IObject
+ public abstract partial class WallPaperBase : IObject
{
/// Identifier
public virtual long ID { get; }
@@ -2637,7 +2637,7 @@ namespace TL
}
/// Represents a wallpaper based on an image. See
[TLDef(0xA437C3ED)]
- public class WallPaper : WallPaperBase
+ public partial class WallPaper : WallPaperBase
{
/// Identifier
public long id;
@@ -2673,7 +2673,7 @@ namespace TL
}
/// Represents a wallpaper only based on colors/gradients. See
[TLDef(0xE0804116)]
- public class WallPaperNoFile : WallPaperBase
+ public partial class WallPaperNoFile : WallPaperBase
{
/// Wallpaper ID
public long id;
@@ -5006,6 +5006,14 @@ namespace TL
{
/// Chat ID
public virtual int ID { get; }
+ /// Checking sum depending on user ID
+ public virtual long AccessHash { get; }
+ /// Date of chat creation
+ public virtual DateTime Date { get; }
+ /// Chat creator ID
+ public virtual long AdminId { get; }
+ /// ID of second chat participant
+ public virtual long ParticipantId { get; }
}
/// Empty constructor. See
[TLDef(0xAB7EC0A0)]
@@ -5034,6 +5042,14 @@ namespace TL
/// Chat ID
public override int ID => id;
+ /// Checking sum depending on user ID
+ public override long AccessHash => access_hash;
+ /// Date of chat creation
+ public override DateTime Date => date;
+ /// Chat creator ID
+ public override long AdminId => admin_id;
+ /// ID of second chat participant
+ public override long ParticipantId => participant_id;
}
/// Request to create an encrypted chat. See
[TLDef(0x48F1D94C)]
@@ -5064,6 +5080,14 @@ namespace TL
/// Chat ID
public override int ID => id;
+ /// Check sum depending on user ID
+ public override long AccessHash => access_hash;
+ /// Chat creation date
+ public override DateTime Date => date;
+ /// Chat creator ID
+ public override long AdminId => admin_id;
+ /// ID of second chat participant
+ public override long ParticipantId => participant_id;
}
/// Encrypted chat See
[TLDef(0x61F0D4C7)]
@@ -5086,6 +5110,14 @@ namespace TL
/// Chat ID
public override int ID => id;
+ /// Check sum dependent on the user ID
+ public override long AccessHash => access_hash;
+ /// Date chat was created
+ public override DateTime Date => date;
+ /// Chat creator ID
+ public override long AdminId => admin_id;
+ /// ID of the second chat participant
+ public override long ParticipantId => participant_id;
}
/// Discarded or deleted chat. See
[TLDef(0x1E1C7C45)]
@@ -9202,10 +9234,20 @@ namespace TL
}
/// Phone call See Derived classes: , , , , ,
- public abstract class PhoneCallBase : IObject
+ public abstract partial class PhoneCallBase : IObject
{
/// Call ID
public virtual long ID { get; }
+ /// Access hash
+ public virtual long AccessHash { get; }
+ /// Date
+ public virtual DateTime Date { get; }
+ /// Admin ID
+ public virtual long AdminId { get; }
+ /// Participant ID
+ public virtual long ParticipantId { get; }
+ /// Phone call protocol info
+ public virtual PhoneCallProtocol Protocol { get; }
}
/// Empty constructor See
[TLDef(0x5366C915)]
@@ -9248,6 +9290,16 @@ namespace TL
/// Call ID
public override long ID => id;
+ /// Access hash
+ public override long AccessHash => access_hash;
+ /// Date
+ public override DateTime Date => date;
+ /// Admin ID
+ public override long AdminId => admin_id;
+ /// Participant ID
+ public override long ParticipantId => participant_id;
+ /// Phone call protocol info
+ public override PhoneCallProtocol Protocol => protocol;
}
/// Requested phone call See
[TLDef(0x14B0ED0C)]
@@ -9278,6 +9330,16 @@ namespace TL
/// Phone call ID
public override long ID => id;
+ /// Access hash
+ public override long AccessHash => access_hash;
+ /// When was the phone call created
+ public override DateTime Date => date;
+ /// ID of the creator of the phone call
+ public override long AdminId => admin_id;
+ /// ID of the other participant of the phone call
+ public override long ParticipantId => participant_id;
+ /// Call protocol info to be passed to libtgvoip
+ public override PhoneCallProtocol Protocol => protocol;
}
/// An accepted phone call See
[TLDef(0x3660C311)]
@@ -9308,6 +9370,16 @@ namespace TL
/// ID of accepted phone call
public override long ID => id;
+ /// Access hash of phone call
+ public override long AccessHash => access_hash;
+ /// When was the call accepted
+ public override DateTime Date => date;
+ /// ID of the call creator
+ public override long AdminId => admin_id;
+ /// ID of the other user in the call
+ public override long ParticipantId => participant_id;
+ /// Protocol to use for phone call
+ public override PhoneCallProtocol Protocol => protocol;
}
/// Phone call See
[TLDef(0x967F7C67)]
@@ -9346,6 +9418,16 @@ namespace TL
/// Call ID
public override long ID => id;
+ /// Access hash
+ public override long AccessHash => access_hash;
+ /// Date of creation of the call
+ public override DateTime Date => date;
+ /// User ID of the creator of the call
+ public override long AdminId => admin_id;
+ /// User ID of the other participant in the call
+ public override long ParticipantId => participant_id;
+ /// Call protocol info to be passed to libtgvoip
+ public override PhoneCallProtocol Protocol => protocol;
}
/// Indicates a discarded phone call See
[TLDef(0x50CA4DE1)]
@@ -11602,7 +11684,7 @@ namespace TL
/// Theme See
[TLDef(0xA00E67D6)]
- public class Theme : IObject
+ public partial class Theme : IObject
{
/// Flags, see TL conditional fields
public Flags flags;
@@ -12433,7 +12515,7 @@ namespace TL
}
/// A group call See Derived classes: ,
- public abstract class GroupCallBase : IObject
+ public abstract partial class GroupCallBase : IObject
{
/// Group call ID
public virtual long ID { get; }
From 42be9508967a924d095702befa5bbfc7c8508599 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Fri, 2 Dec 2022 01:42:39 +0100
Subject: [PATCH 025/336] Alt DC disconnection logged as simple warning
---
EXAMPLES.md | 14 ++++++------
Examples/Program_Heroku.cs | 2 +-
FAQ.md | 2 +-
README.md | 10 ++++-----
src/Client.Helpers.cs | 6 ++---
src/Client.cs | 8 +++++--
src/TL.Helpers.cs | 45 +++++++++++++-------------------------
src/WTelegramClient.csproj | 4 ++--
8 files changed, 40 insertions(+), 51 deletions(-)
diff --git a/EXAMPLES.md b/EXAMPLES.md
index 88bf1de..654e117 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -95,7 +95,7 @@ foreach (Dialog dialog in dialogs.dialogs)
Notes:
- The lists returned by Messages_GetAllDialogs contains the `access_hash` for those chats and users.
-- See also the `Main` method in [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
+- See also the `Main` method in [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs#L20).
- To retrieve the dialog information about a specific [peer](README.md#terminology), use `client.Messages_GetPeerDialogs(inputPeer)`
@@ -114,7 +114,7 @@ Notes:
- The list returned by Messages_GetAllChats contains the `access_hash` for those chats. Read [FAQ #4](FAQ.md#access-hash) about this.
- If a basic chat group has been migrated to a supergroup, you may find both the old `Chat` and a `Channel` with different IDs in the `chats.chats` result,
but the old `Chat` will be marked with flag [deactivated] and should not be used anymore. See [Terminology in ReadMe](README.md#terminology).
-- You can find a longer version of this method call in [Examples/Program_GetAllChats.cs](Examples/Program_GetAllChats.cs)
+- You can find a longer version of this method call in [Examples/Program_GetAllChats.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_GetAllChats.cs#L32)
## List the members from a chat
@@ -189,14 +189,14 @@ Notes:
This is done through the `client.OnUpdate` callback event.
Your event handler implementation can either return `Task.CompletedTask` or be an `async Task` method.
-See [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
+See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs#L23).
## Monitor new messages being posted in chats in real-time
You have to handle `client.OnUpdate` events containing an `UpdateNewMessage`.
-See the `DisplayMessage` method in [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
+See the `DisplayMessage` method in [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs#L23).
You can filter specific chats the message are posted in, by looking at the `Message.peer_id` field.
@@ -206,7 +206,7 @@ You can filter specific chats the message are posted in, by looking at the `Mess
This is done using the helper method `client.DownloadFileAsync(file, outputStream)`
that simplifies the download of a photo/document/file once you get a reference to its location *(through updates or API calls)*.
-See [Examples/Program_DownloadSavedMedia.cs](Examples/Program_DownloadSavedMedia.cs) that download all media files you forward to yourself (Saved Messages)
+See [Examples/Program_DownloadSavedMedia.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_DownloadSavedMedia.cs#L31) that download all media files you forward to yourself (Saved Messages)
## Upload a media file and post it with caption to a chat
@@ -448,7 +448,7 @@ You can automate the collection of `access_hash` for the various resources obtai
so that you don't have to remember them by yourself or ask the API about them each time.
This is done by activating the experimental `client.CollectAccessHash` system.
-See [Examples/Program_CollectAccessHash.cs](Examples/Program_CollectAccessHash.cs) for how to enable it, and save/restore them for later use.
+See [Examples/Program_CollectAccessHash.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_CollectAccessHash.cs#L22) for how to enable it, and save/restore them for later use.
## Use a proxy or MTProxy to connect to Telegram
@@ -516,7 +516,7 @@ You can find an example for such custom session store in [Examples/Program_Herok
This can be done easily using the helper class `WTelegram.SecretChats` offering methods to manage/encrypt/decrypt secret chats & encrypted messages/files.
-You can view a full working example at [Examples/Program_SecretChats.cs](Examples/Program_SecretChats.cs).
+You can view a full working example at [Examples/Program_SecretChats.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_SecretChats.cs#L11).
Secret Chats have been tested successfully with Telegram Android & iOS official clients.
You can also check our [FAQ for more implementation details](FAQ.md#14-secret-chats-implementation-details).
\ No newline at end of file
diff --git a/Examples/Program_Heroku.cs b/Examples/Program_Heroku.cs
index cfdb551..70fffdf 100644
--- a/Examples/Program_Heroku.cs
+++ b/Examples/Program_Heroku.cs
@@ -8,7 +8,7 @@ using TL;
// This is an example userbot designed to run on a Heroku account with a PostgreSQL database for session storage
// This userbot simply answer "Pong" when someone sends him a "Ping" private message (or in Saved Messages)
-// To use/install/deploy this userbot, follow the steps at the end of this file
+// To use/install/deploy this userbot ➡️ follow the steps at the end of this file
// When run locally, close the window or type ALT-F4 to exit cleanly and save session (similar to Heroku SIGTERM)
namespace WTelegramClientTest
diff --git a/FAQ.md b/FAQ.md
index 2cd38db..4d388e9 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -243,7 +243,7 @@ and hosted online on any [VPS Hosting](https://www.google.com/search?q=vps+hosti
Pure WebApp hosts might not be adequate as they will recycle (stop) your app if there is no incoming HTTP requests.
There are many cheap VPS Hosting offers available, for example Heroku:
-See [Examples/Program_Heroku.cs](Examples/Program_Heroku.cs) for such an implementation and the steps to host/deploy it.
+See [Examples/Program_Heroku.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_Heroku.cs#L9) for such an implementation and the steps to host/deploy it.
## 14. Secret Chats implementation details
diff --git a/README.md b/README.md
index 88d7368..7aacdc3 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
-[](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)
-## _Telegram Client API library written 100% in C# and .NET Standard_
+## _Telegram Client API library written 100% in C# and .NET_
This library allows you to connect to Telegram and control a user programmatically (or a bot, but [Telegram.Bot](https://github.com/TelegramBots/Telegram.Bot) is much easier for that).
All the Telegram Client APIs (MTProto) are supported so you can do everything the user could do with a full Telegram GUI client.
@@ -90,7 +90,7 @@ Since version 3.0.0, a new approach to login/configuration has been added. Some
```csharp
WTelegram.Client client = new WTelegram.Client(YOUR_API_ID, "YOUR_API_HASH");
-await DoLogin("+12025550156"); // user's phone_number
+await DoLogin("+12025550156"); // initial call with user's phone_number
async Task DoLogin(string loginInfo) // (add this method to your code)
{
@@ -150,7 +150,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).
-➡️ Check [the FAQ](https://wiz0u.github.io/WTelegramClient/FAQ#compile) if example codes doesn't compile correctly on your machine, or other troubleshooting.
+➡️ Check [the FAQ](https://wiz0u.github.io/WTelegramClient/FAQ#compile) if example codes don't compile correctly on your machine, or other troubleshooting.
# Terminology in Telegram Client API
@@ -189,7 +189,7 @@ as well as generic handling of chats/channels.
This library works best with **.NET 5.0+** (faster, no dependencies) and is also available for **.NET Standard 2.0** (.NET Framework 4.6.1+ & .NET Core 2.0+) and **Xamarin/Mono.Android**
# Library uses and limitations
-This library can be used for any Telegram scenarios including:
+This library can be used for any Telegram scenario including:
- Sequential or parallel automated steps based on API requests/responses
- Real-time [monitoring](https://wiz0u.github.io/WTelegramClient/EXAMPLES#updates) of incoming Updates/Messages
- Download/upload of files/media
diff --git a/src/Client.Helpers.cs b/src/Client.Helpers.cs
index 6fe1510..30da842 100644
--- a/src/Client.Helpers.cs
+++ b/src/Client.Helpers.cs
@@ -586,7 +586,7 @@ namespace WTelegram
public Task AddChatUser(InputPeer peer, InputUserBase user) => peer switch
{
InputPeerChat chat => this.Messages_AddChatUser(chat.chat_id, user, int.MaxValue),
- InputPeerChannel channel => this.Channels_InviteToChannel(channel, new[] { user }),
+ InputPeerChannel channel => this.Channels_InviteToChannel(channel, user),
_ => throw new ArgumentException(OnlyChatChannel),
};
@@ -620,7 +620,7 @@ namespace WTelegram
case InputPeerChat chat:
await this.Messages_EditChatAdmin(chat.chat_id, user, is_admin);
return new Updates { date = DateTime.UtcNow, users = new(), updates = Array.Empty(),
- chats = (await this.Messages_GetChats(new[] { chat.chat_id })).chats };
+ chats = (await this.Messages_GetChats(chat.chat_id)).chats };
case InputPeerChannel channel:
return await this.Channels_EditAdmin(channel, user,
new ChatAdminRights { flags = is_admin ? (ChatAdminRights.Flags)0x8BF : 0 }, null);
@@ -667,7 +667,7 @@ namespace WTelegram
case InputPeerChat chat:
await this.Messages_DeleteChat(chat.chat_id);
return new Updates { date = DateTime.UtcNow, users = new(), updates = Array.Empty(),
- chats = (await this.Messages_GetChats(new[] { chat.chat_id })).chats };
+ chats = (await this.Messages_GetChats(chat.chat_id)).chats };
case InputPeerChannel channel:
return await this.Channels_DeleteChannel(channel);
default:
diff --git a/src/Client.cs b/src/Client.cs
index 891764a..af5234e 100644
--- a/src/Client.cs
+++ b/src/Client.cs
@@ -310,7 +310,11 @@ namespace WTelegram
catch (Exception ex) // an exception in RecvAsync is always fatal
{
if (cts.IsCancellationRequested) return;
- Helpers.Log(5, $"{_dcSession.DcID}>An exception occured in the reactor: {ex}");
+ bool disconnectedAltDC = !IsMainDC && ex is ApplicationException { Message: ConnectionShutDown } or IOException { InnerException: SocketException };
+ if (disconnectedAltDC)
+ Helpers.Log(3, $"{_dcSession.DcID}>Alt DC disconnected: {ex.Message}");
+ else
+ Helpers.Log(5, $"{_dcSession.DcID}>An exception occured in the reactor: {ex}");
var oldSemaphore = _sendSemaphore;
await oldSemaphore.WaitAsync(cts.Token); // prevent any sending while we reconnect
var reactorError = new ReactorError { Exception = ex };
@@ -319,7 +323,7 @@ namespace WTelegram
lock (_msgsToAck) _msgsToAck.Clear();
Reset(false, false);
_reactorReconnects = (_reactorReconnects + 1) % MaxAutoReconnects;
- if (!IsMainDC && _pendingRpcs.Count <= 1 && ex is ApplicationException { Message: ConnectionShutDown } or IOException { InnerException: SocketException })
+ if (disconnectedAltDC && _pendingRpcs.Count <= 1)
if (_pendingRpcs.Values.FirstOrDefault() is not Rpc rpc || rpc.type == typeof(Pong))
_reactorReconnects = 0;
if (_reactorReconnects == 0)
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index dc68173..b0abb38 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -351,19 +351,11 @@ namespace TL
public static implicit operator InputGeoPoint(GeoPoint geo) => new() { lat = geo.lat, lon = geo.lon, accuracy_radius = geo.accuracy_radius, flags = (InputGeoPoint.Flags)geo.flags };
}
- partial class WallPaperBase
- {
- protected abstract InputWallPaperBase ToInputWallPaper();
- public static implicit operator InputWallPaperBase(WallPaperBase wp) => wp.ToInputWallPaper();
- }
- partial class WallPaper
- {
- protected override InputWallPaperBase ToInputWallPaper() => new InputWallPaper { id = id, access_hash = access_hash };
- }
- partial class WallPaperNoFile
- {
- protected override InputWallPaperBase ToInputWallPaper() => new InputWallPaperNoFile { id = id };
- }
+ partial class WallPaperBase { public static implicit operator InputWallPaperBase(WallPaperBase wp) => wp.ToInputWallPaper();
+ protected abstract InputWallPaperBase ToInputWallPaper(); }
+ partial class WallPaper { protected override InputWallPaperBase ToInputWallPaper() => new InputWallPaper { id = id, access_hash = access_hash }; }
+ partial class WallPaperNoFile { protected override InputWallPaperBase ToInputWallPaper() => new InputWallPaperNoFile { id = id }; }
+
partial class Contacts_Blocked { public IPeerInfo UserOrChat(PeerBlocked peer) => peer.peer_id?.UserOrChat(users, chats); }
partial class Messages_DialogsBase { public IPeerInfo UserOrChat(DialogBase dialog) => UserOrChat(dialog.Peer);
public abstract int TotalCount { get; } }
@@ -429,8 +421,8 @@ namespace TL
}, pts = pts, pts_count = pts_count
} }; }
- partial class InputEncryptedChat { public static implicit operator int(InputEncryptedChat chat) => chat.chat_id;
- public static implicit operator InputEncryptedChat(EncryptedChatBase chat) => new() { chat_id = chat.ID, access_hash = chat.AccessHash }; }
+ partial class InputEncryptedChat { public static implicit operator int(InputEncryptedChat chat) => chat.chat_id;
+ public static implicit operator InputEncryptedChat(EncryptedChatBase chat) => new() { chat_id = chat.ID, access_hash = chat.AccessHash }; }
partial class EncryptedFile
{
@@ -568,7 +560,7 @@ namespace TL
partial class Game { public static implicit operator InputGameID(Game game) => new() { id = game.id, access_hash = game.access_hash }; }
partial class WebDocument { public static implicit operator InputWebFileLocation(WebDocument doc) => new() { url = doc.url, access_hash = doc.access_hash }; }
- partial class PhoneCallBase { public static implicit operator InputPhoneCall(PhoneCallBase call) => new() { id = call.ID, access_hash = call.AccessHash }; }
+ partial class PhoneCallBase { public static implicit operator InputPhoneCall(PhoneCallBase call) => new() { id = call.ID, access_hash = call.AccessHash }; }
partial class InputMessage
{
@@ -587,11 +579,11 @@ namespace TL
}
partial class JsonObjectValue { public override string ToString() => $"{HttpUtility.JavaScriptStringEncode(key, true)}:{value}"; }
- partial class JSONValue { public abstract object ToNative(); }
- partial class JsonNull { public override object ToNative() => null; public override string ToString() => "null"; }
- partial class JsonBool { public override object ToNative() => value; public override string ToString() => value ? "true" : "false"; }
- partial class JsonNumber { public override object ToNative() => value; public override string ToString() => value.ToString(CultureInfo.InvariantCulture); }
- partial class JsonString { public override object ToNative() => value; public override string ToString() => HttpUtility.JavaScriptStringEncode(value, true); }
+ partial class JSONValue { public abstract object ToNative(); }
+ partial class JsonNull { public override object ToNative() => null; public override string ToString() => "null"; }
+ partial class JsonBool { public override object ToNative() => value; public override string ToString() => value ? "true" : "false"; }
+ partial class JsonNumber { public override object ToNative() => value; public override string ToString() => value.ToString(CultureInfo.InvariantCulture); }
+ partial class JsonString { public override object ToNative() => value; public override string ToString() => HttpUtility.JavaScriptStringEncode(value, true); }
partial class JsonArray
{
public override string ToString()
@@ -649,13 +641,6 @@ namespace TL
}
}
- partial class Theme
- {
- public static implicit operator InputTheme(Theme theme) => new() { id = theme.id, access_hash = theme.access_hash };
- }
-
- partial class GroupCallBase
- {
- public static implicit operator InputGroupCall(GroupCallBase call) => new() { id = call.ID, access_hash = call.AccessHash };
- }
+ partial class Theme { public static implicit operator InputTheme(Theme theme) => new() { id = theme.id, access_hash = theme.access_hash }; }
+ partial class GroupCallBase { public static implicit operator InputGroupCall(GroupCallBase call) => new() { id = call.ID, access_hash = call.AccessHash }; }
}
diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj
index eccde27..3b1b4a8 100644
--- a/src/WTelegramClient.csproj
+++ b/src/WTelegramClient.csproj
@@ -13,7 +13,7 @@
WTelegramClient
0.0.0
Wizou
- Telegram Client API library written 100% in C# and .NET Standard | Latest MTProto & Telegram API layer version
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: 149
Release Notes:
$(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))
Copyright © Olivier Marcoux 2021-2022
MIT
https://github.com/wiz0u/WTelegramClient
@@ -21,7 +21,7 @@
true
https://github.com/wiz0u/WTelegramClient.git
git
- Telegram;Client;Api;UserBot;MTProto;TLSharp;OpenTl
+ Telegram;MTProto;Client;Api;UserBot;TLSharp
README.md
$(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))
IDE0079;0419;1573;1591;NETSDK1138
From 231bf632e2dddbb838e702e8f66bdf959bc90fd5 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Mon, 5 Dec 2022 20:32:32 +0100
Subject: [PATCH 026/336] Custom emoji Markdown/Html syntax updated for tdlib
compatibility - Markdown:  - Html: Previous syntaxes are still accepted Also, changed Github
examples links with ts=4
---
EXAMPLES.md | 20 ++++++++++----------
FAQ.md | 2 +-
README.md | 18 +++++++++---------
src/Client.Helpers.cs | 2 +-
src/Client.cs | 2 +-
src/TL.Extensions.cs | 17 ++++++++++-------
6 files changed, 32 insertions(+), 29 deletions(-)
diff --git a/EXAMPLES.md b/EXAMPLES.md
index 654e117..f62efda 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -95,7 +95,7 @@ foreach (Dialog dialog in dialogs.dialogs)
Notes:
- The lists returned by Messages_GetAllDialogs contains the `access_hash` for those chats and users.
-- See also the `Main` method in [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs#L20).
+- See also the `Main` method in [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L20).
- To retrieve the dialog information about a specific [peer](README.md#terminology), use `client.Messages_GetPeerDialogs(inputPeer)`
@@ -114,7 +114,7 @@ Notes:
- The list returned by Messages_GetAllChats contains the `access_hash` for those chats. Read [FAQ #4](FAQ.md#access-hash) about this.
- If a basic chat group has been migrated to a supergroup, you may find both the old `Chat` and a `Channel` with different IDs in the `chats.chats` result,
but the old `Chat` will be marked with flag [deactivated] and should not be used anymore. See [Terminology in ReadMe](README.md#terminology).
-- You can find a longer version of this method call in [Examples/Program_GetAllChats.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_GetAllChats.cs#L32)
+- You can find a longer version of this method call in [Examples/Program_GetAllChats.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_GetAllChats.cs?ts=4#L32)
## List the members from a chat
@@ -189,14 +189,14 @@ Notes:
This is done through the `client.OnUpdate` callback event.
Your event handler implementation can either return `Task.CompletedTask` or be an `async Task` method.
-See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs#L23).
+See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L23).
## Monitor new messages being posted in chats in real-time
You have to handle `client.OnUpdate` events containing an `UpdateNewMessage`.
-See the `DisplayMessage` method in [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs#L23).
+See the `DisplayMessage` method in [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L23).
You can filter specific chats the message are posted in, by looking at the `Message.peer_id` field.
@@ -206,7 +206,7 @@ You can filter specific chats the message are posted in, by looking at the `Mess
This is done using the helper method `client.DownloadFileAsync(file, outputStream)`
that simplifies the download of a photo/document/file once you get a reference to its location *(through updates or API calls)*.
-See [Examples/Program_DownloadSavedMedia.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_DownloadSavedMedia.cs#L31) that download all media files you forward to yourself (Saved Messages)
+See [Examples/Program_DownloadSavedMedia.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_DownloadSavedMedia.cs?ts=4#L31) that download all media files you forward to yourself (Saved Messages)
## Upload a media file and post it with caption to a chat
@@ -323,10 +323,10 @@ await Task.Delay(5000);
## Fun with custom emojies and reactions on pinned messages
```csharp
// • Sending a message with custom emojies in Markdown to ourself:
-var text = "Vicksy says Hi! [👋](emoji?id=5190875290439525089)";
+var text = "Vicksy says Hi! ";
var entities = client.MarkdownToEntities(ref text, premium: true);
await client.SendMessageAsync(InputPeer.Self, text, entities: entities);
-// also available in HTML: 👋
+// also available in HTML: 👋
// • Fetch all available standard emoji reactions
var all_emoji = await client.Messages_GetAvailableReactions();
@@ -448,7 +448,7 @@ You can automate the collection of `access_hash` for the various resources obtai
so that you don't have to remember them by yourself or ask the API about them each time.
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#L22) for how to enable it, and save/restore them for later use.
+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.
## Use a proxy or MTProxy to connect to Telegram
@@ -509,14 +509,14 @@ you can choose to store the session data somewhere else, like in a database.
The WTelegram.Client constructor takes an optional `sessionStore` parameter to allow storing sessions in an alternate manner.
Use it to pass a custom Stream-derived class that will **read** (first initial call to Length & Read) and **store** (subsequent Writes) session data to database.
-You can find an example for such custom session store in [Examples/Program_Heroku.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_Heroku.cs#L61)
+You can find an example for such custom session store in [Examples/Program_Heroku.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_Heroku.cs?ts=4#L61)
## Send/receive end-to-end encrypted messages & files in Secret Chats
This can be done easily using the helper class `WTelegram.SecretChats` offering methods to manage/encrypt/decrypt secret chats & encrypted messages/files.
-You can view a full working example at [Examples/Program_SecretChats.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_SecretChats.cs#L11).
+You can view a full working example at [Examples/Program_SecretChats.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_SecretChats.cs?ts=4#L11).
Secret Chats have been tested successfully with Telegram Android & iOS official clients.
You can also check our [FAQ for more implementation details](FAQ.md#14-secret-chats-implementation-details).
\ No newline at end of file
diff --git a/FAQ.md b/FAQ.md
index 4d388e9..2363f45 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -243,7 +243,7 @@ and hosted online on any [VPS Hosting](https://www.google.com/search?q=vps+hosti
Pure WebApp hosts might not be adequate as they will recycle (stop) your app if there is no incoming HTTP requests.
There are many cheap VPS Hosting offers available, for example Heroku:
-See [Examples/Program_Heroku.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_Heroku.cs#L9) for such an implementation and the steps to host/deploy it.
+See [Examples/Program_Heroku.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_Heroku.cs?ts=4#L9) for such an implementation and the steps to host/deploy it.
## 14. Secret Chats implementation details
diff --git a/README.md b/README.md
index 7aacdc3..028de8d 100644
--- a/README.md
+++ b/README.md
@@ -156,23 +156,23 @@ and in the [Examples subdirectory](https://github.com/wiz0u/WTelegramClient/tree
# Terminology in Telegram Client API
In the API, Telegram uses some terms/classnames that can be confusing as they differ from the terms shown to end-users:
-- `Channel` : A (large or public) chat group *(sometimes called [supergroup](https://corefork.telegram.org/api/channel#supergroups))*
+- `Channel`: A (large or public) chat group *(sometimes called [supergroup](https://corefork.telegram.org/api/channel#supergroups))*,
or a [broadcast channel](https://corefork.telegram.org/api/channel#channels) (the `broadcast` flag differentiate those)
-- `Chat` : A private [basic chat group](https://corefork.telegram.org/api/channel#basic-groups) with less than 200 members
+- `Chat`: A private [basic chat group](https://corefork.telegram.org/api/channel#basic-groups) with less than 200 members
(it may be migrated to a supergroup `Channel` with a new ID when it gets bigger or public, in which case the old `Chat` will still exist but will be `deactivated`)
**⚠️ Most chat groups you see are really of type `Channel`, not `Chat`!**
-- chats : In plural or general meaning, it means either `Chat` or `Channel` *(therefore, no private user discussions)*
-- `Peer` : Either a `Chat`, a `Channel` or a `User`
-- Dialog : Status of chat with a `Peer` *(draft, last message, unread count, pinned...)*. It represents each line from your Telegram chat list.
-- Access Hash : Telegram requires you to provide a specific `access_hash` for users, channels, and other resources before interacting with them.
+- **chats**: In plural or general meaning, it means either `Chat` or `Channel` *(therefore, no private user discussions)*
+- `Peer`: Either a `Chat`, a `Channel` or a `User`
+- **Dialog**: Status of chat with a `Peer` *(draft, last message, unread count, pinned...)*. It represents each line from your Telegram chat list.
+- **Access Hash**: Telegram requires you to provide a specific `access_hash` for users, channels, and other resources before interacting with them.
See [FAQ #4](https://wiz0u.github.io/WTelegramClient/FAQ#access-hash) to learn more about it.
-- DC (DataCenter) : There are a few datacenters depending on where in the world the user (or an uploaded media file) is from.
-- Session or Authorization : Pairing between a device and a phone number. You can have several active sessions for the same phone number.
+- **DC** (DataCenter): There are a few datacenters depending on where in the world the user (or an uploaded media file) is from.
+- **Session** or **Authorization**: Pairing between a device and a phone number. You can have several active sessions for the same phone number.
# Other things to know
The Client class also offers an `OnUpdate` event that is triggered when Telegram servers sends Updates (like new messages or status), independently of your API requests.
-See [Examples/Program_ListenUpdates.cs](https://wiz0u.github.io/WTelegramClient/Examples/Program_ListenUpdates.cs)
+See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L23)
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.
diff --git a/src/Client.Helpers.cs b/src/Client.Helpers.cs
index 30da842..f9adc37 100644
--- a/src/Client.Helpers.cs
+++ b/src/Client.Helpers.cs
@@ -25,7 +25,7 @@ namespace WTelegram
/// 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
+ /// 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
{
diff --git a/src/Client.cs b/src/Client.cs
index af5234e..7918d1f 100644
--- a/src/Client.cs
+++ b/src/Client.cs
@@ -24,7 +24,7 @@ namespace WTelegram
public partial class Client : IDisposable
{
/// This event will be called when unsollicited updates/messages are sent by Telegram servers
- /// Make your handler , or return or
See Examples/Program_ListenUpdate.cs for how to use this
+ /// Make your handler , or return or
See Examples/Program_ListenUpdate.cs for how to use this
public event Func OnUpdate;
/// Used to create a TcpClient connected to the given address/port, or throw an exception on failure
public TcpFactory TcpHandler { get; set; } = DefaultTcpHandler;
diff --git a/src/TL.Extensions.cs b/src/TL.Extensions.cs
index f028131..fb18172 100644
--- a/src/TL.Extensions.cs
+++ b/src/TL.Extensions.cs
@@ -91,6 +91,9 @@ namespace TL
else
ProcessEntity();
break;
+ case '!' when offset + 1 < sb.Length && sb[offset + 1] == '[':
+ sb.Remove(offset, 1);
+ goto case '[';
case '[':
entities.Add(new MessageEntityTextUrl { offset = offset, length = -1 });
sb.Remove(offset, 1);
@@ -112,7 +115,7 @@ namespace TL
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)
entities[lastIndex] = new InputMessageEntityMentionName { offset = textUrl.offset, length = textUrl.length, user_id = new InputUser(id, hash) };
- else if (textUrl.url.StartsWith("emoji?id=") && long.TryParse(textUrl.url[9..], out id))
+ 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 };
else entities.RemoveAt(lastIndex);
sb.Remove(offset, offset2 - offset);
@@ -165,7 +168,7 @@ namespace TL
if (entityToMD.TryGetValue(nextEntity.GetType(), out var md))
{
var closing = (nextEntity.offset + nextEntity.length, md);
- if (md[0] == '[')
+ if (md[0] is '[' or '!')
{
if (nextEntity is MessageEntityTextUrl metu)
closing.md = $"]({metu.url.Replace("\\", "\\\\").Replace(")", "\\)").Replace(">", "%3E")})";
@@ -174,7 +177,7 @@ namespace TL
else if (nextEntity is InputMessageEntityMentionName imemn)
closing.md = $"](tg://user?id={imemn.user_id.UserId ?? client.UserId})";
else if (nextEntity is MessageEntityCustomEmoji mecu)
- if (premium) closing.md = $"](emoji?id={mecu.document_id})";
+ if (premium) closing.md = $"](tg://emoji?id={mecu.document_id})";
else continue;
}
else if (nextEntity is MessageEntityPre mep)
@@ -208,7 +211,7 @@ namespace TL
[typeof(MessageEntityUnderline)] = "__",
[typeof(MessageEntityStrike)] = "~",
[typeof(MessageEntitySpoiler)] = "||",
- [typeof(MessageEntityCustomEmoji)] = "[",
+ [typeof(MessageEntityCustomEmoji)] = "![",
};
/// Insert backslashes in front of Markdown reserved characters
@@ -304,8 +307,8 @@ namespace TL
if (entities.LastOrDefault(e => e.length == -1) is MessageEntityPre prevEntity)
prevEntity.language = tag[21..^1];
}
- else if (premium && tag.StartsWith("tg-emoji id=\""))
- entities.Add(new MessageEntityCustomEmoji { offset = offset, length = -1, document_id = long.Parse(tag[13..^1]) });
+ else if (premium && (tag.StartsWith("tg-emoji emoji-id=\"") || tag.StartsWith("tg-emoji id=\"")))
+ entities.Add(new MessageEntityCustomEmoji { offset = offset, length = -1, document_id = long.Parse(tag[(tag.IndexOf('=') + 2)..^1]) });
break;
}
@@ -361,7 +364,7 @@ namespace TL
tag = $"";
}
else if (nextEntity is MessageEntityCustomEmoji mecu)
- if (premium) tag = $"";
+ if (premium) tag = $"";
else continue;
else if (nextEntity is MessageEntityPre mep && !string.IsNullOrEmpty(mep.language))
{
From eb2577beedd7770c3353d2e8a6f39c1ccf7ae961 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Wed, 7 Dec 2022 13:36:49 +0100
Subject: [PATCH 027/336] Upgrade to layer 150: Anti-Spam, web/contact tokens,
chat TTL, hide topics, Fragment login
---
README.md | 2 +-
src/TL.Schema.cs | 50 ++++++++++++++-
src/TL.SchemaFuncs.cs | 122 ++++++++++++++++++++++++++++++++++---
src/TL.Table.cs | 12 ++--
src/WTelegramClient.csproj | 2 +-
5 files changed, 171 insertions(+), 17 deletions(-)
diff --git a/README.md b/README.md
index 028de8d..ccb1edf 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 3da5301..908cd31 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -1344,6 +1344,7 @@ namespace TL
{
/// Can we delete this channel?
can_delete_channel = 0x1,
+ antispam = 0x2,
}
/// ID of the channel
@@ -2103,11 +2104,19 @@ namespace TL
public long[] users;
}
/// The Time-To-Live of messages in this chat was changed. See
- [TLDef(0xAA1AFBFD)]
+ [TLDef(0x3C134D7B)]
public class MessageActionSetMessagesTTL : MessageAction
{
+ public Flags flags;
/// New Time-To-Live
public int period;
+ [IfFlag(0)] public long auto_setting_from;
+
+ [Flags] public enum Flags : uint
+ {
+ /// Field has a value
+ has_auto_setting_from = 0x1,
+ }
}
/// A group call was scheduled See
[TLDef(0xB3A07661)]
@@ -2168,19 +2177,21 @@ namespace TL
}
}
/// See
- [TLDef(0xB18A431C)]
+ [TLDef(0xC0944820)]
public class MessageActionTopicEdit : MessageAction
{
public Flags flags;
[IfFlag(0)] public string title;
[IfFlag(1)] public long icon_emoji_id;
[IfFlag(2)] public bool closed;
+ [IfFlag(3)] public bool hidden;
[Flags] public enum Flags : uint
{
has_title = 0x1,
has_icon_emoji_id = 0x2,
has_closed = 0x4,
+ has_hidden = 0x8,
}
}
@@ -2193,7 +2204,7 @@ namespace TL
public virtual int TopMessage { get; }
}
/// Chat See
- [TLDef(0xA8EDD0F5)]
+ [TLDef(0xD58A08C6)]
public class Dialog : DialogBase
{
/// Flags, see TL conditional fields
@@ -2220,6 +2231,7 @@ namespace TL
[IfFlag(1)] public DraftMessageBase draft;
/// Peer folder ID, for more info click here
[IfFlag(4)] public int folder_id;
+ [IfFlag(5)] public int ttl_period;
[Flags] public enum Flags : uint
{
@@ -2233,6 +2245,8 @@ namespace TL
unread_mark = 0x8,
/// Field has a value
has_folder_id = 0x10,
+ /// Field has a value
+ has_ttl_period = 0x20,
}
/// The chat
@@ -7754,6 +7768,8 @@ namespace TL
FlashCall = 0x226CCEFB,
///The next time, the authentication code will be delivered via an immediately canceled incoming call, handled manually by the user.
MissedCall = 0xD61AD6EE,
+ ///See
+ FragmentSms = 0x06ED998C,
}
/// Type of the verification code that was sent See Derived classes: , , , , , ,
@@ -7831,6 +7847,12 @@ namespace TL
google_signin_allowed = 0x2,
}
}
+ /// See
+ [TLDef(0xD9565C39)]
+ public class Auth_SentCodeTypeFragmentSms : Auth_SentCodeTypeSms
+ {
+ public string url;
+ }
/// Callback answer sent by the bot in response to a button press See
[TLDef(0x36585EA4)]
@@ -10049,6 +10071,12 @@ namespace TL
has_new_topic = 0x2,
}
}
+ /// See
+ [TLDef(0x64F36DFC)]
+ public class ChannelAdminLogEventActionToggleAntiSpam : ChannelAdminLogEventAction
+ {
+ public bool new_value;
+ }
/// Admin log event See
[TLDef(0x1FAD68CD)]
@@ -13954,6 +13982,7 @@ namespace TL
pinned = 0x8,
has_draft = 0x10,
short_ = 0x20,
+ hidden = 0x40,
}
public override int ID => id;
@@ -13978,4 +14007,19 @@ namespace TL
/// returns a or for the given Peer
public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats);
}
+
+ /// See
+ [TLDef(0x43B46B20)]
+ public class DefaultHistoryTTL : IObject
+ {
+ public int period;
+ }
+
+ /// See
+ [TLDef(0x41BF109B)]
+ public class ExportedContactToken : IObject
+ {
+ public string url;
+ public DateTime expires;
+ }
}
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index 93ac53c..66f7c00 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -286,6 +286,15 @@ namespace TL
code = code,
});
+ /// See
+ public static Task Auth_ImportWebTokenAuthorization(this Client client, int api_id, string api_hash, string web_auth_token)
+ => client.Invoke(new Auth_ImportWebTokenAuthorization
+ {
+ api_id = api_id,
+ api_hash = api_hash,
+ web_auth_token = web_auth_token,
+ });
+
/// 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.
@@ -1282,6 +1291,19 @@ namespace TL
phone = phone,
});
+ /// See
+ public static Task Contacts_ExportContactToken(this Client client)
+ => client.Invoke(new Contacts_ExportContactToken
+ {
+ });
+
+ /// See
+ public static Task Contacts_ImportContactToken(this Client client, string token)
+ => client.Invoke(new Contacts_ImportContactToken
+ {
+ token = token,
+ });
+
/// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Returns the list of messages by their IDs. See [bots: ✓]
/// Message ID list
public static Task Messages_GetMessages(this Client client, params InputMessage[] id)
@@ -1603,11 +1625,13 @@ namespace TL
/// Creates a new chat. See Possible codes: 400,403,500 (details)
/// List of user IDs to be invited
/// Chat name
- public static Task Messages_CreateChat(this Client client, InputUserBase[] users, string title)
+ public static Task Messages_CreateChat(this Client client, InputUserBase[] users, string title, int? ttl_period = null)
=> client.Invoke(new Messages_CreateChat
{
+ flags = (Messages_CreateChat.Flags)(ttl_period != null ? 0x1 : 0),
users = users,
title = title,
+ ttl_period = ttl_period.GetValueOrDefault(),
});
/// Returns configuration parameters for Diffie-Hellman key generation. Can also return a random sequence of bytes of required length. See Possible codes: 400 (details)
@@ -3419,6 +3443,19 @@ namespace TL
id = id,
});
+ /// See
+ public static Task Messages_SetDefaultHistoryTTL(this Client client, int period)
+ => client.Invoke(new Messages_SetDefaultHistoryTTL
+ {
+ period = period,
+ });
+
+ /// See
+ public static Task Messages_GetDefaultHistoryTTL(this Client client)
+ => client.Invoke(new Messages_GetDefaultHistoryTTL
+ {
+ });
+
/// Returns a current state of updates. See [bots: ✓]
public static Task Updates_GetState(this Client client)
=> client.Invoke(new Updates_GetState
@@ -3867,14 +3904,15 @@ namespace TL
/// Channel description
/// Geogroup location
/// Geogroup address
- public static Task Channels_CreateChannel(this Client client, string title, string about, bool broadcast = false, bool megagroup = false, bool for_import = false, InputGeoPoint geo_point = null, string address = null)
+ public static Task Channels_CreateChannel(this Client client, string title, string about, bool broadcast = false, bool megagroup = false, bool for_import = false, InputGeoPoint geo_point = null, string address = null, int? ttl_period = null)
=> client.Invoke(new Channels_CreateChannel
{
- flags = (Channels_CreateChannel.Flags)((broadcast ? 0x1 : 0) | (megagroup ? 0x2 : 0) | (for_import ? 0x8 : 0) | (geo_point != null ? 0x4 : 0) | (address != null ? 0x4 : 0)),
+ flags = (Channels_CreateChannel.Flags)((broadcast ? 0x1 : 0) | (megagroup ? 0x2 : 0) | (for_import ? 0x8 : 0) | (geo_point != null ? 0x4 : 0) | (address != null ? 0x4 : 0) | (ttl_period != null ? 0x10 : 0)),
title = title,
about = about,
geo_point = geo_point,
address = address,
+ ttl_period = ttl_period.GetValueOrDefault(),
});
/// Modify the admin rights of a user in a supergroup/channel. See [bots: ✓] Possible codes: 400,403,406 (details)
@@ -4268,15 +4306,16 @@ namespace TL
});
/// See
- public static Task Channels_EditForumTopic(this Client client, InputChannelBase channel, int topic_id, string title = null, long? icon_emoji_id = null, bool? closed = default)
+ public static Task Channels_EditForumTopic(this Client client, InputChannelBase channel, int topic_id, string title = null, long? icon_emoji_id = null, bool? closed = default, bool? hidden = default)
=> client.Invoke(new Channels_EditForumTopic
{
- flags = (Channels_EditForumTopic.Flags)((title != null ? 0x1 : 0) | (icon_emoji_id != null ? 0x2 : 0) | (closed != default ? 0x4 : 0)),
+ flags = (Channels_EditForumTopic.Flags)((title != null ? 0x1 : 0) | (icon_emoji_id != null ? 0x2 : 0) | (closed != default ? 0x4 : 0) | (hidden != default ? 0x8 : 0)),
channel = channel,
topic_id = topic_id,
title = title,
icon_emoji_id = icon_emoji_id.GetValueOrDefault(),
closed = closed.GetValueOrDefault(),
+ hidden = hidden.GetValueOrDefault(),
});
/// See
@@ -4305,6 +4344,22 @@ namespace TL
order = order,
});
+ /// See
+ public static Task Channels_ToggleAntiSpam(this Client client, InputChannelBase channel, bool enabled)
+ => client.Invoke(new Channels_ToggleAntiSpam
+ {
+ channel = channel,
+ enabled = enabled,
+ });
+
+ /// See
+ public static Task Channels_ReportAntiSpamFalsePositive(this Client client, InputChannelBase channel, int msg_id)
+ => client.Invoke(new Channels_ReportAntiSpamFalsePositive
+ {
+ channel = channel,
+ msg_id = msg_id,
+ });
+
/// Sends a custom request; for bots only See [bots: ✓] Possible codes: 400,403 (details)
/// The method name
/// JSON-serialized method parameters
@@ -5274,6 +5329,14 @@ namespace TL.Methods
public string code;
}
+ [TLDef(0x2DB873A9)]
+ public class Auth_ImportWebTokenAuthorization : IMethod
+ {
+ public int api_id;
+ public string api_hash;
+ public string web_auth_token;
+ }
+
[TLDef(0xEC86017A)]
public class Account_RegisterDevice : IMethod
{
@@ -6049,6 +6112,15 @@ namespace TL.Methods
public string phone;
}
+ [TLDef(0xF8654027)]
+ public class Contacts_ExportContactToken : IMethod { }
+
+ [TLDef(0x13005788)]
+ public class Contacts_ImportContactToken : IMethod
+ {
+ public string token;
+ }
+
[TLDef(0x63C66506)]
public class Messages_GetMessages : IMethod
{
@@ -6324,11 +6396,18 @@ namespace TL.Methods
}
}
- [TLDef(0x09CB126E)]
+ [TLDef(0x0034A818)]
public class Messages_CreateChat : IMethod
{
+ public Flags flags;
public InputUserBase[] users;
public string title;
+ [IfFlag(0)] public int ttl_period;
+
+ [Flags] public enum Flags : uint
+ {
+ has_ttl_period = 0x1,
+ }
}
[TLDef(0x26CF8950)]
@@ -7862,6 +7941,15 @@ namespace TL.Methods
public int[] id;
}
+ [TLDef(0x9EB51445)]
+ public class Messages_SetDefaultHistoryTTL : IMethod
+ {
+ public int period;
+ }
+
+ [TLDef(0x658B7188)]
+ public class Messages_GetDefaultHistoryTTL : IMethod { }
+
[TLDef(0xEDD4882A)]
public class Updates_GetState : IMethod { }
@@ -8172,7 +8260,7 @@ namespace TL.Methods
public InputChannelBase channel;
}
- [TLDef(0x3D5FB10F)]
+ [TLDef(0x91006707)]
public class Channels_CreateChannel : IMethod
{
public Flags flags;
@@ -8180,6 +8268,7 @@ namespace TL.Methods
public string about;
[IfFlag(2)] public InputGeoPoint geo_point;
[IfFlag(2)] public string address;
+ [IfFlag(4)] public int ttl_period;
[Flags] public enum Flags : uint
{
@@ -8187,6 +8276,7 @@ namespace TL.Methods
megagroup = 0x2,
has_geo_point = 0x4,
for_import = 0x8,
+ has_ttl_period = 0x10,
}
}
@@ -8505,7 +8595,7 @@ namespace TL.Methods
public int[] topics;
}
- [TLDef(0x6C883E2D)]
+ [TLDef(0xF4DFA185)]
public class Channels_EditForumTopic : IMethod
{
public Flags flags;
@@ -8514,12 +8604,14 @@ namespace TL.Methods
[IfFlag(0)] public string title;
[IfFlag(1)] public long icon_emoji_id;
[IfFlag(2)] public bool closed;
+ [IfFlag(3)] public bool hidden;
[Flags] public enum Flags : uint
{
has_title = 0x1,
has_icon_emoji_id = 0x2,
has_closed = 0x4,
+ has_hidden = 0x8,
}
}
@@ -8551,6 +8643,20 @@ namespace TL.Methods
}
}
+ [TLDef(0x68F3E4EB)]
+ public class Channels_ToggleAntiSpam : IMethod
+ {
+ public InputChannelBase channel;
+ public bool enabled;
+ }
+
+ [TLDef(0xA850A693)]
+ public class Channels_ReportAntiSpamFalsePositive : IMethod
+ {
+ public InputChannelBase channel;
+ public int msg_id;
+ }
+
[TLDef(0xAA2769ED)]
public class Bots_SendCustomRequest : IMethod
{
diff --git a/src/TL.Table.cs b/src/TL.Table.cs
index d991db7..f1f9db4 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 = 149; // fetched 23/11/2022 13:15:45
+ public const int Version = 150; // fetched 07/12/2022 12:23:35
internal const int SecretChats = 144;
internal const int MTProto2 = 73;
internal const uint VectorCtor = 0x1CB5C415;
@@ -184,7 +184,7 @@ namespace TL
[0x98E0D697] = typeof(MessageActionGeoProximityReached),
[0x7A0D7F42] = typeof(MessageActionGroupCall),
[0x502F92F7] = typeof(MessageActionInviteToGroupCall),
- [0xAA1AFBFD] = typeof(MessageActionSetMessagesTTL),
+ [0x3C134D7B] = typeof(MessageActionSetMessagesTTL),
[0xB3A07661] = typeof(MessageActionGroupCallScheduled),
[0xAA786345] = typeof(MessageActionSetChatTheme),
[0xEBBCA3CB] = typeof(MessageActionChatJoinedByRequest),
@@ -192,8 +192,8 @@ namespace TL
[0xB4C38CB5] = typeof(MessageActionWebViewDataSent),
[0xABA0F5C6] = typeof(MessageActionGiftPremium),
[0x0D999256] = typeof(MessageActionTopicCreate),
- [0xB18A431C] = typeof(MessageActionTopicEdit),
- [0xA8EDD0F5] = typeof(Dialog),
+ [0xC0944820] = typeof(MessageActionTopicEdit),
+ [0xD58A08C6] = typeof(Dialog),
[0x71BD134C] = typeof(DialogFolder),
[0x2331B22D] = typeof(PhotoEmpty),
[0xFB197A65] = typeof(Photo),
@@ -598,6 +598,7 @@ namespace TL
[0x82006484] = typeof(Auth_SentCodeTypeMissedCall),
[0x5A159841] = typeof(Auth_SentCodeTypeEmailCode),
[0xA5491DEA] = typeof(Auth_SentCodeTypeSetUpEmailRequired),
+ [0xD9565C39] = typeof(Auth_SentCodeTypeFragmentSms),
[0x36585EA4] = typeof(Messages_BotCallbackAnswer),
[0x26B5DDE6] = typeof(Messages_MessageEditData),
[0x890C3D89] = typeof(InputBotInlineMessageID),
@@ -763,6 +764,7 @@ namespace TL
[0xF06FE208] = typeof(ChannelAdminLogEventActionEditTopic),
[0xAE168909] = typeof(ChannelAdminLogEventActionDeleteTopic),
[0x5D8D353B] = typeof(ChannelAdminLogEventActionPinTopic),
+ [0x64F36DFC] = typeof(ChannelAdminLogEventActionToggleAntiSpam),
[0x1FAD68CD] = typeof(ChannelAdminLogEvent),
[0xED8AF74D] = typeof(Channels_AdminLogResults),
[0xEA107AE4] = typeof(ChannelAdminLogEventsFilter),
@@ -1047,6 +1049,8 @@ namespace TL
[0x023F109B] = typeof(ForumTopicDeleted),
[0x71701DA9] = typeof(ForumTopic),
[0x367617D3] = typeof(Messages_ForumTopics),
+ [0x43B46B20] = typeof(DefaultHistoryTTL),
+ [0x41BF109B] = typeof(ExportedContactToken),
// from TL.Secret:
[0x6ABD9782] = typeof(Layer143.DecryptedMessageMediaDocument),
[0x91CC4674] = typeof(Layer73.DecryptedMessage),
diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj
index 3b1b4a8..5718f70 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: 149
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: 150
Release Notes:
$(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))
Copyright © Olivier Marcoux 2021-2022
MIT
https://github.com/wiz0u/WTelegramClient
From aa9c4b532cad7a01e5f50c09a52ccc1866ab2e97 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Mon, 12 Dec 2022 10:07:07 +0100
Subject: [PATCH 028/336] Improved documentation
---
.github/dev.yml | 2 +-
EXAMPLES.md | 17 ++--
README.md | 2 +-
src/TL.Extensions.cs | 8 +-
src/TL.Helpers.cs | 2 +-
src/TL.Schema.cs | 186 +++++++++++++++++++++---------------------
src/TL.SchemaFuncs.cs | 86 +++++++++----------
7 files changed, 148 insertions(+), 155 deletions(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index 31ee239..da0ac65 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -2,7 +2,7 @@ pr: none
trigger:
- master
-name: 3.1.4-dev.$(Rev:r)
+name: 3.1.6-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/EXAMPLES.md b/EXAMPLES.md
index f62efda..de51ccf 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -352,7 +352,7 @@ var messages = await client.Messages_Search(chat, lim
foreach (var msg in messages.Messages)
await client.Messages_SendReaction(chat, msg.ID, reaction: new[] { reaction });
```
-*Note: you can find custom emoji document IDs via API methods like [Messages_GetFeaturedEmojiStickers](https://corefork.telegram.org/methods#working-with-custom-animated-emojis) or inspecting incoming messages. Access hash is not required*
+*Note: you can find custom emoji document IDs via API methods like [Messages_GetFeaturedEmojiStickers](https://corefork.telegram.org/methods#working-with-custom-animated-emojis) or inspecting messages entities. Access hash is not required*
@@ -371,7 +371,7 @@ To use them, you need to extract the `HASH` part from the URL and then you can u
```csharp
var chatInvite = await client.Messages_CheckChatInvite("HASH"); // optional: get information before joining
await client.Messages_ImportChatInvite("HASH"); // join the channel/group
-// Note: This works also with hash invite links of public channel/group
+// Note: This works also with HASH invite links from public channel/group
```
@@ -452,29 +452,22 @@ See [Examples/Program_CollectAccessHash.cs](https://github.com/wiz0u/WTelegramCl
## Use a proxy or MTProxy to connect to Telegram
-SOCKS/HTTPS proxies can be used through the `client.TcpHandler` delegate and a proxy library like [StarkSoftProxy](https://www.nuget.org/packages/StarkSoftProxy/):
+SOCKS/HTTPS proxies can be used through the `client.TcpHandler` delegate and a proxy library like [StarkSoftProxy](https://www.nuget.org/packages/StarkSoftProxy/) or [xNetStandard](https://www.nuget.org/packages/xNetStandard/):
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
client.TcpHandler = async (address, port) =>
{
var proxy = new Socks5ProxyClient(ProxyHost, ProxyPort, ProxyUsername, ProxyPassword);
+ //var proxy = xNet.Socks5ProxyClient.Parse("host:port:username:password");
return proxy.CreateConnection(address, port);
};
await client.LoginUserIfNeeded();
```
-or with [xNetStandard](https://www.nuget.org/packages/xNetStandard/):
-```csharp
-client.TcpHandler = async (address, port) =>
-{
- var proxy = xNet.Socks5ProxyClient.Parse("host:port:username:password");
- return proxy.CreateConnection(address, port);
-};
-```
MTProxy (MTProto proxy) can be used to prevent ISP blocking Telegram servers, through the `client.MTProxyUrl` property:
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
-client.MTProxyUrl = "http://t.me/proxy?server=...&port=...&secret=...";
+client.MTProxyUrl = "https://t.me/proxy?server=...&port=...&secret=...";
await client.LoginUserIfNeeded();
```
You can find a list of working MTProxies in channels like [@ProxyMTProto](https://t.me/ProxyMTProto) or [@MTProxyT](https://t.me/MTProxyT) *(right-click the "Connect" buttons)*
diff --git a/README.md b/README.md
index ccb1edf..caa4f31 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ If you run this program again, you will notice that only **api_hash** is request
This is because WTelegramClient saves (typically in the encrypted file **bin\WTelegram.session**) its state
and the authentication keys that were negotiated with Telegram so that you needn't sign-in again every time.
-That file path is configurable (session_pathname), and under various circumstances (changing user or server address)
+That file path is configurable (**session_pathname**), and under various circumstances (changing user or server address)
you may want to change it or simply delete the existing session file in order to restart the authentification process.
# Non-interactive configuration
diff --git a/src/TL.Extensions.cs b/src/TL.Extensions.cs
index fb18172..2c6f5b8 100644
--- a/src/TL.Extensions.cs
+++ b/src/TL.Extensions.cs
@@ -142,8 +142,8 @@ namespace TL
/// Converts the (plain text + entities) format used by Telegram messages into a Markdown text
/// Client, used only for getting current user ID in case of InputMessageEntityMentionName+InputUserSelf
- /// The plain text, typically obtained from
- /// The array of formatting entities, typically obtained from
+ /// The plain text, typically obtained from
+ /// 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)
@@ -329,8 +329,8 @@ namespace TL
/// Converts the (plain text + entities) format used by Telegram messages into an HTML-formatted text
/// Client, used only for getting current user ID in case of InputMessageEntityMentionName+InputUserSelf
- /// The plain text, typically obtained from
- /// The array of formatting entities, typically obtained from
+ /// The plain text, typically obtained from
+ /// 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)
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index b0abb38..21adbde 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -113,7 +113,7 @@ namespace TL
public static implicit operator InputMediaPhoto(InputPhoto photo) => new() { id = photo };
}
- /// Use the UserOrChat(peer) method from the root class you received, in order to convert this to a more useful or
+ /// Use the UserOrChat(peer) method from the root class you received, in order to convert this to a more useful or
partial class Peer
{
public abstract long ID { get; }
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index 908cd31..72c0a58 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -114,7 +114,7 @@ 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. 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
[TLDef(0xF392B7F4)]
public class InputPhoneContact : InputContact
{
@@ -138,7 +138,7 @@ namespace TL
/// Full name of the file
public virtual string Name { get; }
}
- /// Defines a file saved in parts using the method upload.saveFilePart. See
+ /// Defines a file saved in parts using the method Upload_SaveFilePart. See
[TLDef(0xF52FF27F)]
public partial class InputFile : InputFileBase
{
@@ -158,7 +158,7 @@ namespace TL
/// Full name of the file
public override string Name => name;
}
- /// Assigns a big file (over 10 MB in size), saved in part using the method upload.saveBigFilePart. See
+ /// Assigns a big file (over 10 MB in size), saved in part using the method Upload_SaveBigFilePart. See
[TLDef(0xFA4F0BB5)]
public partial class InputFileBig : InputFileBase
{
@@ -451,7 +451,7 @@ namespace TL
{
/// Flags, see TL conditional fields
public Flags flags;
- /// File saved in parts using the method upload.saveFilePart
+ /// File saved in parts using the method Upload_SaveFilePart
[IfFlag(0)] public InputFileBase file;
/// Square video for animated profile picture
[IfFlag(1)] public InputFileBase video;
@@ -559,7 +559,7 @@ namespace TL
/// Empty constructor for takeout See
[TLDef(0x29BE5899)]
public class InputTakeoutFileLocation : InputFileLocationBase { }
- /// Use this object to download a photo with upload.getFile method See
+ /// Use this object to download a photo with Upload_GetFile method See
[TLDef(0x40181FFE)]
public class InputPhotoFileLocation : InputFileLocationBase
{
@@ -720,7 +720,7 @@ namespace TL
[IfFlag(5)] public UserProfilePhoto photo;
/// Online status of user
[IfFlag(6)] public UserStatus status;
- /// Version of the , incremented every time it changes
+ /// Version of the bot_info field in userFull, incremented every time it changes
[IfFlag(14)] public int bot_info_version;
/// Contains the reason why access to this user must be restricted.
[IfFlag(18)] public RestrictionReason[] restriction_reason;
@@ -1012,9 +1012,9 @@ namespace TL
gigagroup = 0x4000000,
/// Whether this channel or group is protected, thus does not allow forwarding messages from it
noforwards = 0x8000000,
- /// Whether a user needs to join the supergroup before they can send messages: can be false only for discussion groups », toggle using channels.toggleJoinToSend
+ /// Whether a user needs to join the supergroup before they can send messages: can be false only for discussion groups », toggle using Channels_ToggleJoinToSend
join_to_send = 0x10000000,
- /// Whether a user's join request will have to be approved by administrators, toggle using channels.toggleJoinToSend
+ /// Whether a user's join request will have to be approved by administrators, toggle using Channels_ToggleJoinRequest
join_request = 0x20000000,
forum = 0x40000000,
}
@@ -1084,7 +1084,7 @@ namespace TL
public virtual InputGroupCall Call { get; }
/// Time-To-Live of messages sent by the current user to this chat
public virtual int TtlPeriod { get; }
- /// When using phone.getGroupCallJoinAs to get a list of peers that can be used to join a group call, this field indicates the peer that should be selected by default.
+ /// When using Phone_GetGroupCallJoinAs to get a list of peers that can be used to join a group call, this field indicates the peer that should be selected by default.
public virtual Peer GroupcallDefaultJoinAs { get; }
/// Emoji representing a specific chat theme
public virtual string ThemeEmoticon { get; }
@@ -1123,7 +1123,7 @@ namespace TL
[IfFlag(12)] public InputGroupCall call;
/// Time-To-Live of messages sent by the current user to this chat
[IfFlag(14)] public int ttl_period;
- /// When using phone.getGroupCallJoinAs to get a list of peers that can be used to join a group call, this field indicates the peer that should be selected by default.
+ /// When using Phone_GetGroupCallJoinAs to get a list of peers that can be used to join a group call, this field indicates the peer that should be selected by default.
[IfFlag(15)] public Peer groupcall_default_join_as;
/// Emoji representing a specific chat theme
[IfFlag(16)] public string theme_emoticon;
@@ -1184,7 +1184,7 @@ namespace TL
public override InputGroupCall Call => call;
/// Time-To-Live of messages sent by the current user to this chat
public override int TtlPeriod => ttl_period;
- /// When using phone.getGroupCallJoinAs to get a list of peers that can be used to join a group call, this field indicates the peer that should be selected by default.
+ /// When using Phone_GetGroupCallJoinAs to get a list of peers that can be used to join a group call, this field indicates the peer that should be selected by default.
public override Peer GroupcallDefaultJoinAs => groupcall_default_join_as;
/// Emoji representing a specific chat theme
public override string ThemeEmoticon => theme_emoticon;
@@ -1261,7 +1261,7 @@ namespace TL
[IfFlag(24)] public int ttl_period;
/// A list of suggested actions for the supergroup admin, see here for more info ».
[IfFlag(25)] public string[] pending_suggestions;
- /// When using phone.getGroupCallJoinAs to get a list of peers that can be used to join a group call, this field indicates the peer that should be selected by default.
+ /// When using Phone_GetGroupCallJoinAs to get a list of peers that can be used to join a group call, this field indicates the peer that should be selected by default.
[IfFlag(26)] public Peer groupcall_default_join_as;
/// Emoji representing a specific chat theme
[IfFlag(27)] public string theme_emoticon;
@@ -1290,7 +1290,7 @@ namespace TL
has_pinned_msg_id = 0x20,
/// Can we set the channel's username?
can_set_username = 0x40,
- /// Can we associate a stickerpack to the supergroup?
+ /// Can we Channels_SetStickers a stickerpack to the supergroup?
can_set_stickers = 0x80,
/// Field has a value
has_stickerset = 0x100,
@@ -1367,7 +1367,7 @@ namespace TL
public override InputGroupCall Call => call;
/// Time-To-Live of messages in this channel or supergroup
public override int TtlPeriod => ttl_period;
- /// When using phone.getGroupCallJoinAs to get a list of peers that can be used to join a group call, this field indicates the peer that should be selected by default.
+ /// When using Phone_GetGroupCallJoinAs to get a list of peers that can be used to join a group call, this field indicates the peer that should be selected by default.
public override Peer GroupcallDefaultJoinAs => groupcall_default_join_as;
/// Emoji representing a specific chat theme
public override string ThemeEmoticon => theme_emoticon;
@@ -1555,7 +1555,7 @@ namespace TL
[IfFlag(15)] public DateTime edit_date;
/// Name of the author of this message for channel posts (with signatures enabled)
[IfFlag(16)] public string post_author;
- /// Multiple media messages sent using messages.sendMultiMedia with the same grouped ID indicate an album or media group
+ /// Multiple media messages sent using Messages_SendMultiMedia with the same grouped ID indicate an album or media group
[IfFlag(17)] public long grouped_id;
/// Reactions to this message
[IfFlag(20)] public MessageReactions reactions;
@@ -2446,9 +2446,9 @@ namespace TL
public Flags flags;
/// Phone code type
public Auth_SentCodeType type;
- /// Phone code hash, to be stored and later re-used with auth.signIn
+ /// Phone code hash, to be stored and later re-used with Auth_SignIn
public string phone_code_hash;
- /// Phone code type that will be sent next, if the phone code is not received within timeout seconds: to send it use auth.resendCode
+ /// Phone code type that will be sent next, if the phone code is not received within timeout seconds: to send it use Auth_ResendCode
[IfFlag(1)] public Auth_CodeType next_type;
/// Timeout for reception of the phone code
[IfFlag(2)] public int timeout;
@@ -2630,7 +2630,7 @@ namespace TL
report_geo = 0x20,
/// Field has a value
has_geo_distance = 0x40,
- /// Whether this peer was automatically archived according to and can be unarchived
+ /// Whether this peer was automatically archived according to privacy settings and can be unarchived
autoarchived = 0x80,
/// If set, this is a recently created group chat to which new members can be invited
invite_members = 0x100,
@@ -2972,7 +2972,7 @@ namespace TL
public Flags flags;
/// Total number of messages in the list
public int count;
- /// Rate to use in the offset_rate parameter in the next call to messages.searchGlobal
+ /// Rate to use in the offset_rate parameter in the next call to Messages_SearchGlobal
[IfFlag(0)] public int next_rate;
/// Indicates the absolute position of messages[0] within the total result set with count count.
This is useful, for example, if the result was fetched using offset_id, and we need to display a progress/total counter (like photo 134 of 200, for all media in a chat, we could simply use photo ${offset_id_offset} of ${count}.
[IfFlag(2)] public int offset_id_offset;
@@ -3135,7 +3135,7 @@ namespace TL
/// 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
+ /// New message in a private chat or in a basic group. See
[TLDef(0x1F2B0AFD)]
public class UpdateNewMessage : Update
{
@@ -3508,7 +3508,7 @@ namespace TL
emojis = 0x2,
}
}
- /// The saved gif list has changed, the client should refetch it using messages.getSavedGifs See
+ /// The saved gif list has changed, the client should refetch it using Messages_GetSavedGifs See
[TLDef(0x9375341E)]
public class UpdateSavedGifs : Update { }
/// An incoming inline query See
@@ -3538,7 +3538,7 @@ namespace TL
has_peer_type = 0x2,
}
}
- /// The result of an inline query that was chosen by a user and sent to their chat partner. Please see our documentation on the feedback collecting for details on how to enable these updates for your bot. See
+ /// The result of an inline query that was chosen by a user and sent to their chat partner. Please see our documentation on the feedback collecting for details on how to enable these updates for your bot. See
[TLDef(0x12F12A07)]
public class UpdateBotInlineSend : Update
{
@@ -3665,7 +3665,7 @@ namespace TL
/// The recent sticker list was updated See
[TLDef(0x9A422C20)]
public class UpdateRecentStickers : Update { }
- /// The server-side configuration has changed; the client should re-fetch the config using help.getConfig See
+ /// The server-side configuration has changed; the client should re-fetch the config using Help_GetConfig See
[TLDef(0xA229DD06)]
public class UpdateConfig : Update { }
/// Common message box sequence PTS has changed, state has to be refetched using updates.getState See
@@ -3783,7 +3783,7 @@ namespace TL
/// Phone call
public PhoneCallBase phone_call;
}
- /// A language pack has changed, the client should manually fetch the changed strings using langpack.getDifference See
+ /// A language pack has changed, the client should manually fetch the changed strings using Langpack_GetDifference See
[TLDef(0x46560264)]
public class UpdateLangPackTooLong : Update
{
@@ -3797,7 +3797,7 @@ namespace TL
/// Changed strings
public LangPackDifference difference;
}
- /// The list of favorited stickers was changed, the client should call messages.getFavedStickers to refetch the new list See
+ /// The list of favorited stickers was changed, the client should call Messages_GetFavedStickers to refetch the new list See
[TLDef(0xE511996D)]
public class UpdateFavedStickers : Update { }
/// The specified channel/supergroup messages were read See
@@ -4294,10 +4294,10 @@ namespace TL
has_top_msg_id = 0x1,
}
}
- /// The list of installed attachment menu entries » has changed, use messages.getAttachMenuBots to fetch the updated list. See
+ /// The list of installed attachment menu entries » has changed, use Messages_GetAttachMenuBots to fetch the updated list. See
[TLDef(0x17B7A20B)]
public class UpdateAttachMenuBots : Update { }
- /// Indicates to a bot that a webview was closed and an inline message was sent on behalf of the user using messages.sendWebViewResultMessage See
+ /// Indicates to a bot that a webview was closed and an inline message was sent on behalf of the user using Messages_SendWebViewResultMessage See
[TLDef(0x1592B79D)]
public class UpdateWebViewResultSent : Update
{
@@ -4313,10 +4313,10 @@ namespace TL
/// New menu button
public BotMenuButtonBase button;
}
- /// The list of saved notification sounds has changed, use account.getSavedRingtones to fetch the new list. See
+ /// The list of saved notification sounds has changed, use Account_GetSavedRingtones to fetch the new list. See
[TLDef(0x74D8BE99)]
public class UpdateSavedRingtones : Update { }
- /// A pending voice message transcription » initiated with messages.transcribeAudio was updated. See
+ /// A pending voice message transcription » initiated with Messages_TranscribeAudio was updated. See
[TLDef(0x0084CD5A)]
public class UpdateTranscribedAudio : Update
{
@@ -4520,7 +4520,7 @@ namespace TL
/// returns a or for the given Peer
public abstract IPeerInfo UserOrChat(Peer peer);
}
- /// Too many updates, it is necessary to execute updates.getDifference. See
+ /// Too many updates, it is necessary to execute Updates_GetDifference. See
[TLDef(0xE317AF7E)]
public partial class UpdatesTooLong : UpdatesBase, IPeerResolver
{
@@ -4834,7 +4834,7 @@ namespace TL
public Flags flags;
/// Current date at the server
public DateTime date;
- /// Expiration date of this config: when it expires it'll have to be refetched using help.getConfig
+ /// Expiration date of this config: when it expires it'll have to be refetched using Help_GetConfig
public DateTime expires;
/// Whether we're connected to the test DCs
public bool test_mode;
@@ -4848,9 +4848,9 @@ namespace TL
public int chat_size_max;
/// Maximum member count for supergroups
public int megagroup_size_max;
- /// Maximum number of messages that can be forwarded at once using messages.forwardMessages.
+ /// Maximum number of messages that can be forwarded at once using Messages_ForwardMessages.
public int forwarded_count_max;
- /// The client should update its online status every N milliseconds
+ /// The client should Account_UpdateStatus every N milliseconds
public int online_update_period_ms;
/// Delay before offline status needs to be sent to the server
public int offline_blur_timeout_ms;
@@ -5214,7 +5214,7 @@ namespace TL
/// File ID, value of id parameter from
public override long ID => id;
}
- /// Assigns a new big encrypted file (over 10 MB in size), saved in parts using the method upload.saveBigFilePart. See
+ /// Assigns a new big encrypted file (over 10 MB in size), saved in parts using the method Upload_SaveBigFilePart. See
[TLDef(0x2DC173C8)]
public class InputEncryptedFileBigUploaded : InputEncryptedFileBase
{
@@ -6296,7 +6296,7 @@ namespace TL
[IfFlag(4)] public int thumb_dc_id;
/// Thumbnail version
[IfFlag(4)] public int thumb_version;
- /// Document ID of custom emoji thumbnail, fetch the document using messages.getCustomEmojiDocuments
+ /// Document ID of custom emoji thumbnail, fetch the document using Messages_GetCustomEmojiDocuments
[IfFlag(8)] public long thumb_document_id;
/// Number of stickers in pack
public int count;
@@ -6422,7 +6422,7 @@ namespace TL
[Flags] public enum Flags : uint
{
- /// Whether the user should verify his identity by entering his 2FA SRP parameters to the messages.getBotCallbackAnswer method. NOTE: telegram and the bot WILL NOT have access to the plaintext password, thanks to SRP. This button is mainly used by the official @botfather bot, for verifying the user's identity before transferring ownership of a bot to another user.
+ /// Whether the user should verify his identity by entering his 2FA SRP parameters to the Messages_GetBotCallbackAnswer method. NOTE: telegram and the bot WILL NOT have access to the plaintext password, thanks to SRP. This button is mainly used by the official @botfather bot, for verifying the user's identity before transferring ownership of a bot to another user.
requires_password = 0x1,
}
@@ -6469,7 +6469,7 @@ namespace TL
public class KeyboardButtonBuy : KeyboardButton
{
}
- /// Button to request a user to authorize via URL using Seamless Telegram Login. When the user clicks on such a button, messages.requestUrlAuth should be called, providing the button_id and the ID of the container message. The returned object will contain more details about the authorization request (request_write_access if the bot would like to send messages to the user along with the username of the bot which will be used for user authorization). Finally, the user can choose to call messages.acceptUrlAuth to get a with the URL to open instead of the url of this constructor, or a , in which case the url of this constructor must be opened, instead. If the user refuses the authorization request but still wants to open the link, the url of this constructor must be used. See
+ /// Button to request a user to authorize via URL using Seamless Telegram Login. When the user clicks on such a button, Messages_RequestUrlAuth should be called, providing the button_id and the ID of the container message. The returned object will contain more details about the authorization request (request_write_access if the bot would like to send messages to the user along with the username of the bot which will be used for user authorization). Finally, the user can choose to call Messages_AcceptUrlAuth to get a with the URL to open instead of the url of this constructor, or a , in which case the url of this constructor must be opened, instead. If the user refuses the authorization request but still wants to open the link, the url of this constructor must be used. See
[TLDef(0x10B78D29)]
public class KeyboardButtonUrlAuth : KeyboardButtonBase
{
@@ -6481,7 +6481,7 @@ namespace TL
[IfFlag(0)] public string fwd_text;
/// An HTTP URL to be opened with user authorization data added to the query string when the button is pressed. If the user refuses to provide authorization data, the original URL without information about the user will be opened. The data added is the same as described in Receiving authorization data.
NOTE: Services must always check the hash of the received data to verify the authentication and the integrity of the data as described in Checking authorization.
public string url;
- /// ID of the button to pass to messages.requestUrlAuth
+ /// ID of the button to pass to Messages_RequestUrlAuth
public int button_id;
[Flags] public enum Flags : uint
@@ -6493,7 +6493,7 @@ namespace TL
/// Button label
public override string Text => text;
}
- /// Button to request a user to authorize via URL using Seamless Telegram Login. See
+ /// Button to request a user to Messages_AcceptUrlAuth via URL using Seamless Telegram Login. See
[TLDef(0xD02E7FD4)]
public class InputKeyboardButtonUrlAuth : KeyboardButtonBase
{
@@ -6553,14 +6553,14 @@ namespace TL
/// User ID
public long user_id;
}
- /// Button to open a bot web app using messages.requestWebView, sending over user information after user confirmation. See
+ /// Button to open a bot web app using Messages_RequestWebView, sending over user information after user confirmation. See
[TLDef(0x13767230, inheritBefore = true)]
public class KeyboardButtonWebView : KeyboardButton
{
/// Web app url
public string url;
}
- /// Button to open a bot web app using messages.requestSimpleWebView, without sending user information to the web app. See
+ /// Button to open a bot web app using Messages_RequestSimpleWebView, without sending user information to the web app. See
[TLDef(0xA0C0505C)]
public class KeyboardButtonSimpleWebView : KeyboardButtonWebView
{
@@ -6727,7 +6727,7 @@ namespace TL
[TLDef(0xC8CF05F8, inheritBefore = true)]
public class MessageEntityCustomEmoji : MessageEntity
{
- /// Document ID of the custom emoji, use messages.getCustomEmojiDocuments to fetch the emoji animation and the actual emoji it represents.
+ /// Document ID of the custom emoji, use Messages_GetCustomEmojiDocuments to fetch the emoji animation and the actual emoji it represents.
public long document_id;
}
@@ -8172,7 +8172,7 @@ namespace TL
/// Stickerset
public override StickerSet Set => set;
}
- /// Stickerset preview with all stickers of the stickerset included.
Currently used only for custom emoji stickersets, to avoid a further call to messages.getStickerSet. See
+ /// Stickerset preview with all stickers of the stickerset included.
Currently used only for custom emoji stickersets, to avoid a further call to Messages_GetStickerSet. See
[TLDef(0x40D13C0E)]
public class StickerSetFullCovered : StickerSetCoveredBase
{
@@ -8965,7 +8965,7 @@ namespace TL
/// Map scale; 1-3
public int scale;
}
- /// Used to download an album cover for any music file using upload.getWebFile, see the webfile docs for more info ». See
+ /// Used to download an album cover for any music file using Upload_GetWebFile, see the webfile docs for more info ». See
[TLDef(0xF46FE924)]
public class InputWebFileAudioAlbumThumbLocation : InputWebFileLocationBase
{
@@ -9470,9 +9470,9 @@ namespace TL
has_reason = 0x1,
/// Field has a value
has_duration = 0x2,
- /// Whether the server required the user to rate the call
+ /// Whether the server required the user to Phone_SetCallRating the call
need_rating = 0x4,
- /// Whether the server required the client to send the libtgvoip call debug data
+ /// Whether the server required the client to Phone_SaveCallDebug the libtgvoip call debug data
need_debug = 0x8,
/// Whether the call was a video call
video = 0x40,
@@ -9573,7 +9573,7 @@ namespace TL
public int min_layer;
/// Maximum layer for remote libtgvoip
public int max_layer;
- /// When using phone.requestCall and phone.acceptCall, specify all library versions supported by the client.
The server will merge and choose the best library version supported by both peers, returning only the best value in the result of the callee's phone.acceptCall and in the update received by the caller.
+ /// When using Phone_RequestCall and Phone_AcceptCall, specify all library versions supported by the client.
The server will merge and choose the best library version supported by both peers, returning only the best value in the result of the callee's Phone_AcceptCall and in the update received by the caller.
public string[] library_versions;
[Flags] public enum Flags : uint
@@ -9862,7 +9862,7 @@ namespace TL
/// New stickerset
public InputStickerSet new_stickerset;
}
- /// The hidden prehistory setting was changed See
+ /// The hidden prehistory setting was Channels_TogglePreHistoryHidden See
[TLDef(0x5F5C95F1)]
public class ChannelAdminLogEventActionTogglePreHistoryHidden : ChannelAdminLogEventAction
{
@@ -9903,7 +9903,7 @@ namespace TL
/// New location
public ChannelLocation new_value;
}
- /// Slow mode setting for supergroups was changed See
+ /// Channels_ToggleSlowMode See
[TLDef(0x53909779)]
public class ChannelAdminLogEventActionToggleSlowMode : ChannelAdminLogEventAction
{
@@ -10115,33 +10115,33 @@ namespace TL
[Flags] public enum Flags : uint
{
- ///
+ /// Join events
join = 0x1,
- ///
+ /// Leave events
leave = 0x2,
- ///
+ /// Invite events
invite = 0x4,
- ///
+ /// Ban events
ban = 0x8,
- ///
+ /// Unban events
unban = 0x10,
- ///
+ /// Kick events
kick = 0x20,
- ///
+ /// Unkick events
unkick = 0x40,
- ///
+ /// Admin promotion events
promote = 0x80,
- ///
+ /// Admin demotion events
demote = 0x100,
- /// Info change events (when , , , , , or data of a channel gets modified)
+ /// Info change events (when about, linked chat, location, photo, stickerset, title or username data of a channel gets modified)
info = 0x200,
- /// Settings change events (, , , )
+ /// Settings change events (invites, hidden prehistory, signatures, default banned rights)
settings = 0x400,
- ///
+ /// Message pin events
pinned = 0x800,
- ///
+ /// Message edit events
edit = 0x1000,
- ///
+ /// Message deletion events
delete = 0x2000,
/// Group call events
group_call = 0x4000,
@@ -10228,7 +10228,7 @@ namespace TL
public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats);
}
- /// A single media in an album or grouped media sent with messages.sendMultiMedia. See
+ /// A single media in an album or grouped media sent with Messages_SendMultiMedia. See
[TLDef(0x1CC6E91F)]
public class InputSingleMedia : IObject
{
@@ -10386,14 +10386,14 @@ namespace TL
[TLDef(0xE3309F7F)]
public class Help_TermsOfServiceUpdateEmpty : Help_TermsOfServiceUpdateBase
{
- /// New TOS updates will have to be queried using help.getTermsOfServiceUpdate in expires seconds
+ /// New TOS updates will have to be queried using Help_GetTermsOfServiceUpdate in expires seconds
public DateTime expires;
}
- /// Info about an update of telegram's terms of service. If the terms of service are declined, then the account.deleteAccount method should be called with the reason "Decline ToS update" See
+ /// Info about an update of telegram's terms of service. If the terms of service are declined, then the Account_DeleteAccount method should be called with the reason "Decline ToS update" See
[TLDef(0x28ECF961)]
public class Help_TermsOfServiceUpdate : Help_TermsOfServiceUpdateBase
{
- /// New TOS updates will have to be queried using help.getTermsOfServiceUpdate in expires seconds
+ /// New TOS updates will have to be queried using Help_GetTermsOfServiceUpdate in expires seconds
public DateTime expires;
/// New terms of service
public Help_TermsOfService terms_of_service;
@@ -11143,7 +11143,7 @@ namespace TL
[Flags] public enum Flags : uint
{
- /// Indicates that not full page preview is available to the client and it will need to fetch full Instant View from the server using messages.getWebPagePreview.
+ /// Indicates that not full page preview is available to the client and it will need to fetch full Instant View from the server using Messages_GetWebPagePreview.
part = 0x1,
/// Whether the page contains RTL text
rtl = 0x2,
@@ -11183,7 +11183,7 @@ namespace TL
{
/// Textual representation of the answer
public string text;
- /// The param that has to be passed to messages.sendVote.
+ /// The param that has to be passed to Messages_SendVote.
public byte[] option;
}
@@ -11197,7 +11197,7 @@ namespace TL
public Flags flags;
/// The question of the poll
public string question;
- /// The possible answers, vote using messages.sendVote.
+ /// The possible answers, vote using Messages_SendVote.
public PollAnswer[] answers;
/// Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with close_date.
[IfFlag(4)] public int close_period;
@@ -11227,7 +11227,7 @@ namespace TL
{
/// Flags, see TL conditional fields
public Flags flags;
- /// The param that has to be passed to messages.sendVote.
+ /// The param that has to be passed to Messages_SendVote.
public byte[] option;
/// How many users voted for this option
public int voters;
@@ -11260,7 +11260,7 @@ namespace TL
[Flags] public enum Flags : uint
{
- /// Similar to min objects, used for poll constructors that are the same for all users so they don't have the option chosen by the current user (you can use messages.getPollResults to get the full poll results).
+ /// Similar to min objects, used for poll constructors that are the same for all users so they don't have the option chosen by the current user (you can use Messages_GetPollResults to get the full poll results).
min = 0x1,
/// Field has a value
has_results = 0x2,
@@ -11381,7 +11381,7 @@ namespace TL
/// Unique wallpaper ID
public string slug;
}
- /// Wallpaper with no file access hash, used for example when deleting (unsave=true) wallpapers using account.saveWallPaper, specifying just the wallpaper ID. See
+ /// Wallpaper with no file access hash, used for example when deleting (unsave=true) wallpapers using Account_SaveWallPaper, specifying just the wallpaper ID. See
[TLDef(0x967A462E)]
public class InputWallPaperNoFile : InputWallPaperBase
{
@@ -11591,7 +11591,7 @@ namespace TL
public int folder_id;
}
- /// Indicates how many results would be found by a messages.search call with the same parameters See
+ /// Indicates how many results would be found by a Messages_Search call with the same parameters See
[TLDef(0xE844EBFF)]
public class Messages_SearchCounter : IObject
{
@@ -11618,7 +11618,7 @@ namespace TL
{
/// Flags, see TL conditional fields
public Flags flags;
- /// Username of a bot, which will be used for user authorization. If not specified, the current bot's username will be assumed. The url's domain must be the same as the domain linked with the bot. See Linking your domain to the bot for more details.
+ /// Username of a bot, which will be used for user authorization. If not specified, the current bot's username will be assumed. The url's domain must be the same as the domain linked with the bot. See Linking your domain to the bot for more details.
public UserBase bot;
/// The domain name of the website on which the user will log in.
public string domain;
@@ -11850,7 +11850,7 @@ namespace TL
[IfFlag(3)] public int outbox_accent_color;
/// The fill to be used as a background for outgoing messages, in RGB24 format.
If just one or two equal colors are provided, describes a solid fill of a background.
If two different colors are provided, describes the top and bottom colors of a 0-degree gradient.
If three or four colors are provided, describes a freeform gradient fill of a background.
[IfFlag(0)] public int[] message_colors;
- /// or when passing wallpaper files for image or pattern wallpapers, with id=0 otherwise.
+ /// or inputWallPaperSlug when passing wallpaper files for image or pattern wallpapers, with id=0 otherwise.
[IfFlag(1)] public InputWallPaperBase wallpaper;
/// Wallpaper settings.
[IfFlag(1)] public WallPaperSettings wallpaper_settings;
@@ -11944,7 +11944,7 @@ namespace TL
/// When did the user cast the vote
public override DateTime Date => date;
}
- /// How a user voted in a poll (reduced constructor, returned if an option was provided to messages.getPollVotes) See
+ /// How a user voted in a poll (reduced constructor, returned if an option was provided to Messages_GetPollVotes) See
[TLDef(0x3CA5B0EC)]
public class MessageUserVoteInputOption : MessageUserVoteBase
{
@@ -11981,13 +11981,13 @@ namespace TL
{
/// Flags, see TL conditional fields
public Flags flags;
- /// Total number of votes for all options (or only for the chosen option, if provided to messages.getPollVotes)
+ /// Total number of votes for all options (or only for the chosen option, if provided to Messages_GetPollVotes)
public int count;
/// Vote info for each user
public MessageUserVoteBase[] votes;
/// Info about users that voted in the poll
public Dictionary users;
- /// Offset to use with the next messages.getPollVotes request, empty string if no more results are available.
+ /// Offset to use with the next Messages_GetPollVotes request, empty string if no more results are available.
[IfFlag(0)] public string next_offset;
[Flags] public enum Flags : uint
@@ -12102,7 +12102,7 @@ namespace TL
/// Channel statistics graph See Derived classes: , ,
public abstract class StatsGraphBase : IObject { }
- /// This channel statistics graph must be generated asynchronously using stats.loadAsyncGraph to reduce server load See
+ /// This channel statistics graph must be generated asynchronously using Stats_LoadAsyncGraph to reduce server load See
[TLDef(0x4A27EB2D)]
public class StatsGraphAsync : StatsGraphBase
{
@@ -12597,7 +12597,7 @@ namespace TL
{
/// Whether the user should be muted upon joining the call
join_muted = 0x2,
- /// Whether the current user can change the value of the join_muted flag using phone.toggleGroupCallSettings
+ /// Whether the current user can change the value of the join_muted flag using Phone_ToggleGroupCallSettings
can_change_join_muted = 0x4,
/// Field has a value
has_title = 0x8,
@@ -12619,7 +12619,7 @@ namespace TL
record_video_active = 0x800,
/// Whether RTMP streams are allowed
rtmp_stream = 0x1000,
- /// Whether the listeners list is hidden and cannot be fetched using phone.getGroupParticipants. The phone.groupParticipants.count and groupCall.participants_count counters will still include listeners.
+ /// Whether the listeners list is hidden and cannot be fetched using Phone_GetGroupParticipants. The phone.groupParticipants.count and groupCall.participants_count counters will still include listeners.
listeners_hidden = 0x2000,
}
@@ -12676,7 +12676,7 @@ namespace TL
has_active_date = 0x8,
/// Whether the participant has just joined
just_joined = 0x10,
- /// If set, and .version < locally stored call.version, info about this participant should be ignored. If (...), and .version > call.version+1, the participant list should be refetched using phone.getGroupParticipants.
+ /// If set, and .version < locally stored call.version, info about this participant should be ignored. If (...), and .version > call.version+1, the participant list should be refetched using Phone_GetGroupParticipants.
versioned = 0x20,
/// Field has a value
has_video = 0x40,
@@ -12709,7 +12709,7 @@ namespace TL
public GroupCallBase call;
/// A partial list of participants.
public GroupCallParticipant[] participants;
- /// Next offset to use when fetching the remaining participants using phone.getGroupParticipants
+ /// Next offset to use when fetching the remaining participants using Phone_GetGroupParticipants
public string participants_next_offset;
/// Chats mentioned in the participants vector
public Dictionary chats;
@@ -12727,7 +12727,7 @@ namespace TL
public int count;
/// List of participants
public GroupCallParticipant[] participants;
- /// If not empty, the specified list of participants is partial, and more participants can be fetched specifying this parameter as offset in phone.getGroupParticipants.
+ /// If not empty, the specified list of participants is partial, and more participants can be fetched specifying this parameter as offset in Phone_GetGroupParticipants.
public string next_offset;
/// Mentioned chats
public Dictionary chats;
@@ -12977,7 +12977,7 @@ namespace TL
public string short_name;
}
- /// Represents a scope where the bot commands, specified using bots.setBotCommands will be valid. See Derived classes: , , , , ,
+ /// Represents a scope where the bot commands, specified using Bots_SetBotCommands will be valid. See Derived classes: , , , , ,
/// a value means botCommandScopeDefault
public abstract class BotCommandScope : IObject { }
/// The specified bot commands will only be valid in all private chats with users. See
@@ -13007,7 +13007,7 @@ namespace TL
public InputUserBase user_id;
}
- /// Result of an account.resetPassword request. See Derived classes: , ,
+ /// Result of an Account_ResetPassword request. See Derived classes: , ,
public abstract class Account_ResetPasswordResult : IObject { }
/// You recently requested a password reset that was canceled, please wait until the specified date before requesting another reset. See
[TLDef(0xE3779861)]
@@ -13027,7 +13027,7 @@ namespace TL
[TLDef(0xE926D63E)]
public class Account_ResetPasswordOk : Account_ResetPasswordResult { }
- /// A sponsored message. See
+ /// A sponsored message. See
[TLDef(0x3A836DF8)]
public class SponsoredMessage : IObject
{
@@ -13254,11 +13254,11 @@ namespace TL
[Flags] public enum Flags : uint
{
- /// Similar to min objects, used for message reaction » constructors that are the same for all users so they don't have the reactions sent by the current user (you can use messages.getMessagesReactions to get the full reaction info).
+ /// Similar to min objects, used for message reaction » constructors that are the same for all users so they don't have the reactions sent by the current user (you can use Messages_GetMessagesReactions to get the full reaction info).
min = 0x1,
/// Field has a value
has_recent_reactions = 0x2,
- /// Whether messages.getMessageReactionsList can be used to see how each specific peer reacted to the message
+ /// Whether Messages_GetMessageReactionsList can be used to see how each specific peer reacted to the message
can_see_list = 0x4,
}
}
@@ -13277,7 +13277,7 @@ namespace TL
public Dictionary chats;
/// Mentioned users
public Dictionary users;
- /// If set, indicates the next offset to use to load more results by invoking messages.getMessageReactionsList.
+ /// If set, indicates the next offset to use to load more results by invoking Messages_GetMessageReactionsList.
[IfFlag(0)] public string next_offset;
[Flags] public enum Flags : uint
@@ -13446,7 +13446,7 @@ namespace TL
[Flags] public enum Flags : uint
{
- /// Whether this bot attachment menu entry should be shown in the attachment menu (toggle using messages.toggleBotInAttachMenu)
+ /// Whether this bot attachment menu entry should be shown in the attachment menu (toggle using Messages_ToggleBotInAttachMenu)
inactive = 0x1,
/// True, if the bot supports the "settings_button_pressed" event »
has_settings = 0x2,
@@ -13560,7 +13560,7 @@ namespace TL
[TLDef(0xFF6C8049)]
public class NotificationSoundRingtone : NotificationSound
{
- /// Document ID of notification sound uploaded using account.uploadRingtone
+ /// Document ID of notification sound uploaded using Account_UploadRingtone
public long id;
}
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index 66f7c00..dd0ed40 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -124,7 +124,7 @@ namespace TL
/// Signs in a user with a validated phone number. See Possible codes: 400,406,500 (details)
/// Phone number in the international format
- /// SMS-message ID, obtained from auth.sendCode
+ /// SMS-message ID, obtained from Auth_SendCode
/// Valid numerical code from the SMS-message
/// Email verification code or token
[Obsolete("Use LoginUserIfNeeded instead of this method. See https://wiz0u.github.io/WTelegramClient/FAQ#tlsharp")]
@@ -209,7 +209,7 @@ namespace TL
{
});
- /// Reset the 2FA password using the recovery code sent using auth.requestPasswordRecovery. See Possible codes: 400 (details)
+ /// Reset the 2FA password using the recovery code sent using Auth_RequestPasswordRecovery. See Possible codes: 400 (details)
/// Code received via email
/// New password
public static Task Auth_RecoverPassword(this Client client, string code, Account_PasswordInputSettings new_settings = null)
@@ -222,7 +222,7 @@ namespace TL
/// Resend the login code via another medium, the phone code type is determined by the return value of the previous auth.sendCode/auth.resendCode: see login for more info. See Possible codes: 400,406 (details)
/// The phone number
- /// The phone code hash obtained from auth.sendCode
+ /// 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)
=> client.Invoke(new Auth_ResendCode
@@ -233,7 +233,7 @@ namespace TL
/// Cancel the login verification code See Possible codes: 400,406 (details)
/// Phone number
- /// Phone code hash from auth.sendCode
+ /// Phone code hash from Auth_SendCode
[Obsolete("Use LoginUserIfNeeded instead of this method. See https://wiz0u.github.io/WTelegramClient/FAQ#tlsharp")]
public static Task Auth_CancelCode(this Client client, string phone_number, string phone_code_hash)
=> client.Invoke(new Auth_CancelCode
@@ -278,7 +278,7 @@ namespace TL
token = token,
});
- /// Check if the 2FA recovery code sent using auth.requestPasswordRecovery is valid, before passing it to auth.recoverPassword. See Possible codes: 400 (details)
+ /// Check if the 2FA recovery code sent using Auth_RequestPasswordRecovery is valid, before passing it to Auth_RecoverPassword. See Possible codes: 400 (details)
/// Code received via email
public static Task Auth_CheckRecoveryPassword(this Client client, string code)
=> client.Invoke(new Auth_CheckRecoveryPassword
@@ -462,8 +462,8 @@ namespace TL
/// Change the phone number of the current account See Possible codes: 400,406 (details)
/// New phone number
- /// Phone code hash received when calling account.sendChangePhoneCode
- /// Phone code received when calling account.sendChangePhoneCode
+ /// Phone code hash received when calling Account_SendChangePhoneCode
+ /// Phone code received when calling Account_SendChangePhoneCode
public static Task Account_ChangePhone(this Client client, string phone_number, string phone_code_hash, string phone_code)
=> client.Invoke(new Account_ChangePhone
{
@@ -555,7 +555,7 @@ namespace TL
});
/// Log out an active web telegram login session See Possible codes: 400 (details)
- /// hash
+ /// Session hash
public static Task Account_ResetWebAuthorization(this Client client, long hash)
=> client.Invoke(new Account_ResetWebAuthorization
{
@@ -640,8 +640,8 @@ namespace TL
/// Verify a phone number for telegram passport. See Possible codes: 400 (details)
/// Phone number
- /// Phone code hash received from the call to account.sendVerifyPhoneCode
- /// Code received after the call to account.sendVerifyPhoneCode
+ /// Phone code hash received from the call to Account_SendVerifyPhoneCode
+ /// Code received after the call to Account_SendVerifyPhoneCode
public static Task Account_VerifyPhone(this Client client, string phone_number, string phone_code_hash, string phone_code)
=> client.Invoke(new Account_VerifyPhone
{
@@ -976,7 +976,7 @@ namespace TL
});
/// Change authorization settings See Possible codes: 400 (details)
- /// Session ID from the , fetchable using account.getAuthorizations
+ /// Session ID from the , fetchable using Account_GetAuthorizations
/// Whether to enable or disable receiving encrypted chats: if the flag is not set, the previous setting is not changed
/// Whether to enable or disable receiving calls: if the flag is not set, the previous setting is not changed
public static Task Account_ChangeAuthorizationSettings(this Client client, long hash, bool? encrypted_requests_disabled = default, bool? call_requests_disabled = default)
@@ -998,7 +998,7 @@ namespace TL
});
/// Save or remove saved notification sound. See
- /// Notification sound uploaded using account.uploadRingtone
+ /// Notification sound uploaded using Account_UploadRingtone
/// Whether to add or delete the notification sound
public static Task Account_SaveRingtone(this Client client, InputDocument id, bool unsave)
=> client.Invoke(new Account_SaveRingtone
@@ -1007,7 +1007,7 @@ namespace TL
unsave = unsave,
});
- /// Upload notification sound, use account.saveRingtone to convert it and add it to the list of saved notification sounds. See
+ /// Upload notification sound, use Account_SaveRingtone to convert it and add it to the list of saved notification sounds. See
/// Notification sound
/// File name
/// MIME type of file
@@ -1910,7 +1910,7 @@ namespace TL
/// Global search filter
/// If a positive value was specified, the method will return only messages with date bigger than min_date
/// If a positive value was transferred, the method will return only messages with date smaller than max_date
- /// Initially 0, then set to the
+ /// Initially 0, then set to the next_rate parameter of messages.messagesSlice
/// Offsets for pagination, for more info click here
/// Offsets for pagination, for more info click here
/// Offsets for pagination, for more info click here
@@ -2007,7 +2007,7 @@ namespace TL
switch_pm = switch_pm,
});
- /// Send a result obtained using messages.getInlineBotResults. See Possible codes: 400,403,420,500 (details)
+ /// Send a result obtained using Messages_GetInlineBotResults. See Possible codes: 400,403,420,500 (details)
/// Whether to send the message silently (no notification will be triggered on the other client)
/// Whether to send the message in background
/// Whether to clear the draft
@@ -2015,8 +2015,8 @@ namespace TL
/// Destination
/// ID of the message this message should reply to
/// Random ID to avoid resending the same query
- /// Query ID from messages.getInlineBotResults
- /// Result ID from messages.getInlineBotResults
+ /// Query ID from Messages_GetInlineBotResults
+ /// Result ID from Messages_GetInlineBotResults
/// Scheduled message date for scheduled messages
/// Send this message as the specified peer
public static Task Messages_SendInlineBotResult(this Client client, InputPeer peer, long random_id, long query_id, string id, bool silent = false, bool background = false, bool clear_draft = false, bool hide_via = false, int? reply_to_msg_id = null, int? top_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null)
@@ -2088,7 +2088,7 @@ namespace TL
/// Where was the inline keyboard sent
/// ID of the Message with the inline keyboard
/// Callback data
- /// For buttons , the SRP payload generated using SRP.
+ /// For buttons requiring you to verify your identity with your 2FA password, the SRP payload generated using SRP.
public static Task Messages_GetBotCallbackAnswer(this Client client, InputPeer peer, int msg_id, bool game = false, byte[] data = null, InputCheckPasswordSRP password = null)
=> client.Invoke(new Messages_GetBotCallbackAnswer
{
@@ -2454,7 +2454,7 @@ namespace TL
/// Whether to move used stickersets to top, see here for more info on this flag »
/// The destination chat
/// The message to reply to
- /// The medias to send: note that they must be separately uploaded using messages.uploadMedia first, using raw inputMediaUploaded* constructors is not supported.
+ /// The medias to send: note that they must be separately uploaded using Messages_UploadMedia first, using raw inputMediaUploaded* constructors is not supported.
/// Scheduled message date for scheduled messages
/// Send this message as the specified peer
public static Task Messages_SendMultiMedia(this Client client, InputPeer peer, InputSingleMedia[] multi_media, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, int? reply_to_msg_id = null, int? top_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null)
@@ -2619,7 +2619,7 @@ namespace TL
lang_code = lang_code,
});
- /// Get the number of results that would be found by a messages.search call with the same parameters See Possible codes: 400 (details)
+ /// Get the number of results that would be found by a Messages_Search call with the same parameters See Possible codes: 400 (details)
/// Peer where to search
/// Search filters
public static Task Messages_GetSearchCounters(this Client client, InputPeer peer, MessagesFilter[] filters, int? top_msg_id = null)
@@ -2664,7 +2664,7 @@ namespace TL
url = url,
});
- /// Should be called after the user hides the report spam/add as contact bar of a new chat, effectively prevents the user from executing the actions specified in the . See
+ /// Should be called after the user hides the report spam/add as contact bar of a new chat, effectively prevents the user from executing the actions specified in the peer's settings. See
/// Peer
public static Task Messages_HidePeerSettingsBar(this Client client, InputPeer peer)
=> client.Invoke(new Messages_HidePeerSettingsBar
@@ -2867,7 +2867,7 @@ namespace TL
/// Import chat history from a foreign chat app into a specific Telegram chat, click here for more info about imported chats ». See Possible codes: 400,406 (details)
/// The Telegram chat where the history should be imported.
/// File with messages to import.
- /// Number of media files associated with the chat that will be uploaded using messages.uploadImportedMedia.
+ /// Number of media files associated with the chat that will be uploaded using Messages_UploadImportedMedia.
public static Task Messages_InitHistoryImport(this Client client, InputPeer peer, InputFileBase file, int media_count)
=> client.Invoke(new Messages_InitHistoryImport
{
@@ -2878,7 +2878,7 @@ namespace TL
/// Upload a media file associated with an imported chat, click here for more info ». See
/// The Telegram chat where the media will be imported
- /// Identifier of a history import session, returned by messages.initHistoryImport
+ /// Identifier of a history import session, returned by Messages_InitHistoryImport
/// File name
/// Media metadata
/// a null value means messageMediaEmpty
@@ -2891,9 +2891,9 @@ namespace TL
media = media,
});
- /// Complete the history import process, importing all messages into the chat.
To be called only after initializing the import with messages.initHistoryImport and uploading all files using messages.uploadImportedMedia. See Possible codes: 400 (details)
+ /// Complete the history import process, importing all messages into the chat.
To be called only after initializing the import with Messages_InitHistoryImport and uploading all files using Messages_UploadImportedMedia. See Possible codes: 400 (details)
/// The Telegram chat where the messages should be imported, click here for more info »
- /// Identifier of a history import session, returned by messages.initHistoryImport.
+ /// Identifier of a history import session, returned by Messages_InitHistoryImport.
public static Task Messages_StartHistoryImport(this Client client, InputPeer peer, long import_id)
=> client.Invoke(new Messages_StartHistoryImport
{
@@ -3017,7 +3017,7 @@ namespace TL
/// Change the chat theme of a certain chat See Possible codes: 400 (details)
/// Private chat where to change theme
- /// Emoji, identifying a specific chat theme; a list of chat themes can be fetched using account.getChatThemes
+ /// Emoji, identifying a specific chat theme; a list of chat themes can be fetched using Account_GetChatThemes
public static Task Messages_SetChatTheme(this Client client, InputPeer peer, string emoticon)
=> client.Invoke(new Messages_SetChatTheme
{
@@ -3168,7 +3168,7 @@ namespace TL
hash = hash,
});
- /// Change default emoji reaction to use in the quick reaction menu: the value is synced across devices and can be fetched using help.getConfig, reactions_default field. See Possible codes: 400 (details)
+ /// Change default emoji reaction to use in the quick reaction menu: the value is synced across devices and can be fetched using Help_GetConfig. See Possible codes: 400 (details)
/// New emoji reaction
public static Task Messages_SetDefaultReaction(this Client client, Reaction reaction)
=> client.Invoke(new Messages_SetDefaultReaction
@@ -3264,14 +3264,14 @@ namespace TL
/// Open a bot web app, sending over user information after user confirmation. See
/// Whether the webview was opened by clicking on the bot's menu button ».
- /// Whether the inline message that will be sent by the bot on behalf of the user once the web app interaction is terminated should be sent silently (no notifications for the receivers).
+ /// Whether the inline message that will be sent by the bot on behalf of the user once the web app interaction is Messages_SendWebViewResultMessage should be sent silently (no notifications for the receivers).
/// Dialog where the web app is being opened, and where the resulting message will be sent (see the docs for more info »).
/// Bot that owns the web app
/// Web app URL
/// If the web app was opened from the attachment menu using a attachment menu deep link, start_param should contain the data from the startattach parameter.
/// Theme parameters »
/// Short name of the application; 0-64 English letters, digits, and underscores
- /// Whether the inline message that will be sent by the bot on behalf of the user once the web app interaction is terminated should be sent in reply to this message ID.
+ /// Whether the inline message that will be sent by the bot on behalf of the user once the web app interaction is Messages_SendWebViewResultMessage should be sent in reply to this message ID.
/// Open the web app as the specified peer, sending the resulting the message as the specified peer.
public static Task Messages_RequestWebView(this Client client, InputPeer peer, InputUserBase bot, string platform, bool from_bot_menu = false, bool silent = false, string url = null, string start_param = null, DataJSON theme_params = null, int? reply_to_msg_id = null, int? top_msg_id = null, InputPeer send_as = null)
=> client.Invoke(new Messages_RequestWebView
@@ -3289,11 +3289,11 @@ namespace TL
});
/// Indicate to the server (from the user side) that the user is still using a web app. See
- /// Whether the inline message that will be sent by the bot on behalf of the user once the web app interaction is terminated should be sent silently (no notifications for the receivers).
+ /// Whether the inline message that will be sent by the bot on behalf of the user once the web app interaction is Messages_SendWebViewResultMessage should be sent silently (no notifications for the receivers).
/// Dialog where the web app was opened.
/// Bot that owns the web app
- /// Web app interaction ID obtained from messages.requestWebView
- /// Whether the inline message that will be sent by the bot on behalf of the user once the web app interaction is terminated should be sent in reply to this message ID.
+ /// Web app interaction ID obtained from Messages_RequestWebView
+ /// Whether the inline message that will be sent by the bot on behalf of the user once the web app interaction is Messages_SendWebViewResultMessage should be sent in reply to this message ID.
/// Open the web app as the specified peer
public static Task Messages_ProlongWebView(this Client client, InputPeer peer, InputUserBase bot, long query_id, bool silent = false, int? reply_to_msg_id = null, int? top_msg_id = null, InputPeer send_as = null)
=> client.Invoke(new Messages_ProlongWebView
@@ -3322,8 +3322,8 @@ namespace TL
platform = platform,
});
- /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Terminate webview interaction started with messages.requestWebView, sending the specified message to the chat on behalf of the user. See [bots: ✓] Possible codes: 400 (details)
- /// Webview interaction ID obtained from messages.requestWebView
+ /// ⚠ This method is only for basic Chat. See Terminology to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a Terminate webview interaction started with Messages_RequestWebView, sending the specified message to the chat on behalf of the user. See [bots: ✓] Possible codes: 400 (details)
+ /// Webview interaction ID obtained from Messages_RequestWebView
/// Message to send
public static Task Messages_SendWebViewResultMessage(this Client client, string bot_query_id, InputBotInlineResultBase result)
=> client.Invoke(new Messages_SendWebViewResultMessage
@@ -3502,7 +3502,7 @@ namespace TL
});
/// Updates current user profile photo. See Possible codes: 400 (details)
- /// File saved in parts by means of upload.saveFilePart method
+ /// 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)
@@ -3785,7 +3785,7 @@ namespace TL
});
/// Dismiss a suggestion, see here for more info ». See
- /// In the case of pending suggestions in , the channel ID.
+ /// In the case of pending suggestions in channels, the channel ID.
/// Suggestion, see here for more info ».
public static Task Help_DismissSuggestion(this Client client, InputPeer peer, string suggestion)
=> client.Invoke(new Help_DismissSuggestion
@@ -3899,7 +3899,7 @@ namespace TL
/// Create a supergroup/channel. See Possible codes: 400,406 (details)
/// Whether to create a channel
/// Whether to create a supergroup
- /// Whether the supergroup is being created to import messages from a foreign chat service using messages.initHistoryImport
+ /// Whether the supergroup is being created to import messages from a foreign chat service using Messages_InitHistoryImport
/// Channel title
/// Channel description
/// Geogroup location
@@ -4026,9 +4026,9 @@ namespace TL
enabled = enabled,
});
- /// Get channels/supergroups/geogroups we're admin in. Usually called when the user exceeds the for owned public channels/supergroups/geogroups, and the user is given the choice to remove one of his channels/supergroups/geogroups. See Possible codes: 400 (details)
+ /// Get channels/supergroups/geogroups we're admin in. Usually called when the user exceeds the limit for owned public channels/supergroups/geogroups, and the user is given the choice to remove one of his channels/supergroups/geogroups. See Possible codes: 400 (details)
/// Get geogroups
- /// If set and the user has reached the limit of owned public channels/supergroups/geogroups, instead of returning the channel list one of the specified errors will be returned.
Useful to check if a new public channel can indeed be created, even before asking the user to enter a channel username to use in channels.checkUsername/channels.updateUsername.
+ /// If set and the user has reached the limit of owned public channels/supergroups/geogroups, instead of returning the channel list one of the specified errors will be returned.
Useful to check if a new public channel can indeed be created, even before asking the user to enter a channel username to use in Channels_CheckUsername/Channels_UpdateUsername.
public static Task Channels_GetAdminedPublicChannels(this Client client, bool by_location = false, bool check_limit = false)
=> client.Invoke(new Channels_GetAdminedPublicChannels
{
@@ -4422,7 +4422,7 @@ namespace TL
button = button,
});
- /// Gets the menu button action for a given user or for all users, previously set using bots.setBotMenuButton; users can see this information in the . See [bots: ✓] Possible codes: 400 (details)
+ /// Gets the menu button action for a given user or for all users, previously set using Bots_SetBotMenuButton; users can see this information in the . See [bots: ✓] Possible codes: 400 (details)
/// User ID or empty for the default menu button.
/// a null value means botMenuButtonDefault
public static Task Bots_GetBotMenuButton(this Client client, InputUserBase user_id)
@@ -4483,7 +4483,7 @@ namespace TL
/// Send compiled payment form See Possible codes: 400 (details)
/// Form ID
/// Invoice
- /// ID of saved and validated
+ /// ID of saved and validated order info
/// Chosen shipping option ID
/// Payment credentials
/// Tip, in the smallest units of the currency (integer, not float/double). For example, for a price of US$ 1.45 pass amount = 145. See the exp parameter in currencies.json, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies).
@@ -4974,7 +4974,7 @@ namespace TL
call = call,
});
- /// Get RTMP URL and stream key for RTMP livestreams. Can be used even before creating the actual RTMP livestream with phone.createGroupCall (the rtmp_stream flag must be set). See Possible codes: 400 (details)
+ /// Get RTMP URL and stream key for RTMP livestreams. Can be used even before creating the actual RTMP livestream with Phone_CreateGroupCall (the rtmp_stream flag must be set). See Possible codes: 400 (details)
/// Peer to livestream into
/// Whether to revoke the previous stream key or simply return the existing one
public static Task Phone_GetGroupCallStreamRtmpUrl(this Client client, InputPeer peer, bool revoke)
@@ -5093,7 +5093,7 @@ namespace TL
channel = channel,
});
- /// Obtains a list of messages, indicating to which other public channels was a channel message forwarded.
Will return a list of with peer_id equal to the public channel to which this message was forwarded. See Possible codes: 400 (details)
+ /// Obtains a list of messages, indicating to which other public channels was a channel message forwarded.
Will return a list of messages with peer_id equal to the public channel to which this message was forwarded. See Possible codes: 400 (details)
/// Source channel
/// Source message ID
/// Initially 0, then set to the next_rate parameter of
From e7ec282ac10afe4769b2af2d383efdf201af1348 Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Mon, 12 Dec 2022 10:07:31 +0100
Subject: [PATCH 029/336] Signal wrong use of some params[] methods
---
src/Encryption.cs | 4 +---
src/TL.Extensions.cs | 6 ++++++
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/Encryption.cs b/src/Encryption.cs
index a3a3eaf..03b72c0 100644
--- a/src/Encryption.cs
+++ b/src/Encryption.cs
@@ -388,14 +388,12 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB
internal static async Task Check2FA(Account_Password accountPassword, Func> getPassword)
{
- bool newPassword = false;
if (accountPassword.current_algo is not PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow algo)
if (accountPassword.current_algo == null && (algo = accountPassword.new_algo as PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow) != null)
{
int salt1len = algo.salt1.Length;
Array.Resize(ref algo.salt1, salt1len + 32);
RNG.GetBytes(algo.salt1, salt1len, 32);
- newPassword = true;
}
else
throw new ApplicationException("2FA authentication uses an unsupported algo: " + accountPassword.current_algo?.GetType().Name);
@@ -431,7 +429,7 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB
var x = BigEndianInteger(sha256.Hash);
var v = BigInteger.ModPow(g, x, p);
- if (newPassword)
+ if (accountPassword.current_algo == null) // we're computing a new password
{
await validTask;
return new InputCheckPasswordSRP { A = v.To256Bytes() };
diff --git a/src/TL.Extensions.cs b/src/TL.Extensions.cs
index 2c6f5b8..be79d66 100644
--- a/src/TL.Extensions.cs
+++ b/src/TL.Extensions.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using System.Threading.Tasks;
using System.Web;
namespace TL
@@ -34,6 +35,11 @@ namespace TL
/// The structure having a users
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 class Markdown
From 389f110cfb13e5cc254135d17ba11dcf5577ffec Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Mon, 19 Dec 2022 14:14:17 +0100
Subject: [PATCH 030/336] Helper simplified method for Channels_GetAdminLog
---
src/Client.Helpers.cs | 23 +++++++++++++++++++++++
src/TL.Helpers.cs | 5 +++++
src/TL.Schema.cs | 2 +-
3 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/src/Client.Helpers.cs b/src/Client.Helpers.cs
index f9adc37..115f05a 100644
--- a/src/Client.Helpers.cs
+++ b/src/Client.Helpers.cs
@@ -579,6 +579,29 @@ namespace WTelegram
}
}
+ /// Helper simplified method: Get the admin log of a channel/supergroup See Possible codes: 400,403 (details)
+ /// Channel
+ /// Search query, can be empty
+ /// Event filter
+ /// Only show events from this admin
+ public async Task Channels_GetAdminLog(InputChannelBase channel, ChannelAdminLogEventsFilter.Flags events_filter = 0, string q = null, InputUserBase admin = null)
+ {
+ var admins = admin == null ? null : new[] { admin };
+ var result = await this.Channels_GetAdminLog(channel, q, events_filter: events_filter, admins: admins);
+ if (result.events.Length < 100) return result;
+ var resultFull = result;
+ List events = new(result.events);
+ do
+ {
+ result = await this.Channels_GetAdminLog(channel, q, max_id: result.events[^1].id, events_filter: events_filter, admins: admins);
+ events.AddRange(result.events);
+ foreach (var kvp in result.chats) resultFull.chats[kvp.Key] = kvp.Value;
+ foreach (var kvp in result.users) resultFull.users[kvp.Key] = kvp.Value;
+ } while (result.events.Length >= 100);
+ resultFull.events = events.ToArray();
+ return resultFull;
+ }
+
private const string OnlyChatChannel = "This method works on Chat & Channel only";
/// Generic helper: Adds a single user to a Chat or Channel See
and Possible codes: 400,403
/// Chat/Channel
diff --git a/src/TL.Helpers.cs b/src/TL.Helpers.cs
index 21adbde..625fdae 100644
--- a/src/TL.Helpers.cs
+++ b/src/TL.Helpers.cs
@@ -562,6 +562,11 @@ namespace TL
partial class PhoneCallBase { public static implicit operator InputPhoneCall(PhoneCallBase call) => new() { id = call.ID, access_hash = call.AccessHash }; }
+ partial class ChannelAdminLogEventsFilter
+ {
+ public static implicit operator ChannelAdminLogEventsFilter(Flags flags) => new() { flags = flags };
+ }
+
partial class InputMessage
{
public static implicit operator InputMessage(int id) => new InputMessageID { id = id };
diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs
index 72c0a58..f747ec7 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -10108,7 +10108,7 @@ namespace TL
/// Filter only certain admin log events See
[TLDef(0xEA107AE4)]
- public class ChannelAdminLogEventsFilter : IObject
+ public partial class ChannelAdminLogEventsFilter : IObject
{
/// Flags, see TL conditional fields
public Flags flags;
From 7fa4051e99148196574275b746473f5f9d16acac Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Thu, 29 Dec 2022 22:28:58 +0100
Subject: [PATCH 031/336] Changed the ordering of optional parameters: Moved
bool parameters to the end of parameter list
---
.github/dev.yml | 2 +-
.github/release.yml | 2 +-
src/TL.SchemaFuncs.cs | 132 +++++++++++++++++++++---------------------
3 files changed, 68 insertions(+), 68 deletions(-)
diff --git a/.github/dev.yml b/.github/dev.yml
index da0ac65..3b5849b 100644
--- a/.github/dev.yml
+++ b/.github/dev.yml
@@ -2,7 +2,7 @@ pr: none
trigger:
- master
-name: 3.1.6-dev.$(Rev:r)
+name: 3.2.1-dev.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/.github/release.yml b/.github/release.yml
index 180eb0e..8d4f504 100644
--- a/.github/release.yml
+++ b/.github/release.yml
@@ -1,7 +1,7 @@
pr: none
trigger: none
-name: 3.1.$(Rev:r)
+name: 3.2.$(Rev:r)
pool:
vmImage: ubuntu-latest
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index dd0ed40..9fab31b 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -678,10 +678,10 @@ namespace TL
/// Whether to export messages in channels
/// Whether to export files
/// Maximum size of files to export
- public static Task Account_InitTakeoutSession(this Client client, bool contacts = false, bool message_users = false, bool message_chats = false, bool message_megagroups = false, bool message_channels = false, bool files = false, long? file_max_size = null)
+ public static Task Account_InitTakeoutSession(this Client client, long? file_max_size = null, bool contacts = false, bool message_users = false, bool message_chats = false, bool message_megagroups = false, bool message_channels = false, bool files = false)
=> client.Invoke(new Account_InitTakeoutSession
{
- flags = (Account_InitTakeoutSession.Flags)((contacts ? 0x1 : 0) | (message_users ? 0x2 : 0) | (message_chats ? 0x4 : 0) | (message_megagroups ? 0x8 : 0) | (message_channels ? 0x10 : 0) | (files ? 0x20 : 0) | (file_max_size != null ? 0x20 : 0)),
+ flags = (Account_InitTakeoutSession.Flags)((file_max_size != null ? 0x20 : 0) | (contacts ? 0x1 : 0) | (message_users ? 0x2 : 0) | (message_chats ? 0x4 : 0) | (message_megagroups ? 0x8 : 0) | (message_channels ? 0x10 : 0) | (files ? 0x20 : 0)),
file_max_size = file_max_size.GetValueOrDefault(),
});
@@ -730,10 +730,10 @@ namespace TL
/// Returns list of chats with non-default notification settings See
/// If true, chats with non-default sound will also be returned
/// If specified, only chats of the specified category will be returned
- public static Task Account_GetNotifyExceptions(this Client client, bool compare_sound = false, InputNotifyPeerBase peer = null)
+ public static Task Account_GetNotifyExceptions(this Client client, InputNotifyPeerBase peer = null, bool compare_sound = false)
=> client.Invoke(new Account_GetNotifyExceptions
{
- flags = (Account_GetNotifyExceptions.Flags)((compare_sound ? 0x2 : 0) | (peer != null ? 0x1 : 0)),
+ flags = (Account_GetNotifyExceptions.Flags)((peer != null ? 0x1 : 0) | (compare_sound ? 0x2 : 0)),
peer = peer,
});
@@ -866,10 +866,10 @@ namespace TL
/// Theme to install
/// Theme format, a string that identifies the theming engines supported by the client
/// Indicates a basic theme provided by all clients
- public static Task Account_InstallTheme(this Client client, bool dark = false, InputThemeBase theme = null, string format = null, BaseTheme base_theme = default)
+ public static Task Account_InstallTheme(this Client client, InputThemeBase theme = null, string format = null, BaseTheme base_theme = default, bool dark = false)
=> client.Invoke(new Account_InstallTheme
{
- flags = (Account_InstallTheme.Flags)((dark ? 0x1 : 0) | (theme != null ? 0x2 : 0) | (format != null ? 0x4 : 0) | (base_theme != default ? 0x8 : 0)),
+ flags = (Account_InstallTheme.Flags)((theme != null ? 0x2 : 0) | (format != null ? 0x4 : 0) | (base_theme != default ? 0x8 : 0) | (dark ? 0x1 : 0)),
theme = theme,
format = format,
base_theme = base_theme,
@@ -1263,10 +1263,10 @@ namespace TL
/// While the geolocation of the current user is public, clients should update it in the background every half-an-hour or so, while setting this flag.
Do this only if the new location is more than 1 KM away from the previous one, or if the previous location is unknown.
/// Geolocation
/// If set, the geolocation of the current user will be public for the specified number of seconds; pass 0x7fffffff to disable expiry, 0 to make the current geolocation private; if the flag isn't set, no changes will be applied.
- public static Task Contacts_GetLocated(this Client client, InputGeoPoint geo_point, bool background = false, int? self_expires = null)
+ public static Task Contacts_GetLocated(this Client client, InputGeoPoint geo_point, int? self_expires = null, bool background = false)
=> client.Invoke(new Contacts_GetLocated
{
- flags = (Contacts_GetLocated.Flags)((background ? 0x2 : 0) | (self_expires != null ? 0x1 : 0)),
+ flags = (Contacts_GetLocated.Flags)((self_expires != null ? 0x1 : 0) | (background ? 0x2 : 0)),
geo_point = geo_point,
self_expires = self_expires.GetValueOrDefault(),
});
@@ -1320,10 +1320,10 @@ namespace TL
/// Offset peer for pagination
/// Number of list elements to be returned
/// Hash for pagination, for more info click here
- public static Task Messages_GetDialogs(this Client client, DateTime offset_date = default, int offset_id = default, InputPeer offset_peer = null, int limit = int.MaxValue, long hash = default, bool exclude_pinned = false, int? folder_id = null)
+ public static Task Messages_GetDialogs(this Client client, DateTime offset_date = default, int offset_id = default, InputPeer offset_peer = null, int limit = int.MaxValue, long hash = default, int? folder_id = null, bool exclude_pinned = false)
=> client.Invoke(new Messages_GetDialogs
{
- flags = (Messages_GetDialogs.Flags)((exclude_pinned ? 0x1 : 0) | (folder_id != null ? 0x2 : 0)),
+ flags = (Messages_GetDialogs.Flags)((folder_id != null ? 0x2 : 0) | (exclude_pinned ? 0x1 : 0)),
folder_id = folder_id.GetValueOrDefault(),
offset_date = offset_date,
offset_id = offset_id,
@@ -1404,10 +1404,10 @@ namespace TL
/// Maximum ID of message to delete
/// Delete all messages newer than this UNIX timestamp
/// Delete all messages older than this UNIX timestamp
- public static Task Messages_DeleteHistory(this Client client, InputPeer peer, int max_id = default, bool just_clear = false, bool revoke = false, DateTime? min_date = null, DateTime? max_date = null)
+ public static Task Messages_DeleteHistory(this Client client, InputPeer peer, int max_id = default, DateTime? min_date = null, DateTime? max_date = null, bool just_clear = false, bool revoke = false)
=> client.Invoke(new Messages_DeleteHistory
{
- flags = (Messages_DeleteHistory.Flags)((just_clear ? 0x1 : 0) | (revoke ? 0x2 : 0) | (min_date != null ? 0x4 : 0) | (max_date != null ? 0x8 : 0)),
+ flags = (Messages_DeleteHistory.Flags)((min_date != null ? 0x4 : 0) | (max_date != null ? 0x8 : 0) | (just_clear ? 0x1 : 0) | (revoke ? 0x2 : 0)),
peer = peer,
max_id = max_id,
min_date = min_date.GetValueOrDefault(),
@@ -1460,10 +1460,10 @@ namespace TL
/// Message entities for sending styled text
/// Scheduled message date for scheduled messages
/// Send this message as the specified peer
- public static Task Messages_SendMessage(this Client client, InputPeer peer, string message, long random_id, bool no_webpage = false, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, int? reply_to_msg_id = null, int? top_msg_id = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null, InputPeer send_as = null)
+ public static Task Messages_SendMessage(this Client client, InputPeer peer, string message, long random_id, int? reply_to_msg_id = null, int? top_msg_id = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null, InputPeer send_as = null, bool no_webpage = false, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false)
=> client.Invoke(new Messages_SendMessage
{
- flags = (Messages_SendMessage.Flags)((no_webpage ? 0x2 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_SendMessage.Flags)((reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0) | (no_webpage ? 0x2 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0)),
peer = peer,
reply_to_msg_id = reply_to_msg_id.GetValueOrDefault(),
top_msg_id = top_msg_id.GetValueOrDefault(),
@@ -1490,10 +1490,10 @@ namespace TL
/// Message entities for styled text
/// Scheduled message date for scheduled messages
/// Send this message as the specified peer
- public static Task Messages_SendMedia(this Client client, InputPeer peer, InputMedia media, string message, long random_id, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, int? reply_to_msg_id = null, int? top_msg_id = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null, InputPeer send_as = null)
+ public static Task Messages_SendMedia(this Client client, InputPeer peer, InputMedia media, string message, long random_id, int? reply_to_msg_id = null, int? top_msg_id = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null, InputPeer send_as = null, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false)
=> client.Invoke(new Messages_SendMedia
{
- flags = (Messages_SendMedia.Flags)((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_SendMedia.Flags)((reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0)),
peer = peer,
reply_to_msg_id = reply_to_msg_id.GetValueOrDefault(),
top_msg_id = top_msg_id.GetValueOrDefault(),
@@ -1519,10 +1519,10 @@ namespace TL
/// Destination peer
/// Scheduled message date for scheduled messages
/// Forward the messages as the specified peer
- public static Task Messages_ForwardMessages(this Client client, InputPeer from_peer, int[] id, long[] random_id, InputPeer to_peer, bool silent = false, bool background = false, bool with_my_score = false, bool drop_author = false, bool drop_media_captions = false, bool noforwards = false, int? top_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null)
+ public static Task Messages_ForwardMessages(this Client client, InputPeer from_peer, int[] id, long[] random_id, InputPeer to_peer, int? top_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null, bool silent = false, bool background = false, bool with_my_score = false, bool drop_author = false, bool drop_media_captions = false, bool noforwards = false)
=> client.Invoke(new Messages_ForwardMessages
{
- flags = (Messages_ForwardMessages.Flags)((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (with_my_score ? 0x100 : 0) | (drop_author ? 0x800 : 0) | (drop_media_captions ? 0x1000 : 0) | (noforwards ? 0x4000 : 0) | (top_msg_id != null ? 0x200 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_ForwardMessages.Flags)((top_msg_id != null ? 0x200 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (with_my_score ? 0x100 : 0) | (drop_author ? 0x800 : 0) | (drop_media_captions ? 0x1000 : 0) | (noforwards ? 0x4000 : 0)),
from_peer = from_peer,
id = id,
random_id = random_id,
@@ -1803,10 +1803,10 @@ namespace TL
/// Expiration date
/// Maximum number of users that can join using this link
/// Description of the invite link, visible only to administrators
- public static Task Messages_ExportChatInvite(this Client client, InputPeer peer, bool legacy_revoke_permanent = false, bool request_needed = false, DateTime? expire_date = null, int? usage_limit = null, string title = null)
+ public static Task Messages_ExportChatInvite(this Client client, InputPeer peer, DateTime? expire_date = null, int? usage_limit = null, string title = null, bool legacy_revoke_permanent = false, bool request_needed = false)
=> client.Invoke(new Messages_ExportChatInvite
{
- flags = (Messages_ExportChatInvite.Flags)((legacy_revoke_permanent ? 0x4 : 0) | (request_needed ? 0x8 : 0) | (expire_date != null ? 0x1 : 0) | (usage_limit != null ? 0x2 : 0) | (title != null ? 0x10 : 0)),
+ flags = (Messages_ExportChatInvite.Flags)((expire_date != null ? 0x1 : 0) | (usage_limit != null ? 0x2 : 0) | (title != null ? 0x10 : 0) | (legacy_revoke_permanent ? 0x4 : 0) | (request_needed ? 0x8 : 0)),
peer = peer,
expire_date = expire_date.GetValueOrDefault(),
usage_limit = usage_limit.GetValueOrDefault(),
@@ -1996,10 +1996,10 @@ 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, bool gallery = false, bool private_ = false, string next_offset = null, InlineBotSwitchPM switch_pm = null)
+ 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)
=> client.Invoke(new Messages_SetInlineBotResults
{
- flags = (Messages_SetInlineBotResults.Flags)((gallery ? 0x1 : 0) | (private_ ? 0x2 : 0) | (next_offset != null ? 0x4 : 0) | (switch_pm != null ? 0x8 : 0)),
+ flags = (Messages_SetInlineBotResults.Flags)((next_offset != null ? 0x4 : 0) | (switch_pm != null ? 0x8 : 0) | (gallery ? 0x1 : 0) | (private_ ? 0x2 : 0)),
query_id = query_id,
results = results,
cache_time = cache_time,
@@ -2019,10 +2019,10 @@ namespace TL
/// Result ID from Messages_GetInlineBotResults
/// Scheduled message date for scheduled messages
/// Send this message as the specified peer
- public static Task Messages_SendInlineBotResult(this Client client, InputPeer peer, long random_id, long query_id, string id, bool silent = false, bool background = false, bool clear_draft = false, bool hide_via = false, int? reply_to_msg_id = null, int? top_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null)
+ public static Task Messages_SendInlineBotResult(this Client client, InputPeer peer, long random_id, long query_id, string id, int? reply_to_msg_id = null, int? top_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null, bool silent = false, bool background = false, bool clear_draft = false, bool hide_via = false)
=> client.Invoke(new Messages_SendInlineBotResult
{
- flags = (Messages_SendInlineBotResult.Flags)((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (hide_via ? 0x800 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_SendInlineBotResult.Flags)((reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (hide_via ? 0x800 : 0)),
peer = peer,
reply_to_msg_id = reply_to_msg_id.GetValueOrDefault(),
top_msg_id = top_msg_id.GetValueOrDefault(),
@@ -2052,10 +2052,10 @@ namespace TL
/// Reply markup for inline keyboards
/// Message entities for styled text
/// Scheduled message date for scheduled messages
- public static Task Messages_EditMessage(this Client client, InputPeer peer, int id, bool no_webpage = false, string message = null, InputMedia media = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null)
+ public static Task Messages_EditMessage(this Client client, InputPeer peer, int id, string message = null, InputMedia media = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null, bool no_webpage = false)
=> client.Invoke(new Messages_EditMessage
{
- flags = (Messages_EditMessage.Flags)((no_webpage ? 0x2 : 0) | (message != null ? 0x800 : 0) | (media != null ? 0x4000 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x8000 : 0)),
+ flags = (Messages_EditMessage.Flags)((message != null ? 0x800 : 0) | (media != null ? 0x4000 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x8000 : 0) | (no_webpage ? 0x2 : 0)),
peer = peer,
id = id,
message = message,
@@ -2072,10 +2072,10 @@ namespace TL
/// Media
/// Reply markup for inline keyboards
/// Message entities for styled text
- public static Task Messages_EditInlineBotMessage(this Client client, InputBotInlineMessageIDBase id, bool no_webpage = false, string message = null, InputMedia media = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null)
+ public static Task Messages_EditInlineBotMessage(this Client client, InputBotInlineMessageIDBase id, string message = null, InputMedia media = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, bool no_webpage = false)
=> client.Invoke(new Messages_EditInlineBotMessage
{
- flags = (Messages_EditInlineBotMessage.Flags)((no_webpage ? 0x2 : 0) | (message != null ? 0x800 : 0) | (media != null ? 0x4000 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0)),
+ flags = (Messages_EditInlineBotMessage.Flags)((message != null ? 0x800 : 0) | (media != null ? 0x4000 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (no_webpage ? 0x2 : 0)),
id = id,
message = message,
media = media,
@@ -2089,10 +2089,10 @@ namespace TL
/// ID of the Message with the inline keyboard
/// Callback data
/// For buttons requiring you to verify your identity with your 2FA password, the SRP payload generated using SRP.
- public static Task Messages_GetBotCallbackAnswer(this Client client, InputPeer peer, int msg_id, bool game = false, byte[] data = null, InputCheckPasswordSRP password = null)
+ public static Task Messages_GetBotCallbackAnswer(this Client client, InputPeer peer, int msg_id, byte[] data = null, InputCheckPasswordSRP password = null, bool game = false)
=> client.Invoke(new Messages_GetBotCallbackAnswer
{
- flags = (Messages_GetBotCallbackAnswer.Flags)((game ? 0x2 : 0) | (data != null ? 0x1 : 0) | (password != null ? 0x4 : 0)),
+ flags = (Messages_GetBotCallbackAnswer.Flags)((data != null ? 0x1 : 0) | (password != null ? 0x4 : 0) | (game ? 0x2 : 0)),
peer = peer,
msg_id = msg_id,
data = data,
@@ -2105,10 +2105,10 @@ namespace TL
/// Popup to show
/// URL to open
/// Cache validity
- public static Task Messages_SetBotCallbackAnswer(this Client client, long query_id, DateTime cache_time, bool alert = false, string message = null, string url = null)
+ public static Task Messages_SetBotCallbackAnswer(this Client client, long query_id, DateTime cache_time, string message = null, string url = null, bool alert = false)
=> client.Invoke(new Messages_SetBotCallbackAnswer
{
- flags = (Messages_SetBotCallbackAnswer.Flags)((alert ? 0x2 : 0) | (message != null ? 0x1 : 0) | (url != null ? 0x4 : 0)),
+ flags = (Messages_SetBotCallbackAnswer.Flags)((message != null ? 0x1 : 0) | (url != null ? 0x4 : 0) | (alert ? 0x2 : 0)),
query_id = query_id,
message = message,
url = url,
@@ -2129,10 +2129,10 @@ namespace TL
/// Destination of the message that should be sent
/// The draft
/// Message entities for styled text
- public static Task Messages_SaveDraft(this Client client, InputPeer peer, string message, bool no_webpage = false, int? reply_to_msg_id = null, int? top_msg_id = null, MessageEntity[] entities = null)
+ public static Task Messages_SaveDraft(this Client client, InputPeer peer, string message, int? reply_to_msg_id = null, int? top_msg_id = null, MessageEntity[] entities = null, bool no_webpage = false)
=> client.Invoke(new Messages_SaveDraft
{
- flags = (Messages_SaveDraft.Flags)((no_webpage ? 0x2 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x4 : 0) | (entities != null ? 0x8 : 0)),
+ flags = (Messages_SaveDraft.Flags)((reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (no_webpage ? 0x2 : 0)),
reply_to_msg_id = reply_to_msg_id.GetValueOrDefault(),
top_msg_id = top_msg_id.GetValueOrDefault(),
peer = peer,
@@ -2354,10 +2354,10 @@ namespace TL
/// Set this flag if everything is alright (goods are available, etc.) and the bot is ready to proceed with the order, otherwise do not set it, and set the error field, instead
/// Unique identifier for the query to be answered
/// Required if the success isn't set. Error message in human readable form that explains the reason for failure to proceed with the checkout (e.g. "Sorry, somebody just bought the last of our amazing black T-shirts while you were busy filling out your payment details. Please choose a different color or garment!"). Telegram will display this message to the user.
- public static Task Messages_SetBotPrecheckoutResults(this Client client, long query_id, bool success = false, string error = null)
+ public static Task Messages_SetBotPrecheckoutResults(this Client client, long query_id, string error = null, bool success = false)
=> client.Invoke(new Messages_SetBotPrecheckoutResults
{
- flags = (Messages_SetBotPrecheckoutResults.Flags)((success ? 0x2 : 0) | (error != null ? 0x1 : 0)),
+ flags = (Messages_SetBotPrecheckoutResults.Flags)((error != null ? 0x1 : 0) | (success ? 0x2 : 0)),
query_id = query_id,
error = error,
});
@@ -2457,10 +2457,10 @@ namespace TL
/// The medias to send: note that they must be separately uploaded using Messages_UploadMedia first, using raw inputMediaUploaded* constructors is not supported.
/// Scheduled message date for scheduled messages
/// Send this message as the specified peer
- public static Task Messages_SendMultiMedia(this Client client, InputPeer peer, InputSingleMedia[] multi_media, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, int? reply_to_msg_id = null, int? top_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null)
+ public static Task Messages_SendMultiMedia(this Client client, InputPeer peer, InputSingleMedia[] multi_media, int? reply_to_msg_id = null, int? top_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false)
=> client.Invoke(new Messages_SendMultiMedia
{
- flags = (Messages_SendMultiMedia.Flags)((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_SendMultiMedia.Flags)((reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0)),
peer = peer,
reply_to_msg_id = reply_to_msg_id.GetValueOrDefault(),
top_msg_id = top_msg_id.GetValueOrDefault(),
@@ -2654,10 +2654,10 @@ namespace TL
/// ID of the login button
/// URL used for link URL authorization, click here for more info »
/// a null value means urlAuthResultDefault
- public static Task Messages_AcceptUrlAuth(this Client client, bool write_allowed = false, InputPeer peer = null, int? msg_id = null, int? button_id = null, string url = null)
+ public static Task Messages_AcceptUrlAuth(this Client client, InputPeer peer = null, int? msg_id = null, int? button_id = null, string url = null, bool write_allowed = false)
=> client.Invoke(new Messages_AcceptUrlAuth
{
- flags = (Messages_AcceptUrlAuth.Flags)((write_allowed ? 0x1 : 0) | (peer != null ? 0x2 : 0) | (msg_id != null ? 0x2 : 0) | (button_id != null ? 0x2 : 0) | (url != null ? 0x4 : 0)),
+ flags = (Messages_AcceptUrlAuth.Flags)((peer != null ? 0x2 : 0) | (msg_id != null ? 0x2 : 0) | (button_id != null ? 0x2 : 0) | (url != null ? 0x4 : 0) | (write_allowed ? 0x1 : 0)),
peer = peer,
msg_id = msg_id.GetValueOrDefault(),
button_id = button_id.GetValueOrDefault(),
@@ -2908,10 +2908,10 @@ namespace TL
/// Offsets for pagination, for more info click here
/// Offsets for pagination, for more info click here
/// Maximum number of results to return, see pagination
- public static Task Messages_GetExportedChatInvites(this Client client, InputPeer peer, InputUserBase admin_id, int limit = int.MaxValue, bool revoked = false, DateTime? offset_date = null, string offset_link = null)
+ public static Task Messages_GetExportedChatInvites(this Client client, InputPeer peer, InputUserBase admin_id, int limit = int.MaxValue, DateTime? offset_date = null, string offset_link = null, bool revoked = false)
=> client.Invoke(new Messages_GetExportedChatInvites
{
- flags = (Messages_GetExportedChatInvites.Flags)((revoked ? 0x8 : 0) | (offset_date != null ? 0x4 : 0) | (offset_link != null ? 0x4 : 0)),
+ flags = (Messages_GetExportedChatInvites.Flags)((offset_date != null ? 0x4 : 0) | (offset_link != null ? 0x4 : 0) | (revoked ? 0x8 : 0)),
peer = peer,
admin_id = admin_id,
offset_date = offset_date.GetValueOrDefault(),
@@ -2937,10 +2937,10 @@ namespace TL
/// Maximum number of users that can join using this link
/// Whether admin confirmation is required before admitting each separate user into the chat
/// Description of the invite link, visible only to administrators
- public static Task Messages_EditExportedChatInvite(this Client client, InputPeer peer, string link, bool revoked = false, DateTime? expire_date = null, int? usage_limit = null, bool? request_needed = default, string title = null)
+ public static Task Messages_EditExportedChatInvite(this Client client, InputPeer peer, string link, DateTime? expire_date = null, int? usage_limit = null, bool? request_needed = default, string title = null, bool revoked = false)
=> client.Invoke(new Messages_EditExportedChatInvite
{
- flags = (Messages_EditExportedChatInvite.Flags)((revoked ? 0x4 : 0) | (expire_date != null ? 0x1 : 0) | (usage_limit != null ? 0x2 : 0) | (request_needed != default ? 0x8 : 0) | (title != null ? 0x10 : 0)),
+ flags = (Messages_EditExportedChatInvite.Flags)((expire_date != null ? 0x1 : 0) | (usage_limit != null ? 0x2 : 0) | (request_needed != default ? 0x8 : 0) | (title != null ? 0x10 : 0) | (revoked ? 0x4 : 0)),
peer = peer,
link = link,
expire_date = expire_date.GetValueOrDefault(),
@@ -2985,10 +2985,10 @@ namespace TL
/// Offsets for pagination, for more info click here
/// User ID for pagination
/// Maximum number of results to return, see pagination
- public static Task Messages_GetChatInviteImporters(this Client client, InputPeer peer, DateTime offset_date = default, InputUserBase offset_user = null, int limit = int.MaxValue, bool requested = false, string link = null, string q = null)
+ public static Task Messages_GetChatInviteImporters(this Client client, InputPeer peer, DateTime offset_date = default, InputUserBase offset_user = null, int limit = int.MaxValue, string link = null, string q = null, bool requested = false)
=> client.Invoke(new Messages_GetChatInviteImporters
{
- flags = (Messages_GetChatInviteImporters.Flags)((requested ? 0x1 : 0) | (link != null ? 0x2 : 0) | (q != null ? 0x4 : 0)),
+ flags = (Messages_GetChatInviteImporters.Flags)((link != null ? 0x2 : 0) | (q != null ? 0x4 : 0) | (requested ? 0x1 : 0)),
peer = peer,
link = link,
q = q,
@@ -3079,10 +3079,10 @@ namespace TL
/// Whether to dismiss or approve all chat join requests »
/// The chat or channel
/// Only dismiss or approve join requests » initiated using this invite link
- public static Task Messages_HideAllChatJoinRequests(this Client client, InputPeer peer, bool approved = false, string link = null)
+ public static Task Messages_HideAllChatJoinRequests(this Client client, InputPeer peer, string link = null, bool approved = false)
=> client.Invoke(new Messages_HideAllChatJoinRequests
{
- flags = (Messages_HideAllChatJoinRequests.Flags)((approved ? 0x1 : 0) | (link != null ? 0x2 : 0)),
+ flags = (Messages_HideAllChatJoinRequests.Flags)((link != null ? 0x2 : 0) | (approved ? 0x1 : 0)),
peer = peer,
link = link,
});
@@ -3113,10 +3113,10 @@ namespace TL
/// Peer
/// Message ID to react to
/// Reaction (a UTF8 emoji)
- public static Task Messages_SendReaction(this Client client, InputPeer peer, int msg_id, bool big = false, bool add_to_recent = false, Reaction[] reaction = null)
+ public static Task Messages_SendReaction(this Client client, InputPeer peer, int msg_id, Reaction[] reaction = null, bool big = false, bool add_to_recent = false)
=> client.Invoke(new Messages_SendReaction
{
- flags = (Messages_SendReaction.Flags)((big ? 0x2 : 0) | (add_to_recent ? 0x4 : 0) | (reaction != null ? 0x1 : 0)),
+ flags = (Messages_SendReaction.Flags)((reaction != null ? 0x1 : 0) | (big ? 0x2 : 0) | (add_to_recent ? 0x4 : 0)),
peer = peer,
msg_id = msg_id,
reaction = reaction,
@@ -3273,10 +3273,10 @@ namespace TL
/// Short name of the application; 0-64 English letters, digits, and underscores
/// Whether the inline message that will be sent by the bot on behalf of the user once the web app interaction is Messages_SendWebViewResultMessage should be sent in reply to this message ID.
/// Open the web app as the specified peer, sending the resulting the message as the specified peer.
- public static Task Messages_RequestWebView(this Client client, InputPeer peer, InputUserBase bot, string platform, bool from_bot_menu = false, bool silent = false, string url = null, string start_param = null, DataJSON theme_params = null, int? reply_to_msg_id = null, int? top_msg_id = null, InputPeer send_as = null)
+ public static Task Messages_RequestWebView(this Client client, InputPeer peer, InputUserBase bot, string platform, string url = null, string start_param = null, DataJSON theme_params = null, int? reply_to_msg_id = null, int? top_msg_id = null, InputPeer send_as = null, bool from_bot_menu = false, bool silent = false)
=> client.Invoke(new Messages_RequestWebView
{
- flags = (Messages_RequestWebView.Flags)((from_bot_menu ? 0x10 : 0) | (silent ? 0x20 : 0) | (url != null ? 0x2 : 0) | (start_param != null ? 0x8 : 0) | (theme_params != null ? 0x4 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_RequestWebView.Flags)((url != null ? 0x2 : 0) | (start_param != null ? 0x8 : 0) | (theme_params != null ? 0x4 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (send_as != null ? 0x2000 : 0) | (from_bot_menu ? 0x10 : 0) | (silent ? 0x20 : 0)),
peer = peer,
bot = bot,
url = url,
@@ -3295,10 +3295,10 @@ namespace TL
/// Web app interaction ID obtained from Messages_RequestWebView
/// Whether the inline message that will be sent by the bot on behalf of the user once the web app interaction is Messages_SendWebViewResultMessage should be sent in reply to this message ID.
/// Open the web app as the specified peer
- public static Task Messages_ProlongWebView(this Client client, InputPeer peer, InputUserBase bot, long query_id, bool silent = false, int? reply_to_msg_id = null, int? top_msg_id = null, InputPeer send_as = null)
+ public static Task Messages_ProlongWebView(this Client client, InputPeer peer, InputUserBase bot, long query_id, int? reply_to_msg_id = null, int? top_msg_id = null, InputPeer send_as = null, bool silent = false)
=> client.Invoke(new Messages_ProlongWebView
{
- flags = (Messages_ProlongWebView.Flags)((silent ? 0x20 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (send_as != null ? 0x2000 : 0)),
+ flags = (Messages_ProlongWebView.Flags)((reply_to_msg_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x200 : 0) | (send_as != null ? 0x2000 : 0) | (silent ? 0x20 : 0)),
peer = peer,
bot = bot,
query_id = query_id,
@@ -3904,10 +3904,10 @@ namespace TL
/// Channel description
/// Geogroup location
/// Geogroup address
- public static Task Channels_CreateChannel(this Client client, string title, string about, bool broadcast = false, bool megagroup = false, bool for_import = false, InputGeoPoint geo_point = null, string address = null, int? ttl_period = null)
+ 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)
=> client.Invoke(new Channels_CreateChannel
{
- flags = (Channels_CreateChannel.Flags)((broadcast ? 0x1 : 0) | (megagroup ? 0x2 : 0) | (for_import ? 0x8 : 0) | (geo_point != null ? 0x4 : 0) | (address != null ? 0x4 : 0) | (ttl_period != null ? 0x10 : 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)),
title = title,
about = about,
geo_point = geo_point,
@@ -4569,10 +4569,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, bool masks = false, bool animated = false, bool videos = false, InputDocument thumb = null, string software = null)
+ 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)
=> client.Invoke(new Stickers_CreateStickerSet
{
- flags = (Stickers_CreateStickerSet.Flags)((masks ? 0x1 : 0) | (animated ? 0x2 : 0) | (videos ? 0x10 : 0) | (thumb != null ? 0x4 : 0) | (software != null ? 0x8 : 0)),
+ flags = (Stickers_CreateStickerSet.Flags)((thumb != null ? 0x4 : 0) | (software != null ? 0x8 : 0) | (masks ? 0x1 : 0) | (animated ? 0x2 : 0) | (videos ? 0x10 : 0)),
user_id = user_id,
title = title,
short_name = short_name,
@@ -4751,10 +4751,10 @@ namespace TL
/// Unique client message ID required to prevent creation of duplicate group calls
/// Call title
/// For scheduled group call or livestreams, the absolute date when the group call will start
- public static Task Phone_CreateGroupCall(this Client client, InputPeer peer, int random_id, bool rtmp_stream = false, string title = null, DateTime? schedule_date = null)
+ public static Task Phone_CreateGroupCall(this Client client, InputPeer peer, int random_id, string title = null, DateTime? schedule_date = null, bool rtmp_stream = false)
=> client.Invoke(new Phone_CreateGroupCall
{
- flags = (Phone_CreateGroupCall.Flags)((rtmp_stream ? 0x4 : 0) | (title != null ? 0x1 : 0) | (schedule_date != null ? 0x2 : 0)),
+ flags = (Phone_CreateGroupCall.Flags)((title != null ? 0x1 : 0) | (schedule_date != null ? 0x2 : 0) | (rtmp_stream ? 0x4 : 0)),
peer = peer,
random_id = random_id,
title = title,
@@ -4768,10 +4768,10 @@ namespace TL
/// Join the group call, presenting yourself as the specified user/channel
/// The invitation hash from the invite link », if provided allows speaking in a livestream or muted group chat.
/// WebRTC parameters
- public static Task Phone_JoinGroupCall(this Client client, InputGroupCall call, InputPeer join_as, DataJSON params_, bool muted = false, bool video_stopped = false, string invite_hash = null)
+ public static Task Phone_JoinGroupCall(this Client client, InputGroupCall call, InputPeer join_as, DataJSON params_, string invite_hash = null, bool muted = false, bool video_stopped = false)
=> client.Invoke(new Phone_JoinGroupCall
{
- flags = (Phone_JoinGroupCall.Flags)((muted ? 0x1 : 0) | (video_stopped ? 0x4 : 0) | (invite_hash != null ? 0x2 : 0)),
+ flags = (Phone_JoinGroupCall.Flags)((invite_hash != null ? 0x2 : 0) | (muted ? 0x1 : 0) | (video_stopped ? 0x4 : 0)),
call = call,
join_as = join_as,
invite_hash = invite_hash,
@@ -4810,10 +4810,10 @@ namespace TL
/// Invalidate existing invite links
/// Group call
/// Whether all users will that join this group call are muted by default upon joining the group call
- public static Task Phone_ToggleGroupCallSettings(this Client client, InputGroupCall call, bool reset_invite_hash = false, bool? join_muted = default)
+ public static Task Phone_ToggleGroupCallSettings(this Client client, InputGroupCall call, bool? join_muted = default, bool reset_invite_hash = false)
=> client.Invoke(new Phone_ToggleGroupCallSettings
{
- flags = (Phone_ToggleGroupCallSettings.Flags)((reset_invite_hash ? 0x2 : 0) | (join_muted != default ? 0x1 : 0)),
+ flags = (Phone_ToggleGroupCallSettings.Flags)((join_muted != default ? 0x1 : 0) | (reset_invite_hash ? 0x2 : 0)),
call = call,
join_muted = join_muted.GetValueOrDefault(),
});
@@ -4860,10 +4860,10 @@ namespace TL
/// The group call or livestream
/// Recording title
/// If video stream recording is enabled, whether to record in portrait or landscape mode
- public static Task Phone_ToggleGroupCallRecord(this Client client, InputGroupCall call, bool start = false, bool video = false, string title = null, bool? video_portrait = default)
+ public static Task Phone_ToggleGroupCallRecord(this Client client, InputGroupCall call, string title = null, bool? video_portrait = default, bool start = false, bool video = false)
=> client.Invoke(new Phone_ToggleGroupCallRecord
{
- flags = (Phone_ToggleGroupCallRecord.Flags)((start ? 0x1 : 0) | (video ? 0x4 : 0) | (title != null ? 0x2 : 0) | (video_portrait != default ? 0x4 : 0)),
+ flags = (Phone_ToggleGroupCallRecord.Flags)((title != null ? 0x2 : 0) | (video_portrait != default ? 0x4 : 0) | (start ? 0x1 : 0) | (video ? 0x4 : 0)),
call = call,
title = title,
video_portrait = video_portrait.GetValueOrDefault(),
From 8098f36932b1833f56518a52a5f9251bb89eb4bb Mon Sep 17 00:00:00 2001
From: Wizou <11647984+wiz0u@users.noreply.github.com>
Date: Thu, 29 Dec 2022 22:33:28 +0100
Subject: [PATCH 032/336] API Layer 151: media spoiler flag, personal profile
photo, UpdateUser...
---
Examples/Program_ListenUpdates.cs | 2 +-
README.md | 2 +-
src/TL.Schema.cs | 87 +++++++++++++++++++------------
src/TL.SchemaFuncs.cs | 72 ++++++++++++++++++++++---
src/TL.Table.cs | 11 ++--
src/WTelegramClient.csproj | 2 +-
6 files changed, 129 insertions(+), 47 deletions(-)
diff --git a/Examples/Program_ListenUpdates.cs b/Examples/Program_ListenUpdates.cs
index e463eef..b94165e 100644
--- a/Examples/Program_ListenUpdates.cs
+++ b/Examples/Program_ListenUpdates.cs
@@ -51,7 +51,7 @@ namespace WTelegramClientTest
case UpdateChatParticipants { participants: ChatParticipants cp }: Console.WriteLine($"{cp.participants.Length} participants in {Chat(cp.chat_id)}"); break;
case UpdateUserStatus uus: Console.WriteLine($"{User(uus.user_id)} is now {uus.status.GetType().Name[10..]}"); break;
case UpdateUserName uun: Console.WriteLine($"{User(uun.user_id)} has changed profile name: {uun.first_name} {uun.last_name}"); break;
- case UpdateUserPhoto uup: Console.WriteLine($"{User(uup.user_id)} has changed profile photo"); break;
+ case UpdateUser uu: Console.WriteLine($"{User(uu.user_id)} has changed infos/photo"); break;
default: Console.WriteLine(update.GetType().Name); break; // there are much more update types than the above example cases
}
}
diff --git a/README.md b/README.md
index caa4f31..1c342a3 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 f747ec7..92f176b 100644
--- a/src/TL.Schema.cs
+++ b/src/TL.Schema.cs
@@ -199,6 +199,7 @@ namespace TL
has_stickers = 0x1,
/// Field has a value
has_ttl_seconds = 0x2,
+ spoiler = 0x4,
}
}
/// Forwarded photo See
@@ -216,6 +217,7 @@ namespace TL
{
/// Field has a value
has_ttl_seconds = 0x1,
+ spoiler = 0x2,
}
}
/// Map. See
@@ -269,6 +271,7 @@ namespace TL
nosound_video = 0x8,
/// Force the media file to be uploaded as document
force_file = 0x10,
+ spoiler = 0x20,
}
}
/// Forwarded document See
@@ -290,6 +293,7 @@ namespace TL
has_ttl_seconds = 0x1,
/// Field has a value
has_query = 0x2,
+ spoiler = 0x4,
}
}
/// Can be used to send a venue geolocation. See
@@ -324,6 +328,7 @@ namespace TL
{
/// Field has a value
has_ttl_seconds = 0x1,
+ spoiler = 0x2,
}
}
/// Document that will be downloaded by the telegram servers See
@@ -341,6 +346,7 @@ namespace TL
{
/// Field has a value
has_ttl_seconds = 0x1,
+ spoiler = 0x2,
}
}
/// A game See
@@ -819,6 +825,7 @@ namespace TL
has_video = 0x1,
/// Field has a value
has_stripped_thumb = 0x2,
+ personal = 0x4,
}
}
@@ -1345,6 +1352,7 @@ namespace TL
/// Can we delete this channel?
can_delete_channel = 0x1,
antispam = 0x2,
+ participants_hidden = 0x4,
}
/// ID of the channel
@@ -1708,6 +1716,7 @@ namespace TL
has_photo = 0x1,
/// Field has a value
has_ttl_seconds = 0x4,
+ spoiler = 0x8,
}
}
/// Attached map. See
@@ -1754,6 +1763,7 @@ namespace TL
has_ttl_seconds = 0x4,
/// Whether this is a normal sticker, if not set this is a premium sticker and a premium sticker animation must be played.
nopremium = 0x8,
+ spoiler = 0x10,
}
}
/// Preview of webpage See
@@ -2194,6 +2204,15 @@ namespace TL
has_hidden = 0x8,
}
}
+ /// See
+ [TLDef(0x57DE635E)]
+ public class MessageActionSuggestProfilePhoto : MessageAction
+ {
+ public PhotoBase photo;
+ }
+ /// See
+ [TLDef(0xE7E75F97)]
+ public class MessageActionAttachMenuBotAllowed : MessageAction { }
/// Chat info. See Derived classes: ,
public abstract class DialogBase : IObject
@@ -2738,7 +2757,7 @@ namespace TL
}
/// Extended user info See
- [TLDef(0xC4B1FC3F)]
+ [TLDef(0xF8D32AED)]
public class UserFull : IObject
{
/// Flags, see TL conditional fields
@@ -2749,8 +2768,10 @@ namespace TL
[IfFlag(1)] public string about;
/// Peer settings
public PeerSettings settings;
+ [IfFlag(21)] public PhotoBase personal_photo;
/// Profile photo
[IfFlag(2)] public PhotoBase profile_photo;
+ [IfFlag(22)] public PhotoBase fallback_photo;
/// Notification settings
public PeerNotifySettings notify_settings;
/// For bots, info about the bot (bot commands, etc)
@@ -2812,6 +2833,10 @@ namespace TL
has_premium_gifts = 0x80000,
/// Whether this user doesn't allow sending voice messages in a private chat with them
voice_messages_forbidden = 0x100000,
+ /// Field has a value
+ has_personal_photo = 0x200000,
+ /// Field has a value
+ has_fallback_photo = 0x400000,
}
}
@@ -3167,11 +3192,9 @@ namespace TL
public int pts_count;
}
/// The user is preparing a message; typing, recording, uploading, etc. This update is valid for 6 seconds. If no further updates of this kind are received after 6 seconds, it should be considered that the user stopped doing whatever they were doing See
- [TLDef(0xC01E857F)]
- public class UpdateUserTyping : Update
+ [TLDef(0xC01E857F, inheritBefore = true)]
+ public class UpdateUserTyping : UpdateUser
{
- /// User id
- public long user_id;
/// Action type
public SendMessageAction action;
}
@@ -3192,39 +3215,22 @@ namespace TL
public ChatParticipantsBase participants;
}
/// Contact status update. See
- [TLDef(0xE5BDF8DE)]
- public class UpdateUserStatus : Update
+ [TLDef(0xE5BDF8DE, inheritBefore = true)]
+ public class UpdateUserStatus : UpdateUser
{
- /// User identifier
- public long user_id;
/// New status
public UserStatus status;
}
/// Changes the user's first name, last name and username. See
- [TLDef(0xA7848924)]
- public class UpdateUserName : Update
+ [TLDef(0xA7848924, inheritBefore = true)]
+ public class UpdateUserName : UpdateUser
{
- /// User identifier
- public long user_id;
/// New first name. Corresponds to the new value of real_first_name field of the .
public string first_name;
/// New last name. Corresponds to the new value of real_last_name field of the .
public string last_name;
public Username[] usernames;
}
- /// Change of contact's profile photo. See
- [TLDef(0xF227868C)]
- public class UpdateUserPhoto : Update
- {
- /// User identifier
- public long user_id;
- /// Date of photo update.
- public DateTime date;
- /// New profile photo
- public UserProfilePhoto photo;
- /// (), if one of the previously used photos is set a profile photo.
- public bool previous;
- }
/// New encrypted message. See
[TLDef(0x12BCBD9A)]
public class UpdateNewEncryptedMessage : Update
@@ -3334,11 +3340,9 @@ namespace TL
public PrivacyRule[] rules;
}
/// A user's phone number was changed See
- [TLDef(0x05492A13)]
- public class UpdateUserPhone : Update
+ [TLDef(0x05492A13, inheritBefore = true)]
+ public class UpdateUserPhone : UpdateUser
{
- /// User ID
- public long user_id;
/// New phone number
public string phone;
}
@@ -4341,11 +4345,9 @@ namespace TL
[TLDef(0xFB4C496C)]
public class UpdateReadFeaturedEmojiStickers : Update { }
/// The emoji status of a certain user has changed See
- [TLDef(0x28373599)]
- public class UpdateUserEmojiStatus : Update
+ [TLDef(0x28373599, inheritBefore = true)]
+ public class UpdateUserEmojiStatus : UpdateUser
{
- /// User ID
- public long user_id;
/// New emoji status
public EmojiStatus emoji_status;
}
@@ -4406,6 +4408,12 @@ namespace TL
has_order = 0x1,
}
}
+ /// See
+ [TLDef(0x20529438)]
+ public class UpdateUser : Update
+ {
+ public long user_id;
+ }
/// Updates state. See
[TLDef(0xA56C2A3E)]
@@ -5791,6 +5799,7 @@ namespace TL
{
/// Whether this custom emoji can be sent by non-Premium users
free = 0x1,
+ text_color = 0x2,
}
}
@@ -6629,6 +6638,7 @@ namespace TL
selective = 0x4,
/// Field has a value
has_placeholder = 0x8,
+ persistent = 0x10,
}
}
/// Bot or inline keyboard See
@@ -8187,6 +8197,14 @@ namespace TL
/// Stickerset
public override StickerSet Set => set;
}
+ /// See
+ [TLDef(0x77B15D1C)]
+ public class StickerSetNoCovered : StickerSetCoveredBase
+ {
+ public StickerSet set;
+
+ public override StickerSet Set => set;
+ }
/// Position on a photo where a mask should be placed when attaching stickers to media » See
[TLDef(0xAED6DBB2)]
@@ -13450,6 +13468,7 @@ namespace TL
inactive = 0x1,
/// True, if the bot supports the "settings_button_pressed" event »
has_settings = 0x2,
+ request_write_access = 0x4,
}
}
diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs
index 9fab31b..83fa378 100644
--- a/src/TL.SchemaFuncs.cs
+++ b/src/TL.SchemaFuncs.cs
@@ -3255,9 +3255,10 @@ namespace TL
/// Enable or disable web bot attachment menu » See
/// Bot ID
/// Toggle
- public static Task Messages_ToggleBotInAttachMenu(this Client client, InputUserBase bot, bool enabled)
+ public static Task Messages_ToggleBotInAttachMenu(this Client client, InputUserBase bot, bool enabled, bool write_allowed = false)
=> client.Invoke(new Messages_ToggleBotInAttachMenu
{
+ flags = (Messages_ToggleBotInAttachMenu.Flags)(write_allowed ? 0x1 : 0),
bot = bot,
enabled = enabled,
});
@@ -3495,9 +3496,10 @@ namespace TL
/// Installs a previously uploaded photo as a profile photo. See Possible codes: 400 (details)
/// Input photo
- public static Task Photos_UpdateProfilePhoto(this Client client, InputPhoto id)
+ public static Task Photos_UpdateProfilePhoto(this Client client, InputPhoto id, bool fallback = false)
=> client.Invoke(new Photos_UpdateProfilePhoto
{
+ flags = (Photos_UpdateProfilePhoto.Flags)(fallback ? 0x1 : 0),
id = id,
});
@@ -3505,10 +3507,10 @@ 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)
+ public static Task Photos_UploadProfilePhoto(this Client client, InputFileBase file = null, InputFileBase video = null, double? video_start_ts = 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)),
+ flags = (Photos_UploadProfilePhoto.Flags)((file != null ? 0x1 : 0) | (video != null ? 0x2 : 0) | (video_start_ts != null ? 0x4 : 0) | (fallback ? 0x8 : 0)),
file = file,
video = video,
video_start_ts = video_start_ts.GetValueOrDefault(),
@@ -3536,6 +3538,17 @@ namespace TL
limit = limit,
});
+ /// 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)
+ => 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)),
+ user_id = user_id,
+ file = file,
+ video = video,
+ video_start_ts = video_start_ts.GetValueOrDefault(),
+ });
+
/// Saves a part of file for further sending to one of the methods. See [bots: ✓] Possible codes: 400 (details)
/// Random file identifier created by the client
/// Numerical order of a part
@@ -4360,6 +4373,14 @@ namespace TL
msg_id = msg_id,
});
+ /// See
+ public static Task Channels_ToggleParticipantsHidden(this Client client, InputChannelBase channel, bool enabled)
+ => client.Invoke(new Channels_ToggleParticipantsHidden
+ {
+ channel = channel,
+ enabled = enabled,
+ });
+
/// Sends a custom request; for bots only See [bots: ✓] Possible codes: 400,403 (details)
/// The method name
/// JSON-serialized method parameters
@@ -7790,11 +7811,17 @@ namespace TL.Methods
public InputUserBase bot;
}
- [TLDef(0x1AEE33AF)]
+ [TLDef(0x69F59D69)]
public class Messages_ToggleBotInAttachMenu : IMethod
{
+ public Flags flags;
public InputUserBase bot;
public bool enabled;
+
+ [Flags] public enum Flags : uint
+ {
+ write_allowed = 0x1,
+ }
}
[TLDef(0x178B480B)]
@@ -7983,10 +8010,16 @@ namespace TL.Methods
}
}
- [TLDef(0x72D4742C)]
+ [TLDef(0x1C3D5956)]
public class Photos_UpdateProfilePhoto : IMethod
{
+ public Flags flags;
public InputPhoto id;
+
+ [Flags] public enum Flags : uint
+ {
+ fallback = 0x1,
+ }
}
[TLDef(0x89F30F69)]
@@ -8002,6 +8035,7 @@ namespace TL.Methods
has_file = 0x1,
has_video = 0x2,
has_video_start_ts = 0x4,
+ fallback = 0x8,
}
}
@@ -8020,6 +8054,25 @@ namespace TL.Methods
public int limit;
}
+ [TLDef(0xB91A83BF)]
+ public class Photos_UploadContactProfilePhoto : IMethod
+ {
+ public Flags flags;
+ public InputUserBase user_id;
+ [IfFlag(0)] public InputFileBase file;
+ [IfFlag(1)] public InputFileBase video;
+ [IfFlag(2)] public double video_start_ts;
+
+ [Flags] public enum Flags : uint
+ {
+ has_file = 0x1,
+ has_video = 0x2,
+ has_video_start_ts = 0x4,
+ suggest = 0x8,
+ save = 0x10,
+ }
+ }
+
[TLDef(0xB304A621)]
public class Upload_SaveFilePart : IMethod
{
@@ -8657,6 +8710,13 @@ namespace TL.Methods
public int msg_id;
}
+ [TLDef(0x6A6E7854)]
+ public class Channels_ToggleParticipantsHidden : IMethod
+ {
+ public InputChannelBase channel;
+ public bool enabled;
+ }
+
[TLDef(0xAA2769ED)]
public class Bots_SendCustomRequest : IMethod
{
diff --git a/src/TL.Table.cs b/src/TL.Table.cs
index f1f9db4..cc4740e 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 = 150; // fetched 07/12/2022 12:23:35
+ public const int Version = 151; // fetched 29/12/2022 21:30:31
internal const int SecretChats = 144;
internal const int MTProto2 = 73;
internal const uint VectorCtor = 0x1CB5C415;
@@ -65,7 +65,7 @@ namespace TL
[0x37982646] = typeof(IpPortSecret),
[0x4679B65F] = typeof(AccessPointRule),
[0x5A592A6C] = typeof(Help_ConfigSimple),
- // from TL.Schema:
+ // from TL.SchemaExtensions:
[0x3FEDD339] = typeof(True),
[0xC4B9F9BB] = typeof(Error),
[0x56730BCC] = null,//Null
@@ -193,6 +193,8 @@ namespace TL
[0xABA0F5C6] = typeof(MessageActionGiftPremium),
[0x0D999256] = typeof(MessageActionTopicCreate),
[0xC0944820] = typeof(MessageActionTopicEdit),
+ [0x57DE635E] = typeof(MessageActionSuggestProfilePhoto),
+ [0xE7E75F97] = typeof(MessageActionAttachMenuBotAllowed),
[0xD58A08C6] = typeof(Dialog),
[0x71BD134C] = typeof(DialogFolder),
[0x2331B22D] = typeof(PhotoEmpty),
@@ -219,7 +221,7 @@ namespace TL
[0xA518110D] = typeof(PeerSettings),
[0xA437C3ED] = typeof(WallPaper),
[0xE0804116] = typeof(WallPaperNoFile),
- [0xC4B1FC3F] = typeof(UserFull),
+ [0xF8D32AED] = typeof(UserFull),
[0x145ADE0B] = typeof(Contact),
[0xC13E3C50] = typeof(ImportedContact),
[0x16D9703B] = typeof(ContactStatus),
@@ -264,7 +266,6 @@ namespace TL
[0x07761198] = typeof(UpdateChatParticipants),
[0xE5BDF8DE] = typeof(UpdateUserStatus),
[0xA7848924] = typeof(UpdateUserName),
- [0xF227868C] = typeof(UpdateUserPhoto),
[0x12BCBD9A] = typeof(UpdateNewEncryptedMessage),
[0x1710F156] = typeof(UpdateEncryptedChatTyping),
[0xB4A2E88D] = typeof(UpdateEncryption),
@@ -365,6 +366,7 @@ namespace TL
[0x5A73A98C] = typeof(UpdateMessageExtendedMedia),
[0x192EFBE3] = typeof(UpdateChannelPinnedTopic),
[0xFE198602] = typeof(UpdateChannelPinnedTopics),
+ [0x20529438] = typeof(UpdateUser),
[0xA56C2A3E] = typeof(Updates_State),
[0x5D75A138] = typeof(Updates_DifferenceEmpty),
[0x00F49CA0] = typeof(Updates_Difference),
@@ -622,6 +624,7 @@ namespace TL
[0x6410A5D2] = typeof(StickerSetCovered),
[0x3407E51B] = typeof(StickerSetMultiCovered),
[0x40D13C0E] = typeof(StickerSetFullCovered),
+ [0x77B15D1C] = typeof(StickerSetNoCovered),
[0xAED6DBB2] = typeof(MaskCoords),
[0x4A992157] = typeof(InputStickeredMediaPhoto),
[0x0438865B] = typeof(InputStickeredMediaDocument),
diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj
index 5718f70..ce3ce87 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: 150
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: 151
Release Notes:
$(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))
Copyright © Olivier Marcoux 2021-2022
MIT
https://github.com/wiz0u/WTelegramClient
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 033/336] 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 034/336] 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 035/336] 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 036/336] 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 037/336] 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 038/336] 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