diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 51bae9d..fca0a89 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1 @@ -github: wiz0u -custom: ["https://www.buymeacoffee.com/wizou", "http://t.me/WTelegramClientBot?start=donate"] +custom: ["https://www.paypal.me/wizou"] diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 5efff01..0000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,4 +0,0 @@ -contact_links: - - name: You have a question about the Telegram API or how to do something with WTelegramClient? - url: https://stackoverflow.com/questions/ask?tags=c%23+wtelegramclient+telegram-api - about: The answer to your question can be helpful to the community so it's better to ask them on StackOverflow ---> diff --git a/.github/ci.yml b/.github/ci.yml new file mode 100644 index 0000000..35ac36c --- /dev/null +++ b/.github/ci.yml @@ -0,0 +1,32 @@ +pr: none +trigger: +- master + +name: 1.0.0-ci.$(Rev:r) + +pool: + vmImage: ubuntu-latest + +variables: + buildConfiguration: 'Release' + +steps: +- task: DotNetCoreCLI@2 + inputs: + command: 'pack' + packagesToPack: '**/*.csproj' + includesymbols: true + versioningScheme: 'byEnvVar' + versionEnvVar: 'Build.BuildNumber' + buildProperties: 'NoWarn="0419;1573;1591";Version=$(Build.BuildNumber);ContinuousIntegrationBuild=true' +# buildProperties: 'NoWarn="0419;1573;1591";AllowedOutputExtensionsInPackageBuildOutputFolder=".dll;.xml;.pdb"' + +- task: NuGetCommand@2 + inputs: + command: 'push' + packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.*upkg' + publishPackageMetadata: true + nuGetFeedType: 'internal' + publishVstsFeed: 'WTelegramClient/WTelegramClient' + + diff --git a/.github/dev.yml b/.github/dev.yml deleted file mode 100644 index 6206e8e..0000000 --- a/.github/dev.yml +++ /dev/null @@ -1,63 +0,0 @@ -pr: none -trigger: - branches: - include: [ master ] - paths: - exclude: [ '.github', '*.md', 'Examples' ] - -name: 4.3.2-dev.$(Rev:r) - -pool: - vmImage: ubuntu-latest - -variables: - buildConfiguration: 'Release' - Release_Notes: $[replace(variables['Build.SourceVersionMessage'], '"', '''''')] - -stages: - - stage: publish - jobs: - - job: publish - steps: - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: 'sdk' - version: '9.x' - includePreviewVersions: true - - - task: DotNetCoreCLI@2 - inputs: - command: 'pack' - packagesToPack: 'src/WTelegramClient.csproj' - includesymbols: true - versioningScheme: 'byEnvVar' - versionEnvVar: 'Build.BuildNumber' - buildProperties: NoWarn="0419;1573;1591";ContinuousIntegrationBuild=true;Version=$(Build.BuildNumber);"ReleaseNotes=$(Release_Notes)" - - - task: NuGetCommand@2 - inputs: - command: 'push' - packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg' - publishPackageMetadata: true - nuGetFeedType: 'external' - publishFeedCredentials: 'nuget.org' - - - stage: notify - jobs: - - job: notify - pool: - server - steps: - - task: InvokeRESTAPI@1 - inputs: - connectionType: 'connectedServiceName' - serviceConnection: 'Telegram Deploy Notice' - method: 'POST' - body: | - { - "status": "success", - "complete": true, - "message": "{ \"commitId\": \"$(Build.SourceVersion)\", \"buildNumber\": \"$(Build.BuildNumber)\", \"teamProjectName\": \"$(System.TeamProject)\", \"commitMessage\": \"$(Release_Notes)\" }" - } - waitForCompletion: 'false' diff --git a/.github/release.yml b/.github/release.yml index e4ca17f..edfd937 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -1,38 +1,27 @@ pr: none trigger: none -name: 4.3.$(Rev:r) +name: 1.0.0 pool: vmImage: ubuntu-latest variables: buildConfiguration: 'Release' - Release_Notes: $[replace(variables['releaseNotes'], '"', '''''')] stages: - stage: publish jobs: - job: publish steps: - - checkout: self - persistCredentials: true - - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: 'sdk' - version: '9.x' - includePreviewVersions: true - - task: DotNetCoreCLI@2 inputs: command: 'pack' - packagesToPack: 'src/WTelegramClient.csproj' + packagesToPack: '**/*.csproj' includesymbols: true versioningScheme: 'byEnvVar' versionEnvVar: 'Build.BuildNumber' - buildProperties: NoWarn="0419;1573;1591";ContinuousIntegrationBuild=true;Version=$(Build.BuildNumber);"ReleaseNotes=$(Release_Notes)" + buildProperties: 'NoWarn="0419;1573;1591";Version=$(Build.BuildNumber);ContinuousIntegrationBuild=true' - task: NuGetCommand@2 inputs: @@ -41,12 +30,6 @@ stages: nuGetFeedType: 'external' publishFeedCredentials: 'nuget.org' - - script: | - git tag $(Build.BuildNumber) - git push --tags - workingDirectory: $(Build.SourcesDirectory) - displayName: Git Tag - - stage: notify jobs: - job: notify @@ -59,9 +42,13 @@ stages: serviceConnection: 'Telegram Deploy Notice' method: 'POST' body: | - { + { "status": "success", "complete": true, - "message": "{ \"commitId\": \"$(Build.SourceVersion)\", \"buildNumber\": \"$(Build.BuildNumber)\", \"teamProjectName\": \"$(System.TeamProject)\"}" + "message": "{ + \"commitId\": \"$(Build.SourceVersion)\", + \"buildNumber\": \"$(Build.BuildNumber)\", + \"teamProjectName\": \"$(system.TeamProject)\" + }" } waitForCompletion: 'false' diff --git a/.github/workflows/autolock.yml b/.github/workflows/autolock.yml deleted file mode 100644 index 9a676bc..0000000 --- a/.github/workflows/autolock.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: 'Auto-Lock Issues' - -on: - schedule: - - cron: '17 2 * * 1' - workflow_dispatch: - -permissions: - issues: write - pull-requests: write - discussions: write - -concurrency: - group: lock-threads - -jobs: - action: - runs-on: ubuntu-latest - steps: - - uses: dessant/lock-threads@v5 - with: - issue-inactive-days: '60' - pr-inactive-days: '60' - discussion-inactive-days: '60' diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml deleted file mode 100644 index de5e145..0000000 --- a/.github/workflows/dev.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: Dev build - -on: - push: - branches: [ master ] - paths-ignore: [ '.**', 'Examples/**', '**.md' ] - -env: - PROJECT_PATH: src/WTelegramClient.csproj - CONFIGURATION: Release - RELEASE_NOTES: ${{ github.event.head_commit.message }} - -jobs: - build: - permissions: - id-token: write # enable GitHub OIDC token issuance for this job - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 30 - - name: Determine version - run: | - git fetch --depth=30 --tags - DESCR_TAG=$(git describe --tags) - COMMITS=${DESCR_TAG#*-} - COMMITS=${COMMITS%-*} - LAST_TAG=${DESCR_TAG%%-*} - NEXT_VERSION=${LAST_TAG%.*}.$((${LAST_TAG##*.} + 1))-dev.$COMMITS - RELEASE_VERSION=${{vars.RELEASE_VERSION}}-dev.$COMMITS - if [[ "$RELEASE_VERSION" > "$NEXT_VERSION" ]] then VERSION=$RELEASE_VERSION; else VERSION=$NEXT_VERSION; fi - echo Last tag: $LAST_TAG · Next version: $NEXT_VERSION · Release version: $RELEASE_VERSION · Build version: $VERSION - echo "VERSION=$VERSION" >> $GITHUB_ENV - - # - name: Setup .NET - # uses: actions/setup-dotnet@v4 - # with: - # dotnet-version: 8.0.x - - name: Pack - run: | - RELEASE_NOTES=${RELEASE_NOTES//$'\n'/%0A} - RELEASE_NOTES=${RELEASE_NOTES//\"/%22} - RELEASE_NOTES=${RELEASE_NOTES//,/%2C} - RELEASE_NOTES=${RELEASE_NOTES//;/%3B} - dotnet pack $PROJECT_PATH --configuration $CONFIGURATION -p:Version=$VERSION -p:ReleaseNotes="$RELEASE_NOTES" --output packages - # - name: Upload artifact - # uses: actions/upload-artifact@v4 - # with: - # name: packages - # path: packages/*.nupkg - - - name: NuGet login (OIDC → temp API key) - uses: NuGet/login@v1 - id: login - with: - user: ${{ secrets.NUGET_USER }} - - name: Nuget push - run: dotnet nuget push packages/*.nupkg --api-key ${{steps.login.outputs.NUGET_API_KEY}} --skip-duplicate --source https://api.nuget.org/v3/index.json - - - name: Deployment Notification - env: - JSON: | - { - "status": "success", "complete": true, "commitMessage": ${{ toJSON(env.RELEASE_NOTES) }}, - "message": "{ \"commitId\": \"${{ github.sha }}\", \"buildNumber\": \"${{ env.VERSION }}\", \"repoName\": \"${{ github.repository }}\"}" - } - run: | - curl -X POST -H "Content-Type: application/json" -d "$JSON" ${{ secrets.DEPLOYED_WEBHOOK }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 7bdbcd1..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: Release build - -on: - workflow_dispatch: - inputs: - release_notes: - description: 'Release notes' - required: true - version: - description: "Release version (leave empty for automatic versioning)" - -run-name: '📌 Release build ${{ inputs.version }}' - -env: - PROJECT_PATH: src/WTelegramClient.csproj - CONFIGURATION: Release - RELEASE_NOTES: ${{ inputs.release_notes }} - VERSION: ${{ inputs.version }} - -jobs: - build: - runs-on: ubuntu-latest - permissions: - contents: write # For git tag - id-token: write # enable GitHub OIDC token issuance for this job - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 100 - - name: Determine version - if: ${{ env.VERSION == '' }} - run: | - git fetch --depth=100 --tags - DESCR_TAG=$(git describe --tags) - LAST_TAG=${DESCR_TAG%%-*} - NEXT_VERSION=${LAST_TAG%.*}.$((${LAST_TAG##*.} + 1)) - RELEASE_VERSION=${{vars.RELEASE_VERSION}} - if [[ "$RELEASE_VERSION" > "$NEXT_VERSION" ]] then VERSION=$RELEASE_VERSION; else VERSION=$NEXT_VERSION; fi - echo Last tag: $LAST_TAG · Next version: $NEXT_VERSION · Release version: $RELEASE_VERSION · Build version: $VERSION - echo "VERSION=$VERSION" >> $GITHUB_ENV - - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 8.0.x - - name: Pack - run: | - RELEASE_NOTES=${RELEASE_NOTES//|/%0A} - RELEASE_NOTES=${RELEASE_NOTES// - /%0A- } - RELEASE_NOTES=${RELEASE_NOTES// /%0A%0A} - RELEASE_NOTES=${RELEASE_NOTES//$'\n'/%0A} - RELEASE_NOTES=${RELEASE_NOTES//\"/%22} - RELEASE_NOTES=${RELEASE_NOTES//,/%2C} - RELEASE_NOTES=${RELEASE_NOTES//;/%3B} - dotnet pack $PROJECT_PATH --configuration $CONFIGURATION -p:Version=$VERSION -p:ReleaseNotes="$RELEASE_NOTES" --output packages - # - name: Upload artifact - # uses: actions/upload-artifact@v4 - # with: - # name: packages - # path: packages/*.nupkg - - - name: NuGet login (OIDC → temp API key) - uses: NuGet/login@v1 - id: login - with: - user: ${{ secrets.NUGET_USER }} - - name: Nuget push - run: dotnet nuget push packages/*.nupkg --api-key ${{steps.login.outputs.NUGET_API_KEY}} --skip-duplicate --source https://api.nuget.org/v3/index.json - - - name: Git tag - run: | - git tag $VERSION - git push --tags - - name: Deployment Notification - env: - JSON: | - { - "status": "success", "complete": true, "commitMessage": ${{ toJSON(env.RELEASE_NOTES) }}, - "message": "{ \"commitId\": \"${{ github.sha }}\", \"buildNumber\": \"${{ env.VERSION }}\", \"repoName\": \"${{ github.repository }}\"}" - } - run: | - curl -X POST -H "Content-Type: application/json" -d "$JSON" ${{ secrets.DEPLOYED_WEBHOOK }} diff --git a/.github/workflows/telegram-api.yml b/.github/workflows/telegram-api.yml deleted file mode 100644 index efd921a..0000000 --- a/.github/workflows/telegram-api.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: 'Telegram API issues' - -on: - issues: - types: [labeled] - -permissions: - issues: write - -jobs: - action: - if: contains(github.event.issue.labels.*.name, 'telegram api') - runs-on: ubuntu-latest - steps: - - uses: dessant/support-requests@v4 - with: - support-label: 'telegram api' - issue-comment: > - Please note that **Github issues** should be used only for problems with the library code itself. - - - For questions about Telegram API usage, you can search the [API official documentation](https://core.telegram.org/api#getting-started) and the [full list of methods](https://core.telegram.org/methods). - - WTelegramClient covers 100% of the API and let you do anything you can do in an official client. - - - If the above links didn't answer your problem, [click here to ask your question on **StackOverflow**](https://stackoverflow.com/questions/ask?tags=c%23+wtelegramclient+telegram-api) so the whole community can help and benefit. - close-issue: true - issue-close-reason: 'not planned' diff --git a/.gitignore b/.gitignore index 0c768ca..9491a2f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,6 @@ ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore -launchSettings.json - # User-specific files *.rsuser *.suo diff --git a/EXAMPLES.md b/EXAMPLES.md deleted file mode 100644 index d00c4b5..0000000 --- a/EXAMPLES.md +++ /dev/null @@ -1,624 +0,0 @@ -# Example programs using WTelegramClient - -For these examples to work as a fully-functional Program.cs, be sure to start with these lines: -```csharp -using System; -using System.Linq; -using TL; - -using var client = new WTelegram.Client(Environment.GetEnvironmentVariable); -await client.LoginUserIfNeeded(); -``` - -In this case, environment variables are used for configuration so make sure to -go to your **Project Properties > Debug > Launch Profiles > Environment variables** -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, -and avoid calling the same methods (like `Messages_GetAllChats`) repetitively. - -➡️ 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 -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 (⛔️𝗗𝗢𝗡'𝗧 𝗗𝗢 𝗧𝗛𝗜𝗦 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 -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. -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(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); -// if you need to convert a sent/received Message to HTML: (easier to store) -text = client.EntitiesToHtml(sent.message, sent.entities); -``` -```csharp -// Markdown-style text: -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); -// if you need to convert a sent/received Message to Markdown: (easier to store) -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, 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 -```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); -} -``` - -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?ts=4#L18). -- 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 -```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](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_GetAllChats.cs?ts=4#L31) - - -## 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 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}'"); - 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/user -```csharp -var chats = await client.Messages_GetAllChats(); -InputPeer peer = chats.chats[1234567890]; // the chat (or User) we want -for (int offset_id = 0; ;) -{ - var messages = await client.Messages_GetHistory(peer, offset_id); - 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: -- `peer` can also be a User, obtained through methods like [`Messages_GetAllDialogs`](#list-dialogs) -- To stop at a specific msg ID, use Messages_GetHistory `min_id` argument. For example, `min_id: dialog.read_inbox_max_id` -- To mark the message history as read, use: `await client.ReadHistory(peer);` - - -## Monitor all Telegram events happening for the user - -This is done through the `client.OnUpdates` callback event, or via the [UpdateManager class](FAQ.md#manager) that simplifies the handling of updates. - -See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L21). - - -## Monitor new messages being posted in chats in real-time - -You have to handle update events containing an `UpdateNewMessage`. -This can be done through the `client.OnUpdates` callback event, or via the [UpdateManager class](FAQ.md#manager) that simplifies the handling of updates. - -See the `HandleMessage` method in [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L21). - -You can filter specific chats the message are posted in, by looking at the `Message.peer_id` field. -See also [explanation below](#message-user) to extract user/chat info from messages. - - -## 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](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_DownloadSavedMedia.cs?ts=4#L28) that download all media files you forward to yourself (Saved Messages) - -_Note: To abort an ongoing download, you can throw an exception via the `progress` callback argument. Example: `(t,s) => ct.ThrowIfCancellationRequested()`_ - - -## 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); -``` - - -## Upload a streamable video with optional custom thumbnail -```csharp -var chats = await client.Messages_GetAllChats(); -InputPeer peer = chats.chats[1234567890]; // the chat we want -const string videoPath = @"C:\...\video.mp4"; -const string thumbnailPath = @"C:\...\thumbnail.jpg"; - -// Extract video information using FFMpegCore or similar library -var mediaInfo = await FFmpeg.GetMediaInfo(videoPath); -var videoStream = mediaInfo.VideoStreams.FirstOrDefault(); -int width = videoStream?.Width ?? 0; -int height = videoStream?.Height ?? 0; -int duration = (int)mediaInfo.Duration.TotalSeconds; - -// Upload video file -var inputFile = await Client.UploadFileAsync(videoPath); - -// Prepare InputMedia structure with video attributes -var media = new InputMediaUploadedDocument(inputFile, "video/mp4", - new DocumentAttributeVideo { w = width, h = height, duration = duration, - flags = DocumentAttributeVideo.Flags.supports_streaming }); -if (thumbnailPath != null) -{ - // upload custom thumbnail and complete InputMedia structure - var inputThumb = await client.UploadFileAsync(thumbnailPath); - media.thumb = inputThumb; - media.flags |= InputMediaUploadedDocument.Flags.has_thumb; -} - -// Send the media message -await client.SendMessageAsync(peer, "caption", media); -``` -*Note: This example requires FFMpegCore NuGet package for video metadata extraction. You can also manually set width, height, and duration if you know the video properties.* - - -## 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 }, - //or Document, InputMediaDocument, InputMediaUploadedDocument, InputMediaDocumentExternal... -}; -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.ForwardMessagesAsync(from_chat, [msg.ID], to_chat); - -// • Copy the message without the "Forwarded" header (only the source message id is necessary) -await client.ForwardMessagesAsync(from_chat, [msg.ID], 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); -``` -*Note: Make sure your computer clock is synchronized with Internet time* - - -## 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(); -foreach (var stickerSet in allStickers.sets) - Console.WriteLine($"Pack {stickerSet.short_name} contains {stickerSet.count} stickers"); -//if you need details on each: var sticketSetDetails = await client.Messages_GetStickerSet(stickerSet); - -// • Send a random sticker from the user's favorites stickers -var favedStickers = await client.Messages_GetFavedStickers(); -var stickerDoc = favedStickers.stickers[new Random().Next(favedStickers.stickers.Length)]; -await client.SendMessageAsync(InputPeer.Self, null, stickerDoc); - -// • Send a specific sticker given the stickerset shortname and emoticon -var friendlyPanda = await client.Messages_GetStickerSet("Friendly_Panda"); -var laughId = friendlyPanda.packs.First(p => p.emoticon == "😂").documents[0]; -var laughDoc = friendlyPanda.documents.First(d => d.ID == laughId); -await client.SendMessageAsync(InputPeer.Self, null, laughDoc); - -// • Send a GIF from an internet URL -await client.SendMessageAsync(InputPeer.Self, null, new InputMediaDocumentExternal - { url = "https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif" }); - -// • Send a GIF stored on the computer (you can save inputFile for later reuse) -var inputFile = await client.UploadFileAsync(@"C:\Pictures\Rotating_earth_(large).gif"); -await client.SendMediaAsync(InputPeer.Self, null, inputFile); - -// • Send a random dice/game-of-chance effect from the list of available "dices", see https://core.telegram.org/api/dice -var appConfig = await client.Help_GetAppConfig(); -var emojies_send_dice = appConfig.config["emojies_send_dice"] as string[]; -var dice_emoji = emojies_send_dice[new Random().Next(emojies_send_dice.Length)]; -var diceMsg = await client.SendMessageAsync(InputPeer.Self, null, new InputMediaDice { emoticon = dice_emoji }); -Console.WriteLine("Dice result:" + ((MessageMediaDice)diceMsg.media).value); - -// • Send an animated emoji with full-screen animation, see https://core.telegram.org/api/animated-emojis#emoji-reactions -// Please note that on Telegram Desktop, you won't view the effect from the sender user's point of view -// You can view the effect if you're on Telegram Android, or if you're the receiving user (instead of Self) -var msg = await client.SendMessageAsync(InputPeer.Self, "🎉"); -await Task.Delay(5000); // wait for classic animation to finish -await client.SendMessageAsync(InputPeer.Self, "and now, full-screen animation on the above emoji"); -// trigger the full-screen animation, -var typing = await client.Messages_SetTyping(InputPeer.Self, new SendMessageEmojiInteraction { - emoticon = "🎉", msg_id = msg.id, - interaction = new DataJSON { data = @"{""v"":1,""a"":[{""t"":0.0,""i"":1}]}" } -}); -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! ![👋](tg://emoji?id=5190875290439525089)"; -var entities = client.MarkdownToEntities(ref text); -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/methods#working-with-custom-animated-emojis) or inspecting messages entities. Access hash is not required* - - - -## 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: -```csharp -var resolved = await client.Contacts_ResolveUsername("channelname"); // without the @ -if (resolved.Chat is Channel channel) - await client.Channels_JoinChannel(channel); -``` -* For a private channel/group/chat, you need to have an invite link -Telegram invite links can typically have two forms: `https://t․me/joinchat/HASH` or `https://t․me/+HASH` *(note the '+' prefix here)* -To use them, you need to extract the `HASH` part from the URL and then you can use those two methods: -```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 from public channel/group -``` -`CheckChatInvite` can return [3 different types of invitation object](https://corefork.telegram.org/type/ChatInvite) - -You can also use helper methods `AnalyzeInviteLink` and `GetMessageByLink` to more easily fetch information from links. - -## Add/Invite/Remove someone in a chat -```csharp -var chats = await client.Messages_GetAllChats(); -var chat = chats.chats[1234567890]; // the target chat -``` -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: -var miu = await client.AddChatUser(chat, user); -// You may get exception USER_NOT_MUTUAL_CONTACT if the user left the chat previously and you want to add him again -// or a result with miu.missing_invitees listing users that denied the right to be added to a chat - -// • Obtain the main invite link for the chat, and send it to the user: -var mcf = await client.GetFullChat(chat); -var invite = (ChatInviteExported)mcf.full_chat.ExportedInvite; -await client.SendMessageAsync(user, "Join our group with this link: " + invite.link); - -// • Create a new invite link for the chat/channel, and send it to the user -var invite = (ChatInviteExported)await client.Messages_ExportChatInvite(chat, title: "MyLink"); -await client.SendMessageAsync(user, "Join our group with this link: " + invite.link); -// • Revoke then delete that invite link (when you no longer need it) -await client.Messages_EditExportedChatInvite(chat, invite.link, revoked: true); -await client.Messages_DeleteExportedChatInvite(chat, invite.link); - -// • Remove the user from a Chat/Channel/Group: -await client.DeleteChatUser(chat, user); -``` - - -## 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: 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 -There are two different methods. Here is the simpler one: -```csharp -var contacts = await client.Contacts_GetContacts(); -foreach (User contact in contacts.users.Values) - Console.WriteLine($"{contact} {contact.phone}"); -``` - -The second method uses the more complex GDPR export, **takeout session** system. -Here is an example on how to implement it: -```csharp -using TL.Methods; // methods as structures, for Invoke* calls - -var takeout = await client.Account_InitTakeoutSession(contacts: true); -var finishTakeout = new Account_FinishTakeoutSession(); -try -{ - var savedContacts = await client.InvokeWithTakeout(takeout.id, new Contacts_GetSaved()); - foreach (SavedPhoneContact contact in savedContacts) - Console.WriteLine($"{contact.first_name} {contact.last_name} {contact.phone}, added on {contact.date}"); - finishTakeout.flags = Account_FinishTakeoutSession.Flags.success; -} -finally -{ - await client.InvokeWithTakeout(takeout.id, finishTakeout); -} -``` - - - - -## Collect Users/Chats description structures and access hash - -Many API calls return a structure with a `users` and a `chats` field at the root of the structure. -This is also the case for updates passed to `client.OnUpdates`. - -These two dictionaries give details *(including access hash)* about the various users/chats that will be typically referenced in subobjects deeper in the structure, -typically in the form of a `Peer` object or a `user_id`/`chat_id` field. - -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 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. -This method also helps dealing with [incomplete `min` structures](https://core.telegram.org/api/min). - -Example of usage: -```csharp -private Dictionary _users = new(); -private Dictionary _chats = new(); -... -var dialogs = await client.Messages_GetAllDialogs(); -dialogs.CollectUsersChats(_users, _chats); - -private async Task OnUpdates(UpdatesBase updates) -{ - 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* - - -## Get chat and user info from a message -First, you should read the above [section about collecting users/chats](#collect-users-chats), and the [FAQ about dealing with IDs](FAQ.md#access-hash). - -A message contains those two fields/properties: -- `peer_id`/`Peer` that identify WHERE the message was posted -- `from_id`/`From` that identify WHO posted the message (it can be `null` in some case of anonymous posting) - -These two fields derive from class `Peer` and can be of type `PeerChat`, `PeerChannel` or `PeerUser` depending on the nature of WHERE & WHO -(private chat with a user? message posted BY a channel IN a chat? ...) - -> ✳️ It is recommended that you use the [UpdateManager class](FAQ.md#manager), as it handles automatically all of the details below, and you just need to use `Manager.UserOrChat(peer)` or Manager.Users/Chats dictionaries - -The root structure where you obtained the message (typically `UpdatesBase` or `Messages_MessagesBase`) inherits from `IPeerResolver`. -This allows you to call `.UserOrChat(peer)` on the root structure, in order to resolve those fields into a `User` class, or a `ChatBase`-derived class -(typically `Chat` or `Channel`) which will give you details about the peer, instead of just the ID, and can be implicitly converted to `InputPeer`. - -However, in some case _(typically when dealing with updates)_, Telegram might choose to not include details about a peer -because it expects you to already know about it (`UserOrChat` returns `null`). -That's why you should collect users/chats details each time you're dealing with Updates or other API results inheriting from `IPeerResolver`, -and use the collected dictionaries to find details about users/chats -([see previous section](#collect-users-chats) and [Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L21) example) - -And finally, it may happen that you receive updates of type `UpdateShortMessage` or `UpdateShortChatMessage` with totally unknown peers (even in your collected dictionaries). -In this case, [Telegram recommends](https://core.telegram.org/api/updates#recovering-gaps) that you use the [`Updates_GetDifference`](https://corefork.telegram.org/method/updates.getDifference) method to retrieve the full information associated with the short message. -Here is an example showing how to deal with `UpdateShortMessage`: (same for `UpdateShortChatMessage`) -```csharp -if (updates is UpdateShortMessage usm && !_users.ContainsKey(usm.user_id)) -{ - var fullDiff = await client.Updates_GetDifference(usm.pts - usm.pts_count, usm.date, 0) - fullDiff.CollectUsersChats(_users, _chats); -} -``` - - - -## 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/) 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(); -``` - -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 = "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/s/ProxyMTProto) or [@MTProxyT](https://t.me/s/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 ![🛡](https://raw.githubusercontent.com/telegramdesktop/tdesktop/dev/Telegram/Resources/icons/proxy_on.png) and then **⋮** > **Share** - -*Note: WTelegramClient always uses transport obfuscation when connecting to Telegram servers, even without MTProxy* - - -## 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 -var accountPwd = await client.Account_GetPassword(); -var password = accountPwd.current_algo == null ? null : await WTelegram.Client.InputCheckPassword(accountPwd, old_password); -accountPwd.current_algo = null; // makes InputCheckPassword generate a new password -var new_password_hash = new_password == null ? null : await WTelegram.Client.InputCheckPassword(accountPwd, new_password); -await client.Account_UpdatePasswordSettings(password, new Account_PasswordInputSettings -{ - flags = Account_PasswordInputSettings.Flags.has_new_algo, - new_password_hash = new_password_hash?.A, - new_algo = accountPwd.new_algo, - hint = "new password hint", -}); -``` - - -## 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. - -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?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?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). diff --git a/Examples/ASPnet_webapp.zip b/Examples/ASPnet_webapp.zip deleted file mode 100644 index f1183ce..0000000 Binary files a/Examples/ASPnet_webapp.zip and /dev/null differ diff --git a/Examples/Program_DownloadSavedMedia.cs b/Examples/Program_DownloadSavedMedia.cs deleted file mode 100644 index 00022aa..0000000 --- a/Examples/Program_DownloadSavedMedia.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using TL; - -namespace WTelegramClientTest -{ - static class Program_DownloadSavedMedia - { - // go to Project Properties > Debug > Launch Profiles > Environment variables and add at least these: api_id, api_hash, phone_number - static async Task Main(string[] _) - { - Console.WriteLine("The program will download photos/medias from messages you send/forward to yourself (Saved Messages)"); - var cts = new CancellationTokenSource(); - await using var client = new WTelegram.Client(Environment.GetEnvironmentVariable); - var user = await client.LoginUserIfNeeded(); - client.OnUpdates += Client_OnUpdates; - Console.ReadKey(); - cts.Cancel(); - - async Task Client_OnUpdates(UpdatesBase updates) - { - foreach (var update in updates.UpdateList) - { - if (update is not UpdateNewMessage { message: Message message }) - continue; // if it's not about a new message, ignore the update - if (message.peer_id.ID != user.ID) - continue; // if it's not in the "Saved messages" chat, ignore it - - if (message.media is MessageMediaDocument { document: Document document }) - { - 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, progress: (p, t) => cts.Token.ThrowIfCancellationRequested()); - Console.WriteLine("Download finished"); - } - else if (message.media is MessageMediaPhoto { photo: Photo photo }) - { - var filename = $"{photo.id}.jpg"; - Console.WriteLine("Downloading " + filename); - using var fileStream = File.Create(filename); - var type = await client.DownloadFileAsync(photo, fileStream); - fileStream.Close(); // necessary for the renaming - Console.WriteLine("Download finished"); - if (type is not Storage_FileType.unknown and not Storage_FileType.partial) - File.Move(filename, $"{photo.id}.{type}", true); // rename extension - } - } - } - } - } -} diff --git a/Examples/Program_GetAllChats.cs b/Examples/Program_GetAllChats.cs deleted file mode 100644 index f9ce1ce..0000000 --- a/Examples/Program_GetAllChats.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Threading.Tasks; -using TL; - -namespace WTelegramClientTest -{ - static class Program_GetAllChats - { - // This code is similar to what you should have obtained if you followed the README introduction - // I've just added a few comments to explain further what's going on - - // go to Project Properties > Debug > Launch Profiles > Environment variables and add at least these: api_id, api_hash, phone_number - static string Config(string what) - { - if (what == "api_id") return Environment.GetEnvironmentVariable("api_id"); - if (what == "api_hash") return Environment.GetEnvironmentVariable("api_hash"); - if (what == "phone_number") return Environment.GetEnvironmentVariable("phone_number"); - if (what == "verification_code") return null; // let WTelegramClient ask the user with a console prompt - if (what == "first_name") return "John"; // if sign-up is required - if (what == "last_name") return "Doe"; // if sign-up is required - if (what == "password") return "secret!"; // if user has enabled 2FA - return null; - } - - static async Task Main(string[] _) - { - await using var client = new WTelegram.Client(Config); - var user = await client.LoginUserIfNeeded(); - Console.WriteLine($"We are logged-in as {user.username ?? user.first_name + " " + user.last_name} (id {user.id})"); - - var chats = await client.Messages_GetAllChats(); // chats = groups/channels (does not include users dialogs) - Console.WriteLine("This user has joined the following:"); - foreach (var (id, chat) in chats.chats) - switch (chat) - { - case Chat smallgroup when smallgroup.IsActive: - Console.WriteLine($"{id}: Small group: {smallgroup.title} with {smallgroup.participants_count} members"); - break; - case Channel channel when channel.IsChannel: - Console.WriteLine($"{id}: Channel {channel.username}: {channel.title}"); - //Console.WriteLine($" → access_hash = {channel.access_hash:X}"); - break; - case Channel group: // no broadcast flag => it's a big group, also called supergroup or megagroup - Console.WriteLine($"{id}: Group {group.username}: {group.title}"); - //Console.WriteLine($" → access_hash = {group.access_hash:X}"); - break; - } - - Console.Write("Type a chat ID to send a message: "); - long chatId = long.Parse(Console.ReadLine()); - var target = chats.chats[chatId]; - Console.WriteLine($"Sending a message in chat {chatId}: {target.Title}"); - // Next line implicitely creates an adequate InputPeer from ChatBase: (with the access_hash if these is one) - InputPeer peer = target; - await client.SendMessageAsync(peer, "Hello, World"); - } - } -} diff --git a/Examples/Program_Heroku.cs b/Examples/Program_Heroku.cs deleted file mode 100644 index 4ad3740..0000000 --- a/Examples/Program_Heroku.cs +++ /dev/null @@ -1,139 +0,0 @@ -using Npgsql; -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -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 -// When run locally, close the window or type ALT-F4 to exit cleanly and save session (similar to Heroku SIGTERM) - -namespace WTelegramClientTest -{ - static class Program_Heroku - { - static WTelegram.Client Client; - static User My; - static readonly Dictionary Users = []; - static readonly Dictionary Chats = []; - - // See steps at the end of this file to setup required Environment variables - static async Task Main(string[] _) - { - var exit = new SemaphoreSlim(0); - AppDomain.CurrentDomain.ProcessExit += (s, e) => exit.Release(); // detect SIGTERM to exit gracefully - var store = new PostgreStore(Environment.GetEnvironmentVariable("DATABASE_URL"), Environment.GetEnvironmentVariable("SESSION_NAME")); - // if DB does not contain a session yet, client will be run in interactive mode - Client = new WTelegram.Client(store.Length == 0 ? null : Environment.GetEnvironmentVariable, store); - await using (Client) - { - Client.OnUpdates += Client_OnUpdates; - My = await Client.LoginUserIfNeeded(); - Console.WriteLine($"We are logged-in as {My.username ?? My.first_name + " " + My.last_name} (id {My.id})"); - var dialogs = await Client.Messages_GetAllDialogs(); - dialogs.CollectUsersChats(Users, Chats); - await exit.WaitAsync(); - } - } - - private static async Task Client_OnUpdates(UpdatesBase updates) - { - updates.CollectUsersChats(Users, Chats); - foreach (var update in updates.UpdateList) - { - Console.WriteLine(update.GetType().Name); - if (update is UpdateNewMessage { message: Message { peer_id: PeerUser { user_id: var user_id } } msg }) // private message - if (!msg.flags.HasFlag(Message.Flags.out_)) // ignore our own outgoing messages - if (Users.TryGetValue(user_id, out var user)) - { - Console.WriteLine($"New message from {user}: {msg.message}"); - if (msg.message.Equals("Ping", StringComparison.OrdinalIgnoreCase)) - await Client.SendMessageAsync(user, "Pong"); - } - } - } - } - - #region PostgreSQL session store - class PostgreStore : Stream - { - private readonly NpgsqlConnection _sql; - private readonly string _sessionName; - private readonly byte[] _data; - private readonly int _dataLen; - - /// Heroku DB URL of the form "postgres://user:password@host:port/database" - /// Entry name for the session data in the WTelegram_sessions table (default: "Heroku") - public PostgreStore(string databaseUrl, string sessionName = null) - { - _sessionName = sessionName ?? "Heroku"; - var parts = databaseUrl.Split(':', '/', '@'); - _sql = new NpgsqlConnection($"User ID={parts[3]};Password={parts[4]};Host={parts[5]};Port={parts[6]};Database={parts[7]};Pooling=true;SSL Mode=Require;Trust Server Certificate=True;"); - _sql.Open(); - using (var create = new NpgsqlCommand("CREATE TABLE IF NOT EXISTS WTelegram_sessions (name text NOT NULL PRIMARY KEY, data bytea)", _sql)) - create.ExecuteNonQuery(); - using var cmd = new NpgsqlCommand($"SELECT data FROM WTelegram_sessions WHERE name = '{_sessionName}'", _sql); - using var rdr = cmd.ExecuteReader(); - if (rdr.Read()) - _dataLen = (_data = rdr[0] as byte[]).Length; - } - - protected override void Dispose(bool disposing) - { - _sql.Dispose(); - } - - public override int Read(byte[] buffer, int offset, int count) - { - Array.Copy(_data, 0, buffer, offset, count); - return count; - } - - public override void Write(byte[] buffer, int offset, int count) // Write call and buffer modifications are done within a lock() - { - using var cmd = new NpgsqlCommand($"INSERT INTO WTelegram_sessions (name, data) VALUES ('{_sessionName}', @data) ON CONFLICT (name) DO UPDATE SET data = EXCLUDED.data", _sql); - cmd.Parameters.AddWithValue("data", count == buffer.Length ? buffer : buffer[offset..(offset + count)]); - cmd.ExecuteNonQuery(); - } - - public override long Length => _dataLen; - public override long Position { get => 0; set { } } - public override bool CanSeek => false; - public override bool CanRead => true; - public override bool CanWrite => true; - public override long Seek(long offset, SeekOrigin origin) => 0; - public override void SetLength(long value) { } - public override void Flush() { } - } - #endregion -} - -/****************************************************************************************************************************** -HOW TO USE AND DEPLOY THIS EXAMPLE HEROKU USERBOT: -- From your Heroku.com account dashboard, create a new app -- Navigate to the app Resources and add the add-on "Heroku Postgres" -- Navigate to the app Settings, click Reveal Config Vars and save the Heroku git URL and the value of DATABASE_URL -- Add a new var named "api_hash" with your api hash obtained from https://my.telegram.org/apps -- Add a new var named "phone_number" with the phone_number of the user this userbot will manage -- Scroll down to Buildpacks and add this URL: https://github.com/jincod/dotnetcore-buildpack.git -- In Visual Studio, Clone the Heroku git repository and add some standard .gitignore .gitattributes files -- In this repository folder, create a new .NET Console project with this Program.cs file -- Add these Nuget packages: WTelegramClient and Npgsql -- In Project properties > Debug > Launch Profiles > Environment variables, configure the same values for DATABASE_URL, api_hash, phone_number -- Run the project in Visual Studio. The first time, it should ask you interactively for elements to complete the connection -- On the following runs, the PostgreSQL database contains the session data and it should connect automatically -- You can test the userbot by sending him "Ping" in private message (or saved messages). It should respond with "Pong" -- You can now commit & push your git sources to Heroku, they will be compiled and deployed/run as a web app -- The userbot should work fine for 1 minute, but it will be taken down because it is not a web app. Let's fix that -- Navigate to the app Resources, copy the line starting with: web cd $HOME/....... -- Back in Visual Studio (or Explorer), at the root of the repository create a Procfile text file (without extension) -- Paste inside the line you copied, and replace the initial "web" with "worker:" (don't forget the colon) -- Commit and push the Git changes to Heroku. Wait until the deployment is complete. -- Verify that the Resources "web" line has changed to "worker" and is enabled (use the pencil icon if necessary) -- Now your userbot should be running 24/7. -- To prevent AUTH_KEY_DUPLICATED issues, set a SESSION_NAME env variable in your local VS project with a value like "PC" -DISCLAIMER: I'm not affiliated nor expert with Heroku, so if you have any problem with the above I might not be able to help -******************************************************************************************************************************/ diff --git a/Examples/Program_ListenUpdates.cs b/Examples/Program_ListenUpdates.cs index 59abe49..d4ebebb 100644 --- a/Examples/Program_ListenUpdates.cs +++ b/Examples/Program_ListenUpdates.cs @@ -1,72 +1,103 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using TL; namespace WTelegramClientTest { - static class Program_ListenUpdates + class Program_ListenUpdates { - static WTelegram.Client Client; - static WTelegram.UpdateManager Manager; - static User My; + static string Config(string what) + { + // go to Project Properties > Debug > Environment variables and add at least these: api_id, api_hash, phone_number + if (what == "verification_code") { Console.Write("Code: "); return Console.ReadLine(); } + return Environment.GetEnvironmentVariable(what); + } - // go to Project Properties > Debug > Launch Profiles > Environment variables and add at least these: api_id, api_hash, phone_number static async Task Main(string[] _) { Console.WriteLine("The program will display updates received for the logged-in user. Press any key to terminate"); - WTelegram.Helpers.Log = (l, s) => System.Diagnostics.Debug.WriteLine(s); - Client = new WTelegram.Client(Environment.GetEnvironmentVariable); - await using (Client) - { - Manager = Client.WithUpdateManager(Client_OnUpdate/*, "Updates.state"*/); - My = await Client.LoginUserIfNeeded(); - // Note: on login, Telegram may sends a bunch of updates/messages that happened in the past and were not acknowledged - Console.WriteLine($"We are logged-in as {My.username ?? My.first_name + " " + My.last_name} (id {My.id})"); - // We collect all infos about the users/chats so that updates can be printed with their names - var dialogs = await Client.Messages_GetAllDialogs(); // dialogs = groups/channels/users - dialogs.CollectUsersChats(Manager.Users, Manager.Chats); - - Console.ReadKey(); - } // WTelegram.Client gets disposed when exiting this scope - - //Manager.SaveState("Updates.state"); // if you want to resume missed updates on the next run (see WithUpdateManager above) + WTelegram.Helpers.Log += (l, s) => System.Diagnostics.Debug.WriteLine(s); + using var client = new WTelegram.Client(Config) { CollectAccessHash = true }; + client.Update += Client_Update; + await client.ConnectAsync(); + var my = await client.LoginUserIfNeeded(); + users[my.id] = my; + // note that on logging, Telegram may sends a bunch of updates/messages that happened in the past and were not acknowledged + Console.WriteLine($"We are logged-in as {my.username ?? my.first_name + " " + my.last_name} (id {my.id})"); + var dialogsBase = await client.Messages_GetDialogs(default, 0, null, 0, 0); + if (dialogsBase is Messages_Dialogs dialogs) + while (dialogs.dialogs.Length != 0) + { + foreach (var user in dialogs.users) users[user.ID] = user; + foreach (var chat in dialogs.chats) chats[chat.ID] = chat; + var lastDialog = (Dialog)dialogs.dialogs[^1]; + var lastMsg = dialogs.messages.LastOrDefault(m => m.Peer.ID == lastDialog.peer.ID && m.ID == lastDialog.top_message); + InputPeer offsetPeer = lastDialog.peer is PeerUser pu ? dialogs.users.First(u => u.ID == pu.ID) + : dialogs.chats.First(u => u.ID == lastDialog.peer.ID); + dialogs = (Messages_Dialogs)await client.Messages_GetDialogs(lastMsg?.Date ?? default, lastDialog.top_message, offsetPeer, 500, 0); + } + Console.ReadKey(); + await client.Ping(43); // dummy API call.. this is used to force an acknowledge on this session's updates } - // if not using async/await, we could just return Task.CompletedTask - private static async Task Client_OnUpdate(Update update) + + private static readonly Dictionary users = new(); + private static readonly Dictionary chats = new(); + private static string AUser(long user_id) => users.TryGetValue(user_id, out var user) ? user.DisplayName : $"User {user_id}"; + private static string AChat(long chat_id) => chats.TryGetValue(chat_id, out var chat) ? chat.Title : $"Chat {chat_id}"; + private static string APeer(Peer peer) => peer is null ? null : peer is PeerUser user ? AUser(user.user_id) + : peer is PeerChat chat ? AChat(chat.chat_id) : peer is PeerChannel channel ? AChat(channel.channel_id) : $"Peer {peer.ID}"; + + private static void Client_Update(ITLObject arg) + { + switch (arg) + { + case UpdateShortMessage usm: Console.WriteLine($"{AUser(usm.user_id)}> {usm.message}"); break; + case UpdateShortChatMessage uscm: Console.WriteLine($"{AUser(uscm.from_id)} in {AChat(uscm.chat_id)}> {uscm.message}"); break; + case UpdateShortSentMessage: Console.WriteLine($"You sent a message"); break; + case UpdateShort updateShort: DisplayUpdate(updateShort.update); break; + case Updates u: + foreach (var user in u.users) users[user.ID] = user; + foreach (var chat in u.chats) chats[chat.ID] = chat; + foreach (var update in u.updates) DisplayUpdate(update); + break; + case UpdatesCombined uc: + foreach (var user in uc.users) users[user.ID] = user; + foreach (var chat in uc.chats) chats[chat.ID] = chat; + foreach (var update in uc.updates) DisplayUpdate(update); + break; + default: Console.WriteLine(arg.GetType().Name); break; + } + } + + private static void DisplayUpdate(Update update) { switch (update) { - case UpdateNewMessage unm: await HandleMessage(unm.message); break; - case UpdateEditMessage uem: await HandleMessage(uem.message, true); break; - // Note: UpdateNewChannelMessage and UpdateEditChannelMessage are also handled by above cases - case UpdateDeleteChannelMessages udcm: Console.WriteLine($"{udcm.messages.Length} message(s) deleted in {Chat(udcm.channel_id)}"); break; + case UpdateNewMessage unm: DisplayMessage(unm.message); break; + case UpdateEditMessage uem: Console.Write("(Edit): "); DisplayMessage(uem.message); break; + case UpdateDeleteChannelMessages udcm: Console.WriteLine($"{udcm.messages.Length} message(s) deleted in {AChat(udcm.channel_id)}"); break; case UpdateDeleteMessages udm: Console.WriteLine($"{udm.messages.Length} message(s) deleted"); break; - case UpdateUserTyping uut: Console.WriteLine($"{User(uut.user_id)} is {uut.action}"); break; - case UpdateChatUserTyping ucut: Console.WriteLine($"{Peer(ucut.from_id)} is {ucut.action} in {Chat(ucut.chat_id)}"); break; - 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.first_name} {uun.last_name}"); 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 + case UpdateUserTyping uut: Console.WriteLine($"{AUser(uut.user_id)} is {uut.action.GetType().Name[11..^6]}"); break; + case UpdateChatUserTyping ucut: Console.WriteLine($"{APeer(ucut.from_id)} is {ucut.action.GetType().Name[11..^6]} in {AChat(ucut.chat_id)}"); break; + case UpdateChannelUserTyping ucut2: Console.WriteLine($"{APeer(ucut2.from_id)} is {ucut2.action.GetType().Name[11..^6]} in {AChat(ucut2.channel_id)}"); break; + case UpdateChatParticipants { participants: ChatParticipants cp }: Console.WriteLine($"{cp.participants.Length} participants in {AChat(cp.chat_id)}"); break; + case UpdateUserStatus uus: Console.WriteLine($"{AUser(uus.user_id)} is now {uus.status.GetType().Name[10..]}"); break; + case UpdateUserName uun: Console.WriteLine($"{AUser(uun.user_id)} has changed profile name: @{uun.username} {uun.first_name} {uun.last_name}"); break; + case UpdateUserPhoto uup: Console.WriteLine($"{AUser(uup.user_id)} has changed profile photo"); break; + default: Console.WriteLine(update.GetType().Name); break; } } - // in this example method, we're not using async/await, so we just return Task.CompletedTask - private static Task HandleMessage(MessageBase messageBase, bool edit = false) + private static void DisplayMessage(MessageBase messageBase) { - if (edit) Console.Write("(Edit): "); switch (messageBase) { - case Message m: Console.WriteLine($"{Peer(m.from_id) ?? m.post_author} in {Peer(m.peer_id)}> {m.message}"); break; - case MessageService ms: Console.WriteLine($"{Peer(ms.from_id)} in {Peer(ms.peer_id)} [{ms.action.GetType().Name[13..]}]"); break; + case Message m: Console.WriteLine($"{APeer(m.from_id) ?? m.post_author} in {APeer(m.peer_id)}> {m.message}"); break; + case MessageService ms: Console.WriteLine($"{APeer(ms.from_id)} in {APeer(ms.peer_id)} [{ms.action.GetType().Name[13..]}]"); break; } - return Task.CompletedTask; } - - private static string User(long id) => Manager.Users.TryGetValue(id, out var user) ? user.ToString() : $"User {id}"; - private static string Chat(long id) => Manager.Chats.TryGetValue(id, out var chat) ? chat.ToString() : $"Chat {id}"; - private static string Peer(Peer peer) => Manager.UserOrChat(peer)?.ToString() ?? $"Peer {peer?.ID}"; } } diff --git a/Examples/Program_ReactorError.cs b/Examples/Program_ReactorError.cs deleted file mode 100644 index d84b8a0..0000000 --- a/Examples/Program_ReactorError.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Threading.Tasks; -using TL; - -namespace WTelegramClientTest -{ - static class Program_ReactorError - { - static WTelegram.Client Client; - - // go to Project Properties > Debug > Launch Profiles > 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 handle ReactorError. Press any key to terminate"); - WTelegram.Helpers.Log = (l, s) => System.Diagnostics.Debug.WriteLine(s); - try - { - await CreateAndConnect(); - Console.ReadKey(); - } - finally - { - if (Client != null) await Client.DisposeAsync(); - } - } - - private static async Task CreateAndConnect() - { - Client = new WTelegram.Client(Environment.GetEnvironmentVariable); - Client.OnUpdates += Client_OnUpdates; - Client.OnOther += Client_OnOther; - var my = await Client.LoginUserIfNeeded(); - Console.WriteLine($"We are logged-in as " + my); - } - - private static async Task Client_OnOther(IObject arg) - { - if (arg is ReactorError err) - { - // typically: network connection was totally lost - Console.WriteLine($"Fatal reactor error: {err.Exception.Message}"); - while (true) - { - Console.WriteLine("Disposing the client and trying to reconnect in 5 seconds..."); - if (Client != null) await Client.DisposeAsync(); - Client = null; - await Task.Delay(5000); - try - { - await CreateAndConnect(); - break; - } - catch (Exception ex) when (ex is not ObjectDisposedException) - { - Console.WriteLine("Connection still failing: " + ex.Message); - } - } - } - else - Console.WriteLine("Other: " + arg.GetType().Name); - } - - private static Task Client_OnUpdates(UpdatesBase updates) - { - foreach (var update in updates.UpdateList) - Console.WriteLine(update.GetType().Name); - return Task.CompletedTask; - } - } -} diff --git a/Examples/Program_SecretChats.cs b/Examples/Program_SecretChats.cs deleted file mode 100644 index cff9092..0000000 --- a/Examples/Program_SecretChats.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using TL; -using WTelegram; - -namespace WTelegramClientTest -{ - static class Program_SecretChats - { - static Client Client; - static SecretChats Secrets; - static ISecretChat ActiveChat; // the secret chat currently selected - static readonly Dictionary Users = []; - static readonly Dictionary Chats = []; - - // go to Project Properties > Debug > Launch Profiles > Environment variables and add at least these: api_id, api_hash, phone_number - static async Task Main() - { - 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(); - - Client.OnUpdates += Client_OnUpdates; - var myself = await Client.LoginUserIfNeeded(); - Users[myself.id] = myself; - Console.WriteLine($"We are logged-in as {myself}"); - - var dialogs = await Client.Messages_GetAllDialogs(); // load the list of users/chats - dialogs.CollectUsersChats(Users, Chats); - Console.WriteLine(@"Available commands: -/request Initiate Secret Chat with user (see /users) -/discard [delete] Terminate active secret chat [and delete history] -/select Select another Secret Chat -/photo filename.jpg Send a JPEG photo -/read Mark active discussion as read -/users List collected users and their IDs -Type a command, or a message to send to the active secret chat:"); - do - { - try - { - var line = Console.ReadLine(); - if (line.StartsWith('/')) - { - 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 ")) - if (Users.TryGetValue(long.Parse(line[9..]), out var user)) - SelectActiveChat(await Secrets.Request(user)); - else - Console.WriteLine("User not found"); - else if (line.StartsWith("/photo ")) - { - 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.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.ChatId, new TL.Layer73.DecryptedMessage { message = line, random_id = Helpers.RandomLong() }); - } - catch (Exception ex) - { - Console.WriteLine(ex); - } - } while (true); - } - - private static async Task Client_OnUpdates(UpdatesBase updates) - { - updates.CollectUsersChats(Users, Chats); - foreach (var update in updates.UpdateList) - switch (update) - { - case UpdateEncryption ue: // Change in Secret Chat status - await Secrets.HandleUpdate(ue); - break; - case UpdateNewEncryptedMessage unem: // Encrypted message or service message: - 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 }) - { - int slash = msg.Media.MimeType?.IndexOf('/') ?? 0; // quick & dirty conversion from MIME type to file extension - 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); - } - else if (msg.Action == null) Console.WriteLine($"{unem.message.ChatId}> {msg.Message}"); - else Console.WriteLine($"{unem.message.ChatId}> Service Message {msg.Action.GetType().Name[22..]}"); - } - break; - case UpdateEncryptedChatTyping: - case UpdateEncryptedMessagesRead: - //Console.WriteLine(update.GetType().Name); - break; - } - } - - private static void SelectActiveChat(int newActiveChat = 0) - { - ActiveChat = Secrets.Chats.FirstOrDefault(sc => newActiveChat == 0 || sc.ChatId == newActiveChat); - Console.WriteLine("Active secret chat ID: " + ActiveChat?.ChatId); - } - } -} diff --git a/Examples/WinForms_app.zip b/Examples/WinForms_app.zip deleted file mode 100644 index 419b21b..0000000 Binary files a/Examples/WinForms_app.zip and /dev/null differ diff --git a/FAQ.md b/FAQ.md deleted file mode 100644 index 76a889d..0000000 --- a/FAQ.md +++ /dev/null @@ -1,362 +0,0 @@ -# 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? - -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, ...). -In any case, it is not recommended to totally ignore those logs because you wouldn't be able to diagnose a problem after it happens. - -Read the [example about logging settings](EXAMPLES.md#logging) for how to write logs to a file. - - -## 2. How to handle multiple user accounts - -The WTelegram.session file contains the authentication keys negociated for the current user. - -You could switch the current user via an `Auth_Logout` followed by a `LoginUserIfNeeded` but that would require the user to sign in with a verification_code each time. - -Instead, if you want to deal with multiple users from the same machine, the recommended solution is to have a different session file for each user. -This can be done by having your Config callback reply with a different filename (or folder) for "**session_pathname**" for each user. -This way, you can keep separate session files (each with their authentication keys) for each user. - -If you need to manage these user accounts in parallel, you can create multiple instances of WTelegram.Client, -and give them a Config callback that will select a different session file ; -for example: `new WTelegram.Client(what => Config(what, "session42"))` - -Also please note that the session files are encrypted with your api_hash (or session_key), so if you change it, the existing session files can't be read anymore. -Your api_id/api_hash represents your application, and shouldn't change with each user account the application will manage. - - - -## 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. - -For GUI apps, an easy solution is to call `Interaction.InputBox("Enter verification code")` instead. -This might require adding a reference *(and `using`)* to the Microsoft.VisualBasic assembly. - -A more complex solution requires the use of a `ManualResetEventSlim` that you will wait for in Config callback, -and when the user has provided the verification_code through your app, you "set" the event to release your Config callback so it can return the code. - -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](Examples/WinForms_app.zip) and [for ASP.NET](Examples/ASPnet_webapp.zip) - - -## 4. How to use IDs and access_hash? Why the error `CHANNEL_INVALID` or `USER_ID_INVALID`? - -⚠️ In Telegram Client API *(contrary to Bot API)*, you **cannot** interact with channels/users/etc. with only their IDs. - -You also need to obtain their `access_hash` which is specific to the resource you want to access AND to the currently logged-in user. -This serves as a proof that the logged-in user is entitled to access that channel/user/photo/document/... -(otherwise, anybody with the ID could access it) - -> A small private group `Chat` don't need an access_hash and can be queried using their `chat_id` only. -However most common chat groups are not `Chat` but a `Channel` supergroup (without the `broadcast` flag). See [Terminology in ReadMe](README.md#terminology). -Some TL methods only applies to private `Chat`, some only applies to `Channel` and some to both. - -The `access_hash` must usually be provided within the `Input...` structure you pass in argument to an API method (`InputPeer`, `InputChannel`, `InputUser`, etc...). - -You obtain the `access_hash` through TL **description structures** like `Channel`, `User`, `Photo`, `Document` that you receive through updates -or when you query them through API methods like `Messages_GetAllChats`, `Messages_GetAllDialogs`, `Contacts_ResolveUsername`, etc... - -You can use the [`UserOrChat` and `CollectUsersChats` methods](EXAMPLES.md#collect-users-chats) to help you in obtaining/collecting -the description structures you receive via API calls or updates. - -Once you obtained the description structure, there are 2 methods for building your `Input...` request structure: -* **Recommended:** Just pass that description structure you already have, in place of the `Input...` argument, it will work! -*The implicit conversion operators on base classes like `ChatBase/UserBase` will create the `Input...` structure for you automatically.* -* Alternatively, you can manually create the `Input...` structure yourself by extracting the `access_hash` from the description structure - -*Note: An `access_hash` obtained from a User/Channel structure with flag `min` may not be usable for most requests. See [Min constructors](https://core.telegram.org/api/min).* - - -## 5. I need to test a feature that has been recently developed but seems not available in my program - -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 -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. - -You can verify this is your issue by looking at [WTelegram logs](EXAMPLES.md#logging) on the line `Connected to (Test) DC x...` - -This wrong-server problem typically happens when you use WTelegramClient Github source project in your application in DEBUG builds. -It is **not recommended** to use WTelegramClient in source code form. -Instead, you should use the Nuget manager to **install package WTelegramClient** into your application. -*And remember to delete the WTelegram.session file to force a new login on the correct server.* - -If you use the Github source project in an old .NET Framework 4.x or .NET Core x.x application, you may also experience the following error -> System.TypeInitializationException (FileNotFoundException for "System.Text.Json Version=5.0.0.0 ...") - -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. - -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. - -You can try to wait more between the requests, wait for a day or two to see if the requests become possible again. - ->ℹ️ For FLOOD_WAIT_X with X < 60 seconds (see `client.FloodRetryThreshold`), WTelegramClient will automatically wait the specified delay and retry the request for you. -For longer delays, you can catch the thrown `RpcException` and check the value of property X. - -An account that was restricted due to reported spam might receive PEER_FLOOD errors. Read [Telegram Spam FAQ](https://telegram.org/faq_spam) to learn more. - -If you think your phone number was banned from Telegram for a wrong reason, you may try to contact [recover@telegram.org](mailto:recover@telegram.org), explaining what you were doing. - -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? - -**Do not share publicly your app's ID and hash!** They cannot be regenerated and are bound to your Telegram account. - -From the [official documentation](https://core.telegram.org/api/obtaining_api_id): - -> Note that all API client libraries are strictly monitored to prevent abuse. -> If you use the Telegram API for flooding, spamming, faking subscriber and view counters of channels, you **will be banned forever**. -> Due to excessive abuse of the Telegram API, **all accounts that sign up or log in using unofficial Telegram clients are automatically -> put under observation** to avoid violations of the [Terms of Service](https://core.telegram.org/api/terms). - -Here are some advices from [another similar library](https://github.com/gotd/td/blob/main/.github/SUPPORT.md#how-to-not-get-banned): - -1. This client is unofficial, Telegram treats such clients suspiciously, especially fresh ones. -2. Use regular bots instead of userbots whenever possible. -3. If you still want to automate things with a user, use it passively (i.e. receive more than sending). -4. When using it with a user: - * Do not use QR code login, this will result in permaban. - * Do it with extreme care. - * Do not use VoIP numbers. - * Do not abuse, spam or use it for other suspicious activities. - * Implement a rate limiting system. - -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 `OnUpdates` events. -6. Don't buy fake user accounts/sessions and don't extract api_id/hash/authkey/sessions from official clients, this is [specifically forbidden by API TOS](https://core.telegram.org/api/terms#2-transparency). You must use your own api_id and create your own sessions associated with it. -7. If a phone number is brand new, it will be closely monitored by Telegram for abuse, and it can even already be considered a bad user due to bad behavior from the previous owner of that phone number (which may happen often with VoIP or other easy-to-buy-online numbers, so expect fast ban) -8. You may want to use your new phone number account with an official Telegram client and act like a normal user for some time (some weeks/months), before using it for automation with WTelegramClient. -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. -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. -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`? - -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 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_` ... - -However, note that those Channel-compatible methods will require an `InputChannel` or `InputPeerChannel` object as argument instead of a simple channel ID. -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 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. -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 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. - - -## 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: - -1) On secondary DCs *(DC used to download files)*, a Connection shut down is considered "normal" -Your main DC is the one WTelegramClient connects to during login. Secondary DC connections are established and maintained when you download files. -The DC number for an operation or error is indicated with a prefix like "2>" on the log line. -If Telegram servers decide to shutdown this secondary connection, it's not an issue, WTelegramClient will re-establish the connection later if necessary. - -2) Occasional connection shutdowns on the main DC should be caught by WTelegramClient and the reactor should automatically reconnect to the DC -*(up to `MaxAutoReconnects` times)*. -This should be transparent and pending API calls should automatically be resent upon reconnection. -You can choose to increase `MaxAutoReconnects` if it happens too often because your Internet connection is unstable. - -3) If you reach `MaxAutoReconnects` disconnections or a reconnection fails, then the **OnOther** event handler will receive a `ReactorError` object to notify you of the problem, -and pending API calls throw the network IOException. -In this case, the recommended action would be to dispose the client and recreate one (see example [Program_ReactorError.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ReactorError.cs)) - -4) In case of slow Internet connection or if you break in the debugger for some time, -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](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? - -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. - -WTelegramClient approach is much more simpler and secure than TLSharp. - -All client APIs have dedicated async methods that you can call like this: `await client.Method_Name(param1, param2, ...)` -See the [full method list](https://core.telegram.org/methods) (just replace the dot with an underscore in the names) - -A session file is created or resumed automatically on startup, and maintained up-to-date automatically throughout the session. -That session file is incompatible with TLSharp so you cannot reuse a TLSharp .dat file. You'll need to create a new session. -To fight against the reselling of fake user accounts, we don't support the import/export of session files from external sources. - -**DON'T** call methods Auth_SendCode/SignIn/SignUp/... because all the login phase is handled automatically by calling `await client.LoginUserIfNeeded()` after creating the client. -Your Config callback just need to provide the various login answers if they are needed (see [ReadMe](README.md) and [FAQ #4](#GUI)). -In particular, it will detect and handle automatically and properly the various login cases/particularity like: -* Login not necessary (when a session is resumed with an already logged-in user) -* Logout required (if you want to change the logged-in user) -* 2FA password required (your Config needs to provide "password") -* Email registration procedure required (your Config needs to provide "email", "email_verification_code") -* Account registration/sign-up required (your Config needs to provide "first_name", "last_name") -* Request to resend the verification code through alternate ways (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](EXAMPLES.md#proxy), real-time updates, multiple DC connections, API documentation in Intellisense... - - -## 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). -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?ts=4#L9) for such an implementation and the steps to host/deploy it. - - -## 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)* -- It doesn't store outgoing messages *(so if remote client was offline for a week and ask us to resend old messages, we will send void data)* -- It doesn't store incoming messages on disk *(it's up to you if you want to store them)* -- If you pass `DecryptMessage` parameter `fillGaps: true` *(default)*, incoming messages are ensured to be delivered to you in correct order. -If for some reason, we received them in incorrect order, messages are kept in memory until the requested missing messages are obtained. -If those missing messages are never obtained during the session, incoming messages might get stuck and lost. -- SecretChats file data is only valid for the current user, so make sure to pick the right file *(or a new file name)* if you change logged-in user. -- If you want to accept incoming Secret Chats request only from specific user, you must check it in OnUpdates before: -`await Secrets.HandleUpdate(ue, ue.chat is EncryptedChatRequested ecr && ecr.admin_id == EXPECTED_USER_ID);` -- As recommended, new encryption keys are negotiated every 100 sent/received messages or after one week. -If remote client doesn't complete this negotiation before reaching 200 messages, the Secret Chat is aborted. - - -## 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; - } - } - ``` - -Also, remember to add a `using TL;` at the top of your files to have access to all the Telegram API methods. - - -# 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)). -So you can either: - - **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) - -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. -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 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()` - - -# About the UpdateManager - -The UpdateManager does the following: -- ensure the correct sequential order of receiving updates (Telegram may send them in wrong order) -- fetch the missing updates if there was a gap (missing update) in the flow of incoming updates -- resume the flow of updates where you left off if you stopped your program (with saved state) -- collect the users & chats from updates automatically for you _(by default)_ -- simplifies the handling of the various containers of update (UpdatesBase) - -To use the UpdateManager, instead of setting `client.OnUpdates`, you call: -```csharp -// if you don't care about missed updates while your program was down: -var manager = client.WithUpdateManager(OnUpdate); - -// if you want to recover missed updates using the state saved on the last run of your program -var manager = client.WithUpdateManager(OnUpdate, "Updates.state"); -// to save the state later, preferably after disposing the client: -manager.SaveState("Updates.state") -``` - -Your `OnUpdate` method will directly take a single `Update` as parameter, instead of a container of updates. -The `manager.Users` and `manager.Chats` dictionaries will collect the users/chats data from updates. -You can also feed them manually from result of your API calls by calling `result.CollectUsersChats(manager.Users, manager.Chats);` and resolve Peer fields via `manager.UserOrChat(peer)` -See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L21) for an example of implementation. - -Notes: -- set `manager.Log` if you want different logger settings than the client -- `WithUpdateManager()` has other parameters for advanced use \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt index 3265a97..08900bc 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2024 Olivier Marcoux +Copyright (c) 2021 Olivier Marcoux Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 05aecf3..0e1217d 100644 --- a/README.md +++ b/README.md @@ -1,209 +1,148 @@ -[![API Layer](https://img.shields.io/badge/API_Layer-223-blueviolet)](https://corefork.telegram.org/methods) -[![NuGet version](https://img.shields.io/nuget/v/WTelegramClient?color=00508F)](https://www.nuget.org/packages/WTelegramClient/) -[![NuGet prerelease](https://img.shields.io/nuget/vpre/WTelegramClient?color=C09030&label=dev+nuget)](https://www.nuget.org/packages/WTelegramClient/absoluteLatest) -[![Donate](https://img.shields.io/badge/Help_this_project:-Donate-ff4444)](https://buymeacoffee.com/wizou) +[![NuGet version](https://img.shields.io/nuget/v/WTelegramClient)](https://www.nuget.org/packages/WTelegramClient/) +[![Dev nuget](https://img.shields.io/badge/dynamic/json?color=ffc040&label=Dev%20nuget&query=%24.versions%5B0%5D&url=https%3A%2F%2Fpkgs.dev.azure.com%2Fwiz0u%2F81bd92b7-0bb9-4701-b426-09090b27e037%2F_packaging%2F46ce0497-7803-4bd4-8c6c-030583e7c371%2Fnuget%2Fv3%2Fflat2%2Fwtelegramclient%2Findex.json)](https://dev.azure.com/wiz0u/WTelegramClient/_packaging?_a=package&feed=WTelegramClient&package=WTelegramClient&protocolType=NuGet) +[![Build Status](https://img.shields.io/azure-devops/build/wiz0u/WTelegramClient/7)](https://dev.azure.com/wiz0u/WTelegramClient/_build?definitionId=7) +[![API Layer](https://img.shields.io/badge/API_Layer-133-blueviolet)](https://schema.horner.tj) +[![Support Chat](https://img.shields.io/badge/Chat_with_us-on_Telegram-0088cc)](https://t.me/WTelegramClient) -## *Telegram Client API library written 100% in C# and .NET* +# WTelegramClient +### _Telegram client library written 100% in C# and .NET Standard_ -This library allows you to connect to Telegram and control a user programmatically (or a bot, but [WTelegramBot](https://www.nuget.org/packages/WTelegramBot) 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. +## How to use -Library was developed solely by one unemployed guy. [Donations](https://buymeacoffee.com/wizou) or [Patreon memberships are welcome](https://patreon.com/wizou). +⚠️ This library relies on asynchronous C# programming (`async/await`) so make sure you are familiar with this before proceeding. -This ReadMe is a **quick but important tutorial** to learn the fundamentals about this library. Please read it all. - -> ⚠️ 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 - -After installing WTelegramClient through [Nuget](https://www.nuget.org/packages/WTelegramClient/), your first Console program will be as simple as: +After installing WTelegramClient through Nuget, your first Console program will be as simple as: ```csharp static async Task Main(string[] _) { using var client = new WTelegram.Client(); - var myself = await client.LoginUserIfNeeded(); - Console.WriteLine($"We are logged-in as {myself} (id {myself.id})"); + await client.ConnectAsync(); + var user = await client.LoginUserIfNeeded(); + Console.WriteLine($"We are logged-in as {user.username ?? user.first_name + " " + user.last_name} (id {user.id})"); } ``` -When run, this will prompt you interactively for your App **api_hash** and **api_id** (that you obtain through Telegram's -[API development tools](https://my.telegram.org/apps) page) and try to connect to Telegram servers. -Those api hash/id represent your application and one can be used for handling many user accounts. +When run, this will prompt you interactively for your App **api_id** and **api_hash** (that you obtain through Telegram's [API development tools](https://my.telegram.org/apps) page) and try to connect to Telegram servers. -Then it will attempt to sign-in *(login)* as a user for which you must enter the **phone_number** and the **verification_code** -that will be sent to this user (for example through SMS, Email, or another Telegram client app the user is connected to). +Then it will attempt to sign-in as a user for which you must enter the **phone_number** and the **verification_code** that will be sent to this user (for example through SMS or another Telegram client app the user is connected to). -If the verification succeeds but the phone number is unknown to Telegram, the user might be prompted to sign-up -*(register their account by accepting the Terms of Service)* and provide their **first_name** and **last_name**. -If the account already exists and has enabled two-step verification (2FA) a **password** might be required. -In some case, Telegram may request that you associate an **email** with your account for receiving login verification codes, -you may skip this step by leaving **email** empty, otherwise the email address will first receive an **email_verification_code**. -All these login scenarios are handled automatically within the call to `LoginUserIfNeeded`. +If the verification succeeds but the phone number is unknown to Telegram, the user might be prompted to sign-up (accepting the Terms of Service) and enter their **first_name** and **last_name**. -After login, you now have access to the **[full range of Telegram Client APIs](https://corefork.telegram.org/methods)**. -All those API methods require `using TL;` namespace and are called with an underscore instead of a dot in the method name, like this: `await client.Method_Name(...)` +And that's it, you now have access to the [full range of Telegram services](https://core.telegram.org/methods), mainly through calls to `await client.Some_TL_Method(...)` # Saved session -If you run this program again, you will notice that only **api_hash** is requested, the other prompts are gone and you are automatically logged-on and ready to go. +If you run this program again, you will notice that only **api_id** and **api_hash** are requested, the other prompts are gone and you are automatically logged-on and ready to go. -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. +This is because WTelegramClient saves (typically in the encrypted file **bin\WTelegram.session**) its state and the authentication keys that were negociated 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, write permissions)* -you may want to change it or simply delete the existing session file in order to restart the authentification process. +That file path is configurable, 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 -Your next step will probably be to provide a configuration to the client so that the required elements are not prompted through the Console but answered by your program. +Your next step will probably be to provide a configuration to the client so that the required elements (in bold above) are not prompted through the Console but answered by your program. To do this, you need to write a method that will provide the answers, and pass it on the constructor: ```csharp static string Config(string what) { - switch (what) - { - case "api_id": return "YOUR_API_ID"; - case "api_hash": return "YOUR_API_HASH"; - case "phone_number": return "+12025550156"; - case "verification_code": Console.Write("Code: "); return Console.ReadLine(); - case "first_name": return "John"; // if sign-up is required - case "last_name": return "Doe"; // if sign-up is required - case "password": return "secret!"; // if user has enabled 2FA - default: return null; // let WTelegramClient decide the default config - } + if (what == "api_id") return "YOUR_API_ID"; + if (what == "api_hash") return "YOUR_API_HASH"; + if (what == "phone_number") return "+12025550156"; + if (what == "verification_code") { Console.Write("Code: "); return Console.ReadLine(); } + if (what == "first_name") return "John"; // if sign-up is required + if (what == "last_name") return "Doe"; // if sign-up is required + if (what == "password") return "secret!"; // if user has enabled 2FA + return null; } ... using var client = new WTelegram.Client(Config); ``` -There are other configuration items that are queried to your method but returning `null` let WTelegramClient choose a default adequate value. -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://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 -*(undefined variables get the default `null` behavior)*. +There are other configuration items that are queried to your method but returning `null` let WTelegramClient choose a default adequate value. Those shown above are the only ones that have no default values and are required to be provided by your method. 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). - -# 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: - -```csharp -WTelegram.Client client = new WTelegram.Client(YOUR_API_ID, "YOUR_API_HASH"); // this constructor doesn't need a Config method -await DoLogin("+12025550156"); // initial call with user's phone_number -... -//client.Dispose(); // the client must be disposed when you're done running your userbot. - -async Task DoLogin(string loginInfo) // (add this method to your code) -{ - 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})"); -} -``` - -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://wiz0u.github.io/WTelegramClient/Examples/WinForms_app.zip) and [ASP.NET example](https://wiz0u.github.io/WTelegramClient/Examples/ASPnet_webapp.zip) +Its `int` argument is the log severity, compatible with the classic [LogLevel enum](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel) # Example of API call -> The Telegram API makes extensive usage of base and derived classes, so be ready to use the various C# syntaxes -to check/cast base classes into the more useful derived classes (`is`, `as`, `case DerivedType` ) +ℹ️ The Telegram API makes extensive usage of base and derived classes, so be ready to use the various syntaxes C# offer to check/cast base classes into the more useful derived classes (`is`, `as`, `case DerivedType` ) -All the Telegram API classes/methods are fully documented through Intellisense: Place your mouse over a class/method name, -or start typing the call arguments to see a tooltip displaying their description, the list of derived classes and a web link to the official API page. +To find which derived classes are available for a given base class, the fastest is to check our [TL.Schema.cs](src/TL.Schema.cs) source file as they are listed in groups. +Intellisense tooltips on API structures/methods will also display a web link to the adequate Telegram documentation page. -The Telegram [API object classes](https://corefork.telegram.org/schema) are defined in the `TL` namespace, -and the [API functions](https://corefork.telegram.org/methods) are available as async methods of `Client`. +The Telegram [API object classes](https://core.telegram.org/schema) are defined in the `TL` namespace, and the [API functions](https://core.telegram.org/methods) are available as async methods of `Client`. -Below is an example of calling the [messages.getAllChats](https://corefork.telegram.org/method/messages.getAllChats) API function, -enumerating the various groups/channels the user is in, and then using `client.SendMessageAsync` helper function to easily send a message: +Below is an example of calling the [messages.getAllChats](https://core.telegram.org/method/messages.getAllChats) API function and enumerating the various groups/channels the user is in, and then using `client.SendMessageAsync` helper function to easily send a message: ```csharp using TL; ... -var chats = await client.Messages_GetAllChats(); +var chats = await client.Messages_GetAllChats(null); Console.WriteLine("This user has joined the following:"); -foreach (var (id, chat) in chats.chats) - if (chat.IsActive) - Console.WriteLine($"{id,10}: {chat}"); +foreach (var chat in chats.chats) + switch (chat) + { + case Chat smallgroup when (smallgroup.flags & Chat.Flags.deactivated) == 0: + Console.WriteLine($"{smallgroup.id}: Small group: {smallgroup.title} with {smallgroup.participants_count} members"); + break; + case Channel channel when (channel.flags & Channel.Flags.broadcast) != 0: + Console.WriteLine($"{channel.id}: Channel {channel.username}: {channel.title}"); + break; + case Channel group: + Console.WriteLine($"{group.id}: Group {group.username}: {group.title}"); + break; + } Console.Write("Type a chat ID to send a message: "); -long chatId = long.Parse(Console.ReadLine()); -var target = chats.chats[chatId]; -Console.WriteLine($"Sending a message in chat {chatId}: {target.Title}"); +long id = long.Parse(Console.ReadLine()); +var target = chats.First(chat => chat.ID == id); await client.SendMessageAsync(target, "Hello, World"); ``` -➡️ You can find lots of useful code snippets in [EXAMPLES](https://wiz0u.github.io/WTelegramClient/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. - - -# 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))*, -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 -(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. -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. -- **Participant**: A member/subscriber of a chat group or channel - # Other things to know -The Client class offers `OnUpdates` and `OnOther` events that are triggered when Telegram servers sends Updates (like new messages or status) or other notifications, independently of your API requests. -You can also use the [UpdateManager class](https://wiz0u.github.io/WTelegramClient/FAQ#manager) to simplify the handling of such updates. -See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L21) and [Examples/Program_ReactorError.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ReactorError.cs?ts=4#L30) +The Client class also offers an `Update` event that is triggered when Telegram servers sends unsollicited Updates or notifications/information/status/service messages, independently of your API requests. -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. +An invalid API request can result in a `RpcException` being raised, reflecting the [error code and status text](https://core.telegram.org/api/errors) of the problem. -To [prevent getting banned](https://wiz0u.github.io/WTelegramClient/FAQ#prevent-ban) during dev, you can connect to [test servers](https://docs.pyrogram.org/topics/test-servers), by adding this line in your Config callback: -`case "server_address": return "2>149.154.167.40:443"; // test DC` +The other configuration items that you can override include: **session_pathname, server_address, device_model, system_version, app_version, system_lang_code, lang_pack, lang_code, user_id** -The other configuration items that you can provide include: **session_pathname, email, email_verification_code, session_key, device_model, system_version, app_version, system_lang_code, lang_pack, lang_code, firebase, user_id, bot_token** +Optional API parameters have a default value of `null` when unset. Passing `null` for a required string/array is the same as *empty* (0-length). Required API parameters/fields can sometimes be set to 0 or `null` when unused (check API documentation). -Optional API parameters have a default value of `null` when unset. Passing `null` for a required string/array is the same as *empty* (0-length). -Required API parameters/fields can sometimes be set to 0 or `null` when unused (check API documentation or experiment). +I've added several useful converters or implicit cast to various API object so that they are more easy to manipulate. -I've added several useful converters, implicit cast or helper properties to various API 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 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+** and is also available for **.NET Standard 2.0** (.NET Framework 4.6.1+ & .NET Core 2.0+) -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** +# 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 instead of 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. 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/_packaging?_a=package&feed=WTelegramClient&package=WTelegramClient&protocolType=NuGet) + - 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) After `ConnectAsync()`, are you calling `LoginUserIfNeeded()`? +
If you don't authenticate as a user (or bot), you have access to a very limited subset of Telegram APIs + +3) Did you use `await` with every Client methods? +
This library is completely Task-based and 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. + +4) Are you keeping a live reference to the Client instance and dispose it only at the end of your program? +
If you create the instance in a submethod and don't store it somewhere permanent, it might be destroyed by the garbage collector at some point. So as long as the client must be running, make sure the reference is stored in a (static) field or somewhere appropriate. +
Also, as the Client class inherits `IDisposable`, remember to call `client.Dispose()` when your program ends (or exit a `using` scope). + +5) 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. + +6) 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()` # Library uses and limitations -This library can be used for any Telegram scenario including: +This library can be used for any Telegram scenarios 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](https://wiz0u.github.io/WTelegramClient/EXAMPLES#download)/[upload](https://wiz0u.github.io/WTelegramClient/EXAMPLES#upload) of files/media -- Exchange end-to-end encrypted messages/files in [Secret Chats](https://wiz0u.github.io/WTelegramClient/EXAMPLES#e2e) -- Building a full-featured interactive client +- Real-time monitoring of incoming Updates/Messages +- Download/upload of files/media +- etc... -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. +Secret chats (end-to-end encryption, PFS) and connection to CDN DCs have not been tested yet. -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://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, you can [buy me a coffee](https://buymeacoffee.com/wizou) ❤ This will help the project keep going. - -© 2021-2026 Olivier Marcoux +Developers feedbacks are welcome in the Telegram channel [@WTelegramClient](https://t.me/WTelegramClient) diff --git a/generator/MTProtoGenerator.cs b/generator/MTProtoGenerator.cs deleted file mode 100644 index 44c7c35..0000000 --- a/generator/MTProtoGenerator.cs +++ /dev/null @@ -1,267 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Diagnostics; -using System.Linq; -using System.Text; - -#pragma warning disable RS1024 // Symbols should be compared for equality - -namespace TL.Generator; - -[Generator] -public class MTProtoGenerator : IIncrementalGenerator -{ - public void Initialize(IncrementalGeneratorInitializationContext context) - { - var classDeclarations = context.SyntaxProvider.ForAttributeWithMetadataName("TL.TLDefAttribute", - (_, _) => true, (context, _) => (ClassDeclarationSyntax)context.TargetNode); - var source = context.CompilationProvider.Combine(classDeclarations.Collect()); - context.RegisterSourceOutput(source, Execute); - } - - static void Execute(SourceProductionContext context, (Compilation compilation, ImmutableArray classes) unit) - { - var object_ = unit.compilation.GetSpecialType(SpecialType.System_Object); - if (unit.compilation.GetTypeByMetadataName("TL.TLDefAttribute") is not { } tlDefAttribute) return; - if (unit.compilation.GetTypeByMetadataName("TL.IfFlagAttribute") is not { } ifFlagAttribute) return; - if (unit.compilation.GetTypeByMetadataName("TL.Layer") is not { } layer) return; - if (unit.compilation.GetTypeByMetadataName("TL.IObject") is not { } iobject) return; - var nullables = LoadNullables(layer); - var namespaces = new Dictionary>(); // namespace,class,methods - var tableTL = new StringBuilder(); - var methodsTL = new StringBuilder(); - var source = new StringBuilder(); - source - .AppendLine("using System;") - .AppendLine("using System.Collections.Generic;") - .AppendLine("using System.ComponentModel;") - .AppendLine("using System.IO;") - .AppendLine("using System.Linq;") - .AppendLine("using TL;") - .AppendLine() - .AppendLine("#pragma warning disable CS0109") - .AppendLine(); - tableTL - .AppendLine("\t\tpublic static readonly Dictionary> Table = new()") - .AppendLine("\t\t{"); - methodsTL - .AppendLine("\t\tpublic static readonly Dictionary> Methods = new()") - .AppendLine("\t\t{"); - - foreach (var classDecl in unit.classes) - { - var semanticModel = unit.compilation.GetSemanticModel(classDecl.SyntaxTree); - if (semanticModel.GetDeclaredSymbol(classDecl) is not { } symbol) continue; - var tldef = symbol.GetAttributes().FirstOrDefault(a => a.AttributeClass == tlDefAttribute); - if (tldef == null) continue; - var id = (uint)tldef.ConstructorArguments[0].Value; - StringBuilder writeTl = new(), readTL = new(); - var ns = symbol.BaseType.ContainingNamespace.ToString(); - var name = symbol.BaseType.Name; - if (ns != "System") - { - if (!namespaces.TryGetValue(ns, out var parentClasses)) namespaces[ns] = parentClasses = []; - parentClasses.TryGetValue(name, out var parentMethods); - if (symbol.BaseType.IsAbstract) - { - if (parentMethods == null) - { - if (name is "Peer") - writeTl.AppendLine("\t\tpublic virtual void WriteTL(BinaryWriter writer) => throw new NotSupportedException();"); - else - writeTl.AppendLine("\t\tpublic abstract void WriteTL(BinaryWriter writer);"); - parentClasses[name] = writeTl.ToString(); - writeTl.Clear(); - } - } - else if (parentMethods?.Contains(" virtual ") == false) - parentClasses[name] = parentMethods.Replace("public void WriteTL(", "public virtual void WriteTL("); - } - ns = symbol.ContainingNamespace.ToString(); - name = symbol.Name; - if (!namespaces.TryGetValue(ns, out var classes)) namespaces[ns] = classes = []; - if (name is "_Message" or "MsgCopy") - { - classes[name] = "\t\tpublic void WriteTL(BinaryWriter writer) => throw new NotSupportedException();"; - continue; - } - if (id == 0x3072CFA1) // GzipPacked - tableTL.AppendLine($"\t\t\t[0x{id:X8}] = reader => (IObject)reader.ReadTLGzipped(typeof(IObject)),"); - else if (name != "Null") - { - if (ns == "TL.Methods") - methodsTL.AppendLine($"\t\t\t[0x{id:X8}] = {(ns == "TL" ? "" : ns + '.')}{name}{(symbol.IsGenericType ? "" : "")}.ReadTL,"); - if (ns != "TL.Methods" || name == "Ping") - tableTL.AppendLine($"\t\t\t[0x{id:X8}] = {(ns == "TL" ? "" : ns + '.')}{name}.ReadTL,"); - } - var override_ = symbol.BaseType == object_ ? "" : "override "; - if (name == "Messages_AffectedMessages") override_ = "virtual "; - //if (symbol.Constructors[0].IsImplicitlyDeclared) - // ctorTL.AppendLine($"\t\tpublic {name}() {{ }}"); - if (symbol.IsGenericType) name += ""; - readTL - .AppendLine($"\t\tpublic static new {name} ReadTL(BinaryReader reader)") - .AppendLine("\t\t{") - .AppendLine($"\t\t\tvar r = new {name}();"); - writeTl - .AppendLine("\t\t[EditorBrowsable(EditorBrowsableState.Never)]") - .AppendLine($"\t\tpublic {override_}void WriteTL(BinaryWriter writer)") - .AppendLine("\t\t{") - .AppendLine($"\t\t\twriter.Write(0x{id:X8});"); - var members = symbol.GetMembers().ToList(); - int inheritIndex = 0; - for (var parent = symbol.BaseType; parent != object_; parent = parent.BaseType) - { - var inheritAt = (int?)tldef.NamedArguments.FirstOrDefault(k => k.Key == "inheritAt").Value.Value ?? -1; - if (inheritAt >= 0) members.InsertRange(inheritIndex += inheritAt, parent.GetMembers()); - else { inheritIndex = members.Count; members.AddRange(parent.GetMembers()); } - tldef = parent.GetAttributes().FirstOrDefault(a => a.AttributeClass == tlDefAttribute); - } - foreach (var member in members.OfType()) - { - if (member.DeclaredAccessibility != Accessibility.Public || member.IsStatic) continue; - readTL.Append("\t\t\t"); - writeTl.Append("\t\t\t"); - var ifFlag = (int?)member.GetAttributes().FirstOrDefault(a => a.AttributeClass == ifFlagAttribute)?.ConstructorArguments[0].Value; - if (ifFlag != null) - { - readTL.Append(ifFlag < 32 ? $"if (((uint)r.flags & 0x{1 << ifFlag:X}) != 0) " - : $"if (((uint)r.flags2 & 0x{1 << (ifFlag - 32):X}) != 0) "); - writeTl.Append(ifFlag < 32 ? $"if (((uint)flags & 0x{1 << ifFlag:X}) != 0) " - : $"if (((uint)flags2 & 0x{1 << (ifFlag - 32):X}) != 0) "); - } - string memberType = member.Type.ToString(); - switch (memberType) - { - case "int": - readTL.AppendLine($"r.{member.Name} = reader.ReadInt32();"); - writeTl.AppendLine($"writer.Write({member.Name});"); - break; - case "long": - readTL.AppendLine($"r.{member.Name} = reader.ReadInt64();"); - writeTl.AppendLine($"writer.Write({member.Name});"); - break; - case "double": - readTL.AppendLine($"r.{member.Name} = reader.ReadDouble();"); - writeTl.AppendLine($"writer.Write({member.Name});"); - break; - case "bool": - readTL.AppendLine($"r.{member.Name} = reader.ReadTLBool();"); - writeTl.AppendLine($"writer.Write({member.Name} ? 0x997275B5 : 0xBC799737);"); - break; - case "System.DateTime": - readTL.AppendLine($"r.{member.Name} = reader.ReadTLStamp();"); - writeTl.AppendLine($"writer.WriteTLStamp({member.Name});"); - break; - case "string": - readTL.AppendLine($"r.{member.Name} = reader.ReadTLString();"); - writeTl.AppendLine($"writer.WriteTLString({member.Name});"); - break; - case "byte[]": - readTL.AppendLine($"r.{member.Name} = reader.ReadTLBytes();"); - writeTl.AppendLine($"writer.WriteTLBytes({member.Name});"); - break; - case "TL.Int128": - readTL.AppendLine($"r.{member.Name} = new Int128(reader);"); - writeTl.AppendLine($"writer.Write({member.Name});"); - break; - case "TL.Int256": - readTL.AppendLine($"r.{member.Name} = new Int256(reader);"); - writeTl.AppendLine($"writer.Write({member.Name});"); - break; - case "System.Collections.Generic.List": - readTL.AppendLine($"r.{member.Name} = reader.ReadTLRawVector<_Message>(0x5BB8E511);"); - writeTl.AppendLine($"writer.WriteTLMessages({member.Name});"); - break; - case "TL.IObject": case "TL.IMethod": - readTL.AppendLine($"r.{member.Name} = {(memberType == "TL.IObject" ? "reader.ReadTLObject()" : "reader.ReadTLMethod()")};"); - writeTl.AppendLine($"{member.Name}.WriteTL(writer);"); - break; - case "System.Collections.Generic.Dictionary": - readTL.AppendLine($"r.{member.Name} = reader.ReadTLDictionary();"); - writeTl.AppendLine($"writer.WriteTLVector({member.Name}?.Values.ToArray());"); - break; - case "System.Collections.Generic.Dictionary": - readTL.AppendLine($"r.{member.Name} = reader.ReadTLDictionary();"); - writeTl.AppendLine($"writer.WriteTLVector({member.Name}?.Values.ToArray());"); - break; - case "object": - readTL.AppendLine($"r.{member.Name} = reader.ReadTLObject();"); - writeTl.AppendLine($"writer.WriteTLValue({member.Name}, {member.Name}.GetType());"); - break; - default: - if (member.Type is IArrayTypeSymbol arrayType) - { - if (name is "FutureSalts") - { - readTL.AppendLine($"r.{member.Name} = reader.ReadTLRawVector<{memberType.Substring(0, memberType.Length - 2)}>(0x0949D9DC).ToArray();"); - writeTl.AppendLine($"writer.WriteTLRawVector({member.Name}, 16);"); - } - else - { - readTL.AppendLine($"r.{member.Name} = reader.ReadTLVector<{memberType.Substring(0, memberType.Length - 2)}>();"); - writeTl.AppendLine($"writer.WriteTLVector({member.Name});"); - } - } - else if (member.Type.BaseType.SpecialType == SpecialType.System_Enum) - { - readTL.AppendLine($"r.{member.Name} = ({memberType})reader.ReadUInt32();"); - writeTl.AppendLine($"writer.Write((uint){member.Name});"); - } - else if (memberType.StartsWith("TL.")) - { - readTL.AppendLine($"r.{member.Name} = ({memberType})reader.ReadTLObject();"); - var nullStr = nullables.TryGetValue(memberType, out uint nullCtor) ? $"0x{nullCtor:X8}" : "Layer.NullCtor"; - writeTl.AppendLine($"if ({member.Name} != null) {member.Name}.WriteTL(writer); else writer.Write({nullStr});"); - } - else - writeTl.AppendLine($"Cannot serialize {memberType}"); - break; - } - } - readTL.AppendLine("\t\t\treturn r;"); - readTL.AppendLine("\t\t}"); - writeTl.AppendLine("\t\t}"); - readTL.Append(writeTl.ToString()); - classes[name] = readTL.ToString(); - } - - foreach (var nullable in nullables) - tableTL.AppendLine($"\t\t\t[0x{nullable.Value:X8}] = null,"); - tableTL.AppendLine("\t\t};"); - methodsTL.AppendLine("\t\t};"); - namespaces["TL"]["Layer"] = tableTL.ToString() + methodsTL.ToString(); - foreach (var namesp in namespaces) - { - source.Append("namespace ").AppendLine(namesp.Key).Append('{'); - foreach (var method in namesp.Value) - source.AppendLine().Append("\tpartial class ").AppendLine(method.Key).AppendLine("\t{").Append(method.Value).AppendLine("\t}"); - source.AppendLine("}").AppendLine(); - } - string text = source.ToString(); - Debug.Write(text); - context.AddSource("TL.Generated.cs", text); - } - - private static Dictionary LoadNullables(INamedTypeSymbol layer) - { - var nullables = layer.GetMembers("Nullables").Single() as IFieldSymbol; - var initializer = nullables.DeclaringSyntaxReferences[0].GetSyntax().ToString(); - var table = new Dictionary(); - foreach (var line in initializer.Split('\n')) - { - int index = line.IndexOf("[typeof("); - if (index == -1) continue; - int index2 = line.IndexOf(')', index += 8); - string className = "TL." + line.Substring(index, index2 - index); - index = line.IndexOf("= 0x", index2); - if (index == -1) continue; - index2 = line.IndexOf(',', index += 4); - table[className] = uint.Parse(line.Substring(index, index2 - index), System.Globalization.NumberStyles.HexNumber); - } - return table; - } -} diff --git a/generator/MTProtoGenerator.csproj b/generator/MTProtoGenerator.csproj deleted file mode 100644 index 881f2da..0000000 --- a/generator/MTProtoGenerator.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - netstandard2.0 - true - true - true - True - latest - - - - - - - - - - \ No newline at end of file diff --git a/src/Client.Helpers.cs b/src/Client.Helpers.cs deleted file mode 100644 index eb0f8a6..0000000 --- a/src/Client.Helpers.cs +++ /dev/null @@ -1,950 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using TL; - -// necessary for .NET Standard 2.0 compilation: -#pragma warning disable CA1835 // Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync' - -namespace WTelegram -{ - partial class Client - { - /// Used to indicate progression of file download/upload - /// transmitted bytes - /// total size of file in bytes, or 0 if unknown - public delegate void ProgressCallback(long transmitted, long totalSize); - - /// Helper method to upload a file to Telegram - /// Path to the file to upload - /// (optional) Callback for tracking the progression of the transfer - /// an or than can be used in various requests - public Task UploadFileAsync(string pathname, ProgressCallback progress = null) - => UploadFileAsync(File.OpenRead(pathname), Path.GetFileName(pathname), progress); - - /// Helper method to upload a file to Telegram - /// Content of the file to upload. This method close/dispose the stream - /// Name of the file - /// (optional) Callback for tracking the progression of the transfer - /// an or than can be used in various requests - public async Task UploadFileAsync(Stream stream, string filename, ProgressCallback progress = null) - { - var client = await GetClientForDC(-_dcSession.DcID, true); - using (stream) - { - const long SMALL_FILE_MAX_SIZE = 10 << 20; - bool hasLength = stream.CanSeek; - long transmitted = 0, length = hasLength ? stream.Length : -1; - bool isBig = !hasLength || length > SMALL_FILE_MAX_SIZE; - int file_total_parts = hasLength ? (int)((length - 1) / FilePartSize) + 1 : -1; - long file_id = Helpers.RandomLong(); - int file_part = 0, read; - var tasks = new Dictionary(); - bool abort = false; - for (long bytesLeft = hasLength ? length : long.MaxValue; !abort && bytesLeft != 0; file_part++) - { - var bytes = new byte[Math.Min(FilePartSize, bytesLeft)]; - read = await stream.FullReadAsync(bytes, bytes.Length, default); - await _parallelTransfers.WaitAsync(); - bytesLeft -= read; - if (!hasLength && read < bytes.Length) - { - file_total_parts = file_part; - if (read == 0) break; else file_total_parts++; - bytes = bytes[..read]; - bytesLeft = 0; - } - var task = SavePart(file_part, bytes); - lock (tasks) tasks[file_part] = task; - if (read < FilePartSize && bytesLeft != 0) throw new WTException($"Failed to fully read stream ({read},{bytesLeft})"); - - async Task SavePart(int file_part, byte[] bytes) - { - try - { - if (isBig) - await client.Upload_SaveBigFilePart(file_id, file_part, file_total_parts, bytes); - else - await client.Upload_SaveFilePart(file_id, file_part, bytes); - lock (tasks) { transmitted += bytes.Length; tasks.Remove(file_part); } - progress?.Invoke(transmitted, length); - } - catch (Exception) - { - abort = true; - throw; - } - finally - { - _parallelTransfers.Release(); - } - } - } - Task[] remainingTasks; - lock (tasks) remainingTasks = [.. tasks.Values]; - await Task.WhenAll(remainingTasks); // wait completion and eventually propagate any task exception - return isBig ? new InputFileBig { id = file_id, parts = file_total_parts, name = filename } - : new InputFile { id = file_id, parts = file_total_parts, name = filename }; - } - } - - /// Search messages in chat with filter and text See - /// See for a list of possible filter types - /// User or chat, histories with which are searched, or constructor for global search - /// Text search request - /// Only return messages starting from the specified message ID - /// Number of results to return - public Task Messages_Search(InputPeer peer, string q = null, int offset_id = 0, int limit = int.MaxValue) where T : MessagesFilter, new() - => this.Messages_Search(peer, q, new T(), offset_id: offset_id, limit: limit); - - /// Search messages globally with filter and text See - /// See for a list of possible filter types - /// Query - /// Only return messages starting from the specified message ID - /// Number of results to return - public Task Messages_SearchGlobal(string q = null, int offset_id = 0, int limit = int.MaxValue) where T : MessagesFilter, new() - => this.Messages_SearchGlobal(q, new T(), offset_id: offset_id, limit: limit); - - /// Helper method to send a media message more easily - /// Destination of message (chat group, channel, user chat, etc..) - /// Caption for the media (in plain text) or - /// Media file already uploaded to TG (see UploadFileAsync) - /// for automatic detection, "photo" for an inline photo, "video" for a streamable MP4 video, or a MIME type to send as a document - /// Your message is a reply to an existing message with this ID, in the same chat - /// Text formatting entities for the caption. You can use MarkdownToEntities to create these - /// UTC timestamp when the message should be sent - /// The transmitted message confirmed by Telegram - public Task SendMediaAsync(InputPeer peer, string caption, InputFileBase uploadedFile, string mimeType = null, int reply_to_msg_id = 0, MessageEntity[] entities = null, DateTime schedule_date = default) - { - mimeType ??= Path.GetExtension(uploadedFile.Name)?.ToLowerInvariant() switch - { - ".jpg" or ".jpeg" or ".png" or ".bmp" => "photo", - ".mp4" => "video", - ".gif" => "image/gif", - ".webp" => "image/webp", - ".mp3" => "audio/mpeg", - ".wav" => "audio/x-wav", - _ => "", // send as generic document with undefined MIME type - }; - if (mimeType == "photo") - return SendMessageAsync(peer, caption, new InputMediaUploadedPhoto { file = uploadedFile }, reply_to_msg_id, entities, schedule_date); - else if (mimeType == "video") - return SendMessageAsync(peer, caption, new InputMediaUploadedDocument(uploadedFile, "video/mp4", new DocumentAttributeVideo { flags = DocumentAttributeVideo.Flags.supports_streaming }), reply_to_msg_id, entities, schedule_date); - else - return SendMessageAsync(peer, caption, new InputMediaUploadedDocument(uploadedFile, mimeType), reply_to_msg_id, entities, schedule_date); - } - - public enum LinkPreview { Disabled = 0, BelowText = 1, AboveText = 2 }; - /// Helper method to send a text or media message easily - /// Destination of message (chat group, channel, user chat, etc..) - /// The plain text of the message (or media caption) - /// An instance of InputMedia-derived class, or if there is no associated media - /// Your message is a reply to an existing message with this ID, in the same chat - /// Text formatting entities. You can use HtmlToEntities or MarkdownToEntities to create these - /// UTC timestamp when the message should be sent - /// Should website/media preview be shown below, above or not, for URL links in your message - /// The transmitted message as confirmed by Telegram - public async Task SendMessageAsync(InputPeer peer, string text, InputMedia media = null, int reply_to_msg_id = 0, MessageEntity[] entities = null, DateTime schedule_date = default, LinkPreview preview = LinkPreview.BelowText) - { - UpdatesBase updates; - long random_id = Helpers.RandomLong(); - if (media == null) - updates = await this.Messages_SendMessage(peer, text, random_id, entities: entities, - no_webpage: preview == LinkPreview.Disabled, invert_media: preview == LinkPreview.AboveText, - reply_to: reply_to_msg_id == 0 ? null : new InputReplyToMessage { reply_to_msg_id = reply_to_msg_id }, schedule_date: schedule_date == default ? null : schedule_date); - else - updates = await this.Messages_SendMedia(peer, media, text, random_id, entities: entities, - reply_to: reply_to_msg_id == 0 ? null : new InputReplyToMessage { reply_to_msg_id = reply_to_msg_id }, schedule_date: schedule_date == default ? null : schedule_date); - if (updates is UpdateShortSentMessage sent) - return new Message - { - flags = (Message.Flags)sent.flags | (reply_to_msg_id == 0 ? 0 : Message.Flags.has_reply_to) | (peer is InputPeerSelf ? 0 : Message.Flags.has_from_id), - id = sent.id, date = sent.date, message = text, entities = sent.entities, media = sent.media, ttl_period = sent.ttl_period, - reply_to = reply_to_msg_id == 0 ? null : new MessageReplyHeader { reply_to_msg_id = reply_to_msg_id, flags = MessageReplyHeader.Flags.has_reply_to_msg_id }, - from_id = peer is InputPeerSelf ? null : new PeerUser { user_id = _session.UserId }, - peer_id = InputToPeer(peer) - }; - int msgId = -1; - foreach (var update in updates.UpdateList) - { - switch (update) - { - case UpdateMessageID updMsgId when updMsgId.random_id == random_id: msgId = updMsgId.id; break; - case UpdateNewMessage { message: Message message } when message.id == msgId: return message; - case UpdateNewScheduledMessage { message: Message schedMsg } when schedMsg.id == msgId: return schedMsg; - } - } - return null; - } - - /// Helper method to send an album (media group) of photos or documents more easily - /// Destination of message (chat group, channel, user chat, etc..) - /// An array or List of InputMedia-derived class - /// Caption for the media (in plain text) or - /// Your message is a reply to an existing message with this ID, in the same chat - /// Text formatting entities for the caption. You can use MarkdownToEntities to create these - /// UTC timestamp when the message should be sent - /// Any URL pointing to a video should be considered as non-streamable - /// The media group messages, as received by Telegram - /// - /// * The caption/entities are set on the first media
- /// * and are supported natively for bot accounts, and for user accounts by downloading the file from the web via HttpClient and sending it to Telegram. - /// WTelegramClient proxy settings don't apply to HttpClient
- /// * You may run into errors if you mix, in the same album, photos and file documents having no thumbnails/video attributes - ///
- public async Task SendAlbumAsync(InputPeer peer, ICollection medias, string caption = null, int reply_to_msg_id = 0, MessageEntity[] entities = null, DateTime schedule_date = default, bool videoUrlAsFile = false) - { - System.Net.Http.HttpClient httpClient = null; - int i = 0, length = medias.Count; - var multiMedia = new InputSingleMedia[length]; - var random_id = Helpers.RandomLong(); - foreach (var media in medias) - { - var ism = multiMedia[i] = new InputSingleMedia { random_id = random_id + i, media = media }; - i++; - retry: - switch (ism.media) - { - case InputMediaUploadedPhoto imup: - var mmp = (MessageMediaPhoto)await this.Messages_UploadMedia(peer, imup); - ism.media = mmp.photo; - break; - case InputMediaUploadedDocument imud: - var mmd = (MessageMediaDocument)await this.Messages_UploadMedia(peer, imud); - ism.media = mmd.document; - break; - case InputMediaPhotoExternal impe: - if (User.IsBot) - try - { - mmp = (MessageMediaPhoto)await this.Messages_UploadMedia(peer, impe); - ism.media = mmp.photo; - break; - } - catch (RpcException) { } - var inputFile = await UploadFromUrl(impe.url); - ism.media = new InputMediaUploadedPhoto { file = inputFile }; - goto retry; - case InputMediaDocumentExternal imde: - if (!videoUrlAsFile && User.IsBot) - try - { - mmd = (MessageMediaDocument)await this.Messages_UploadMedia(peer, imde); - ism.media = mmd.document; - break; - } - catch (RpcException) { } - string mimeType = null; - inputFile = await UploadFromUrl(imde.url); - if (videoUrlAsFile || mimeType?.StartsWith("video/") != true) - ism.media = new InputMediaUploadedDocument(inputFile, mimeType); - else - ism.media = new InputMediaUploadedDocument(inputFile, mimeType, new DocumentAttributeVideo { flags = DocumentAttributeVideo.Flags.supports_streaming }); - goto retry; - - async Task UploadFromUrl(string url) - { - var filename = Path.GetFileName(new Uri(url).LocalPath); - httpClient ??= new(); - using var response = await httpClient.GetAsync(url, System.Net.Http.HttpCompletionOption.ResponseHeadersRead); - response.EnsureSuccessStatusCode(); - using var stream = await response.Content.ReadAsStreamAsync(); - mimeType = response.Content.Headers.ContentType?.MediaType; - if (response.Content.Headers.ContentLength is long length) - return await UploadFileAsync(new Helpers.IndirectStream(stream) { ContentLength = length }, filename); - else - return await UploadFileAsync(stream, filename); - } - } - } - var firstMedia = multiMedia[0]; - firstMedia.message = caption; - firstMedia.entities = entities; - if (entities != null) firstMedia.flags = InputSingleMedia.Flags.has_entities; - - var updates = await this.Messages_SendMultiMedia(peer, multiMedia, reply_to: reply_to_msg_id == 0 ? null : new InputReplyToMessage { reply_to_msg_id = reply_to_msg_id }, schedule_date: schedule_date); - var msgIds = new int[length]; - var result = new Message[length]; - foreach (var update in updates.UpdateList) - { - switch (update) - { - case UpdateMessageID updMsgId: msgIds[updMsgId.random_id - random_id] = updMsgId.id; break; - case UpdateNewMessage { message: Message message }: result[Array.IndexOf(msgIds, message.id)] = message; break; - case UpdateNewScheduledMessage { message: Message schedMsg }: result[Array.IndexOf(msgIds, schedMsg.id)] = schedMsg; break; - } - } - return result; - } - - /// Helper method to forwards messages more easily by their IDs. - /// Whether to forward messages without quoting the original author - /// Whether to strip captions from media - /// Source of messages - /// IDs of messages - /// Destination peer - /// Destination forum topic - /// The resulting forwarded messages, as received by Telegram Some of them might be if they could not all be forwarded - public async Task ForwardMessagesAsync(InputPeer from_peer, int[] msg_ids, InputPeer to_peer, int top_msg_id = 0, bool drop_author = false, bool drop_media_captions = false) - { - int msgCount = msg_ids.Length; - var random_id = Helpers.RandomLong(); - var random_ids = Enumerable.Range(0, msgCount).Select(i => random_id + i).ToArray(); - var updates = await this.Messages_ForwardMessages(from_peer, msg_ids, random_ids, to_peer, top_msg_id == 0 ? null : top_msg_id, drop_author: drop_author, drop_media_captions: drop_media_captions); - var msgIds = new int[msgCount]; - var result = new Message[msgCount]; - foreach (var update in updates.UpdateList) - { - switch (update) - { - case UpdateMessageID updMsgId: msgIds[updMsgId.random_id - random_id] = updMsgId.id; break; - case UpdateNewMessage { message: Message message }: result[Array.IndexOf(msgIds, message.id)] = message; break; - case UpdateNewScheduledMessage { message: Message schedMsg }: result[Array.IndexOf(msgIds, schedMsg.id)] = schedMsg; break; - } - } - return result; - } - - private Peer InputToPeer(InputPeer peer) => peer switch - { - InputPeerSelf => new PeerUser { user_id = _session.UserId }, - InputPeerUser ipu => new PeerUser { user_id = ipu.user_id }, - InputPeerChat ipc => new PeerChat { chat_id = ipc.chat_id }, - InputPeerChannel ipch => new PeerChannel { channel_id = ipch.channel_id }, - InputPeerUserFromMessage ipufm => new PeerUser { user_id = ipufm.user_id }, - InputPeerChannelFromMessage ipcfm => new PeerChannel { channel_id = ipcfm.channel_id }, - _ => null, - }; - - /// Download a photo from Telegram into the outputStream - /// The photo to download - /// Stream to write the file content to. This method does not close/dispose the stream - /// A specific size/version of the photo, or to download the largest version of the photo - /// (optional) Callback for tracking the progression of the transfer - /// The file type of the photo - public async Task DownloadFileAsync(Photo photo, Stream outputStream, PhotoSizeBase photoSize = null, ProgressCallback progress = null) - { - if (photoSize is PhotoStrippedSize psp) - return InflateStrippedThumb(outputStream, psp.bytes) ? Storage_FileType.jpeg : 0; - photoSize ??= photo.LargestPhotoSize; - var fileLocation = photo.ToFileLocation(photoSize); - return await DownloadFileAsync(fileLocation, outputStream, photo.dc_id, photoSize.FileSize, progress); - } - - /// Download an animated photo from Telegram into the outputStream - /// The photo to download - /// Stream to write the file content to. This method does not close/dispose the stream - /// A specific size/version of the animated photo. Use photo.LargestVideoSize to download the largest version of the animated photo - /// (optional) Callback for tracking the progression of the transfer - /// The file type of the photo - public async Task DownloadFileAsync(Photo photo, Stream outputStream, VideoSize videoSize, ProgressCallback progress = null) - { - var fileLocation = photo.ToFileLocation(videoSize); - return await DownloadFileAsync(fileLocation, outputStream, photo.dc_id, videoSize.size, progress); - } - - /// Download a document from Telegram into the outputStream - /// The document to download - /// Stream to write the file content to. This method does not close/dispose the stream - /// A specific size/version of the document thumbnail to download, or to download the document itself - /// (optional) Callback for tracking the progression of the transfer - /// MIME type of the document/thumbnail - public async Task DownloadFileAsync(Document document, Stream outputStream, PhotoSizeBase thumbSize = null, ProgressCallback progress = null) - { - if (thumbSize is PhotoStrippedSize psp) - return InflateStrippedThumb(outputStream, psp.bytes) ? "image/jpeg" : null; - var fileLocation = document.ToFileLocation(thumbSize); - var fileType = await DownloadFileAsync(fileLocation, outputStream, document.dc_id, thumbSize?.FileSize ?? document.size, progress); - return thumbSize == null ? document.mime_type : "image/" + fileType; - } - - /// Download a document from Telegram into the outputStream - /// The document to download - /// Stream to write the file content to. This method does not close/dispose the stream - /// A specific size/version of the animated photo. Use photo.LargestVideoSize to download the largest version of the animated photo - /// (optional) Callback for tracking the progression of the transfer - /// MIME type of the document/thumbnail - public async Task DownloadFileAsync(Document document, Stream outputStream, VideoSize videoSize, ProgressCallback progress = null) - { - var fileLocation = document.ToFileLocation(videoSize); - return await DownloadFileAsync(fileLocation, outputStream, document.dc_id, videoSize.size, progress); - } - - /// Download a file from Telegram into the outputStream - /// Telegram file identifier, typically obtained with a .ToFileLocation() call - /// Stream to write file content to. This method does not close/dispose the stream - /// (optional) DC on which the file is stored - /// (optional) Expected file size - /// (optional) Callback for tracking the progression of the transfer - /// The file type - public async Task DownloadFileAsync(InputFileLocationBase fileLocation, Stream outputStream, int dc_id = 0, long fileSize = 0, ProgressCallback progress = null) - { - Storage_FileType fileType = Storage_FileType.unknown; - var client = dc_id == 0 ? this : await GetClientForDC(-dc_id, true); - using var writeSem = new SemaphoreSlim(1); - bool canSeek = outputStream.CanSeek; - long streamStartPos = canSeek ? outputStream.Position : 0; - long fileOffset = 0, maxOffsetSeen = 0; - long transmitted = 0; - var tasks = new Dictionary(); - progress?.Invoke(0, fileSize); - bool abort = false; - while (!abort) - { - await _parallelTransfers.WaitAsync(); - var task = LoadPart(fileOffset); - lock (tasks) tasks[fileOffset] = task; - if (dc_id == 0) { await task; dc_id = client._dcSession.DcID; } - if (!canSeek) await task; - fileOffset += FilePartSize; - if (fileSize != 0 && fileOffset >= fileSize) - { - if (await task != ((fileSize - 1) % FilePartSize) + 1) - throw new WTException("Downloaded file size does not match expected file size"); - break; - } - - async Task LoadPart(long offset) - { - Upload_FileBase fileBase; - try - { - fileBase = await client.Upload_GetFile(fileLocation, offset, FilePartSize); - } - catch (RpcException ex) when (ex.Code == 303 && ex.Message == "FILE_MIGRATE_X") - { - client = await GetClientForDC(-ex.X, true); - fileBase = await client.Upload_GetFile(fileLocation, offset, FilePartSize); - } - catch (RpcException ex) when (ex.Code == 400 && ex.Message == "OFFSET_INVALID") - { - abort = true; - return 0; - } - catch (Exception) - { - abort = true; - throw; - } - finally - { - _parallelTransfers.Release(); - } - if (fileBase is not Upload_File fileData) - throw new WTException("Upload_GetFile returned unsupported " + fileBase?.GetType().Name); - if (fileData.bytes.Length != FilePartSize) abort = true; - if (fileData.bytes.Length != 0) - { - fileType = fileData.type; - await writeSem.WaitAsync(); - try - { - if (canSeek && streamStartPos + offset != outputStream.Position) // if we're about to write out of order - { - await outputStream.FlushAsync(); // async flush, otherwise Seek would do a sync flush - outputStream.Seek(streamStartPos + offset, SeekOrigin.Begin); - } - await outputStream.WriteAsync(fileData.bytes, 0, fileData.bytes.Length); - maxOffsetSeen = Math.Max(maxOffsetSeen, offset + fileData.bytes.Length); - transmitted += fileData.bytes.Length; - progress?.Invoke(transmitted, fileSize); - } - catch (Exception) - { - abort = true; - throw; - } - finally - { - writeSem.Release(); - } - } - lock (tasks) tasks.Remove(offset); - return fileData.bytes.Length; - } - } - Task[] remainingTasks; - lock (tasks) remainingTasks = [.. tasks.Values]; - await Task.WhenAll(remainingTasks); // wait completion and eventually propagate any task exception - await outputStream.FlushAsync(); - if (canSeek) outputStream.Seek(streamStartPos + maxOffsetSeen, SeekOrigin.Begin); - return fileType; - } - - /// Download the profile photo for a given peer into the outputStream - /// User, Chat or Channel - /// Stream to write the file content to. This method does not close/dispose the stream - /// Whether to download the high-quality version of the picture - /// Whether to extract the embedded very low-res thumbnail (synchronous, no actual download needed) - /// The file type of the photo, or 0 if no photo available - public async Task DownloadProfilePhotoAsync(IPeerInfo peer, Stream outputStream, bool big = false, bool miniThumb = false) - { - int dc_id; - long photo_id; - byte[] stripped_thumb; - switch (peer) - { - case User user: - if (user.photo == null) return 0; - dc_id = user.photo.dc_id; - photo_id = user.photo.photo_id; - stripped_thumb = user.photo.stripped_thumb; - break; - case ChatBase { Photo: var photo }: - if (photo == null) return 0; - dc_id = photo.dc_id; - photo_id = photo.photo_id; - stripped_thumb = photo.stripped_thumb; - break; - default: - return 0; - } - if (miniThumb && !big) - return InflateStrippedThumb(outputStream, stripped_thumb) ? Storage_FileType.jpeg : 0; - var fileLocation = new InputPeerPhotoFileLocation { peer = peer.ToInputPeer(), photo_id = photo_id }; - if (big) fileLocation.flags |= InputPeerPhotoFileLocation.Flags.big; - return await DownloadFileAsync(fileLocation, outputStream, dc_id); - } - - private static bool InflateStrippedThumb(Stream outputStream, byte[] stripped_thumb) - { - if (stripped_thumb == null || stripped_thumb.Length <= 3 || stripped_thumb[0] != 1) - return false; - var header = Helpers.StrippedThumbJPG; - outputStream.Write(header, 0, 164); - outputStream.WriteByte(stripped_thumb[1]); - outputStream.WriteByte(0); - outputStream.WriteByte(stripped_thumb[2]); - outputStream.Write(header, 167, header.Length - 167); - outputStream.Write(stripped_thumb, 3, stripped_thumb.Length - 3); - outputStream.WriteByte(0xff); - outputStream.WriteByte(0xd9); - return true; - } - - /// Get all chats, channels and supergroups - public async Task Messages_GetAllChats() - { - var dialogs = await Messages_GetAllDialogs(); - var result = new Messages_Chats { chats = [] }; - foreach (var dialog in dialogs.dialogs) - if (dialog.Peer is (PeerChat or PeerChannel) and { ID: var id }) - result.chats[id] = dialogs.chats[id]; - return result; - } - - /// Returns the current user dialog list. Possible codes: 400 (details) - /// Peer folder ID, for more info click here - /// See - public async Task Messages_GetAllDialogs(int? folder_id = null) - { - var dialogs = await this.Messages_GetDialogs(folder_id: folder_id); - switch (dialogs) - { - case Messages_DialogsSlice mds: - var dialogList = new List(); - var messageList = new List(); - int skip = 0; - while (dialogs.Dialogs.Length > skip) - { - dialogList.AddRange(skip == 0 ? dialogs.Dialogs : dialogs.Dialogs[skip..]); - messageList.AddRange(dialogs.Messages); - skip = 0; - int last = dialogs.Dialogs.Length - 1; - var lastDialog = dialogs.Dialogs[last]; - retryDate: - var lastPeer = dialogs.UserOrChat(lastDialog).ToInputPeer(); - var lastMsgId = lastDialog.TopMessage; - var lastDate = dialogs.Messages.LastOrDefault(m => m.Peer.ID == lastDialog.Peer.ID && m.ID == lastDialog.TopMessage)?.Date ?? default; - if (lastDate == default) - if (--last < 0) break; else { ++skip; lastDialog = dialogs.Dialogs[last]; goto retryDate; } - dialogs = await this.Messages_GetDialogs(lastDate, lastMsgId, lastPeer, folder_id: folder_id); - if (dialogs is not Messages_Dialogs md) break; - foreach (var (key, value) in md.chats) mds.chats[key] = value; - foreach (var (key, value) in md.users) mds.users[key] = value; - } - mds.dialogs = [.. dialogList]; - mds.messages = [.. messageList]; - return mds; - case Messages_Dialogs md: return md; - default: throw new WTException("Messages_GetDialogs returned unexpected " + dialogs?.GetType().Name); - } - } - - /// Helper method that tries to fetch all participants from a Channel (beyond Telegram server-side limitations) - /// The channel to query - /// Also fetch the kicked/banned members? - /// first letters used to search for in participants names
(default values crafted with ♥ to find most latin and cyrillic names) - /// second (and further) letters used to search for in participants names - /// Can be used to abort the work of this method - /// Field count indicates the total count of members. Field participants contains those that were successfully fetched - /// ⚠ This method can take a few minutes to complete on big broadcast channels. It likely won't be able to obtain the full total count of members - public async Task Channels_GetAllParticipants(InputChannelBase channel, bool includeKickBan = false, string alphabet1 = "АБCДЕЄЖФГHИІJКЛМНОПQРСТУВWХЦЧШЩЫЮЯЗ", string alphabet2 = "АCЕHИJЛМНОРСТУВWЫ", CancellationToken cancellationToken = default) - { - alphabet2 ??= alphabet1; - var result = new Channels_ChannelParticipants { chats = [], users = [] }; - var user_ids = new HashSet(); - var participants = new List(); - - var mcf = await this.Channels_GetFullChannel(channel); - result.count = mcf.full_chat.ParticipantsCount; - if (result.count > 2000 && ((Channel)mcf.chats[channel.ChannelId]).IsChannel) - Helpers.Log(2, "Fetching all participants on a big channel can take several minutes..."); - await GetWithFilter(new ChannelParticipantsAdmins()); - await GetWithFilter(new ChannelParticipantsBots()); - await GetWithFilter(new ChannelParticipantsSearch { q = "" }, (f, c) => new ChannelParticipantsSearch { q = f.q + c }, alphabet1); - if (includeKickBan) - { - await GetWithFilter(new ChannelParticipantsKicked { q = "" }, (f, c) => new ChannelParticipantsKicked { q = f.q + c }, alphabet1); - await GetWithFilter(new ChannelParticipantsBanned { q = "" }, (f, c) => new ChannelParticipantsBanned { q = f.q + c }, alphabet1); - } - result.participants = [.. participants]; - return result; - - async Task GetWithFilter(T filter, Func recurse = null, string alphabet = null) where T : ChannelParticipantsFilter - { - Channels_ChannelParticipants ccp; - int maxCount = 0; - for (int offset = 0; ;) - { - cancellationToken.ThrowIfCancellationRequested(); - ccp = await this.Channels_GetParticipants(channel, filter, offset, 1024, 0); - if (ccp.count > maxCount) maxCount = ccp.count; - foreach (var kvp in ccp.chats) result.chats[kvp.Key] = kvp.Value; - foreach (var kvp in ccp.users) result.users[kvp.Key] = kvp.Value; - lock (participants) - foreach (var participant in ccp.participants) - if (user_ids.Add(participant.UserId)) - participants.Add(participant); - offset += ccp.participants.Length; - if (offset >= ccp.count || ccp.participants.Length == 0) break; - } - Helpers.Log(0, $"GetParticipants({(filter as ChannelParticipantsSearch)?.q}) returned {ccp.count}/{maxCount}.\tAccumulated count: {participants.Count}"); - if (recurse != null && (ccp.count < maxCount - 100 || ccp.count == 200 || ccp.count == 1000)) - foreach (var c in alphabet) - await GetWithFilter(recurse(filter, c), recurse, c == 'А' ? alphabet : alphabet2); - } - } - - ///
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); - var resultFull = result; - var events = new List(result.events); - while (result.events.Length > 0) - { - 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; - } - resultFull.events = [.. events]; - return resultFull; - } - - /// Helper simplified method: Get all topics of a forum See Possible codes: 400 (details) - /// Supergroup or Bot peer - /// Search query - public async Task Channels_GetAllForumTopics(InputPeer peer, string q = null) - { - var result = await this.Messages_GetForumTopics(peer, offset_date: DateTime.MaxValue, q: q); - if (result.topics.Length < result.count) - { - var topics = result.topics.ToList(); - var messages = result.messages.ToList(); - while (true) - { - var more_topics = await this.Messages_GetForumTopics(peer, messages[^1].Date, messages[^1].ID, topics[^1].ID); - if (more_topics.topics.Length == 0) break; - topics.AddRange(more_topics.topics); - messages.AddRange(more_topics.messages); - foreach (var kvp in more_topics.chats) result.chats[kvp.Key] = kvp.Value; - foreach (var kvp in more_topics.users) result.users[kvp.Key] = kvp.Value; - if (topics.Count >= more_topics.count) break; - } - result.topics = [.. topics]; - result.messages = [.. messages]; - } - return result; - } - - 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 - /// User to be added - 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, 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), - InputPeerChannel channel => this.Channels_EditBanned(channel, user, new ChatBannedRights { flags = ChatBannedRights.Flags.view_messages }), - _ => 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), - InputPeerChannel channel => this.Channels_LeaveChannel(channel), - _ => 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) - { - case InputPeerChat chat: - await this.Messages_EditChatAdmin(chat.chat_id, user, is_admin); - return new Updates { date = DateTime.UtcNow, users = [], updates = [], - 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)0x1E8BF : 0 }, null); - default: - throw new ArgumentException(OnlyChatChannel); - } - } - - /// 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), - InputPeerChannel channel => this.Channels_EditPhoto(channel, photo), - _ => 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), - InputPeerChannel channel => this.Channels_EditTitle(channel, title), - _ => 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), - InputPeerChannel channel => this.Channels_GetFullChannel(channel), - _ => 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) - { - case InputPeerChat chat: - await this.Messages_DeleteChat(chat.chat_id); - return new Updates { date = DateTime.UtcNow, users = [], updates = [], - chats = (await this.Messages_GetChats(chat.chat_id)).chats }; - case InputPeerChannel channel: - return await this.Channels_DeleteChannel(channel); - default: - throw new ArgumentException(OnlyChatChannel); - } - } - - /// If you want to get all messages from a chat, use method Messages_GetHistory - [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822")] - public Task GetMessages(InputPeer peer) - => throw new WTException("If you want to get all messages from a chat, use method Messages_GetHistory"); - - /// 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, true); - - /// 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 is InputPeerChannel channel ? await this.Channels_ReadHistory(channel, max_id) : (await this.Messages_ReadHistory(peer, max_id)) != null; - - private static readonly char[] UrlSeparator = ['?', '#', '/']; - - /// Return information about a chat/channel based on Invite Link or Public Link - /// Public link or Invite link, like https://t.me/+InviteHash, https://t.me/joinchat/InviteHash or https://t.me/channelname
Works also without https:// prefix - /// to also join the chat/channel - /// previously collected chats, to prevent unnecessary ResolveUsername - /// a Chat or Channel, possibly partial Channel information only (with flag ) - public async Task AnalyzeInviteLink(string url, bool join = false, IDictionary chats = null) - { - int start = url.IndexOf("//"); - start = url.IndexOf('/', start + 2) + 1; - int end = url.IndexOfAny(UrlSeparator, start); - if (end == -1) end = url.Length; - if (start == 0 || end == start) throw new ArgumentException("Invalid URL"); - string hash; - if (url[start] == '+') - hash = url[(start + 1)..end]; - else if (string.Compare(url, start, "joinchat/", 0, 9, StringComparison.OrdinalIgnoreCase) == 0) - hash = url[(end + 1)..]; - else - { - var chat = await CachedOrResolveUsername(url[start..end], chats); - if (join && chat is Channel channel) - try - { - var res = await this.Channels_JoinChannel(channel); - chat = res.Chats[channel.id]; - } - catch (RpcException ex) when (ex.Code == 400 && ex.Message == "INVITE_REQUEST_SENT") { } - return chat; - } - var chatInvite = await this.Messages_CheckChatInvite(hash); - if (join) - try - { - var res = await this.Messages_ImportChatInvite(hash); - if (res.Chats.Values.FirstOrDefault() is ChatBase chat) return chat; - } - catch (RpcException ex) when (ex.Code == 400 && ex.Message == "INVITE_REQUEST_SENT") { } - switch (chatInvite) - { - case ChatInviteAlready cia: return cia.chat; - case ChatInvitePeek cip: return cip.chat; - case ChatInvite ci: - ChatPhoto chatPhoto = null; - if (ci.photo is Photo photo) - { - var stripped_thumb = photo.sizes.OfType().FirstOrDefault()?.bytes; - chatPhoto = new ChatPhoto - { - dc_id = photo.dc_id, - photo_id = photo.id, - stripped_thumb = stripped_thumb, - flags = (stripped_thumb != null ? ChatPhoto.Flags.has_stripped_thumb : 0) | - (photo.flags.HasFlag(Photo.Flags.has_video_sizes) ? ChatPhoto.Flags.has_video : 0), - }; - } - var rrAbout = ci.about == null ? null : new RestrictionReason[] { new() { text = ci.about } }; - return !ci.flags.HasFlag(ChatInvite.Flags.channel) - ? new Chat { title = ci.title, photo = chatPhoto, participants_count = ci.participants_count, - flags = ci.flags.HasFlag(ChatInvite.Flags.request_needed) ? (Chat.Flags)Channel.Flags.join_request : 0 } - : new Channel { title = ci.title, photo = chatPhoto, participants_count = ci.participants_count, - restriction_reason = rrAbout, flags = Channel.Flags.min | - (ci.flags.HasFlag(ChatInvite.Flags.broadcast) ? Channel.Flags.broadcast : 0) | - (ci.flags.HasFlag(ChatInvite.Flags.public_) ? Channel.Flags.has_username : 0) | - (ci.flags.HasFlag(ChatInvite.Flags.megagroup) ? Channel.Flags.megagroup : 0) | - (ci.flags.HasFlag(ChatInvite.Flags.verified) ? Channel.Flags.verified : 0) | - (ci.flags.HasFlag(ChatInvite.Flags.scam) ? Channel.Flags.scam : 0) | - (ci.flags.HasFlag(ChatInvite.Flags.fake) ? Channel.Flags.fake : 0) | - (ci.flags.HasFlag(ChatInvite.Flags.request_needed) ? Channel.Flags.join_request : 0) }; - } - return null; - } - - /// Return chat and message details based on a Message Link (URL) - /// Message Link, like https://t.me/c/1234567890/1234 or t.me/channelname/1234 - /// previously collected chats, to prevent unnecessary ResolveUsername - /// Structure containing the message, chat and user details - /// If link is for private group (t.me/c/..), user must have joined that group - public async Task GetMessageByLink(string url, IDictionary chats = null) - { - int start = url.IndexOf("//"); - start = url.IndexOf('/', start + 2) + 1; - int slash = url.IndexOf('/', start + 2); - int msgStart = slash + 1; - int end = url.IndexOfAny(UrlSeparator, msgStart); - if (end == -1) end = url.Length; - else if (url[end] == '/' && char.IsDigit(url[msgStart]) && url.Length > end + 1 && char.IsDigit(url[end + 1])) - { - end = url.IndexOfAny(UrlSeparator, msgStart = end + 1); - if (end == -1) end = url.Length; - } - if (start == 0 || slash == -1 || end <= slash + 1 || !char.IsDigit(url[msgStart])) throw new ArgumentException("Invalid URL"); - int msgId = int.Parse(url[msgStart..end]); - ChatBase chat; - if (url[start] is 'c' or 'C' && url[start + 1] == '/') - { - long chatId = long.Parse(url[(start + 2)..slash]); - if (chats?.TryGetValue(chatId, out chat) != true) - { - var mc = await this.Channels_GetChannels(new InputChannel(chatId, 0)); - if (!mc.chats.TryGetValue(chatId, out chat)) - throw new WTException($"Channel {chatId} not found"); - else - chats?[chatId] = chat; - } - } - else - chat = await CachedOrResolveUsername(url[start..slash], chats); - if (chat is not Channel channel) throw new WTException($"URL does not identify a valid Channel"); - return await this.Channels_GetMessages(channel, msgId) as Messages_ChannelMessages; - } - - private async Task CachedOrResolveUsername(string username, IDictionary chats = null) - { - if (chats == null) - return (await this.Contacts_ResolveUsername(username)).Chat; - ChatBase chat; - lock (chats) - chat = chats.Values.OfType().FirstOrDefault(ch => ch.ActiveUsernames.Contains(username, StringComparer.OrdinalIgnoreCase)); - if (chat == null) - { - chat = (await this.Contacts_ResolveUsername(username)).Chat; - if (chat != null) lock (chats) chats[chat.ID] = chat; - } - return chat; - } - - /// Receive updates for a given group/channel until cancellation is requested. - /// Group/channel to monitor without joining - /// Cancel token to stop the monitoring - /// After cancelling, you may still receive updates for a few more seconds - public async void OpenChat(InputChannel channel, CancellationToken ct) - { - var cts = CancellationTokenSource.CreateLinkedTokenSource(_cts.Token, ct); - try - { - while (!cts.IsCancellationRequested) - { - var diff = await this.Updates_GetChannelDifference(channel, null, 1, 1, true); - var timeout = diff.Timeout * 1000; - await Task.Delay(timeout != 0 ? timeout : 30000, cts.Token); - } - } - catch (Exception ex) - { - if (!cts.IsCancellationRequested) - Console.WriteLine($"An exception occured for OpenChat {channel.channel_id}: {ex.Message}"); - } - } - } -} diff --git a/src/Client.cs b/src/Client.cs index fbeb56b..80a03d1 100644 --- a/src/Client.cs +++ b/src/Client.cs @@ -1,18 +1,17 @@ using System; using System.Buffers.Binary; using System.Collections.Generic; -using System.ComponentModel; +using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net; -using System.Net.Http; using System.Net.Sockets; using System.Reflection; using System.Security.Cryptography; +using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Web; using TL; using static WTelegram.Encryption; @@ -21,298 +20,188 @@ using static WTelegram.Encryption; namespace WTelegram { - public partial class Client : IDisposable -#if NETCOREAPP2_1_OR_GREATER - , IAsyncDisposable -#endif + public sealed 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_ReactorError.cs for how to use this
or Examples/Program_ListenUpdate.cs using the UpdateManager class instead
- public event Func OnUpdates; - /// This event is called for other types of notifications (login states, reactor errors, ...) - public event Func OnOther; - /// Use this handler to intercept Updates that resulted from your own API calls - public event Func OnOwnUpdates; - /// Used to create a TcpClient connected to the given address/port, or throw an exception on failure - public TcpFactory TcpHandler { get; set; } = DefaultTcpHandler; - public delegate Task TcpFactory(string host, int port); - /// Url for using a MTProxy. https://t.me/proxy?server=... - public string MTProxyUrl { get; set; } - /// Telegram configuration, obtained at connection time + public event Action Update; public Config TLConfig { get; private set; } - /// Number of automatic reconnections on connection/reactor failure - public int MaxAutoReconnects { get; set; } = 5; - /// Number of attempts in case of wrong verification_code or password - public int MaxCodePwdAttempts { get; set; } = 3; - /// Number of seconds under which an error 420 FLOOD_WAIT_X will not be raised and your request will instead be auto-retried after the delay - public int FloodRetryThreshold { get; set; } = 60; - /// Number of seconds between each keep-alive ping. Increase this if you have a slow connection or you're debugging your code - public int PingInterval { get; set; } = 60; - /// Size of chunks when uploading/downloading files. Reduce this if you don't have much memory - public int FilePartSize { get; set; } = 512 * 1024; - /// Is this Client instance the main or a secondary DC session - public bool IsMainDC => _dcSession?.DataCenter?.flags.HasFlag(DcOption.Flags.media_only) != true - && (_dcSession?.DataCenter?.id - _session.MainDC) is null or 0; - /// Has this Client established connection been disconnected? - 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. This is only filled after a successful (re)login, not updated later - public User User { get; private set; } - /// Number of parallel transfers operations (uploads/downloads) allowed at the same time. - /// Don't use this property while transfers are ongoing! - public int ParallelTransfers - { - get => _parallelTransfers.CurrentCount; - set - { - int delta = value - _parallelTransfers.CurrentCount; - for (; delta < 0; delta++) _parallelTransfers.Wait(); - if (delta > 0) _parallelTransfers.Release(delta); - } - } + public int MaxAutoReconnects { get; set; } = 5; // number of automatic reconnections on connection/reactor failure + public bool IsMainDC => (_dcSession?.DataCenter?.id ?? 0) == _session.MainDC; - private Func _config; + private readonly Func _config; + private readonly int _apiId; + private readonly string _apiHash; private readonly Session _session; - private string _apiHash; private Session.DCSession _dcSession; + private static readonly byte[] IntermediateHeader = new byte[4] { 0xee, 0xee, 0xee, 0xee }; private TcpClient _tcpClient; - private Stream _networkStream; - private HttpClient _httpClient; - private HttpWait _httpWait; - private IObject _lastSentMsg; + private NetworkStream _networkStream; + private ITLFunction _lastSentMsg; private long _lastRecvMsgId; - private readonly List _msgsToAck = []; + private readonly List _msgsToAck = new(); private readonly Random _random = new(); private int _saltChangeCounter; private Task _reactorTask; - private Rpc _bareRpc; - private readonly Dictionary _pendingRpcs = []; + private long _bareRequest; + private readonly Dictionary tcs)> _pendingRequests = new(); private SemaphoreSlim _sendSemaphore = new(0); private readonly SemaphoreSlim _semaphore = new(1); private Task _connecting; private CancellationTokenSource _cts; private int _reactorReconnects = 0; - private const string ConnectionShutDown = "Could not read payload length : Connection shut down"; - private const long Ticks5Secs = 5 * TimeSpan.TicksPerSecond; - private readonly SemaphoreSlim _parallelTransfers = new(2); // max parallel part uploads/downloads +#if MTPROTO1 + private readonly SHA1 _sha1 = SHA1.Create(); + private readonly SHA1 _sha1Recv = SHA1.Create(); +#else private readonly SHA256 _sha256 = SHA256.Create(); private readonly SHA256 _sha256Recv = SHA256.Create(); -#if OBFUSCATION - private AesCtr _sendCtr, _recvCtr; #endif - private bool _paddedMode; - public Client(int apiID, string apiHash, string sessionPathname = null) - : this(what => what switch - { - "api_id" => apiID.ToString(), - "api_hash" => apiHash, - "session_pathname" => sessionPathname, - _ => null - }) - { } - - public Client(Func configProvider, byte[] startSession, Action saveSession) - : this(configProvider, new ActionStore(startSession, saveSession)) { } - - /// Welcome to WTelegramClient! 🙂 - /// Config callback, is queried for: api_id, api_hash, session_pathname - /// if specified, must support initial Length & Read() of a session, then calls to Write() the updated session. Other calls can be ignored - public Client(Func configProvider = null, Stream sessionStore = null) + /// Welcome to WTelegramClient! 😀 + /// Config callback, is queried for: api_id, api_hash, session_pathname + public Client(Func configProvider = null) { _config = configProvider ?? DefaultConfigOrAsk; - var session_key = _config("session_key") ?? (_apiHash = Config("api_hash")); - sessionStore ??= new SessionStore(Config("session_pathname")); - _session = Session.LoadOrCreate(sessionStore, Convert.FromHexString(session_key)); - if (_session.ApiId == 0) _session.ApiId = int.Parse(Config("api_id")); + _apiId = int.Parse(Config("api_id")); + _apiHash = Config("api_hash"); + _session = Session.LoadOrCreate(Config("session_pathname"), Convert.FromHexString(_apiHash)); if (_session.MainDC != 0) _session.DCSessions.TryGetValue(_session.MainDC, out _dcSession); - _dcSession ??= new(); + _dcSession ??= new() { Id = Helpers.RandomLong() }; _dcSession.Client = this; - var version = Assembly.GetExecutingAssembly().GetCustomAttribute().InformationalVersion; - Helpers.Log(1, $"WTelegramClient {version} running under {System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription}"); } private Client(Client cloneOf, Session.DCSession dcSession) { _config = cloneOf._config; + _apiId = cloneOf._apiId; + _apiHash = cloneOf._apiHash; _session = cloneOf._session; - TcpHandler = cloneOf.TcpHandler; - MTProxyUrl = cloneOf.MTProxyUrl; - PingInterval = cloneOf.PingInterval; - MaxAutoReconnects = cloneOf.MaxAutoReconnects; - TLConfig = cloneOf.TLConfig; _dcSession = dcSession; } - internal Task ConfigAsync(string what) => Task.Run(() => Config(what)); - internal string Config(string what) - => _config(what) ?? DefaultConfig(what) ?? throw new WTException("You must provide a config value for " + what); + public string Config(string config) + => _config(config) ?? DefaultConfig(config) ?? throw new ApplicationException("You must provide a config value for " + config); - /// Default config values, used if your Config callback returns - public static string DefaultConfig(string what) => what switch + public static string DefaultConfig(string config) => config switch { "session_pathname" => Path.Combine( - Path.GetDirectoryName(Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar))) - ?? AppDomain.CurrentDomain.BaseDirectory, "WTelegram.session"), + Path.GetDirectoryName(Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar))), + "WTelegram.session"), #if DEBUG - "server_address" => "2>149.154.167.40:443", // Test DC 2 + "server_address" => "149.154.167.40:443", #else - "server_address" => "2>149.154.167.50:443", // DC 2 + "server_address" => "149.154.167.50:443", #endif "device_model" => Environment.Is64BitOperatingSystem ? "PC 64bit" : "PC 32bit", - "system_version" => Helpers.GetSystemVersion(), - "app_version" => Helpers.GetAppVersion(), + "system_version" => System.Runtime.InteropServices.RuntimeInformation.OSDescription, + "app_version" => Assembly.GetEntryAssembly().GetName().Version.ToString(), "system_lang_code" => CultureInfo.InstalledUICulture.TwoLetterISOLanguageName, "lang_pack" => "", "lang_code" => CultureInfo.CurrentUICulture.TwoLetterISOLanguageName, "user_id" => "-1", - "verification_code" or "email_verification_code" or "password" => AskConfig(what), - "init_params" => "{}", - _ => null // api_id api_hash phone_number... it's up to you to reply to these correctly + _ => null // api_id api_hash phone_number verification_code... it's up to you to reply to these correctly }; - internal static string DefaultConfigOrAsk(string config) => DefaultConfig(config) ?? AskConfig(config); - - private static string AskConfig(string config) + public static string DefaultConfigOrAsk(string config) { - if (config == "session_key") - { - Console.WriteLine("Welcome! You can obtain your api_id/api_hash at https://my.telegram.org/apps"); - return null; - } + var value = DefaultConfig(config); + if (value != null) return value; Console.Write($"Enter {config.Replace('_', ' ')}: "); return Console.ReadLine(); } - /// Builds a structure that is used to validate a 2FA password - /// Password validation configuration. You can obtain this via Account_GetPassword or through OnOther as part of the login process - /// The password to validate - public static Task InputCheckPassword(Account_Password accountPassword, string password) - => Check2FA(accountPassword, () => Task.FromResult(password)); + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822")] + public void LoadPublicKey(string pem) => Encryption.LoadPublicKey(pem); - [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA1816")] - public void Dispose() => DisposeAsync().AsTask().Wait(); - public async ValueTask DisposeAsync() + public void Dispose() { Helpers.Log(2, $"{_dcSession.DcID}>Disposing the client"); - await ResetAsync(false, IsMainDC).ConfigureAwait(false); - var ex = new ObjectDisposedException("WTelegram.Client was disposed"); - lock (_pendingRpcs) // abort all pending requests - foreach (var rpc in _pendingRpcs.Values) - rpc.tcs.TrySetException(ex); - _sendSemaphore.Dispose(); - _httpClient?.Dispose(); - _networkStream = null; - if (IsMainDC) _session.Dispose(); - GC.SuppressFinalize(this); + Reset(false, IsMainDC); } - public void DisableUpdates(bool disable = true) => _dcSession.DisableUpdates(disable); - - /// Enable connecting to Telegram via on-demand HTTP requests instead of permanent TCP connection - /// HttpClient to use. Leave for a default one - /// Default HttpWait parameters for requests.⚠️ Telegram servers don't support this correctly at the moment.So leave for the default 25 seconds long poll - public void HttpMode(HttpClient httpClient = null, HttpWait defaultHttpWait = null) + // disconnect and eventually forget user and disconnect other sessions + public void Reset(bool resetUser = true, bool resetSessions = true) { - if (_tcpClient != null) throw new InvalidOperationException("Cannot switch to HTTP after TCP connection"); - _httpClient = httpClient ?? new(); - _httpWait = defaultHttpWait; - ParallelTransfers = 1; - } - - /// Disconnect from Telegram (shouldn't be needed in normal usage) - /// Forget about logged-in user - /// Disconnect secondary sessions with other DCs - public void Reset(bool resetUser = true, bool resetSessions = true) => ResetAsync(resetUser, resetSessions).Wait(); - - /// Disconnect from Telegram (shouldn't be needed in normal usage) - /// Forget about logged-in user - /// Disconnect secondary sessions with other DCs - public async Task ResetAsync(bool resetUser = true, bool resetSessions = true) - { - try - { - if (_httpClient == null && CheckMsgsToAck() is MsgsAck msgsAck) - await SendAsync(msgsAck, false).WaitAsync(1000).ConfigureAwait(false); - } - catch { } + if (CheckMsgsToAck() is MsgsAck msgsAck) + SendAsync(MakeFunction(msgsAck), false).Wait(1000); _cts?.Cancel(); - _sendSemaphore = new(0); // initially taken, first released during DoConnectAsync - try - { - await _reactorTask.WaitAsync(1000).ConfigureAwait(false); - } - catch { } - _reactorTask = resetSessions ? null : Task.CompletedTask; - _networkStream?.Close(); + _sendSemaphore = new(0); + _reactorTask = null; _tcpClient?.Dispose(); -#if OBFUSCATION - _sendCtr?.Dispose(); - _recvCtr?.Dispose(); -#endif - _paddedMode = false; _connecting = null; - _bareRpc = null; if (resetSessions) { foreach (var altSession in _session.DCSessions.Values) if (altSession.Client != null && altSession.Client != this) { - await altSession.Client.DisposeAsync(); + altSession.Client.Dispose(); altSession.Client = null; } } if (resetUser) - { - _loginCfg = default; - _session.UserId = 0; - User = null; - } + _session.User = null; } - private Session.DCSession GetOrCreateDCSession(int dcId, DcOption.Flags flags) + /// Establish connection to Telegram servers. Config callback is queried for: server_address + /// Most methods of this class are async Task, so please use + public async Task ConnectAsync() { - if (_session.DCSessions.TryGetValue(dcId, out var dcSession) && dcSession.Client != null) - return dcSession; // we have already a connected session with this DC, use it - if (dcSession == null && _session.DCSessions.TryGetValue(-dcId, out dcSession) && dcSession.AuthKey != null) - { - // we have already negociated an AuthKey with this DC - if (dcSession.DataCenter.flags == flags && _session.DCSessions.Remove(-dcId)) - return _session.DCSessions[dcId] = dcSession; // we found a misclassed DC, change its sign - dcSession = new Session.DCSession { // clone AuthKey for a session on the matching media_only DC - authKeyID = dcSession.authKeyID, AuthKey = dcSession.AuthKey, UserId = dcSession.UserId }; - } - // try to find the most appropriate DcOption for this DC - if (dcSession?.AuthKey == null) // we'll need to negociate an AuthKey => can't use media_only DC - { - flags &= ~DcOption.Flags.media_only; - dcId = Math.Abs(dcId); - } - var dcOptions = GetDcOptions(Math.Abs(dcId), flags); - var dcOption = dcOptions.FirstOrDefault(); - dcSession ??= new(); // create new session only if not already existing - if (dcOption != null) dcSession.DataCenter = dcOption; - else if (dcSession.DataCenter == null) throw new WTException($"Could not find adequate dc_option for DC {dcId}"); - return _session.DCSessions[dcId] = dcSession; + lock (this) + _connecting ??= DoConnectAsync(); + await _connecting; + } + + private async Task DoConnectAsync() + { + var endpoint = _dcSession?.EndPoint ?? Compat.IPEndPoint_Parse(Config("server_address")); + Helpers.Log(2, $"Connecting to {endpoint}..."); + _tcpClient = new TcpClient(endpoint.AddressFamily); + await _tcpClient.ConnectAsync(endpoint.Address, endpoint.Port); + _networkStream = _tcpClient.GetStream(); + await _networkStream.WriteAsync(IntermediateHeader, 0, 4); + _cts = new(); + _saltChangeCounter = 0; + _reactorTask = Reactor(_networkStream, _cts); + _sendSemaphore.Release(); + + try + { + if (_dcSession.AuthKeyID == 0) + await CreateAuthorizationKey(this, _dcSession); + + var keepAliveTask = KeepAlive(_cts.Token); + TLConfig = await this.InvokeWithLayer(Layer.Version, + Schema.InitConnection(_apiId, + Config("device_model"), + Config("system_version"), + Config("app_version"), + Config("system_lang_code"), + Config("lang_pack"), + Config("lang_code"), + Schema.Help_GetConfig)); + _saltChangeCounter = 0; + if (_dcSession.DataCenter == null) + { + _dcSession.DataCenter = TLConfig.dc_options.Where(dc => dc.id == TLConfig.this_dc) + .OrderByDescending(dc => dc.ip_address == endpoint.Address.ToString()) + .ThenByDescending(dc => dc.port == endpoint.Port).First(); + _session.DCSessions[TLConfig.this_dc] = _dcSession; + } + if (_session.MainDC == 0) _session.MainDC = TLConfig.this_dc; + } + finally + { + _session.Save(); + } + Helpers.Log(2, $"Connected to {(TLConfig.test_mode ? "Test DC" : "DC")} {TLConfig.this_dc}... {TLConfig.flags & (Config.Flags)~0xE00}"); } - /// Obtain/create a Client for a secondary session on a specific Data Center - /// ID of the Data Center (use negative values for media_only) - /// Connect immediately - /// Client connected to the selected DC - /// ⚠️ You shouldn't have to use this method unless you know what you're doing public async Task GetClientForDC(int dcId, bool connect = true) { if (_dcSession.DataCenter?.id == dcId) return this; Session.DCSession altSession; lock (_session) { - var flags = _dcSession.DataCenter.flags; - if (dcId < 0) flags = (flags & DcOption.Flags.ipv6) | DcOption.Flags.media_only; - altSession = GetOrCreateDCSession(dcId, flags); - _session.Save(); - if (altSession.Client?.Disconnected ?? false) { altSession.Client.Dispose(); altSession.Client = null; } + altSession = GetOrCreateDCSession(dcId); altSession.Client ??= new Client(this, altSession); } Helpers.Log(2, $"Requested connection to DC {dcId}..."); @@ -322,16 +211,16 @@ namespace WTelegram try { Auth_ExportedAuthorization exported = null; - if (_session.UserId != 0 && IsMainDC && altSession.UserId != _session.UserId && Math.Abs(altSession.DcID) != Math.Abs(_dcSession.DcID)) - exported = await this.Auth_ExportAuthorization(Math.Abs(dcId)); + if (_session.User != null && IsMainDC && altSession.UserId != _session.User.id) + exported = await this.Auth_ExportAuthorization(dcId); await altSession.Client.ConnectAsync(); if (exported != null) { var authorization = await altSession.Client.Auth_ImportAuthorization(exported.id, exported.bytes); if (authorization is not Auth_Authorization { user: User user }) - throw new WTException("Failed to get Authorization: " + authorization.GetType().Name); + throw new ApplicationException("Failed to get Authorization: " + authorization.GetType().Name); + _session.User = user; altSession.UserId = user.id; - lock (_session) _session.Save(); } } finally @@ -342,379 +231,495 @@ namespace WTelegram return altSession.Client; } - private async Task Reactor(Stream stream, CancellationToken ct) + private Session.DCSession GetOrCreateDCSession(int dcId) + { + if (_session.DCSessions.TryGetValue(dcId, out var dcSession)) + return dcSession; + var prevFamily = _tcpClient.Client.RemoteEndPoint.AddressFamily; + var dcOptions = TLConfig.dc_options.Where(dc => dc.id == dcId && (dc.flags & (DcOption.Flags.media_only | DcOption.Flags.cdn)) == 0); + if (prevFamily == AddressFamily.InterNetworkV6) // try to stay in the same connectivity + dcOptions = dcOptions.OrderByDescending(dc => dc.flags & DcOption.Flags.ipv6); // list ipv6 first + else + dcOptions = dcOptions.OrderBy(dc => dc.flags & DcOption.Flags.ipv6); // list ipv4 first + var dcOption = dcOptions.FirstOrDefault() ?? throw new ApplicationException($"Could not find adequate dc_option for DC {dcId}"); + return dcSession = _session.DCSessions[dcId] = new Session.DCSession { DataCenter = dcOption, Id = Helpers.RandomLong() }; + } + + internal DateTime MsgIdToStamp(long serverMsgId) + => new((serverMsgId >> 32) * 10000000 - _dcSession.ServerTicksOffset + 621355968000000000L, DateTimeKind.Utc); + + internal (long msgId, int seqno) NewMsgId(bool isContent) + { + int seqno; + long msgId = DateTime.UtcNow.Ticks + _dcSession.ServerTicksOffset - 621355968000000000L; + msgId = msgId * 428 + (msgId >> 24) * 25110956; // approximately unixtime*2^32 and divisible by 4 + lock (_session) + { + if (msgId <= _dcSession.LastSentMsgId) msgId = _dcSession.LastSentMsgId += 4; else _dcSession.LastSentMsgId = msgId; + seqno = isContent ? _dcSession.Seqno++ * 2 + 1 : _dcSession.Seqno * 2; + _session.Save(); + } + return (msgId, seqno); + } + + private async Task KeepAlive(CancellationToken ct) + { + int ping_id = _random.Next(); + while (!ct.IsCancellationRequested) + { + await Task.Delay(60000, ct); + if (_saltChangeCounter > 0) --_saltChangeCounter; +#if DEBUG + await this.PingDelayDisconnect(ping_id++, 300); +#else + await this.PingDelayDisconnect(ping_id++, 75); +#endif + } + } + + private async Task Reactor(NetworkStream stream, CancellationTokenSource cts) { const int MinBufferSize = 1024; var data = new byte[MinBufferSize]; - while (!ct.IsCancellationRequested) + while (!cts.IsCancellationRequested) { - IObject obj = null; + ITLObject obj = null; try { - if (await stream.FullReadAsync(data, 4, ct) != 4) - throw new WTException(ConnectionShutDown); -#if OBFUSCATION - _recvCtr.EncryptDecrypt(data.AsSpan(0, 4)); -#endif + if (await FullReadAsync(stream, data, 4, cts.Token) != 4) + throw new ApplicationException("Could not read payload length : Connection shut down"); int payloadLen = BinaryPrimitives.ReadInt32LittleEndian(data); - if (payloadLen <= 0) - throw new WTException("Could not read frame data : Invalid payload length"); - else if (payloadLen > data.Length) + if (payloadLen > data.Length) data = new byte[payloadLen]; else if (Math.Max(payloadLen, MinBufferSize) < data.Length / 4) data = new byte[Math.Max(payloadLen, MinBufferSize)]; - if (await stream.FullReadAsync(data, payloadLen, ct) != payloadLen) - throw new WTException("Could not read frame data : Connection shut down"); -#if OBFUSCATION - _recvCtr.EncryptDecrypt(data.AsSpan(0, payloadLen)); -#endif + if (await FullReadAsync(stream, data, payloadLen, cts.Token) != payloadLen) + throw new ApplicationException("Could not read frame data : Connection shut down"); + obj = ReadFrame(data, payloadLen); } catch (Exception ex) // an exception in RecvAsync is always fatal { - if (ct.IsCancellationRequested) return; - bool disconnectedAltDC = !IsMainDC && ex is WTException { 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}"); + if (cts.IsCancellationRequested) return; + Helpers.Log(5, $"An exception occured in the reactor: {ex}"); var oldSemaphore = _sendSemaphore; - await oldSemaphore.WaitAsync(ct); // prevent any sending while we reconnect + await oldSemaphore.WaitAsync(cts.Token); // prevent any sending while we reconnect var reactorError = new ReactorError { Exception = ex }; try { - lock (_msgsToAck) _msgsToAck.Clear(); - await ResetAsync(false, false); _reactorReconnects = (_reactorReconnects + 1) % MaxAutoReconnects; - if (disconnectedAltDC && _pendingRpcs.Count <= 1) - if (_pendingRpcs.Values.FirstOrDefault() is not Rpc rpc || rpc.type == typeof(Pong)) - _reactorReconnects = 0; - if (_reactorReconnects == 0) + if (_reactorReconnects != 0) + { + lock (_msgsToAck) _msgsToAck.Clear(); + Reset(false, false); + await Task.Delay(5000); + await ConnectAsync(); // start a new reactor after 5 secs + lock (_pendingRequests) // retry all pending requests + { + foreach (var (_, tcs) in _pendingRequests.Values) + tcs.SetResult(reactorError); + _pendingRequests.Clear(); + _bareRequest = 0; + } + } + else throw; -#pragma warning disable CA2016 - await Task.Delay(5000); -#pragma warning restore CA2016 - 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.TrySetResult(reactorError); // this leads to a retry (see Invoke method) - _pendingRpcs.Clear(); - _bareRpc = null; - } - if (IsMainDC) - { - var updatesState = await this.Updates_GetState(); // this call reenables incoming Updates - RaiseUpdates(updatesState); - } } - catch (Exception e) when (e is not ObjectDisposedException) + catch { - if (IsMainDC) - RaiseUpdates(reactorError); - lock (_pendingRpcs) // abort all pending requests + lock (_pendingRequests) // abort all pending requests { - foreach (var rpc in _pendingRpcs.Values) - rpc.tcs.TrySetException(ex); - _pendingRpcs.Clear(); - _bareRpc = null; + foreach (var (_, tcs) in _pendingRequests.Values) + tcs.SetException(ex); + _pendingRequests.Clear(); + _bareRequest = 0; } + OnUpdate(reactorError); } finally { oldSemaphore.Release(); } + cts.Cancel(); // always stop the reactor } if (obj != null) await HandleMessageAsync(obj); } } - internal DateTime MsgIdToStamp(long serverMsgId) - => new((serverMsgId >> 32) * 10000000 - _dcSession.serverTicksOffset + 621355968000000000L, DateTimeKind.Utc); - - internal IObject ReadFrame(byte[] data, int dataLen) + internal ITLObject ReadFrame(byte[] data, int dataLen) { - if (dataLen < 8 && data[3] == 0xFF) + if (dataLen == 4 && data[3] == 0xFF) { int error_code = -BinaryPrimitives.ReadInt32LittleEndian(data); throw new RpcException(error_code, TransportError(error_code)); } if (dataLen < 24) // authKeyId+msgId+length+ctorNb | authKeyId+msgKey - throw new WTException($"Packet payload too small: {dataLen}"); + throw new ApplicationException($"Packet payload too small: {dataLen}"); long authKeyId = BinaryPrimitives.ReadInt64LittleEndian(data); - if (authKeyId != _dcSession.authKeyID) - throw new WTException($"Received a packet encrypted with unexpected key {authKeyId:X}"); + if (authKeyId != _dcSession.AuthKeyID) + throw new ApplicationException($"Received a packet encrypted with unexpected key {authKeyId:X}"); if (authKeyId == 0) // Unencrypted message { - using var reader = new BinaryReader(new MemoryStream(data, 8, dataLen - 8)); + using var reader = new TL.BinaryReader(new MemoryStream(data, 8, dataLen - 8), this); long msgId = _lastRecvMsgId = reader.ReadInt64(); - if ((msgId & 1) == 0) throw new WTException($"Invalid server msgId {msgId}"); + if ((msgId & 1) == 0) throw new ApplicationException($"Invalid server msgId {msgId}"); int length = reader.ReadInt32(); - dataLen -= 20; - if (length > dataLen || dataLen - length > (_paddedMode ? 256 : 0)) - throw new WTException($"Unexpected unencrypted/padding length {dataLen} - {length}"); + if (length != dataLen - 20) throw new ApplicationException($"Unexpected unencrypted length {length} != {dataLen - 20}"); var obj = reader.ReadTLObject(); Helpers.Log(1, $"{_dcSession.DcID}>Receiving {obj.GetType().Name,-40} {MsgIdToStamp(msgId):u} clear{((msgId & 2) == 0 ? "" : " NAR")}"); - if (_bareRpc == null) throw new WTException("Shouldn't receive unencrypted packet at this point"); return obj; } else { - byte[] decrypted_data = EncryptDecryptMessage(data.AsSpan(24, (dataLen - 24) & ~0xF), false, 8, _dcSession.AuthKey, data, 8, _sha256Recv); +#if MTPROTO1 + byte[] decrypted_data = EncryptDecryptMessage(data.AsSpan(24, dataLen - 24), false, _dcSession.AuthKey, data, 8, _sha1Recv); +#else + byte[] decrypted_data = EncryptDecryptMessage(data.AsSpan(24, dataLen - 24), false, _dcSession.AuthKey, data, 8, _sha256Recv); +#endif if (decrypted_data.Length < 36) // header below+ctorNb - throw new WTException($"Decrypted packet too small: {decrypted_data.Length}"); + throw new ApplicationException($"Decrypted packet too small: {decrypted_data.Length}"); + using var reader = new TL.BinaryReader(new MemoryStream(decrypted_data), this); + var serverSalt = reader.ReadInt64(); // int64 salt + var sessionId = reader.ReadInt64(); // int64 session_id + var msgId = _lastRecvMsgId = reader.ReadInt64();// int64 message_id + var seqno = reader.ReadInt32(); // int32 msg_seqno + var length = reader.ReadInt32(); // int32 message_data_length + var msgStamp = MsgIdToStamp(msgId); + + if (serverSalt != _dcSession.Salt) // salt change happens every 30 min + { + Helpers.Log(2, $"{_dcSession.DcID}>Server salt has changed: {_dcSession.Salt:X} -> {serverSalt:X}"); + _dcSession.Salt = serverSalt; + _saltChangeCounter += 20; // counter is decreased by KeepAlive every minute (we have margin of 10) + if (_saltChangeCounter >= 30) + throw new ApplicationException($"Server salt changed too often! Security issue?"); + } + if (sessionId != _dcSession.Id) throw new ApplicationException($"Unexpected session ID {sessionId} != {_dcSession.Id}"); + if ((msgId & 1) == 0) throw new ApplicationException($"Invalid server msgId {msgId}"); + if ((seqno & 1) != 0) lock (_msgsToAck) _msgsToAck.Add(msgId); + if ((msgStamp - DateTime.UtcNow).Ticks / TimeSpan.TicksPerSecond is > 30 or < -300) + return null; +#if MTPROTO1 + if (decrypted_data.Length - 32 - length is < 0 or > 15) throw new ApplicationException($"Unexpected decrypted message_data_length {length} / {decrypted_data.Length - 32}"); + if (!data.AsSpan(8, 16).SequenceEqual(_sha1Recv.ComputeHash(decrypted_data, 0, 32 + length).AsSpan(4))) + throw new ApplicationException($"Mismatch between MsgKey & decrypted SHA1"); +#else + if (decrypted_data.Length - 32 - length is < 12 or > 1024) throw new ApplicationException($"Unexpected decrypted message_data_length {length} / {decrypted_data.Length - 32}"); + _sha256Recv.Initialize(); _sha256Recv.TransformBlock(_dcSession.AuthKey, 96, 32, null, 0); _sha256Recv.TransformFinalBlock(decrypted_data, 0, decrypted_data.Length); if (!data.AsSpan(8, 16).SequenceEqual(_sha256Recv.Hash.AsSpan(8, 16))) - throw new WTException("Mismatch between MsgKey & decrypted SHA256"); - _sha256Recv.Initialize(); - using var reader = new BinaryReader(new MemoryStream(decrypted_data)); - var serverSalt = reader.ReadInt64(); // int64 salt - var sessionId = reader.ReadInt64(); // int64 session_id - var msgId = reader.ReadInt64(); // int64 message_id - var seqno = reader.ReadInt32(); // int32 msg_seqno - var length = reader.ReadInt32(); // int32 message_data_length - - if (length < 0 || length % 4 != 0) throw new WTException($"Invalid message_data_length: {length}"); - if (decrypted_data.Length - 32 - length is < 12 or > 1024) throw new WTException($"Invalid message padding length: {decrypted_data.Length - 32}-{length}"); - if (sessionId != _dcSession.id) throw new WTException($"Unexpected session ID: {sessionId} != {_dcSession.id}"); - if ((msgId & 1) == 0) throw new WTException($"msg_id is not odd: {msgId}"); - if (!_dcSession.CheckNewMsgId(msgId)) - { - Helpers.Log(3, $"{_dcSession.DcID}>Ignoring duplicate or old msg_id {msgId}"); - return null; - } - var utcNow = DateTime.UtcNow; - if (_lastRecvMsgId == 0) // resync ServerTicksOffset on first message - _dcSession.serverTicksOffset = (msgId >> 32) * 10000000 - utcNow.Ticks + 621355968000000000L; - var msgStamp = MsgIdToStamp(_lastRecvMsgId = msgId); - long deltaTicks = (msgStamp - utcNow).Ticks; - if (deltaTicks is > 0) - if (deltaTicks < Ticks5Secs) // resync if next message is less than 5 seconds in the future - _dcSession.serverTicksOffset += deltaTicks; - else if (_dcSession.serverTicksOffset < -Ticks5Secs && deltaTicks + _dcSession.serverTicksOffset < 0) - _dcSession.serverTicksOffset += deltaTicks; - if (serverSalt != _dcSession.Salt && serverSalt != _dcSession.OldSalt && serverSalt != _dcSession.Salts?.Values.ElementAtOrDefault(1)) - { - Helpers.Log(3, $"{_dcSession.DcID}>Server salt has changed: {_dcSession.Salt:X} -> {serverSalt:X}"); - _dcSession.OldSalt = _dcSession.Salt; - _dcSession.Salt = serverSalt; - lock (_session) _session.Save(); - if (++_saltChangeCounter >= 10) - throw new WTException("Server salt changed too often! Security issue?"); - CheckSalt(); - } - if ((seqno & 1) != 0) lock (_msgsToAck) _msgsToAck.Add(msgId); - + throw new ApplicationException($"Mismatch between MsgKey & decrypted SHA1"); +#endif var ctorNb = reader.ReadUInt32(); - if (ctorNb != Layer.BadMsgCtor && deltaTicks / TimeSpan.TicksPerSecond is > 30 or < -300) - { // msg_id values that belong over 30 seconds in the future or over 300 seconds in the past are to be ignored. - Helpers.Log(1, $"{_dcSession.DcID}>Ignoring 0x{ctorNb:X8} because of wrong timestamp {msgStamp:u} - {utcNow:u} Δ={new TimeSpan(_dcSession.serverTicksOffset):c}"); - return null; - } - try + if (ctorNb == Layer.MsgContainerCtor) { - if (ctorNb == Layer.MsgContainerCtor) - { - Helpers.Log(1, $"{_dcSession.DcID}>Receiving {"MsgContainer",-40} {msgStamp:u} (svc)"); - return ReadMsgContainer(reader); - } - else if (ctorNb == Layer.RpcResultCtor) - { - Helpers.Log(1, $"{_dcSession.DcID}>Receiving {"RpcResult",-40} {msgStamp:u}"); - return ReadRpcResult(reader); - } + Helpers.Log(1, $"{_dcSession.DcID}>Receiving {"MsgContainer",-40} {msgStamp:u} (svc)"); + return ReadMsgContainer(reader); + } + else if (ctorNb == Layer.RpcResultCtor) + { + Helpers.Log(1, $"{_dcSession.DcID}>Receiving {"RpcResult",-40} {msgStamp:u}"); + return ReadRpcResult(reader); + } + else + { + var obj = reader.ReadTLObject(ctorNb); + Helpers.Log(1, $"{_dcSession.DcID}>Receiving {obj.GetType().Name,-40} {msgStamp:u} {((seqno & 1) != 0 ? "" : "(svc)")} {((msgId & 2) == 0 ? "" : "NAR")}"); + return obj; + } + } + + static string TransportError(int error_code) => error_code switch + { + 404 => "Auth key not found", + 429 => "Transport flood", + _ => ((HttpStatusCode)error_code).ToString(), + }; + } + + private static async Task FullReadAsync(Stream stream, byte[] buffer, int length, CancellationToken ct = default) + { + for (int offset = 0; offset < length;) + { + var read = await stream.ReadAsync(buffer, offset, length - offset, ct); + if (read == 0) return offset; + offset += read; + } + return length; + } + + private async Task SendAsync(ITLFunction func, bool isContent) + { + if (_dcSession.AuthKeyID != 0 && isContent && CheckMsgsToAck() is MsgsAck msgsAck) + { + var ackMsg = NewMsgId(false); + var mainMsg = NewMsgId(true); + await SendAsync(MakeContainer((MakeFunction(msgsAck), ackMsg), (func, mainMsg)), false); + return mainMsg.msgId; + } + (long msgId, int seqno) = NewMsgId(isContent && _dcSession.AuthKeyID != 0); + await _sendSemaphore.WaitAsync(); + try + { + using var memStream = new MemoryStream(1024); + using var writer = new BinaryWriter(memStream, Encoding.UTF8); + writer.Write(0); // int32 payload_len (to be patched with payload length) + + if (_dcSession.AuthKeyID == 0) // send unencrypted message + { + writer.Write(0L); // int64 auth_key_id = 0 (Unencrypted) + writer.Write(msgId); // int64 message_id + writer.Write(0); // int32 message_data_length (to be patched) + var typeName = func(writer); // bytes message_data + Helpers.Log(1, $"{_dcSession.DcID}>Sending {typeName}..."); + BinaryPrimitives.WriteInt32LittleEndian(memStream.GetBuffer().AsSpan(20), (int)memStream.Length - 24); // patch message_data_length + } + else + { + using var clearStream = new MemoryStream(1024); + using var clearWriter = new BinaryWriter(clearStream, Encoding.UTF8); +#if MTPROTO1 + const int prepend = 0; +#else + const int prepend = 32; + clearWriter.Write(_dcSession.AuthKey, 88, prepend); +#endif + clearWriter.Write(_dcSession.Salt); // int64 salt + clearWriter.Write(_dcSession.Id); // int64 session_id + clearWriter.Write(msgId); // int64 message_id + clearWriter.Write(seqno); // int32 msg_seqno + clearWriter.Write(0); // int32 message_data_length (to be patched) + var typeName = func(clearWriter); // bytes message_data + if ((seqno & 1) != 0) + Helpers.Log(1, $"{_dcSession.DcID}>Sending {typeName,-40} #{(short)msgId.GetHashCode():X4}"); else - { - var obj = reader.ReadTLObject(ctorNb); - Helpers.Log(1, $"{_dcSession.DcID}>Receiving {obj.GetType().Name,-40} {msgStamp:u} {((seqno & 1) != 0 ? "" : "(svc)")} {((msgId & 2) == 0 ? "" : "NAR")}"); - return obj; - } - } - catch (Exception ex) - { - Helpers.Log(4, $"While deserializing frame #{ctorNb:x}: " + ex.ToString()); - return null; + Helpers.Log(1, $"{_dcSession.DcID}>Sending {typeName,-40} {MsgIdToStamp(msgId):u} (svc)"); + int clearLength = (int)clearStream.Length - prepend; // length before padding (= 32 + message_data_length) + int padding = (0x7FFFFFF0 - clearLength) % 16; +#if !MTPROTO1 + padding += _random.Next(1, 64) * 16; // MTProto 2.0 padding must be between 12..1024 with total length divisible by 16 +#endif + clearStream.SetLength(prepend + clearLength + padding); + byte[] clearBuffer = clearStream.GetBuffer(); + BinaryPrimitives.WriteInt32LittleEndian(clearBuffer.AsSpan(prepend + 28), clearLength - 32); // patch message_data_length + RNG.GetBytes(clearBuffer, prepend + clearLength, padding); +#if MTPROTO1 + var msgKeyLarge = _sha1.ComputeHash(clearBuffer, 0, clearLength); // padding excluded from computation! + const int msgKeyOffset = 4; // msg_key = low 128-bits of SHA1(plaintext) + byte[] encrypted_data = EncryptDecryptMessage(clearBuffer.AsSpan(prepend, clearLength + padding), true, _dcSession.AuthKey, msgKeyLarge, msgKeyOffset, _sha1); +#else + var msgKeyLarge = _sha256.ComputeHash(clearBuffer, 0, prepend + clearLength + padding); + const int msgKeyOffset = 8; // msg_key = middle 128-bits of SHA256(authkey_part+plaintext+padding) + byte[] encrypted_data = EncryptDecryptMessage(clearBuffer.AsSpan(prepend, clearLength + padding), true, _dcSession.AuthKey, msgKeyLarge, msgKeyOffset, _sha256); +#endif + + writer.Write(_dcSession.AuthKeyID); // int64 auth_key_id + writer.Write(msgKeyLarge, msgKeyOffset, 16); // int128 msg_key + writer.Write(encrypted_data); // bytes encrypted_data } + var buffer = memStream.GetBuffer(); + int frameLength = (int)memStream.Length; + BinaryPrimitives.WriteInt32LittleEndian(buffer, frameLength - 4); // patch payload_len with correct value + //TODO: support Transport obfuscation? + + await _networkStream.WriteAsync(memStream.GetBuffer(), 0, frameLength); + _lastSentMsg = func; } + finally + { + _sendSemaphore.Release(); + } + return msgId; } - static string TransportError(int error_code) => error_code switch - { - 404 => "Auth key not found", - 429 => "Transport flood", - 444 => "Invalid DC", - _ => Enum.GetName(typeof(HttpStatusCode), error_code) ?? "Transport error" - }; - - internal void CheckSalt() - { - lock (_session) + private static ITLFunction MakeFunction(ITLObject msg) + => writer => { - _dcSession.Salts ??= []; - if (_dcSession.Salts.Count != 0) - { - var keys = _dcSession.Salts.Keys; - if (keys[^1] == DateTime.MaxValue) return; // GetFutureSalts ongoing - var now = DateTime.UtcNow.AddTicks(_dcSession.serverTicksOffset - TimeSpan.TicksPerMinute); - bool removed = false; - for (; keys.Count > 1 && keys[1] < now; _dcSession.OldSalt = _dcSession.Salt, _dcSession.Salt = _dcSession.Salts.Values[0], removed = true) - _dcSession.Salts.RemoveAt(0); - if (removed) _session.Save(); - if (_dcSession.Salts.Count > 48) return; - } - _dcSession.Salts[DateTime.MaxValue] = 0; - } - Task.Delay(5000).ContinueWith(_ => this.GetFutureSalts(128).ContinueWith(gfs => - { - lock (_session) - { - _dcSession.Salts.Remove(DateTime.MaxValue); - foreach (var entry in gfs.Result.salts) - _dcSession.Salts[entry.valid_since] = entry.salt; - _dcSession.OldSalt = _dcSession.Salt; - _dcSession.Salt = _dcSession.Salts.Values[0]; - _session.Save(); - } - })); - } + writer.WriteTLObject(msg); + return msg.GetType().Name; + }; - internal MsgContainer ReadMsgContainer(BinaryReader reader) + internal MsgContainer ReadMsgContainer(TL.BinaryReader reader) { int count = reader.ReadInt32(); - var messages = new List<_Message>(count); + var array = new _Message[count]; for (int i = 0; i < count; i++) { - var msg = new _Message(reader.ReadInt64(), reader.ReadInt32(), null) { bytes = reader.ReadInt32() }; - messages.Add(msg); - if ((msg.seqno & 1) != 0) lock (_msgsToAck) _msgsToAck.Add(msg.msg_id); + var msg = array[i] = new _Message + { + msg_id = reader.ReadInt64(), + seqno = reader.ReadInt32(), + bytes = reader.ReadInt32(), + }; + if ((msg.seqno & 1) != 0) lock(_msgsToAck) _msgsToAck.Add(msg.msg_id); var pos = reader.BaseStream.Position; try { var ctorNb = reader.ReadUInt32(); if (ctorNb == Layer.RpcResultCtor) { - Helpers.Log(1, $" → {"RpcResult",-38} {MsgIdToStamp(msg.msg_id):u}"); + Helpers.Log(1, $" → {"RpcResult",-38} {MsgIdToStamp(msg.msg_id):u}"); msg.body = ReadRpcResult(reader); } else { var obj = msg.body = reader.ReadTLObject(ctorNb); - Helpers.Log(1, $" → {obj.GetType().Name,-38} {MsgIdToStamp(msg.msg_id):u} {((msg.seqno & 1) != 0 ? "" : "(svc)")} {((msg.msg_id & 2) == 0 ? "" : "NAR")}"); + Helpers.Log(1, $" → {obj.GetType().Name,-38} {MsgIdToStamp(msg.msg_id):u} {((msg.seqno & 1) != 0 ? "" : "(svc)")} {((msg.msg_id & 2) == 0 ? "" : "NAR")}"); } } catch (Exception ex) { Helpers.Log(4, "While deserializing vector<%Message>: " + ex.ToString()); } - reader.BaseStream.Position = pos + msg.bytes; + reader.BaseStream.Position = pos + array[i].bytes; } - return new MsgContainer { messages = messages }; + return new MsgContainer { messages = array }; } - private RpcResult ReadRpcResult(BinaryReader reader) + private RpcResult ReadRpcResult(TL.BinaryReader reader) { long msgId = reader.ReadInt64(); - var rpc = PullPendingRequest(msgId); + var (type, tcs) = PullPendingRequest(msgId); object result; - if (rpc != null) + if (tcs != null) { - try - { - if (!rpc.type.IsArray) - result = reader.ReadTLValue(rpc.type); - else - { - var peek = reader.ReadUInt32(); - if (peek == Layer.RpcErrorCtor) - result = reader.ReadTLObject(Layer.RpcErrorCtor); - else if (peek == Layer.GZipedCtor) - result = reader.ReadTLGzipped(rpc.type); - else - { - reader.BaseStream.Position -= 4; - result = reader.ReadTLVector(rpc.type); - } - } - if (rpc.type.IsEnum) result = Enum.ToObject(rpc.type, result); - if (result is RpcError rpcError) - Helpers.Log(4, $" → RpcError {rpcError.error_code,3} {rpcError.error_message,-24} #{(short)msgId.GetHashCode():X4}"); - else - { - Helpers.Log(1, $" → {result?.GetType().Name,-37} #{(short)msgId.GetHashCode():X4}"); - CheckRaiseOwnUpdates(result); - } - - rpc.tcs.SetResult(result); - } - catch (Exception ex) - { - rpc.tcs.SetException(ex); - throw; - } + result = reader.ReadTLValue(type); + if (type.IsEnum) result = Enum.ToObject(type, result); + Log(1, ""); + tcs.SetResult(result); } else { - var ctorNb = reader.ReadUInt32(); - if (ctorNb == Layer.VectorCtor) - { - reader.BaseStream.Position -= 4; - result = reader.ReadTLVector(typeof(IObject[])); - } - else if (ctorNb == (uint)Bool.False) result = false; - else if (ctorNb == (uint)Bool.True) result = true; - else - { - result = reader.ReadTLObject(ctorNb); - CheckRaiseOwnUpdates(result); - } - - var typeName = result?.GetType().Name; + result = reader.ReadTLObject(); if (MsgIdToStamp(msgId) >= _session.SessionStart) - Helpers.Log(4, $" → {typeName,-37} for unknown msgId #{(short)msgId.GetHashCode():X4}"); + Log(4, "for unknown msgId "); else - Helpers.Log(1, $" → {typeName,-37} for past msgId #{(short)msgId.GetHashCode():X4}"); + Log(1, "for past msgId "); } return new RpcResult { req_msg_id = msgId, result = result }; + + void Log(int level, string msgIdprefix) + { + if (result is RpcError rpcError) + Helpers.Log(4, $" → RpcError {rpcError.error_code,3} {rpcError.error_message,-24} {msgIdprefix}#{(short)msgId.GetHashCode():X4}"); + else + Helpers.Log(level, $" → {result?.GetType().Name,-37} {msgIdprefix}#{(short)msgId.GetHashCode():X4}"); + } } - private sealed class Rpc + private (Type type, TaskCompletionSource tcs) PullPendingRequest(long msgId) { - internal Type type; - internal TaskCompletionSource tcs = new(TaskCreationOptions.RunContinuationsAsynchronously); - internal long msgId; - public Task Task => tcs.Task; - } - - private Rpc PullPendingRequest(long msgId) - { - Rpc request; - lock (_pendingRpcs) - if (_pendingRpcs.TryGetValue(msgId, out request)) - _pendingRpcs.Remove(msgId); + (Type type, TaskCompletionSource tcs) request; + lock (_pendingRequests) + if (_pendingRequests.TryGetValue(msgId, out request)) + _pendingRequests.Remove(msgId); return request; } - private async Task HandleMessageAsync(IObject obj) + internal async Task CallBareAsync(ITLFunction request) { - if (_bareRpc != null) + if (_bareRequest != 0) throw new ApplicationException("A bare request is already undergoing"); + var msgId = await SendAsync(request, false); + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + lock (_pendingRequests) + _pendingRequests[msgId] = (typeof(X), tcs); + _bareRequest = msgId; + return (X)await tcs.Task; + } + + public async Task CallAsync(ITLFunction request) + { + retry: + var msgId = await SendAsync(request, true); + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + lock (_pendingRequests) + _pendingRequests[msgId] = (typeof(X), tcs); + var result = await tcs.Task; + switch (result) { - var rpc = PullPendingRequest(_bareRpc.msgId); - if ((rpc?.type.IsAssignableFrom(obj.GetType())) == true) - { - _bareRpc = null; - rpc.tcs.SetResult(obj); - return; - } - else if (_dcSession.authKeyID == 0) - throw new WTException($"Received a {obj.GetType()} incompatible with expected bare {rpc?.type}"); - lock (_pendingRpcs) - _pendingRpcs[_bareRpc.msgId] = _bareRpc; + case X resultX: return resultX; + case RpcError rpcError: + int number; + if (rpcError.error_code == 303 && ((number = rpcError.error_message.IndexOf("_MIGRATE_")) > 0)) + { + if (!rpcError.error_message.StartsWith("FILE_")) + { + number = int.Parse(rpcError.error_message[(number + 9)..]); + // this is a hack to migrate _dcSession in-place (staying in same Client): + Session.DCSession dcSession; + lock (_session) + dcSession = GetOrCreateDCSession(number); + Reset(false, false); + _session.MainDC = number; + _dcSession.Client = null; + _dcSession = dcSession; + _dcSession.Client = this; + await ConnectAsync(); + goto retry; + } + } + else if (rpcError.error_code == 420 && ((number = rpcError.error_message.IndexOf("_WAIT_")) > 0)) + { + number = int.Parse(rpcError.error_message[(number + 6)..]); + if (number <= 60) + { + await Task.Delay(number * 1000); + goto retry; + } + } + else if (rpcError.error_code == 500 && rpcError.error_message == "AUTH_RESTART") + { + _session.User = null; // force a full login authorization flow, next time + _session.Save(); + } + throw new RpcException(rpcError.error_code, rpcError.error_message); + case ReactorError: + goto retry; + default: + throw new ApplicationException($"{request.GetType().Name} call got a result of type {result.GetType().Name} instead of {typeof(X).Name}"); } + } + + private MsgsAck CheckMsgsToAck() + { + lock (_msgsToAck) + { + if (_msgsToAck.Count == 0) return null; + var msgsAck = new MsgsAck { msg_ids = _msgsToAck.ToArray() }; + _msgsToAck.Clear(); + return msgsAck; + } + } + + private ITLFunction MakeContainer(params (ITLFunction func, (long msgId, int seqno))[] msgs) + => writer => + { + writer.Write(0x73F1F8DC); + writer.Write(msgs.Length); + foreach (var (func, (msgId, seqno)) in msgs) + { + writer.Write(msgId); + writer.Write(seqno); + var patchPos = writer.BaseStream.Position; + writer.Write(0); + var typeName = func(writer); + if ((seqno & 1) != 0) + Helpers.Log(1, $" Sending → {typeName,-40} #{(short)msgId.GetHashCode():X4}"); + else + Helpers.Log(1, $" Sending → {typeName,-40} {MsgIdToStamp(msgId):u} (svc)"); + writer.BaseStream.Position = patchPos; + writer.Write((int)(writer.BaseStream.Length - patchPos - 4)); // patch bytes field + writer.Seek(0, SeekOrigin.End); + } + return "as MsgContainer"; + }; + + private async Task HandleMessageAsync(ITLObject obj) + { switch (obj) { case MsgContainer container: @@ -726,12 +731,24 @@ namespace WTelegram if (msgCopy?.orig_message?.body != null) await HandleMessageAsync(msgCopy.orig_message.body); break; - case TL.Methods.Ping ping: - _ = SendAsync(new Pong { msg_id = _lastRecvMsgId, ping_id = ping.ping_id }, false); + case BadServerSalt badServerSalt: + _dcSession.Salt = badServerSalt.new_server_salt; + if (badServerSalt.bad_msg_id == _dcSession.LastSentMsgId) + { + var newMsgId = await SendAsync(_lastSentMsg, true); + lock (_pendingRequests) + if (_pendingRequests.TryGetValue(badServerSalt.bad_msg_id, out var t)) + { + _pendingRequests.Remove(badServerSalt.bad_msg_id); + _pendingRequests[newMsgId] = t; + } + } + break; + case Ping ping: + _ = SendAsync(MakeFunction(new Pong { msg_id = _lastRecvMsgId, ping_id = ping.ping_id }), false); break; case Pong pong: SetResult(pong.msg_id, pong); - RaiseUpdates(pong); break; case FutureSalts futureSalts: SetResult(futureSalts.req_msg_id, futureSalts); @@ -741,955 +758,361 @@ namespace WTelegram case MsgsAck msgsAck: break; // we don't do anything with these, for now case BadMsgNotification badMsgNotification: - bool retryRpcs = true; - var logLevel = badMsgNotification.error_code == 48 ? 2 : 4; - Helpers.Log(logLevel, $"BadMsgNotification {badMsgNotification.error_code} for msg #{(short)badMsgNotification.bad_msg_id.GetHashCode():X4}"); - switch (badMsgNotification.error_code) { - case 16: // msg_id too low (most likely, client time is wrong; synchronize it using msg_id notifications and re-send the original message) - case 17: // msg_id too high (similar to the previous case, the client time has to be synchronized, and the message re-sent with the correct msg_id) - _dcSession.lastSentMsgId = 0; - var localTime = DateTime.UtcNow; - _dcSession.serverTicksOffset = (_lastRecvMsgId >> 32) * 10000000 - localTime.Ticks + 621355968000000000L; - Helpers.Log(1, $"Time offset: {_dcSession.serverTicksOffset} | Server: {MsgIdToStamp(_lastRecvMsgId).AddTicks(_dcSession.serverTicksOffset).TimeOfDay} UTC | Local: {localTime.TimeOfDay} UTC"); - break; - case 32: // msg_seqno too low (the server has already received a message with a lower msg_id but with either a higher or an equal and odd seqno) - case 33: // msg_seqno too high (similarly, there is a message with a higher msg_id but with either a lower or an equal and odd seqno) - if (_dcSession.seqno <= 1) - retryRpcs = false; - else - { - await ResetAsync(false, false); - _dcSession.Renew(); - await ConnectAsync(); - } - break; - case 48: // incorrect server salt (in this case, the bad_server_salt response is received with the correct salt, and the message is to be re-sent with it) - _dcSession.OldSalt = _dcSession.Salt; - _dcSession.Salt = ((BadServerSalt)badMsgNotification).new_server_salt; - lock (_session) _session.Save(); - CheckSalt(); - break; - default: - retryRpcs = false; - break; - } - if (retryRpcs) - { - lock (_pendingRpcs) + Helpers.Log(4, $"BadMsgNotification {badMsgNotification.error_code} for msg #{(short)badMsgNotification.bad_msg_id.GetHashCode():X4}"); + var tcs = PullPendingRequest(badMsgNotification.bad_msg_id).tcs; + if (tcs != null) { - foreach (var rpc in _pendingRpcs.Values) - rpc.tcs.TrySetResult(new RpcError { error_code = -503, error_message = $"BadMsgNotification {badMsgNotification.error_code}" }); - _pendingRpcs.Clear(); + if (_bareRequest == badMsgNotification.bad_msg_id) _bareRequest = 0; + tcs.SetException(new ApplicationException($"BadMsgNotification {badMsgNotification.error_code}")); } - RaiseUpdates(badMsgNotification); + else + OnUpdate(obj); } break; default: - RaiseUpdates(obj); + if (_bareRequest != 0) + { + var (type, tcs) = PullPendingRequest(_bareRequest); + if (type?.IsAssignableFrom(obj.GetType()) == true) + { + _bareRequest = 0; + tcs.SetResult(obj); + break; + } + } + OnUpdate(obj); break; } void SetResult(long msgId, object result) { - var rpc = PullPendingRequest(msgId); - if (rpc != null) - rpc.tcs.SetResult(result); + var tcs = PullPendingRequest(msgId).tcs; + if (tcs != null) + tcs.SetResult(result); else - RaiseUpdates(obj); + OnUpdate(obj); } } - private async void RaiseUpdates(IObject obj) + private void OnUpdate(ITLObject obj) { try { - var task = obj is UpdatesBase updates ? OnUpdates?.Invoke(updates) : OnOther?.Invoke(obj); - if (task != null) await task; + Update?.Invoke(obj); } catch (Exception ex) { - Helpers.Log(4, $"{nameof(OnUpdates)}({obj?.GetType().Name}) raised {ex}"); + Helpers.Log(4, $"Update callback on {obj.GetType().Name} raised {ex}"); } } - private void CheckRaiseOwnUpdates(object result) + /// + /// Login as bot (if not already done). + /// Config callback is queried for: bot_token + /// + /// Detail about the logged bot + public async Task LoginBotIfNeeded() { - if (OnOwnUpdates == null) return; - if (result is UpdatesBase updates) - RaiseOwnUpdates(updates); - else if (result is Payments_PaymentResult ppr) - RaiseOwnUpdates(ppr.updates); - else if (result is Messages_InvitedUsers miu) - RaiseOwnUpdates(miu.updates); - } - - private async void RaiseOwnUpdates(UpdatesBase updates) - { - try - { - await OnOwnUpdates?.Invoke(updates); - } - catch (Exception ex) - { - Helpers.Log(4, $"{nameof(OnOwnUpdates)}({updates.GetType().Name}) raised {ex}"); - } - } - - static async Task DefaultTcpHandler(string host, int port) - { - var tcpClient = new TcpClient(); - await tcpClient.ConnectAsync(host, port); - return tcpClient; - } - - private IPEndPoint GetDefaultEndpoint(out int dcId) - { - string addr = Config("server_address"); - dcId = addr.Length > 2 && addr[1] == '>' && addr[0] is > '0' and <= '9' ? addr[0] - '0' : 0; - return Compat.IPEndPoint_Parse(dcId == 0 ? addr : addr[2..]); - } - - /// Establish connection to Telegram servers without negociating a user session - /// Attempt to resume session immediately without issuing Layer/InitConnection/GetConfig (not recommended by default) - /// Usually you shouldn't need to call this method: Use LoginUserIfNeeded instead.
Config callback is queried for: server_address
- /// Most methods of this class are async (Task), so please use - public async Task ConnectAsync(bool quickResume = false) - { - lock (this) - _connecting ??= DoConnectAsync(quickResume); - await _connecting; - } - - private IEnumerable GetDcOptions(int dcId, DcOption.Flags flags) => !flags.HasFlag(DcOption.Flags.media_only) - ? _session.DcOptions.Where(dc => dc.id == dcId && (dc.flags & (DcOption.Flags.cdn | DcOption.Flags.tcpo_only | DcOption.Flags.media_only)) == 0) - .OrderBy(dc => dc.flags ^ flags) - : _session.DcOptions.Where(dc => dc.id == dcId && (dc.flags & (DcOption.Flags.cdn | DcOption.Flags.tcpo_only)) == 0) - .OrderBy(dc => ~dc.flags & DcOption.Flags.media_only).ThenBy(dc => dc.flags ^ flags) - .Select(dc => dc.flags.HasFlag(DcOption.Flags.media_only) ? dc : new DcOption { id = dc.id, port = dc.port, - ip_address = dc.ip_address, secret = dc.secret, flags = dc.flags | DcOption.Flags.media_only }); - - private async Task DoConnectAsync(bool quickResume) - { - _cts = new(); - IPEndPoint endpoint = null; - bool needMigrate = false; - byte[] preamble, secret = null; - int dcId = _dcSession?.DcID ?? 0; - if (dcId == 0) dcId = 2; - if (MTProxyUrl != null) - { -#if OBFUSCATION - if (TLConfig?.test_mode == true) dcId += dcId < 0 ? -10000 : 10000; - var parms = HttpUtility.ParseQueryString(MTProxyUrl[MTProxyUrl.IndexOf('?')..]); - var server = parms["server"]; - int port = int.Parse(parms["port"]); - var str = parms["secret"]; // can be hex or base64 - var secretBytes = secret = str.All("0123456789ABCDEFabcdef".Contains) ? Convert.FromHexString(str) : - System.Convert.FromBase64String(str.Replace('_', '/').Replace('-', '+') + new string('=', (2147483644 - str.Length) % 4)); - var tlsMode = secret.Length >= 21 && secret[0] == 0xEE; - if (tlsMode || (secret.Length == 17 && secret[0] == 0xDD)) - { - _paddedMode = true; - secret = secret[1..17]; - } - else if (secret.Length != 16) throw new ArgumentException("Invalid/unsupported secret"); - Helpers.Log(2, $"Connecting to DC {dcId} via MTProxy {server}:{port}..."); - _tcpClient = await TcpHandler(server, port); - _networkStream = _tcpClient.GetStream(); - if (tlsMode) - _networkStream = await TlsStream.HandshakeAsync(_networkStream, secret, secretBytes[17..], _cts.Token); -#else - throw new Exception("Library was not compiled with OBFUSCATION symbol"); -#endif - } - else if (_httpClient != null) - { - Helpers.Log(2, $"Using HTTP Mode"); - _reactorTask = Task.CompletedTask; - } - else - { - endpoint = _dcSession?.EndPoint ?? GetDefaultEndpoint(out int defaultDc); - Helpers.Log(2, $"Connecting to {endpoint}..."); - TcpClient tcpClient = null; + string botToken = Config("bot_token"); + if (_session.User != null) + { try { - try - { - tcpClient = await TcpHandler(endpoint.Address.ToString(), endpoint.Port); - } - catch (SocketException ex) // cannot connect to target endpoint, try to find an alternate - { - Helpers.Log(4, $"SocketException {ex.SocketErrorCode} ({ex.ErrorCode}): {ex.Message}"); - if (_dcSession?.DataCenter == null) throw; - var triedEndpoints = new HashSet { endpoint }; - if (_session.DcOptions != null) - { - var altOptions = GetDcOptions(_dcSession.DataCenter.id, _dcSession.DataCenter.flags); - // try alternate addresses for this DC - foreach (var dcOption in altOptions) - { - endpoint = new(IPAddress.Parse(dcOption.ip_address), dcOption.port); - if (!triedEndpoints.Add(endpoint)) continue; - Helpers.Log(2, $"Connecting to {endpoint}..."); - try - { - tcpClient = await TcpHandler(endpoint.Address.ToString(), endpoint.Port); - _dcSession.DataCenter = dcOption; - break; - } - catch (SocketException) { } - } - } - if (tcpClient == null) - { - endpoint = GetDefaultEndpoint(out defaultDc); // re-ask callback for an address - if (!triedEndpoints.Add(endpoint)) throw; - needMigrate = _dcSession.DataCenter.id == _session.MainDC && defaultDc != _session.MainDC; - _dcSession.Client = null; - // is it address for a known DCSession? - _dcSession = _session.DCSessions.Values.FirstOrDefault(dcs => dcs.EndPoint.Equals(endpoint)); - if (defaultDc != 0) _dcSession ??= _session.DCSessions.GetValueOrDefault(defaultDc); - _dcSession ??= new(); - _dcSession.Client = this; - _dcSession.DataCenter = null; - Helpers.Log(2, $"Connecting to {endpoint}..."); - tcpClient = await TcpHandler(endpoint.Address.ToString(), endpoint.Port); - } - } - } - catch - { - tcpClient?.Dispose(); - throw; - } - _tcpClient = tcpClient; - _networkStream = _tcpClient.GetStream(); - } - - _dcSession.Salts?.Remove(DateTime.MaxValue); - if (_networkStream != null) - { - byte protocolId = (byte)(_paddedMode ? 0xDD : 0xEE); -#if OBFUSCATION - (_sendCtr, _recvCtr, preamble) = InitObfuscation(secret, protocolId, dcId); -#else - preamble = new byte[] { protocolId, protocolId, protocolId, protocolId }; -#endif - await _networkStream.WriteAsync(preamble, 0, preamble.Length, _cts.Token); - - _reactorTask = Reactor(_networkStream, _cts.Token); - } - _sendSemaphore.Release(); - - try - { - if (_dcSession.authKeyID == 0) - await CreateAuthorizationKey(this, _dcSession); - - if (_networkStream != null) _ = KeepAlive(_cts.Token); - if (quickResume && _dcSession.Layer == Layer.Version && _dcSession.DataCenter != null && _session.MainDC != 0) - TLConfig = new Config { this_dc = _session.MainDC, dc_options = _session.DcOptions }; - else - { - if (_dcSession.Layer != 0 && _dcSession.Layer != Layer.Version) _dcSession.Renew(); - await InitConnection(); - if (_dcSession.DataCenter == null) - { - _dcSession.DataCenter = _session.DcOptions.Where(dc => dc.id == TLConfig.this_dc) - .OrderByDescending(dc => dc.ip_address == endpoint?.Address.ToString()) - .ThenByDescending(dc => dc.port == endpoint?.Port) - .ThenByDescending(dc => dc.flags == (endpoint?.AddressFamily == AddressFamily.InterNetworkV6 ? DcOption.Flags.ipv6 : 0)) - .First(); - _session.DCSessions[TLConfig.this_dc] = _dcSession; - } - if (_session.MainDC == 0) _session.MainDC = TLConfig.this_dc; - else if (needMigrate) await MigrateToDC(_session.MainDC); - } - } - finally - { - if (_reactorTask != null) // client not disposed - lock (_session) _session.Save(); - } - Helpers.Log(2, $"Connected to {(TLConfig.test_mode ? "Test DC" : "DC")} {TLConfig.this_dc}... {TLConfig.flags & (Config.Flags)~0x18E00U}"); - } - - private async Task InitConnection() - { - var initParams = JSONValue.FromJsonElement(System.Text.Json.JsonDocument.Parse(Config("init_params")).RootElement); - TLConfig = await this.InvokeWithLayer(Layer.Version, - new TL.Methods.InitConnection - { - flags = TL.Methods.InitConnection.Flags.has_params, - api_id = _session.ApiId, - device_model = Config("device_model"), - system_version = Config("system_version"), - app_version = Config("app_version"), - system_lang_code = Config("system_lang_code"), - lang_pack = Config("lang_pack"), - lang_code = Config("lang_code"), - params_ = initParams, - query = new TL.Methods.Help_GetConfig() - }); - _dcSession.Layer = Layer.Version; - _session.DcOptions = TLConfig.dc_options; - } - - private async Task KeepAlive(CancellationToken ct) - { - int ping_id = _random.Next(); - while (!ct.IsCancellationRequested) - { - await Task.Delay(Math.Abs(PingInterval) * 1000, ct); - if (PingInterval <= 0) - await this.Ping(ping_id++); - else // see https://core.telegram.org/api/optimisation#grouping-updates -#if DEBUG - await this.PingDelayDisconnect(ping_id++, PingInterval * 5); -#else - await this.PingDelayDisconnect(ping_id++, PingInterval * 5 / 4); -#endif - } - } - - /// Login as a user with given phone number (or resume previous session)
Call this method again to provide additional requested login information
- /// First call should be with phone number
Further calls should be with the requested configuration value - /// Configuration item requested to continue login, or when login is successful
- /// Possible values: verification_code, name (signup), password (2FA), email & email_verification_code (email registration)
- /// - public async Task Login(string loginInfo) - { - if (_loginCfg.request == default) RunLoginAsync(loginInfo); - else - { - if (await _loginCfg.request.Task == null) return null; - loginInfo ??= AskConfig(await _loginCfg.request.Task); - _loginCfg.request = new(); - _loginCfg.response.SetResult(loginInfo); - } - return await _loginCfg.request.Task; - } - private (TaskCompletionSource request, TaskCompletionSource response) _loginCfg; - private async void RunLoginAsync(string phone) - { - _loginCfg.request = new(); - var prevConfig = _config; - _config = what => - { - if (prevConfig(what) is string value) return value; - switch (what) - { - case "phone_number": return phone; - case "last_name": break; - case "first_name": what = "name"; goto case "email"; - case "email": case "email_verification_code": - case "password": case "verification_code": _loginCfg.response = new(); _loginCfg.request.SetResult(what); break; - default: return null; - }; - value = _loginCfg.response.Task.Result; - if (what == "name" && value != null) - { - var lf = value.IndexOf('\n'); - if (lf < 0) lf = value.IndexOf(' '); - _loginCfg.response = new(); - _loginCfg.response.SetResult(lf < 0 ? "" : value[(lf + 1)..]); - value = lf < 0 ? value : value[0..lf]; - return value; - } - return value; - }; - try - { - await ConnectAsync(); // start reactor on the current (UI?) context - // Login logic is executed on TaskScheduler while request TCS are still received on current SynchronizationContext - await Task.Run(() => LoginUserIfNeeded()); - _loginCfg.request.SetResult(null); - } - catch (Exception ex) - { - _loginCfg.request.SetException(ex); - } - finally - { - _config = prevConfig; - } - } - - /// Login as a bot (if not already logged-in). - /// bot token, or if token is provided by Config callback - /// Config callback may be queried for: bot_token - ///
Bots can only call API methods marked with [bots: ✓] in their documentation.
- /// Detail about the logged-in bot - public async Task LoginBotIfNeeded(string bot_token = null) - { - await ConnectAsync(); - string botToken = bot_token ?? Config("bot_token"); - if (_session.UserId != 0) // a user is already logged-in - { - try - { - var users = await this.Users_GetUsers(InputUser.Self); // this call also reenable incoming Updates - var self = users[0] as User; - if (self.id == long.Parse(botToken.Split(':')[0])) - { - _session.UserId = _dcSession.UserId = self.id; - lock (_session) _session.Save(); - RaiseUpdates(self); - return User = self; - } - Helpers.Log(3, $"Current logged user {self.id} mismatched bot_token. Logging out and in..."); + var prevUser = _session.User; + if (prevUser?.id == int.Parse(botToken.Split(':')[0])) + return prevUser; } catch (Exception ex) { - Helpers.Log(4, $"Error while verifying current bot! ({ex.Message}) Proceeding to login..."); + Helpers.Log(4, $"Error deserializing User! ({ex.Message}) Proceeding to login..."); } await this.Auth_LogOut(); - _session.UserId = _dcSession.UserId = 0; - User = null; + _dcSession.UserId = 0; } - var authorization = await this.Auth_ImportBotAuthorization(0, _session.ApiId, _apiHash ??= Config("api_hash"), botToken); - return LoginAlreadyDone(authorization); + var authorization = await this.Auth_ImportBotAuthorization(0, _apiId, _apiHash, botToken); + if (authorization is not Auth_Authorization { user: User user }) + throw new ApplicationException("Failed to get Authorization: " + authorization.GetType().Name); + _session.User = user; + _dcSession.UserId = user.id; + _session.Save(); + return user; } - /// Login as a user (if not already logged-in). - ///
(this method calls ConnectAsync if necessary)
- /// Config callback is queried for: phone_number, verification_code
and eventually first_name, last_name (signup required), password (2FA auth), email & email_verification_code (email registration), user_id (alt validation)
- /// (optional) Preference for verification_code sending - /// Proceed to logout and login if active user session cannot be resumed successfully - /// Detail about the logged-in user - ///
Most methods of this class are async (Task), so please use to get the result
- public async Task LoginUserIfNeeded(CodeSettings settings = null, bool reloginOnFailedResume = true) + /// + /// Login as a user (if not already done). + /// Config callback is queried for: phone_number, verification_code + ///
and eventually first_name, last_name (signup required), password (2FA auth), user_id (alt validation) + ///
+ /// + /// Detail about the logged user + public async Task LoginUserIfNeeded(CodeSettings settings = null) { - await ConnectAsync(); string phone_number = null; - if (_session.UserId != 0) // a user is already logged-in + if (_session.User != null) { try { - var users = await this.Users_GetUsers(InputUser.Self); // this call also reenable incoming Updates - var self = users[0] as User; - // check user_id or phone_number match currently logged-in user - if ((long.TryParse(_config("user_id"), out long id) && (id == -1 || self.id == id)) || - self.phone == string.Concat((phone_number = Config("phone_number")).Where(char.IsDigit))) + var prevUser = _session.User; + var userId = _config("user_id"); // if config prefers to validate current user by its id, use it + if (userId == null || !int.TryParse(userId, out int id) || id != -1 && prevUser.id != id) { - _session.UserId = _dcSession.UserId = self.id; - lock (_session) _session.Save(); - RaiseUpdates(self); - return User = self; + phone_number = Config("phone_number"); // otherwise, validation is done by the phone number + if (prevUser?.phone != string.Concat(phone_number.Where(char.IsDigit))) + prevUser = null; + } + if (prevUser != null) + { + // TODO: implement a more complete Updates gaps handling system? https://core.telegram.org/api/updates + var udpatesState = await this.Updates_GetState(); + OnUpdate(udpatesState); + return prevUser; } - var mismatch = $"Current logged user {self.id} mismatched user_id or phone_number"; - Helpers.Log(3, mismatch); - if (!reloginOnFailedResume) throw new WTException(mismatch); } - catch (RpcException ex) when (reloginOnFailedResume) + catch (Exception ex) { - Helpers.Log(4, $"Error while fetching current user! ({ex.Message})"); + Helpers.Log(4, $"Error deserializing User! ({ex.Message}) Proceeding to login..."); } - Helpers.Log(3, $"Proceeding to logout and login..."); await this.Auth_LogOut(); - _session.UserId = _dcSession.UserId = 0; - User = null; + _dcSession.UserId = 0; } phone_number ??= Config("phone_number"); - Auth_SentCodeBase sentCodeBase; -#pragma warning disable CS0618 // Auth_* methods are marked as obsolete + Auth_SentCode sentCode; try { - sentCodeBase = await this.Auth_SendCode(phone_number, _session.ApiId, _apiHash ??= Config("api_hash"), settings ??= new()); + sentCode = await this.Auth_SendCode(phone_number, _apiId, _apiHash, settings ??= new()); } catch (RpcException ex) when (ex.Code == 500 && ex.Message == "AUTH_RESTART") { - sentCodeBase = await this.Auth_SendCode(phone_number, _session.ApiId, _apiHash, settings); + sentCode = await this.Auth_SendCode(phone_number, _apiId, _apiHash, settings ??= new()); } - Auth_AuthorizationBase authorization = null; - string phone_code_hash = null, email = null; - try - { - if (sentCodeBase is Auth_SentCode { type: Auth_SentCodeTypeSetUpEmailRequired setupEmail } setupSentCode) + Helpers.Log(3, $"A verification code has been sent via {sentCode.type.GetType().Name[17..]}"); + Auth_AuthorizationBase authorization; + for (int retry = 1; ; retry++) + try { - phone_code_hash = setupSentCode.phone_code_hash; - Helpers.Log(3, "A login email is required"); - RaiseUpdates(sentCodeBase); - email = _config("email"); - if (string.IsNullOrEmpty(email)) - sentCodeBase = await this.Auth_ResendCode(phone_number, phone_code_hash); - else - { - var purpose = new EmailVerifyPurposeLoginSetup { phone_number = phone_number, phone_code_hash = phone_code_hash }; - if (email is not "Google" and not "Apple") - { - var sentEmail = await this.Account_SendVerifyEmailCode(purpose, email); - Helpers.Log(3, "An email verification code has been sent to " + sentEmail.email_pattern); - RaiseUpdates(sentEmail); - } - Account_EmailVerified verified = null; - for (int retry = 1; verified == null; retry++) - try - { - var code = await ConfigAsync("email_verification_code"); - verified = await this.Account_VerifyEmail(purpose, EmailVerification(email, code)); - } - catch (RpcException e) when (e.Code == 400 && e.Message is "CODE_INVALID" or "EMAIL_TOKEN_INVALID") - { - Helpers.Log(4, "Wrong email verification code!"); - if (retry >= MaxCodePwdAttempts) throw; - } - if (verified is Account_EmailVerifiedLogin verifiedLogin) // (it should always be) - sentCodeBase = verifiedLogin.sent_code; - } - RaiseUpdates(sentCodeBase); + var verification_code = Config("verification_code"); + authorization = await this.Auth_SignIn(phone_number, sentCode.phone_code_hash, verification_code); + break; } - resent: - if (sentCodeBase is Auth_SentCodeSuccess success) - authorization = success.authorization; - else if (sentCodeBase is Auth_SentCodePaymentRequired paymentRequired) - throw new WTException("Auth_SentCodePaymentRequired unsupported"); - else if (sentCodeBase is Auth_SentCode sentCode) + catch (RpcException e) when (e.Code == 401 && e.Message == "SESSION_PASSWORD_NEEDED") { - phone_code_hash = sentCode.phone_code_hash; - var timeout = DateTime.UtcNow + TimeSpan.FromSeconds(sentCode.timeout); - Helpers.Log(3, $"A verification code has been sent via {sentCode.type.GetType().Name[17..]}"); - RaiseUpdates(sentCode); - if (sentCode.type is Auth_SentCodeTypeFirebaseSms firebaseSms) - { - var token = await ConfigAsync("firebase"); - int index = token?.IndexOf(':') ?? -1; - if (!(index > 0 && token[..index] switch - { - "safety_net_token" => await this.Auth_RequestFirebaseSms(phone_number, phone_code_hash, safety_net_token: token[(index + 1)..]), - "ios_push_secret" => await this.Auth_RequestFirebaseSms(phone_number, phone_code_hash, ios_push_secret: token[(index + 1)..]), - _ => false - })) - { - sentCodeBase = await this.Auth_ResendCode(phone_number, phone_code_hash); - goto resent; - } - } - for (int retry = 1; authorization == null; retry++) - try - { - var verification_code = await ConfigAsync("verification_code"); - if (verification_code == "" && sentCode.next_type != 0) - { - var mustWait = timeout - DateTime.UtcNow; - if (mustWait.Ticks > 0) - { - Helpers.Log(3, $"You must wait {(int)(mustWait.TotalSeconds + 0.5)} more seconds before requesting the code to be sent via {sentCode.next_type}"); - continue; - } - sentCodeBase = await this.Auth_ResendCode(phone_number, phone_code_hash); - goto resent; - } - if (sentCode.type is Auth_SentCodeTypeEmailCode) - authorization = await this.Auth_SignIn(phone_number, phone_code_hash, null, EmailVerification(email ??= _config("email"), verification_code)); - else - authorization = await this.Auth_SignIn(phone_number, phone_code_hash, verification_code); - } - catch (RpcException e) when (e.Code == 400 && e.Message == "PHONE_CODE_INVALID") - { - Helpers.Log(4, "Wrong verification code!"); - if (retry >= MaxCodePwdAttempts) throw; - } - catch (RpcException e) when (e.Code == 401 && e.Message == "SESSION_PASSWORD_NEEDED") - { - authorization = await LoginPasswordNeeded(); - } + var accountPassword = await this.Account_GetPassword(); + Helpers.Log(3, $"This account has enabled 2FA. A password is needed. {accountPassword.hint}"); + var checkPasswordSRP = Check2FA(accountPassword, Config("password")); + authorization = await this.Auth_CheckPassword(checkPasswordSRP); + break; } - - static EmailVerification EmailVerification(string email, string code) => email switch + catch (RpcException e) when (e.Code == 400 && e.Message == "PHONE_CODE_INVALID" && retry != 3) { - "Google" => new EmailVerificationGoogle { token = code }, - "Apple" => new EmailVerificationApple { token = code }, - _ => new EmailVerificationCode { code = code } - }; - } - catch (Exception ex) when (ex is not RpcException { Message: "FLOOD_WAIT_X" }) - { - try { await this.Auth_CancelCode(phone_number, phone_code_hash); } catch { } - throw; - } + continue; + } if (authorization is Auth_AuthorizationSignUpRequired signUpRequired) { var waitUntil = DateTime.UtcNow.AddSeconds(3); - RaiseUpdates(signUpRequired); // give caller the possibility to read and accept TOS + if (signUpRequired.terms_of_service != null) + OnUpdate(signUpRequired.terms_of_service); // give caller the possibility to read and accept TOS var first_name = Config("first_name"); var last_name = Config("last_name"); var wait = waitUntil - DateTime.UtcNow; if (wait > TimeSpan.Zero) await Task.Delay(wait); // we get a FLOOD_WAIT_3 if we SignUp too fast - authorization = await this.Auth_SignUp(phone_number, phone_code_hash, first_name, last_name); + authorization = await this.Auth_SignUp(phone_number, sentCode.phone_code_hash, first_name, last_name); } -#pragma warning restore CS0618 - LoginAlreadyDone(authorization); - if (User.phone != string.Concat(phone_number.Where(char.IsDigit))) - Helpers.Log(3, $"Mismatched phone_number (+{User.phone} != {phone_number}). Fix this to avoid verification code each time"); - return User; + if (authorization is not Auth_Authorization { user: User user }) + throw new ApplicationException("Failed to get Authorization: " + authorization.GetType().Name); + //TODO: find better serialization for User not subject to TL changes? + _session.User = user; + _dcSession.UserId = user.id; + _session.Save(); + return user; } - /// Login via QR code - /// Callback to display the login url as QR code to the user (QRCoder library can help you) - /// (optional) To prevent logging as these user ids - /// If session is already connected to a user, this method will first log out.
You can also check property before calling this method. - /// If you need to abort the method before login is completed - /// Detail about the logged-in user - public async Task LoginWithQRCode(Action qrDisplay, long[] except_ids = null, bool logoutFirst = true, CancellationToken ct = default) +#region TL-Helpers + /// Helper function to upload a file to Telegram + /// an or than can be used in various requests + public Task UploadFileAsync(string pathname) + => UploadFileAsync(File.OpenRead(pathname), Path.GetFileName(pathname)); + + public async Task UploadFileAsync(Stream stream, string filename) { - await ConnectAsync(); - if (logoutFirst && _session.UserId != 0) // a user is already logged-in + using var md5 = MD5.Create(); + using (stream) { - await this.Auth_LogOut(); - _session.UserId = _dcSession.UserId = 0; - User = null; - } - var tcs = new TaskCompletionSource(); - OnUpdates += CatchQRUpdate; - try - { - while (!ct.IsCancellationRequested) + long length = stream.Length; + var isBig = length >= 10 * 1024 * 1024; + const int partSize = 512 * 1024; + int file_total_parts = (int)((length - 1) / partSize) + 1; + long file_id = Helpers.RandomLong(); + int file_part = 0, read; + const int ParallelSends = 10; + var semaphore = new SemaphoreSlim(ParallelSends); + var tasks = new Dictionary(); + bool abort = false; + for (long bytesLeft = length; !abort && bytesLeft != 0; file_part++) { - var ltb = await this.Auth_ExportLoginToken(_session.ApiId, _apiHash ??= Config("api_hash"), except_ids); - retry: - switch (ltb) + var bytes = new byte[Math.Min(partSize, bytesLeft)]; + read = await FullReadAsync(stream, bytes, bytes.Length); + await semaphore.WaitAsync(); + var task = SavePart(file_part, bytes); + lock (tasks) tasks[file_part] = task; + if (!isBig) + md5.TransformBlock(bytes, 0, read, null, 0); + bytesLeft -= read; + if (read < partSize && bytesLeft != 0) throw new ApplicationException($"Failed to fully read stream ({read},{bytesLeft})"); + + async Task SavePart(int file_part, byte[] bytes) { - case Auth_LoginToken lt: - var url = "tg://login?token=" + System.Convert.ToBase64String(lt.token).Replace('/', '_').Replace('+', '-'); - Helpers.Log(3, $"Waiting for this QR code login to be accepted: " + url); - qrDisplay(url); - if (lt.expires - DateTime.UtcNow is { Ticks: >= 0 } delay) - await Task.WhenAny(Task.Delay(delay, ct), tcs.Task); - break; - case Auth_LoginTokenMigrateTo ltmt: - await MigrateToDC(ltmt.dc_id); - ltb = await this.Auth_ImportLoginToken(ltmt.token); - goto retry; - case Auth_LoginTokenSuccess lts: - return LoginAlreadyDone(lts.authorization); + try + { + if (isBig) + await this.Upload_SaveBigFilePart(file_id, file_part, file_total_parts, bytes); + else + await this.Upload_SaveFilePart(file_id, file_part, bytes); + lock (tasks) tasks.Remove(file_part); + } + catch (Exception) + { + abort = true; + } + finally + { + semaphore.Release(); + } } } - ct.ThrowIfCancellationRequested(); - return null; - } - catch (RpcException e) when (e.Code == 401 && e.Message == "SESSION_PASSWORD_NEEDED") - { - return LoginAlreadyDone(await LoginPasswordNeeded()); - } - finally - { - OnUpdates -= CatchQRUpdate; - } - - Task CatchQRUpdate(UpdatesBase updates) - { - if (updates.UpdateList.OfType().Any()) - tcs.TrySetResult(true); - return Task.CompletedTask; + for (int i = 0; i < ParallelSends; i++) + await semaphore.WaitAsync(); // wait for all the remaining parts to be sent + await Task.WhenAll(tasks.Values); // propagate any task exception (tasks should be empty on success) + if (!isBig) md5.TransformFinalBlock(Array.Empty(), 0, 0); + return isBig ? new InputFileBig { id = file_id, parts = file_total_parts, name = filename } + : new InputFile { id = file_id, parts = file_total_parts, name = filename, md5_checksum = md5.Hash }; } } - private async Task LoginPasswordNeeded() + /// Helper function to send a text or media message more easily + /// destination of message + /// media caption + /// media file already uploaded to TG (see ) + /// for automatic detection, "photo" for an inline photo, or a MIME type to send as a document + public Task SendMediaAsync(InputPeer peer, string caption, InputFileBase mediaFile, string mimeType = null, int reply_to_msg_id = 0, MessageEntity[] entities = null, DateTime schedule_date = default, bool disable_preview = false) { - for (int pwdRetry = 1; ; pwdRetry++) + var filename = mediaFile is InputFile iFile ? iFile.name : (mediaFile as InputFileBig)?.name; + mimeType ??= Path.GetExtension(filename).ToLowerInvariant() switch + { + ".jpg" or ".jpeg" or ".png" or ".bmp" => "photo", + ".gif" => "image/gif", + ".webp" => "image/webp", + ".mp4" => "video/mp4", + ".mp3" => "audio/mpeg", + ".wav" => "audio/x-wav", + _ => "", // send as generic document with undefined MIME type + }; + if (mimeType == "photo") + return SendMessageAsync(peer, caption, new InputMediaUploadedPhoto { file = mediaFile }, + reply_to_msg_id, entities, schedule_date, disable_preview); + var attributes = filename == null ? Array.Empty() : new[] { new DocumentAttributeFilename { file_name = filename } }; + return SendMessageAsync(peer, caption, new InputMediaUploadedDocument + { + file = mediaFile, mime_type = mimeType, attributes = attributes + }, reply_to_msg_id, entities, schedule_date, disable_preview); + } + + /// Helper function to send a text or media message + /// destination of message + /// text, or media caption + /// media specification or + public Task SendMessageAsync(InputPeer peer, string text, InputMedia media = null, int reply_to_msg_id = 0, MessageEntity[] entities = null, DateTime schedule_date = default, bool disable_preview = false) + { + if (media == null) + return this.Messages_SendMessage(peer, text, Helpers.RandomLong(), + no_webpage: disable_preview, reply_to_msg_id: reply_to_msg_id, entities: entities, schedule_date: schedule_date); + else + return this.Messages_SendMedia(peer, media, text, Helpers.RandomLong(), + reply_to_msg_id: reply_to_msg_id, entities: entities, schedule_date: schedule_date); + } + + /// Download given photo from Telegram into the outputStream + /// stream to write to. This method does not close/dispose the stream + /// if unspecified, will download the largest version of the photo + public async Task DownloadFileAsync(Photo photo, Stream outputStream, PhotoSizeBase photoSize = null) + { + var fileLocation = photo.ToFileLocation(photoSize ?? photo.LargestPhotoSize); + return await DownloadFileAsync(fileLocation, outputStream, photo.dc_id); + } + + /// Download given document from Telegram into the outputStream + /// stream to write to. This method does not close/dispose the stream + /// if specified, will download the given thumbnail instead of the full document + /// MIME type of the document or thumbnail + public async Task DownloadFileAsync(Document document, Stream outputStream, PhotoSizeBase thumbSize = null) + { + var fileLocation = document.ToFileLocation(thumbSize); + var fileType = await DownloadFileAsync(fileLocation, outputStream, document.dc_id); + return thumbSize == null ? document.mime_type : "image/" + fileType; + } + + /// Download given file from Telegram into the outputStream + /// Telegram file identifier, typically obtained with a .ToFileLocation() call + /// stream to write to. This method does not close/dispose the stream + /// (optional) DC on which the file is stored + public async Task DownloadFileAsync(InputFileLocationBase fileLocation, Stream outputStream, int fileDC = 0) + { + const int ChunkSize = 128 * 1024; + int fileSize = 0; + Upload_File fileData; + var client = fileDC == 0 ? this : await GetClientForDC(fileDC); + do + { + Upload_FileBase fileBase; try { - var accountPassword = await this.Account_GetPassword(); - RaiseUpdates(accountPassword); - var checkPasswordSRP = await Check2FA(accountPassword, () => ConfigAsync("password")); - return await this.Auth_CheckPassword(checkPasswordSRP); + // TODO: speed-up download with multiple parallel getFile (share 10-parallel semaphore with upload) + fileBase = await client.Upload_GetFile(fileLocation, fileSize, ChunkSize); } - catch (RpcException pe) when (pe.Code == 400 && pe.Message == "PASSWORD_HASH_INVALID") + catch (RpcException ex) when (ex.Code == 303 && ex.Message.StartsWith("FILE_MIGRATE_")) { - Helpers.Log(4, "Wrong password!"); - if (pwdRetry >= MaxCodePwdAttempts) throw; + var dcId = int.Parse(ex.Message[13..]); + client = await GetClientForDC(dcId); + fileBase = await client.Upload_GetFile(fileLocation, fileSize, ChunkSize); } + fileData = fileBase as Upload_File; + if (fileData == null) + throw new ApplicationException("Upload_GetFile returned unsupported " + fileBase.GetType().Name); + await outputStream.WriteAsync(fileData.bytes, 0, fileData.bytes.Length); + fileSize += fileData.bytes.Length; + } while (fileData.bytes.Length == ChunkSize); + await outputStream.FlushAsync(); + return fileData.type; } +#endregion - /// [Not recommended] You can use this if you have already obtained a login authorization manually - /// if this was not a successful Auth_Authorization, an exception is thrown - /// the User that was authorized - /// This approach is not recommended because you likely didn't properly handle all aspects of the login process - ///
(transient failures, unnecessary login, 2FA, sign-up required, slowness to respond, verification code resending, encryption key safety, etc..) - ///
Methods LoginUserIfNeeded and LoginBotIfNeeded handle these automatically for you
- [EditorBrowsable(EditorBrowsableState.Never)] - public User LoginAlreadyDone(Auth_AuthorizationBase authorization) + /// Enable the collection of id/access_hash pairs (experimental) + public bool CollectAccessHash { get; set; } + readonly Dictionary> _accessHashes = new(); + public IEnumerable> AllAccessHashesFor() where T : ITLObject + => _accessHashes.GetValueOrDefault(typeof(T)); + /// Retrieve the access_hash associated with this id (for a TL class) + /// a TL object class. For example User, Channel or Photo + public long? GetAccessHashFor(long id) where T : ITLObject { - if (authorization is not Auth_Authorization { user: User self }) - throw new WTException("Failed to get Authorization: " + authorization?.GetType().Name); - _session.UserId = _dcSession.UserId = self.id; - lock (_session) _session.Save(); - RaiseUpdates(self); - return User = self; + lock (_accessHashes) + return _accessHashes.GetOrCreate(typeof(T)).TryGetValue(id, out var access_hash) ? access_hash : null; } - - private MsgsAck CheckMsgsToAck() + public void SetAccessHashFor(long id, long access_hash) where T : ITLObject { - lock (_msgsToAck) - { - if (_msgsToAck.Count == 0) return null; - var msgsAck = new MsgsAck { msg_ids = [.. _msgsToAck] }; - _msgsToAck.Clear(); - return msgsAck; - } + lock (_accessHashes) + _accessHashes.GetOrCreate(typeof(T))[id] = access_hash; } - - internal (long msgId, int seqno) NewMsgId(bool isContent) + internal void UpdateAccessHash(object obj, Type type, object access_hash) { - int seqno; - long msgId = DateTime.UtcNow.Ticks + _dcSession.serverTicksOffset - 621355968000000000L; - msgId = msgId * 428 + (msgId >> 24) * 25110956; // approximately unixtime*2^32 and divisible by 4 - lock (_session) - { - if (msgId <= _dcSession.lastSentMsgId) msgId = _dcSession.lastSentMsgId += 4; else _dcSession.lastSentMsgId = msgId; - seqno = isContent ? _dcSession.seqno++ * 2 + 1 : _dcSession.seqno * 2; - } - return (msgId, seqno); - } - - private async Task SendAsync(IObject msg, bool isContent, Rpc rpc = null) - { - if (_reactorTask == null) throw new WTException("You must connect to Telegram first"); - isContent &= _dcSession.authKeyID != 0; - var (msgId, seqno) = NewMsgId(isContent); - if (rpc != null) - lock (_pendingRpcs) - _pendingRpcs[rpc.msgId = msgId] = rpc; - if (isContent) - { - List<_Message> messages = null; - if (_httpWait != null && NewMsgId(false) is var (hwId, hwSeqno)) - (messages ??= []).Add(new(hwId, hwSeqno, _httpWait)); - if (CheckMsgsToAck() is MsgsAck msgsAck && NewMsgId(false) is var (ackId, ackSeqno)) - (messages ??= []).Add(new(ackId, ackSeqno, msgsAck)); - if (messages != null) - { - messages.Add(new(msgId, seqno, msg)); - await SendAsync(new MsgContainer { messages = messages }, false); - return; - } - } - Task receiveTask = null; - var sem = _sendSemaphore; - await sem.WaitAsync(_cts.Token); - try - { - using var memStream = new MemoryStream(1024); - using var writer = new BinaryWriter(memStream); - writer.Write(0); // int32 payload_len (to be patched with payload length) - - if (_dcSession.authKeyID == 0) // send unencrypted message - { - if (_bareRpc == null) throw new WTException($"Shouldn't send a {msg.GetType().Name} unencrypted"); - writer.Write(0L); // int64 auth_key_id = 0 (Unencrypted) - writer.Write(msgId); // int64 message_id - writer.Write(0); // int32 message_data_length (to be patched) - Helpers.Log(1, $"{_dcSession.DcID}>Sending {msg.GetType().Name.TrimEnd('_')}"); - writer.WriteTLObject(msg); // bytes message_data - BinaryPrimitives.WriteInt32LittleEndian(memStream.GetBuffer().AsSpan(20), (int)memStream.Length - 24); // patch message_data_length - } - else - { - CheckSalt(); - using var clearStream = new MemoryStream(1024); - using var clearWriter = new BinaryWriter(clearStream); - clearWriter.Write(_dcSession.AuthKey, 88, 32); - clearWriter.Write(_dcSession.Salt); // int64 salt - clearWriter.Write(_dcSession.id); // int64 session_id - clearWriter.Write(msgId); // int64 message_id - clearWriter.Write(seqno); // int32 msg_seqno - clearWriter.Write(0); // int32 message_data_length (to be patched) - if ((seqno & 1) != 0) - Helpers.Log(1, $"{_dcSession.DcID}>Sending {msg.GetType().Name.TrimEnd('_'),-40} #{(short)msgId.GetHashCode():X4}"); - else - Helpers.Log(1, $"{_dcSession.DcID}>Sending {msg.GetType().Name.TrimEnd('_'),-40} {MsgIdToStamp(msgId):u} (svc)"); - clearWriter.WriteTLObject(msg); // bytes message_data - int clearLength = (int)clearStream.Length - 32; // length before padding (= 32 + message_data_length) - int padding = (0x7FFFFFF0 - clearLength) % 16; - padding += _random.Next(2, 16) * 16; // MTProto 2.0 padding must be between 12..1024 with total length divisible by 16 - clearStream.SetLength(32 + clearLength + padding); - byte[] clearBuffer = clearStream.GetBuffer(); - BinaryPrimitives.WriteInt32LittleEndian(clearBuffer.AsSpan(60), clearLength - 32); // patch message_data_length - RNG.GetBytes(clearBuffer, 32 + clearLength, padding); - var msgKeyLarge = _sha256.ComputeHash(clearBuffer, 0, 32 + clearLength + padding); - const int msgKeyOffset = 8; // msg_key = middle 128-bits of SHA256(authkey_part+plaintext+padding) - byte[] encrypted_data = EncryptDecryptMessage(clearBuffer.AsSpan(32, clearLength + padding), true, 0, _dcSession.AuthKey, msgKeyLarge, msgKeyOffset, _sha256); - - writer.Write(_dcSession.authKeyID); // int64 auth_key_id - writer.Write(msgKeyLarge, msgKeyOffset, 16); // int128 msg_key - writer.Write(encrypted_data); // bytes encrypted_data - } - if (_paddedMode) // Padded intermediate mode => append random padding - { - var padding = new byte[_random.Next(_dcSession.authKeyID == 0 ? 257 : 16)]; - RNG.GetBytes(padding); - writer.Write(padding); - } - var buffer = memStream.GetBuffer(); - int frameLength = (int)memStream.Length; - BinaryPrimitives.WriteInt32LittleEndian(buffer, frameLength - 4); // patch payload_len with correct value -#if OBFUSCATION - _sendCtr?.EncryptDecrypt(buffer.AsSpan(0, frameLength)); -#endif - if (_networkStream != null) - await _networkStream.WriteAsync(buffer, 0, frameLength); - else - receiveTask = SendReceiveHttp(buffer, frameLength); - _lastSentMsg = msg; - } - finally - { - sem.Release(); - } - if (receiveTask != null) await receiveTask; - } - - private async Task SendReceiveHttp(byte[] buffer, int frameLength) - { - var endpoint = _dcSession?.EndPoint ?? GetDefaultEndpoint(out _); - var content = new ByteArrayContent(buffer, 4, frameLength - 4); - var response = await _httpClient.PostAsync($"http://{endpoint}/api", content, _cts.Token); - if (response.StatusCode != HttpStatusCode.OK) - throw new RpcException((int)response.StatusCode, TransportError((int)response.StatusCode)); - var data = await response.Content.ReadAsByteArrayAsync(); - var obj = ReadFrame(data, data.Length); - if (obj != null) - await HandleMessageAsync(obj); - } - - /// Long poll on HTTP connections - /// Parameters for the long poll. Leave for the default 25 seconds. - /// ⚠️ Telegram servers don't seem to support other parameter than correctly - public async Task HttpWait(HttpWait httpWait = null) - { - if (_networkStream != null) throw new InvalidOperationException("Can't use HttpWait over TCP connection"); - var container = new MsgContainer { messages = [] }; - if (httpWait != null && NewMsgId(false) is var (hwId, hwSeqno)) - container.messages.Add(new(hwId, hwSeqno, httpWait)); - if (CheckMsgsToAck() is MsgsAck msgsAck && NewMsgId(false) is var (ackId, ackSeqno)) - container.messages.Add(new(ackId, ackSeqno, msgsAck)); - await SendAsync(container, false); - } - - internal async Task InvokeBare(IMethod request) - { - if (_bareRpc != null) throw new WTException("A bare request is already undergoing"); - retry: - var bareRpc = _bareRpc = new Rpc { type = typeof(T) }; - await SendAsync(request, false, _bareRpc); - var result = await bareRpc.Task; - if (result is ReactorError) goto retry; - return (T)result; - } - - /// Call the given TL method (You shouldn't need to use this method directly) - /// Expected type of the returned object - /// TL method structure - /// Wait for the reply and return the resulting object, or throws an RpcException if an error was replied - public virtual async Task Invoke(IMethod query) - { - if (_dcSession.withoutUpdates && query is not IMethod and not IMethod) - query = new TL.Methods.InvokeWithoutUpdates { query = query }; - bool got503 = false; - retry: - var rpc = new Rpc { type = typeof(T) }; - await SendAsync(query, true, rpc); - while (_httpClient != null && !rpc.Task.IsCompleted) - await HttpWait(_httpWait); // need to wait a bit more in some case - - var result = await rpc.Task; - switch (result) - { - case null: return default; - case T resultT: return resultT; - case RpcError { error_code: var code, error_message: var message }: - int x = -1; - for (int index = message.Length - 1; index > 0 && (index = message.LastIndexOf('_', index - 1)) >= 0;) - if (message[index + 1] is >= '0' and <= '9') - { - int end = ++index; - do end++; while (end < message.Length && message[end] is >= '0' and <= '9'); - x = int.Parse(message[index..end]); - message = $"{message[0..index]}X{message[end..]}"; - break; - } - - if (code == 303 && message.EndsWith("_MIGRATE_X")) - { - if (message != "FILE_MIGRATE_X") - { - await MigrateToDC(x); - goto retry; - } - } - else if (code == 420 && (message.EndsWith("_WAIT_X") || message.EndsWith("_DELAY_X"))) - { - if (x <= FloodRetryThreshold) - { - if (x == 0) x = 1; - await Task.Delay(x * 1000); - goto retry; - } - } - else if (code == -503 && !got503) - { - got503 = true; - goto retry; - } - else if (code == 401 && !IsMainDC && message is "SESSION_REVOKED" or "AUTH_KEY_UNREGISTERED") // need to renegociate alt-DC auth - { - lock (_session) - { - _session.DCSessions.Remove(_dcSession.DcID); - if (_session.MainDC != -_dcSession.DcID) _session.DCSessions.Remove(-_dcSession.DcID); - _session.Save(); - } - await DisposeAsync(); - } - else if (code == 400 && message == "CONNECTION_NOT_INITED") - { - await InitConnection(); - lock (_session) _session.Save(); - goto retry; - } - else if (code == 500 && message == "AUTH_RESTART") - lock (_session) - { - _session.UserId = 0; // force a full login authorization flow, next time - User = null; - _session.Save(); - } - throw new RpcException(code, message, x); - case ReactorError: - goto retry; - default: - throw new WTException($"{query.GetType().Name} call got a result of type {result.GetType().Name} instead of {typeof(T).Name}"); - } - } - - private async Task MigrateToDC(int dcId) - { - // this is a hack to migrate _dcSession in-place (staying in same Client): - Session.DCSession dcSession; - lock (_session) - dcSession = GetOrCreateDCSession(dcId, _dcSession.DataCenter.flags); - await ResetAsync(false, false); - _session.MainDC = dcId; - _dcSession.Client = null; - _dcSession = dcSession; - _dcSession.Client = this; - await ConnectAsync(); - } - - [EditorBrowsable(EditorBrowsableState.Never)] - public async Task InvokeAffected(IMethod query, long peerId) where T : Messages_AffectedMessages - { - var result = await Invoke(query); - if (OnOwnUpdates != null) - RaiseOwnUpdates(new UpdateShort - { - update = new UpdateAffectedMessages { mbox_id = peerId, pts = result.pts, pts_count = result.pts_count }, - date = MsgIdToStamp(_lastRecvMsgId) - }); - return result; + if (!CollectAccessHash) return; + if (access_hash is not long accessHash) return; + if (type.GetField("id") is not FieldInfo idField) return; + if (idField.GetValue(obj) is not long id) + if (idField.GetValue(obj) is not int idInt) return; + else id = idInt; + lock (_accessHashes) + _accessHashes.GetOrCreate(type)[id] = accessHash; } } } diff --git a/src/Compat.cs b/src/Compat.cs index 31f26d8..f34c2e3 100644 --- a/src/Compat.cs +++ b/src/Compat.cs @@ -1,27 +1,18 @@ using System; -using System.Buffers.Binary; using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; +using System.Formats.Asn1; using System.Net; using System.Numerics; using System.Security.Cryptography; -using System.Threading.Tasks; +namespace WTelegram +{ + static class Compat + { #if NETCOREAPP2_1_OR_GREATER -namespace WTelegram -{ - static partial class Compat - { - internal static BigInteger BigEndianInteger(byte[] value) => new(value, true, true); internal static IPEndPoint IPEndPoint_Parse(string addr) => IPEndPoint.Parse(addr); - } -} -#else // Compatibility shims for methods missing in netstandard2.0: -namespace WTelegram -{ - static partial class Compat - { + internal static BigInteger BigEndianInteger(byte[] value) => new(value, true, true); +#else internal static BigInteger BigEndianInteger(byte[] value) { var data = new byte[value.Length + 1]; @@ -30,7 +21,7 @@ namespace WTelegram return new BigInteger(data); } - internal static byte[] ToByteArray(this BigInteger bigInteger, bool isUnsigned, bool isBigEndian) + internal static byte[] ToByteArray(this BigInteger bigInteger, bool isUnsigned = false, bool isBigEndian = false) { if (!isBigEndian || !isUnsigned) throw new ArgumentException("Unexpected parameters to ToByteArray"); var result = bigInteger.ToByteArray(); @@ -48,14 +39,18 @@ namespace WTelegram return length; } - public static V GetValueOrDefault(this IReadOnlyDictionary dictionary, K key, V defaultValue = default) + public static V GetValueOrDefault(this Dictionary dictionary, K key, V defaultValue = default) => dictionary.TryGetValue(key, out V value) ? value : defaultValue; - public static void Deconstruct(this KeyValuePair kvp, out K key, out V value) { key = kvp.Key; value = kvp.Value; } + public static void Deconstruct(this KeyValuePair kvp, out K key, out V value) + { + key = kvp.Key; + value = kvp.Value; + } internal static IPEndPoint IPEndPoint_Parse(string addr) { - int colon = addr.LastIndexOf(':'); + int colon = addr.IndexOf(':'); return new IPEndPoint(IPAddress.Parse(addr[0..colon]), int.Parse(addr[(colon + 1)..])); } @@ -65,26 +60,27 @@ namespace WTelegram var footer = pem.IndexOf("-----END RSA PUBLIC KEY-----"); if (header == -1 || footer <= header) throw new ArgumentException("Invalid RSA Public Key"); byte[] bytes = System.Convert.FromBase64String(pem[(header+30)..footer]); - if (bytes.Length != 270 || BinaryPrimitives.ReadInt64BigEndian(bytes) != 0x3082010A02820101 || bytes[265] != 0x02 || bytes[266] != 0x03) - throw new ArgumentException("Unrecognized sequence in RSA Public Key"); - rsa.ImportParameters(new RSAParameters { Modulus = bytes[8..265], Exponent = bytes[267..270] }); + var reader = new AsnReader(bytes, AsnEncodingRules.BER); + reader = reader.ReadSequence(Asn1Tag.Sequence); + var m = reader.ReadIntegerBytes(); + var e = reader.ReadIntegerBytes(); + rsa.ImportParameters(new RSAParameters { Modulus = m.ToArray(), Exponent = e.ToArray() }); } } -} -static class Convert -{ - internal static string ToHexString(byte[] data) => BitConverter.ToString(data).Replace("-", ""); - internal static byte[] FromHexString(string hex) => [.. Enumerable.Range(0, hex.Length / 2).Select(i => System.Convert.ToByte(hex.Substring(i * 2, 2), 16))]; -} -public class RandomNumberGenerator -{ - internal static readonly RNGCryptoServiceProvider RNG = new(); - public static RandomNumberGenerator Create() => new(); - public void GetBytes(byte[] data) => RNG.GetBytes(data); - public void GetBytes(byte[] data, int offset, int count) => RNG.GetBytes(data, offset, count); -} + static class Convert + { + internal static byte[] FromHexString(string hex) + { + int NumberChars = hex.Length; + byte[] bytes = new byte[NumberChars / 2]; + for (int i = 0; i < NumberChars; i += 2) + bytes[i / 2] = System.Convert.ToByte(hex.Substring(i, 2), 16); + return bytes; + } #endif + } +} #if NETSTANDARD2_0 namespace System.Runtime.CompilerServices @@ -95,27 +91,12 @@ namespace System.Runtime.CompilerServices { if (array == null) throw new ArgumentNullException(); var (offset, length) = range.GetOffsetAndLength(array.Length); - if (length == 0) return []; + if (length == 0) return Array.Empty(); var dest = typeof(T).IsValueType || typeof(T[]) == array.GetType() ? new T[length] : (T[])Array.CreateInstance(array.GetType().GetElementType()!, length); Array.Copy(array, offset, dest, 0, length); return dest; } } - [EditorBrowsable(EditorBrowsableState.Never)] - internal class IsExternalInit { } -} -#endif - -namespace WTelegram -{ - static partial class Compat - { - internal static Task WaitAsync(this Task source, int timeout) -#if NET8_0_OR_GREATER - => source?.WaitAsync(TimeSpan.FromMilliseconds(timeout)) ?? Task.CompletedTask; -#else - => source == null ? Task.CompletedTask : Task.WhenAny(source, Task.Delay(timeout)); -#endif - } } +#endif \ No newline at end of file diff --git a/src/Encryption.cs b/src/Encryption.cs index c24845e..f3ce552 100644 --- a/src/Encryption.cs +++ b/src/Encryption.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Numerics; -using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; @@ -13,18 +12,10 @@ using static WTelegram.Compat; namespace WTelegram { - public static class Encryption + internal static class Encryption { - private static readonly Dictionary PublicKeys = []; - internal static readonly RandomNumberGenerator RNG = RandomNumberGenerator.Create(); - internal static readonly Aes AesECB = Aes.Create(); - - static Encryption() - { - AesECB.Mode = CipherMode.ECB; - AesECB.Padding = PaddingMode.Zeros; - if (AesECB.BlockSize != 128) throw new WTException("AES Blocksize is not 16 bytes"); - } + internal static readonly RNGCryptoServiceProvider RNG = new(); + private static readonly Dictionary PublicKeys = new(); internal static async Task CreateAuthorizationKey(Client client, Session.DCSession session) { @@ -33,12 +24,16 @@ namespace WTelegram var sha256 = SHA256.Create(); //1) - var nonce = new TL.Int128(RNG); - var resPQ = await client.ReqPqMulti(nonce); + var nonce = new Int128(RNG); +#if MTPROTO1 + var resPQ = await client.ReqPQ(nonce); +#else + var resPQ = await client.ReqPqMulti(nonce); +#endif //2) - if (resPQ.nonce != nonce) throw new WTException("Nonce mismatch"); + if (resPQ.nonce != nonce) throw new ApplicationException("Nonce mismatch"); var fingerprint = resPQ.server_public_key_fingerprints.FirstOrDefault(PublicKeys.ContainsKey); - if (fingerprint == 0) throw new WTException("Couldn't match any server_public_key_fingerprints"); + if (fingerprint == 0) throw new ApplicationException("Couldn't match any server_public_key_fingerprints"); var publicKey = PublicKeys[fingerprint]; Helpers.Log(2, $"Selected public key with fingerprint {fingerprint:X}"); //3) @@ -57,23 +52,34 @@ namespace WTelegram new_nonce = new Int256(RNG), dc = session.DataCenter?.id ?? 0 }; - if (client.TLConfig?.test_mode == true) pqInnerData.dc += 10000; - if (session.DataCenter?.flags.HasFlag(DcOption.Flags.media_only) == true) pqInnerData.dc = -pqInnerData.dc; byte[] encrypted_data = null; { +#if OLDKEY + using var clearStream = new MemoryStream(255); + clearStream.Position = 20; // skip SHA1 area (to be patched) + using var writer = new BinaryWriter(clearStream, Encoding.UTF8); + writer.WriteTLObject(pqInnerData); + int clearLength = (int)clearStream.Length; // length before padding (= 20 + message_data_length) + if (clearLength > 255) throw new ApplicationException("PQInnerData too big"); + byte[] clearBuffer = clearStream.GetBuffer(); + RNG.GetBytes(clearBuffer, clearLength, 255 - clearLength); + sha1.ComputeHash(clearBuffer, 20, clearLength - 20).CopyTo(clearBuffer, 0); // patch with SHA1 + encrypted_data = BigInteger.ModPow(BigEndianInteger(clearBuffer), // encrypt with RSA key + BigEndianInteger(publicKey.e), BigEndianInteger(publicKey.n)).ToByteArray(true, true); +#else //4.1) RSA_PAD(data, server_public_key) using var clearStream = new MemoryStream(256); - using var writer = new BinaryWriter(clearStream); + using var writer = new BinaryWriter(clearStream, Encoding.UTF8); byte[] aes_key = new byte[32], zero_iv = new byte[32]; var n = BigEndianInteger(publicKey.n); - do + while (encrypted_data == null) { RNG.GetBytes(aes_key); clearStream.Position = 0; clearStream.Write(aes_key, 0, 32); // write aes_key as prefix for initial Sha256 computation writer.WriteTLObject(pqInnerData); int clearLength = (int)clearStream.Position - 32; // length before padding - if (clearLength > 144) throw new WTException("PQInnerData too big"); + if (clearLength > 144) throw new ApplicationException("PQInnerData too big"); byte[] clearBuffer = clearStream.GetBuffer(); RNG.GetBytes(clearBuffer, 32 + clearLength, 192 - clearLength); sha256.ComputeHash(clearBuffer, 0, 32 + 192).CopyTo(clearBuffer, 224); // append Sha256 @@ -86,40 +92,39 @@ namespace WTelegram var x = BigEndianInteger(clearBuffer); if (x < n) // if good result, encrypt with RSA key: encrypted_data = BigInteger.ModPow(x, BigEndianInteger(publicKey.e), n).To256Bytes(); - } while (encrypted_data == null); // otherwise, repeat the steps + } // otherwise, repeat the steps +#endif } var serverDHparams = await client.ReqDHParams(pqInnerData.nonce, pqInnerData.server_nonce, pqInnerData.p, pqInnerData.q, fingerprint, encrypted_data); //5) var localTime = DateTimeOffset.UtcNow; - if (serverDHparams is not ServerDHParamsOk serverDHparamsOk) throw new WTException("not server_DH_params_ok"); - if (serverDHparamsOk.nonce != nonce) throw new WTException("Nonce mismatch"); - if (serverDHparamsOk.server_nonce != resPQ.server_nonce) throw new WTException("Server Nonce mismatch"); - var (tmp_aes_key, tmp_aes_iv) = ConstructTmpAESKeyIV(sha1, resPQ.server_nonce, pqInnerData.new_nonce); + if (serverDHparams is not ServerDHParamsOk serverDHparamsOk) throw new ApplicationException("not server_DH_params_ok"); + if (serverDHparamsOk.nonce != nonce) throw new ApplicationException("Nonce mismatch"); + if (serverDHparamsOk.server_nonce != resPQ.server_nonce) throw new ApplicationException("Server Nonce mismatch"); + var (tmp_aes_key, tmp_aes_iv) = ConstructTmpAESKeyIV(resPQ.server_nonce, pqInnerData.new_nonce); var answer = AES_IGE_EncryptDecrypt(serverDHparamsOk.encrypted_answer, tmp_aes_key, tmp_aes_iv, false); - using var answerReader = new BinaryReader(new MemoryStream(answer)); - var answerHash = answerReader.ReadBytes(20); - var answerObj = answerReader.ReadTLObject(); - if (answerObj is not ServerDHInnerData serverDHinnerData) throw new WTException("not server_DH_inner_data"); - long padding = answerReader.BaseStream.Length - answerReader.BaseStream.Position; - if (padding >= 16) throw new WTException("Too much pad"); + using var encryptedReader = new TL.BinaryReader(new MemoryStream(answer), client); + var answerHash = encryptedReader.ReadBytes(20); + var answerObj = encryptedReader.ReadTLObject(); + if (answerObj is not ServerDHInnerData serverDHinnerData) throw new ApplicationException("not server_DH_inner_data"); + long padding = encryptedReader.BaseStream.Length - encryptedReader.BaseStream.Position; + if (padding >= 16) throw new ApplicationException("Too much pad"); if (!Enumerable.SequenceEqual(sha1.ComputeHash(answer, 20, answer.Length - (int)padding - 20), answerHash)) - throw new WTException("Answer SHA1 mismatch"); - if (serverDHinnerData.nonce != nonce) throw new WTException("Nonce mismatch"); - if (serverDHinnerData.server_nonce != resPQ.server_nonce) throw new WTException("Server Nonce mismatch"); + throw new ApplicationException("Answer SHA1 mismatch"); + if (serverDHinnerData.nonce != nonce) throw new ApplicationException("Nonce mismatch"); + if (serverDHinnerData.server_nonce != resPQ.server_nonce) throw new ApplicationException("Server Nonce mismatch"); var g_a = BigEndianInteger(serverDHinnerData.g_a); var dh_prime = BigEndianInteger(serverDHinnerData.dh_prime); - CheckGoodPrime(dh_prime, serverDHinnerData.g); - session.lastSentMsgId = 0; - session.serverTicksOffset = (serverDHinnerData.server_time - localTime).Ticks; - Helpers.Log(1, $"Time offset: {session.serverTicksOffset} | Server: {serverDHinnerData.server_time.TimeOfDay} UTC | Local: {localTime.TimeOfDay} UTC"); + ValidityChecks(dh_prime, serverDHinnerData.g); + Helpers.Log(1, $"Server time: {serverDHinnerData.server_time} UTC"); + session.ServerTicksOffset = (serverDHinnerData.server_time - localTime).Ticks; //6) - var salt = new byte[256]; - RNG.GetBytes(salt); - var b = BigEndianInteger(salt); + var bData = new byte[256]; + RNG.GetBytes(bData); + var b = BigEndianInteger(bData); var g_b = BigInteger.ModPow(serverDHinnerData.g, b, dh_prime); - CheckGoodGaAndGb(g_a, dh_prime); - CheckGoodGaAndGb(g_b, dh_prime); + ValidityChecksDH(g_a, g_b, dh_prime); var clientDHinnerData = new ClientDHInnerData { nonce = nonce, @@ -130,7 +135,7 @@ namespace WTelegram { using var clearStream = new MemoryStream(384); clearStream.Position = 20; // skip SHA1 area (to be patched) - using var writer = new BinaryWriter(clearStream); + using var writer = new BinaryWriter(clearStream, Encoding.UTF8); writer.WriteTLObject(clientDHinnerData); int clearLength = (int)clearStream.Length; // length before padding (= 20 + message_data_length) int paddingToAdd = (0x7FFFFFF0 - clearLength) % 16; @@ -149,112 +154,103 @@ namespace WTelegram var authKeyHash = sha1.ComputeHash(authKey); retry_id = BinaryPrimitives.ReadInt64LittleEndian(authKeyHash); // (auth_key_aux_hash) //9) - if (setClientDHparamsAnswer is not DhGenOk dhGenOk) throw new WTException("not dh_gen_ok"); - if (dhGenOk.nonce != nonce) throw new WTException("Nonce mismatch"); - if (dhGenOk.server_nonce != resPQ.server_nonce) throw new WTException("Server Nonce mismatch"); + if (setClientDHparamsAnswer is not DhGenOk dhGenOk) throw new ApplicationException("not dh_gen_ok"); + if (dhGenOk.nonce != nonce) throw new ApplicationException("Nonce mismatch"); + if (dhGenOk.server_nonce != resPQ.server_nonce) throw new ApplicationException("Server Nonce mismatch"); var expected_new_nonceN = new byte[32 + 1 + 8]; pqInnerData.new_nonce.raw.CopyTo(expected_new_nonceN, 0); expected_new_nonceN[32] = 1; Array.Copy(authKeyHash, 0, expected_new_nonceN, 33, 8); // (auth_key_aux_hash) if (!Enumerable.SequenceEqual(dhGenOk.new_nonce_hash1.raw, sha1.ComputeHash(expected_new_nonceN).Skip(4))) - throw new WTException("setClientDHparamsAnswer.new_nonce_hashN mismatch"); + throw new ApplicationException("setClientDHparamsAnswer.new_nonce_hashN mismatch"); - session.authKeyID = BinaryPrimitives.ReadInt64LittleEndian(authKeyHash.AsSpan(12)); + session.AuthKeyID = BinaryPrimitives.ReadInt64LittleEndian(authKeyHash.AsSpan(12)); session.AuthKey = authKey; session.Salt = BinaryPrimitives.ReadInt64LittleEndian(pqInnerData.new_nonce.raw) ^ BinaryPrimitives.ReadInt64LittleEndian(resPQ.server_nonce.raw); - session.OldSalt = session.Salt; + + (byte[] key, byte[] iv) ConstructTmpAESKeyIV(Int128 server_nonce, Int256 new_nonce) + { + byte[] tmp_aes_key = new byte[32], tmp_aes_iv = new byte[32]; + sha1.Initialize(); + sha1.TransformBlock(new_nonce, 0, 32, null, 0); + sha1.TransformFinalBlock(server_nonce, 0, 16); + sha1.Hash.CopyTo(tmp_aes_key, 0); // tmp_aes_key := SHA1(new_nonce + server_nonce) + sha1.Initialize(); + sha1.TransformBlock(server_nonce, 0, 16, null, 0); + sha1.TransformFinalBlock(new_nonce, 0, 32); + Array.Copy(sha1.Hash, 0, tmp_aes_key, 20, 12); // + SHA1(server_nonce, new_nonce)[0:12] + Array.Copy(sha1.Hash, 12, tmp_aes_iv, 0, 8); // tmp_aes_iv != SHA1(server_nonce, new_nonce)[12:8] + sha1.Initialize(); + sha1.TransformBlock(new_nonce, 0, 32, null, 0); + sha1.TransformFinalBlock(new_nonce, 0, 32); + sha1.Hash.CopyTo(tmp_aes_iv, 8); // + SHA(new_nonce + new_nonce) + Array.Copy(new_nonce, 0, tmp_aes_iv, 28, 4); // + new_nonce[0:4] + return (tmp_aes_key, tmp_aes_iv); + } } - public static (byte[] key, byte[] iv) ConstructTmpAESKeyIV(SHA1 sha1, TL.Int128 server_nonce, Int256 new_nonce) - { - byte[] tmp_aes_key = new byte[32], tmp_aes_iv = new byte[32]; - sha1.TransformBlock(new_nonce, 0, 32, null, 0); - sha1.TransformFinalBlock(server_nonce, 0, 16); - sha1.Hash.CopyTo(tmp_aes_key, 0); // tmp_aes_key := SHA1(new_nonce + server_nonce) - sha1.Initialize(); - sha1.TransformBlock(server_nonce, 0, 16, null, 0); - sha1.TransformFinalBlock(new_nonce, 0, 32); - Array.Copy(sha1.Hash, 0, tmp_aes_key, 20, 12); // + SHA1(server_nonce, new_nonce)[0:12] - Array.Copy(sha1.Hash, 12, tmp_aes_iv, 0, 8); // tmp_aes_iv != SHA1(server_nonce, new_nonce)[12:8] - sha1.Initialize(); - sha1.TransformBlock(new_nonce, 0, 32, null, 0); - sha1.TransformFinalBlock(new_nonce, 0, 32); - sha1.Hash.CopyTo(tmp_aes_iv, 8); // + SHA(new_nonce + new_nonce) - Array.Copy(new_nonce, 0, tmp_aes_iv, 28, 4); // + new_nonce[0:4] - sha1.Initialize(); - return (tmp_aes_key, tmp_aes_iv); - } - - internal static void CheckGoodPrime(BigInteger p, int g) + private static void ValidityChecks(BigInteger p, int g) { Helpers.Log(2, "Verifying encryption key safety... (this should happen only once per DC)"); // check that 2^2047 <= p < 2^2048 - if (p.GetBitLength() != 2048) throw new WTException("p is not 2048-bit number"); + if (p.GetBitLength() != 2048) throw new ApplicationException("p is not 2048-bit number"); // check that g generates a cyclic subgroup of prime order (p - 1) / 2, i.e. is a quadratic residue mod p. + BigInteger mod_r; if (g switch { 2 => p % 8 != 7, 3 => p % 3 != 2, 4 => false, - 5 => (int)(p % 5) is not 1 and not 4, - 6 => (int)(p % 24) is not 19 and not 23, - 7 => (int)(p % 7) is not 3 and not 5 and not 6, + 5 => (mod_r = p % 5) != 1 && mod_r != 4, + 6 => (mod_r = p % 24) != 19 && mod_r != 23, + 7 => (mod_r = p % 7) != 3 && mod_r != 5 && mod_r != 6, _ => true, }) - throw new WTException("Bad prime mod 4g"); + throw new ApplicationException("Bad prime mod 4g"); // check whether p is a safe prime (meaning that both p and (p - 1) / 2 are prime) - if (SafePrimes.Contains(p)) return; - if (!p.IsProbablePrime()) throw new WTException("p is not a prime number"); - if (!((p - 1) / 2).IsProbablePrime()) throw new WTException("(p - 1) / 2 is not a prime number"); - SafePrimes.Add(p); + if (!p.IsProbablePrime()) throw new ApplicationException("p is not a prime number"); + if (!((p - 1) / 2).IsProbablePrime()) throw new ApplicationException("(p - 1) / 2 is not a prime number"); } - private static readonly HashSet SafePrimes = [ new( // C71CAEB9C6B1C904... - [ - 0x5B, 0xCC, 0x2F, 0xB9, 0xE3, 0xD8, 0x9C, 0x11, 0x03, 0x04, 0xB1, 0x34, 0xF0, 0xAD, 0x4F, 0x6F, - 0xBF, 0x54, 0x24, 0x4B, 0xD0, 0x15, 0x4E, 0x2E, 0xEE, 0x05, 0xB1, 0x35, 0xF6, 0x15, 0x81, 0x0D, - 0x1F, 0x85, 0x29, 0xE9, 0x0C, 0x85, 0x56, 0xD9, 0x59, 0xF9, 0x7B, 0xF4, 0x49, 0x28, 0xED, 0x0D, - 0x05, 0x70, 0xED, 0x5E, 0xFF, 0xA9, 0x7F, 0xF8, 0xA0, 0xBE, 0x3E, 0xE8, 0x15, 0xFC, 0x18, 0xE4, - 0xE4, 0x9A, 0x5B, 0xEF, 0x8F, 0x92, 0xA3, 0x9C, 0xFF, 0xD6, 0xB0, 0x65, 0xC4, 0x6B, 0x9C, 0x16, - 0x8D, 0x17, 0xB1, 0x2D, 0x58, 0x46, 0xDD, 0xB9, 0xB4, 0x65, 0x59, 0x0D, 0x95, 0xED, 0x17, 0xFD, - 0x54, 0x47, 0x28, 0xF1, 0x0E, 0x4E, 0x14, 0xB3, 0x14, 0x2A, 0x4B, 0xA8, 0xD8, 0x74, 0xBA, 0x0D, - 0x41, 0x6B, 0x0F, 0x6B, 0xB5, 0x53, 0x27, 0x16, 0x7E, 0x90, 0x51, 0x10, 0x81, 0x95, 0xA6, 0xA4, - 0xA4, 0xF9, 0x7C, 0xE6, 0xBE, 0x60, 0x90, 0x3A, 0x4F, 0x3C, 0x8E, 0x37, 0x9B, 0xFA, 0x08, 0x07, - 0x88, 0x49, 0xCC, 0xC8, 0x4A, 0x1D, 0xCD, 0x5B, 0x1D, 0x94, 0x2A, 0xBB, 0x96, 0xFE, 0x77, 0x24, - 0x64, 0x5F, 0x59, 0x8C, 0xAF, 0x8F, 0xF1, 0x54, 0x84, 0x32, 0x69, 0x29, 0x51, 0x46, 0x97, 0xDC, - 0xAB, 0x13, 0x6B, 0x6B, 0xFE, 0xD4, 0x8C, 0xC6, 0x5A, 0x70, 0x58, 0x94, 0xF6, 0x51, 0xFD, 0x20, - 0x37, 0x7C, 0xCE, 0x4C, 0xD4, 0xAE, 0x43, 0x95, 0x13, 0x25, 0xC9, 0x0A, 0x6E, 0x6F, 0x33, 0xFA, - 0xDB, 0xF4, 0x30, 0x25, 0xD2, 0x93, 0x94, 0x22, 0x58, 0x40, 0xC1, 0xA7, 0x0A, 0x8A, 0x19, 0x48, - 0x0F, 0x93, 0x3D, 0x56, 0x37, 0xD0, 0x34, 0x49, 0xC1, 0x21, 0x3E, 0x8E, 0x23, 0x40, 0x0D, 0x98, - 0x73, 0x3F, 0xF1, 0x70, 0x2F, 0x52, 0x6C, 0x8E, 0x04, 0xC9, 0xB1, 0xC6, 0xB9, 0xAE, 0x1C, 0xC7, 0x00 - ])]; - - internal static void CheckGoodGaAndGb(BigInteger g, BigInteger dh_prime) + private static void ValidityChecksDH(BigInteger g_a, BigInteger g_b, BigInteger dh_prime) { // check that g, g_a and g_b are greater than 1 and less than dh_prime - 1. // We recommend checking that g_a and g_b are between 2^{2048-64} and dh_prime - 2^{2048-64} as well. - if (g.GetBitLength() < 2048 - 64 || (dh_prime - g).GetBitLength() < 2048 - 64) - throw new WTException("g^a or g^b is not between 2^{2048-64} and dh_prime - 2^{2048-64}"); + var l = BigInteger.One << (2048 - 64); + var r = dh_prime - l; + if (g_a < l || g_a > r || g_b < l || g_b > r) + throw new ApplicationException("g^a or g^b is not between 2^{2048-64} and dh_prime - 2^{2048-64}"); } - /// Load a specific Telegram server public key - /// A string starting with -----BEGIN RSA PUBLIC KEY----- + [TLDef(0x7A19CB76)] //RSA_public_key#7a19cb76 n:bytes e:bytes = RSAPublicKey + public partial class RSAPublicKey : ITLObject { public byte[] n, e; } + public static void LoadPublicKey(string pem) { using var rsa = RSA.Create(); using var sha1 = SHA1.Create(); rsa.ImportFromPem(pem); var rsaParam = rsa.ExportParameters(false); - if (rsaParam.Modulus[0] == 0) rsaParam.Modulus = rsaParam.Modulus[1..]; var publicKey = new RSAPublicKey { n = rsaParam.Modulus, e = rsaParam.Exponent }; - var bareData = publicKey.ToBytes(); + var bareData = publicKey.Serialize(); // bare serialization var fingerprint = BinaryPrimitives.ReadInt64LittleEndian(sha1.ComputeHash(bareData, 4, bareData.Length - 4).AsSpan(12)); // 64 lower-order bits of SHA1 PublicKeys[fingerprint] = publicKey; Helpers.Log(1, $"Loaded a public key with fingerprint {fingerprint:X}"); } - private static void LoadDefaultPublicKeys() + private static void LoadDefaultPublicKeys() { +#if OLDKEY + // Old Public Key (C3B42B026CE86B21) + LoadPublicKey(@"-----BEGIN RSA PUBLIC KEY----- +MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6 +lyDONS789sVoD/xCS9Y0hkkC3gtL1tSfTlgCMOOul9lcixlEKzwKENj1Yz/s7daS +an9tqw3bfUV/nqgbhGX81v/+7RFAEd+RwFnK7a+XYl9sluzHRyVVaTTveB2GazTw +Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+ +8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n +Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB +-----END RSA PUBLIC KEY-----"); +#else // Production Public Key (D09D1D85DE64FD85) LoadPublicKey(@"-----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEA6LszBcC1LGzyr992NzE0ieY+BSaOW622Aa9Bd4ZHLl+TuFQ4lo4g @@ -273,12 +269,48 @@ j25sIWeYPHYeOrFp/eXaqhISP6G+q2IeTaWTXpwZj4LzXq5YOpk4bYEQ6mvRq7D1 aHWfYmlEGepfaYR8Q0YqvvhYtMte3ITnuSJs171+GDqpdKcSwHnd6FudwGO4pcCO j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB -----END RSA PUBLIC KEY-----"); +#endif } - public static byte[] EncryptDecryptMessage(Span input, bool encrypt, int x, byte[] authKey, byte[] msgKey, int msgKeyOffset, SHA256 sha256) +#if MTPROTO1 + internal static byte[] EncryptDecryptMessage(Span input, bool encrypt, byte[] authKey, byte[] msgKey, int msgKeyOffset, SHA1 sha1) { // first, construct AES key & IV byte[] aes_key = new byte[32], aes_iv = new byte[32]; + int x = encrypt ? 0 : 8; + sha1.Initialize(); + sha1.TransformBlock(msgKey, msgKeyOffset, 16, null, 0); // msgKey + sha1.TransformFinalBlock(authKey, x, 32); // authKey[x:32] + var sha1_a = sha1.Hash; + sha1.Initialize(); + sha1.TransformBlock(authKey, 32 + x, 16, null, 0); // authKey[32+x:16] + sha1.TransformBlock(msgKey, msgKeyOffset, 16, null, 0); // msgKey + sha1.TransformFinalBlock(authKey, 48 + x, 16); // authKey[48+x:16] + var sha1_b = sha1.Hash; + sha1.Initialize(); + sha1.TransformBlock(authKey, 64 + x, 32, null, 0); // authKey[64+x:32] + sha1.TransformFinalBlock(msgKey, msgKeyOffset, 16); // msgKey + var sha1_c = sha1.Hash; + sha1.Initialize(); + sha1.TransformBlock(msgKey, msgKeyOffset, 16, null, 0); // msgKey + sha1.TransformFinalBlock(authKey, 96 + x, 32); // authKey[96+x:32] + var sha1_d = sha1.Hash; + Array.Copy(sha1_a, 0, aes_key, 0, 8); + Array.Copy(sha1_b, 8, aes_key, 8, 12); + Array.Copy(sha1_c, 4, aes_key, 20, 12); + Array.Copy(sha1_a, 8, aes_iv, 0, 12); + Array.Copy(sha1_b, 0, aes_iv, 12, 8); + Array.Copy(sha1_c, 16, aes_iv, 20, 4); + Array.Copy(sha1_d, 0, aes_iv, 24, 8); + return AES_IGE_EncryptDecrypt(input, aes_key, aes_iv, encrypt); + } +#else + internal static byte[] EncryptDecryptMessage(Span input, bool encrypt, byte[] authKey, byte[] msgKey, int msgKeyOffset, SHA256 sha256) + { + // first, construct AES key & IV + byte[] aes_key = new byte[32], aes_iv = new byte[32]; + int x = encrypt ? 0 : 8; + sha256.Initialize(); sha256.TransformBlock(msgKey, msgKeyOffset, 16, null, 0); // msgKey sha256.TransformFinalBlock(authKey, x, 36); // authKey[x:36] var sha256_a = sha256.Hash; @@ -286,7 +318,6 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB sha256.TransformBlock(authKey, 40 + x, 36, null, 0); // authKey[40+x:36] sha256.TransformFinalBlock(msgKey, msgKeyOffset, 16); // msgKey var sha256_b = sha256.Hash; - sha256.Initialize(); Array.Copy(sha256_a, 0, aes_key, 0, 8); Array.Copy(sha256_b, 8, aes_key, 8, 16); Array.Copy(sha256_a, 24, aes_key, 24, 8); @@ -295,111 +326,55 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB Array.Copy(sha256_b, 24, aes_iv, 24, 8); return AES_IGE_EncryptDecrypt(input, aes_key, aes_iv, encrypt); } +#endif - public static byte[] AES_IGE_EncryptDecrypt(Span input, byte[] aes_key, byte[] aes_iv, bool encrypt) + private static byte[] AES_IGE_EncryptDecrypt(Span input, byte[] aes_key, byte[] aes_iv, bool encrypt) { - if (input.Length % 16 != 0) throw new WTException("AES_IGE input size not divisible by 16"); + using var aes = Aes.Create(); + aes.Mode = CipherMode.ECB; + aes.Padding = PaddingMode.Zeros; + if (aes.BlockSize != 128) throw new ApplicationException("AES Blocksize is not 16 bytes"); + if (input.Length % 16 != 0) throw new ApplicationException("intput size not divisible by 16"); - using var aesCrypto = encrypt ? AesECB.CreateEncryptor(aes_key, null) : AesECB.CreateDecryptor(aes_key, null); + // code adapted from PHP implementation found at https://mgp25.com/AESIGE/ var output = new byte[input.Length]; - var prevBytes = (byte[])aes_iv.Clone(); - var span = MemoryMarshal.Cast(input); - var sout = MemoryMarshal.Cast(output.AsSpan()); - var prev = MemoryMarshal.Cast(prevBytes.AsSpan()); - if (!encrypt) { (prev[2], prev[0]) = (prev[0], prev[2]); (prev[3], prev[1]) = (prev[1], prev[3]); } - for (int i = 0, count = input.Length / 8; i < count;) + var xPrev = aes_iv.AsSpan(encrypt ? 16 : 0, 16); + var yPrev = aes_iv.AsSpan(encrypt ? 0 : 16, 16); + var aesCrypto = encrypt ? aes.CreateEncryptor(aes_key, null) : aes.CreateDecryptor(aes_key, null); + using (aesCrypto) { - sout[i] = span[i] ^ prev[0]; sout[i + 1] = span[i + 1] ^ prev[1]; - aesCrypto.TransformBlock(output, i * 8, 16, output, i * 8); - prev[0] = sout[i] ^= prev[2]; prev[1] = sout[i + 1] ^= prev[3]; - prev[2] = span[i++]; prev[3] = span[i++]; + byte[] yXOR = new byte[16]; + for (int i = 0; i < input.Length; i += 16) + { + var x = input.Slice(i, 16); + var y = output.AsSpan(i, 16); + for (int j = 0; j < 16; j++) + yXOR[j] = (byte)(x[j] ^ yPrev[j]); + var yFinal = aesCrypto.TransformFinalBlock(yXOR, 0, 16); + for (int j = 0; j < 16; j++) + y[j] = (byte)(yFinal[j] ^ xPrev[j]); + xPrev = x; + yPrev = y; + } } return output; } -#if OBFUSCATION - public sealed class AesCtr(byte[] key, byte[] ivec) : IDisposable - { - readonly ICryptoTransform _encryptor = AesECB.CreateEncryptor(key, null); - readonly byte[] _ecount = new byte[16]; - int _num; - - public void Dispose() => _encryptor.Dispose(); - - public void EncryptDecrypt(Span buffer) - { - for (int i = 0; i < buffer.Length; i++) - { - if (_num == 0) - { - _encryptor.TransformBlock(ivec, 0, 16, _ecount, 0); - for (int n = 15; n >= 0; n--) // increment big-endian counter - if (++ivec[n] != 0) break; - } - buffer[i] ^= _ecount[_num]; - _num = (_num + 1) % 16; - } - } - } - - // see https://core.telegram.org/mtproto/mtproto-transports#transport-obfuscation - internal static (AesCtr, AesCtr, byte[]) InitObfuscation(byte[] secret, byte protocolId, int dcId) - { - byte[] preamble = new byte[64]; - do - RNG.GetBytes(preamble, 0, 58); - while (preamble[0] == 0xef || - BinaryPrimitives.ReadUInt32LittleEndian(preamble) is 0x44414548 or 0x54534f50 or 0x20544547 or 0x4954504f or 0x02010316 or 0xdddddddd or 0xeeeeeeee || - BinaryPrimitives.ReadInt32LittleEndian(preamble.AsSpan(4)) == 0); - preamble[62] = preamble[56]; preamble[63] = preamble[57]; - preamble[56] = preamble[57] = preamble[58] = preamble[59] = protocolId; - preamble[60] = (byte)dcId; preamble[61] = (byte)(dcId >> 8); - - byte[] recvKey = preamble[8..40], recvIV = preamble[40..56]; - Array.Reverse(preamble, 8, 48); - byte[] sendKey = preamble[8..40], sendIV = preamble[40..56]; - if (secret != null) - { - using var sha256 = SHA256.Create(); - sha256.TransformBlock(sendKey, 0, 32, null, 0); - sha256.TransformFinalBlock(secret, 0, 16); - sendKey = sha256.Hash; - sha256.Initialize(); - sha256.TransformBlock(recvKey, 0, 32, null, 0); - sha256.TransformFinalBlock(secret, 0, 16); - recvKey = sha256.Hash; - } - var sendCtr = new AesCtr(sendKey, sendIV); - var recvCtr = new AesCtr(recvKey, recvIV); - var encrypted = (byte[])preamble.Clone(); - sendCtr.EncryptDecrypt(encrypted); - for (int i = 56; i < 64; i++) - preamble[i] = encrypted[i]; - return (sendCtr, recvCtr, preamble); - } -#endif - - internal static async Task Check2FA(Account_Password accountPassword, Func> getPassword) + internal static InputCheckPasswordSRP Check2FA(Account_Password accountPassword, string password) { 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); - } - else - throw new WTException("2FA authentication uses an unsupported algo: " + accountPassword.current_algo?.GetType().Name); + throw new ApplicationException("2FA authentication uses an unsupported algo: " + accountPassword.current_algo?.GetType().Name); + var passwordBytes = Encoding.UTF8.GetBytes(password); var g = new BigInteger(algo.g); var p = BigEndianInteger(algo.p); - var validTask = Task.Run(() => CheckGoodPrime(p, algo.g)); - - System.Threading.Thread.Sleep(100); - Helpers.Log(3, $"This account has enabled 2FA. A password is needed. {accountPassword.hint}"); - var passwordBytes = Encoding.UTF8.GetBytes(await getPassword()); + var g_b = BigEndianInteger(accountPassword.srp_B); + var g_b_256 = g_b.To256Bytes(); + var g_256 = g.To256Bytes(); + ValidityChecks(p, algo.g); using var sha256 = SHA256.Create(); + sha256.Initialize(); sha256.TransformBlock(algo.salt1, 0, algo.salt1.Length, null, 0); sha256.TransformBlock(passwordBytes, 0, passwordBytes.Length, null, 0); sha256.TransformFinalBlock(algo.salt1, 0, algo.salt1.Length); @@ -421,22 +396,12 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB sha256.TransformFinalBlock(algo.salt2, 0, algo.salt2.Length); var x = BigEndianInteger(sha256.Hash); - var v = BigInteger.ModPow(g, x, p); - if (accountPassword.current_algo == null) // we're computing a new password - { - await validTask; - return new InputCheckPasswordSRP { A = v.To256Bytes() }; - } - - var g_b = BigEndianInteger(accountPassword.srp_B); - var g_b_256 = g_b.To256Bytes(); - var g_256 = g.To256Bytes(); - sha256.Initialize(); sha256.TransformBlock(algo.p, 0, 256, null, 0); sha256.TransformFinalBlock(g_256, 0, 256); var k = BigEndianInteger(sha256.Hash); + var v = BigInteger.ModPow(g, x, p); var k_v = (k * v) % p; var a = BigEndianInteger(new Int256(RNG).raw); var g_a = BigInteger.ModPow(g, a, p); @@ -450,7 +415,6 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB var t = (g_b - k_v) % p; //(positive modulo, if the result is negative increment by p) if (t.Sign < 0) t += p; var s_a = BigInteger.ModPow(t, a + u * x, p); - sha256.Initialize(); var k_a = sha256.ComputeHash(s_a.To256Bytes()); hash = sha256.ComputeHash(algo.p); @@ -467,13 +431,12 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB sha256.TransformFinalBlock(k_a, 0, 32); var m1 = sha256.Hash; - await validTask; return new InputCheckPasswordSRP { A = g_a_256, M1 = m1, srp_id = accountPassword.srp_id }; } #if !NETCOREAPP2_0_OR_GREATER // adapted from https://github.com/dotnet/aspnetcore/blob/main/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/ManagedPbkdf2Provider.cs - private static byte[] PBKDF2_SHA512(byte[] password, byte[] salt, int iterationCount, int numBytesRequested) + public static byte[] PBKDF2_SHA512(byte[] password, byte[] salt, int iterationCount, int numBytesRequested) { // PBKDF2 is defined in NIST SP800-132, Sec. 5.3: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf byte[] retVal = new byte[numBytesRequested]; @@ -516,55 +479,4 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB } #endif } - - internal sealed class AES_IGE_Stream : Helpers.IndirectStream - { - private readonly ICryptoTransform _aesCrypto; - private readonly byte[] _prevBytes; - - 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); - if (encrypt) _prevBytes = (byte[])iv.Clone(); - 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(); - - public override int Read(byte[] buffer, int offset, int count) - { - count = _innerStream.Read(buffer, offset, count); - if (count == 0) return 0; - Process(buffer, offset, count); - if (ContentLength.HasValue && _innerStream.Position == _innerStream.Length) - return count - (int)(_innerStream.Position - ContentLength.Value); - return count + 15 & ~15; - } - - public override void Write(byte[] buffer, int offset, int count) - { - Process(buffer, offset, count); - if (ContentLength.HasValue && _innerStream.Position + count > ContentLength) - count -= (int)(_innerStream.Position + count - ContentLength.Value); - _innerStream.Write(buffer, offset, count); - } - - public void Process(byte[] buffer, int offset, int count) - { - count = count + 15 & ~15; - var span = MemoryMarshal.Cast(buffer.AsSpan(offset, count)); - var prev = MemoryMarshal.Cast(_prevBytes.AsSpan()); - for (offset = 0, count /= 8; offset < count;) - { - prev[0] ^= span[offset]; prev[1] ^= span[offset + 1]; - _aesCrypto.TransformBlock(_prevBytes, 0, 16, _prevBytes, 0); - prev[0] ^= prev[2]; prev[1] ^= prev[3]; - prev[2] = span[offset]; prev[3] = span[offset + 1]; - span[offset++] = prev[0]; span[offset++] = prev[1]; - } - } - } } diff --git a/src/Generator.cs b/src/Generator.cs new file mode 100644 index 0000000..cbe34ce --- /dev/null +++ b/src/Generator.cs @@ -0,0 +1,746 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Text.Json; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace WTelegram +{ + public class Generator + { + readonly Dictionary ctorToTypes = new(); + readonly HashSet allTypes = new(); + readonly Dictionary knownStyles = new() { ["InitConnection"] = 1, ["Help_GetConfig"] = 0, ["HttpWait"] = -1 }; + readonly Dictionary typeInfos = new(); + readonly HashSet enumTypes = new(); + int currentLayer; + string tabIndent; + private string currentJson; + + public async Task FromWeb() + { + Console.WriteLine("Fetch web pages..."); +#if DEBUG + currentLayer = await Task.FromResult(TL.Layer.Version); +#else + using var http = new HttpClient(); + //var html = await http.GetStringAsync("https://core.telegram.org/api/layers"); + //currentLayer = int.Parse(Regex.Match(html, @"#layer-(\d+)").Groups[1].Value); + //File.WriteAllBytes("TL.MTProto.json", await http.GetByteArrayAsync("https://core.telegram.org/schema/mtproto-json")); + //File.WriteAllBytes("TL.Schema.json", await http.GetByteArrayAsync("https://core.telegram.org/schema/json")); + File.WriteAllBytes("TL.MTProto.tl", await http.GetByteArrayAsync("https://raw.githubusercontent.com/telegramdesktop/tdesktop/dev/Telegram/Resources/tl/mtproto.tl")); + File.WriteAllBytes("TL.Schema.tl", await http.GetByteArrayAsync("https://raw.githubusercontent.com/telegramdesktop/tdesktop/dev/Telegram/Resources/tl/api.tl")); + File.WriteAllBytes("TL.Secret.json", await http.GetByteArrayAsync("https://core.telegram.org/schema/end-to-end-json")); +#endif + //FromJson("TL.MTProto.json", "TL.MTProto.cs", @"TL.Table.cs"); + //FromJson("TL.Schema.json", "TL.Schema.cs", @"TL.Table.cs"); + FromTL("TL.MTProto.tl", "TL.MTProto.cs"); + FromTL("TL.Schema.tl", "TL.Schema.cs"); + FromJson("TL.Secret.json", "TL.Secret.cs"); + } + + private void FromTL(string tlPath, string outputCs) + { + using var sr = new StreamReader(tlPath); + var schema = new SchemaJson { constructors = new(), methods = new() }; + string line; + bool inFunctions = false; + while ((line = sr.ReadLine()) != null) + { + line = line.Trim(); + if (line == "---functions---") + inFunctions = true; + else if (line == "---types---") + inFunctions = false; + else if (line.StartsWith("// LAYER ")) + currentLayer = int.Parse(line[9..]); + else if (line != "" && !line.StartsWith("//")) + { + if (!line.EndsWith(";")) System.Diagnostics.Debugger.Break(); + var words = line.Split(' '); + int hash = words[0].IndexOf('#'); + if (hash == -1) { Console.WriteLine(line); continue; } + if (words[^2] != "=") { Console.WriteLine(line); continue; } + string name = words[0][0..hash]; + int id = int.Parse(words[0][(hash + 1)..], System.Globalization.NumberStyles.HexNumber); + string type = words[^1].TrimEnd(';'); + var @params = words[1..^2].Where(word => word != "{X:Type}").Select(word => + { + int colon = word.IndexOf(':'); + string name = word[0..colon]; + string type = word[(colon + 1)..]; + if (type == "string" && outputCs == "TL.MTProto.cs" && !name.Contains("message")) type = "bytes"; + return new Param { name = name, type = type }; + }).ToArray(); + if (inFunctions) + schema.methods.Add(new Method { id = id.ToString(), method = name, type = type, @params = @params }); + else + schema.constructors.Add(new Constructor { id = id.ToString(), predicate = name, type = type, @params = @params }); + } + } + FromSchema(schema, outputCs); + } + + public void FromJson(string jsonPath, string outputCs) + { + Console.WriteLine("Parsing " + jsonPath); + var schema = JsonSerializer.Deserialize(File.ReadAllText(jsonPath)); + FromSchema(schema, outputCs); + } + + public void FromSchema(SchemaJson schema, string outputCs) + { + currentJson = Path.GetFileNameWithoutExtension(outputCs); + using var sw = new StreamWriter(outputCs, false, Encoding.UTF8); + sw.WriteLine("// This file is generated automatically using the Generator class"); + sw.WriteLine("using System;"); + if (schema.methods.Count != 0) sw.WriteLine("using System.Threading.Tasks;"); + sw.WriteLine(); + sw.WriteLine("namespace TL"); + sw.WriteLine("{"); + sw.WriteLine("\tusing BinaryWriter = System.IO.BinaryWriter;"); + sw.WriteLine("\tusing Client = WTelegram.Client;"); + tabIndent = "\t"; + foreach (var ctor in schema.constructors) + { + if (ctorToTypes.ContainsKey(ctor.ID)) continue; + if (ctor.type == "Vector t") continue; + var structName = CSharpName(ctor.predicate); + ctorToTypes[ctor.ID] = ctor.layer == 0 ? structName : $"Layer{ctor.layer}.{structName}"; + var typeInfo = typeInfos.GetOrCreate(ctor.type); + if (ctor.ID == 0x5BB8E511) { ctorToTypes[ctor.ID] = structName = ctor.predicate = ctor.type = "_Message"; } + else if (ctor.ID == TL.Layer.NullCtor) { ctorToTypes[ctor.ID] += "=null"; typeInfo.Nullable = ctor; } + if (typeInfo.ReturnName == null) typeInfo.ReturnName = CSharpName(ctor.type); + typeInfo.Structs.Add(ctor); + if (structName == typeInfo.ReturnName) typeInfo.MainClass = ctor; + } + foreach (var (name, typeInfo) in typeInfos) + { + if (allTypes.Contains(typeInfo.ReturnName)) + { + if (typeInfos.TryGetValue(typeInfo.ReturnName, out var existingType)) + { + typeInfo.ReturnName = existingType.ReturnName; + typeInfo.MainClass = existingType.MainClass; + } + continue; + } + if (typeInfo.Structs.All(ctor => ctor.@params.Length == 0)) + typeInfo.AsEnum = true; + var nullable = typeInfo.Structs.Where(c => c.predicate == "help.noAppUpdate" || + c.predicate.EndsWith("Empty") || c.predicate.EndsWith("Unknown") || c.predicate.EndsWith("NotModified")).ToList(); + if (nullable.Count == 1 && nullable[0].@params.Length == 0 && !typeInfo.AsEnum) + { + typeInfo.Nullable = nullable[0]; + typeInfo.Structs.Remove(typeInfo.Nullable); + ctorToTypes[typeInfo.Nullable.ID] += "=null"; + } + if (typeInfo.MainClass == null) + { + List fakeCtorParams = new(); + if (typeInfo.Structs.Count > 1) + { + while (typeInfo.Structs[0].@params.Length > fakeCtorParams.Count) + { + fakeCtorParams.Add(typeInfo.Structs[0].@params[fakeCtorParams.Count]); + if (!typeInfo.Structs.All(ctor => HasPrefix(ctor, fakeCtorParams))) + { + fakeCtorParams.RemoveAt(fakeCtorParams.Count - 1); + break; + } + } + if (fakeCtorParams.Count == 0) + while (typeInfo.Structs[0].@params.Length > fakeCtorParams.Count) + { + fakeCtorParams.Insert(0, typeInfo.Structs[0].@params[^(fakeCtorParams.Count + 1)]); + if (!typeInfo.Structs.All(ctor => HasSuffix(ctor, fakeCtorParams))) + { + fakeCtorParams.RemoveAt(0); + break; + } + } + } + typeInfo.MainClass = new Constructor { id = null, @params = fakeCtorParams.ToArray(), predicate = typeInfo.ReturnName, type = name }; + typeInfo.Structs.Insert(0, typeInfo.MainClass); + typeInfo.CommonFields = fakeCtorParams.Count; // generation of abstract main class with some common fields + } + else if (typeInfo.Structs.Count > 1) + { + if (typeInfo.Structs.All(ctor => ctor == typeInfo.MainClass || HasPrefix(ctor, typeInfo.MainClass.@params) || HasSuffix(ctor, typeInfo.MainClass.@params))) + typeInfo.CommonFields = typeInfo.MainClass.@params.Length; + else + { + // the previous MainClass (ctor have the same name as ReturnName) is incompatible with other classes fields + typeInfo.MainClass = new Constructor { id = null, @params = Array.Empty(), predicate = typeInfo.ReturnName + "Base", type = name }; + typeInfo.Structs.Insert(0, typeInfo.MainClass); + typeInfo.ReturnName = typeInfo.MainClass.predicate; + } + } + } + var layers = schema.constructors.Select(c => c.layer).Distinct().ToList(); + if (layers.Count > 1) // multi-layer file => generate abstract classes out of layer namespaces first + foreach (var typeInfo in typeInfos.Values) + WriteTypeInfo(sw, typeInfo, 0); + foreach (var layer in layers) + { + if (layer != 0) + { + sw.WriteLine(); + sw.WriteLine("\tnamespace Layer" + layer); + sw.Write("\t{"); + tabIndent += "\t"; + } + foreach (var typeInfo in typeInfos.Values) + WriteTypeInfo(sw, typeInfo, layer); + if (layer != 0) + { + sw.WriteLine("\t}"); + tabIndent = tabIndent[1..]; + } + } + if (typeInfos.GetValueOrDefault("Message")?.MainClass.ID == 0x5BB8E511) typeInfos.Remove("Message"); + + if (schema.methods.Count != 0) + { + var ping = schema.methods.FirstOrDefault(m => m.method == "ping"); + if (ping != null) + { + var typeInfo = new TypeInfo { ReturnName = ping.type, MainClass = + new Constructor { id = ping.id, @params = ping.@params, predicate = ping.method, type = ping.type } }; + typeInfo.Structs.Add(typeInfo.MainClass); + ctorToTypes[int.Parse(ping.id)] = CSharpName(ping.method); + WriteTypeInfo(sw, typeInfo, 0); + } + sw.WriteLine(); + sw.WriteLine("\t// ---functions---"); + sw.WriteLine(); + sw.WriteLine($"\tpublic static class {currentJson[3..]}"); + //sw.WriteLine("\tpublic static partial class Fn // ---functions---"); + sw.Write("\t{"); + tabIndent = "\t\t"; + foreach (var method in schema.methods) + { + WriteMethod(sw, method); + //var typeInfo = new TypeInfo { ReturnName = method.type }; + //typeInfo.Structs.Add(new Constructor { id = method.id, @params = method.@params, predicate = method.method, type = method.type }); + //methods.Add(typeInfo); + //WriteTypeInfo(sw, typeInfo, "", true); + } + sw.WriteLine("\t}"); + } + sw.WriteLine("}"); + + UpdateTable("TL.Table.cs"); + } + + void WriteTypeInfo(StreamWriter sw, TypeInfo typeInfo, int layer) + { + var genericType = typeInfo.ReturnName.Length == 1 ? $"<{typeInfo.ReturnName}>" : null; + bool needNewLine = true; + int commonFields = 0; + foreach (var ctor in typeInfo.Structs) + { + if (ctor.layer != layer) continue; + int ctorId = ctor.ID; + string className = CSharpName(ctor.predicate) + genericType; + if (!allTypes.Add((layer == 0 ? "" : $"Layer{layer}.") + className)) continue; + if (needNewLine) { needNewLine = false; sw.WriteLine(); } + var parentClass = ctor == typeInfo.MainClass ? "ITLObject" : typeInfo.ReturnName; + var parms = ctor.@params; + if (ctorId == 0) // abstract parent + { + if (currentJson != "TL.MTProto") + sw.WriteLine($"{tabIndent}///See "); + if (typeInfo.Nullable != null) + sw.WriteLine($"{tabIndent}///a null value means {typeInfo.Nullable.predicate}"); + if (typeInfo.AsEnum) + { + WriteTypeAsEnum(sw, typeInfo); + return; + } + sw.Write($"{tabIndent}public abstract partial class {ctor.predicate}"); + } + else + { + string tldefReverse = null; + if (commonFields != 0) + { + if (ctor.@params[0].name == typeInfo.MainClass.@params[0].name) + parms = ctor.@params.Skip(commonFields).ToArray(); + else + { + parms = ctor.@params.Take(ctor.@params.Length - commonFields).ToArray(); + tldefReverse = ", inheritAfter = true"; + } + } + else + { + foreach (var other in typeInfo.Structs) + { + if (other == ctor) continue; + var otherParams = other.@params; + if (otherParams.Length <= commonFields) continue; + if (!IsDerivedName(ctor.predicate, other.predicate)) continue; + if (HasPrefix(ctor, otherParams)) + { + parms = ctor.@params.Skip(otherParams.Length).ToArray(); + tldefReverse = null; + } + else if (HasSuffix(ctor, otherParams)) + { + parms = ctor.@params.Take(ctor.@params.Length - otherParams.Length).ToArray(); + tldefReverse = ", inheritAfter = true"; + } + else continue; + commonFields = otherParams.Length; + parentClass = CSharpName(other.predicate) + genericType; + } + } + if (currentJson != "TL.MTProto") + { + sw.WriteLine($"{tabIndent}///See "); + if (typeInfo.Nullable != null && ctor == typeInfo.MainClass) + sw.WriteLine($"{tabIndent}///a null value means {typeInfo.Nullable.predicate}"); + sw.WriteLine($"{tabIndent}[TLDef(0x{ctor.ID:X8}{tldefReverse})]"); + } + else + { + sw.Write($"{tabIndent}[TLDef(0x{ctor.ID:X8}{tldefReverse})] //{ctor.predicate}#{ctor.ID:x8} "); + if (genericType != null) sw.Write($"{{{typeInfo.ReturnName}:Type}} "); + foreach (var parm in ctor.@params) sw.Write($"{parm.name}:{parm.type} "); + sw.WriteLine($"= {ctor.type}"); + } + sw.Write($"{tabIndent}public partial class {className}"); + //sw.Write(skipParams == 0 && typeInfo.NeedAbstract > 0 ? "ITLObject" : parentClass); + } + sw.Write(" : "); + sw.Write(parentClass); + if (parms.Length == 0) + { + sw.WriteLine(" { }"); + commonFields = typeInfo.CommonFields; + continue; + } + var hasFlagEnum = parms.Any(p => p.type.StartsWith("flags.")); + bool multiline = hasFlagEnum || parms.Length > 1; + if (multiline) + { + sw.WriteLine(); + sw.WriteLine(tabIndent + "{"); + } + else + sw.Write(" { "); + if (hasFlagEnum) + { + var list = new SortedList(); + foreach (var parm in parms) + { + if (!parm.type.StartsWith("flags.") || !parm.type.EndsWith("?true")) continue; + var mask = 1 << int.Parse(parm.type[6..parm.type.IndexOf('?')]); + if (!list.ContainsKey(mask)) list[mask] = MapName(parm.name); + } + foreach (var parm in parms) + { + if (!parm.type.StartsWith("flags.") || parm.type.EndsWith("?true")) continue; + var mask = 1 << int.Parse(parm.type[6..parm.type.IndexOf('?')]); + if (list.ContainsKey(mask)) continue; + var name = MapName("has_" + parm.name); + if (list.Values.Contains(name)) name += "_field"; + list[mask] = name; + } + string line = tabIndent + "\t[Flags] public enum Flags { "; + foreach (var (mask, name) in list) + { + var str = $"{name} = 0x{mask:X}, "; + if (line.Length + str.Length + tabIndent.Length * 3 >= 134) { sw.WriteLine(line); line = tabIndent + "\t\t"; } + line += str; + } + sw.WriteLine(line.TrimEnd(',', ' ') + " }"); + } + foreach (var parm in parms) + { + if (parm.type.EndsWith("?true")) continue; + if (multiline) sw.Write(tabIndent + "\t"); + if (parm.type == "#") + sw.Write($"public {(hasFlagEnum ? "Flags" : "int")} {parm.name};"); + else + { + if (parm.type.StartsWith("flags.")) + { + int qm = parm.type.IndexOf('?'); + sw.Write($"[IfFlag({parm.type[6..qm]})] public {MapType(parm.type[(qm + 1)..], parm.name)} {MapName(parm.name)};"); + } + else + sw.Write($"public {MapType(parm.type, parm.name)} {MapName(parm.name)};"); + } + if (multiline) sw.WriteLine(); + } + + if (multiline) + sw.WriteLine(tabIndent + "}"); + else + sw.WriteLine(" }"); + commonFields = typeInfo.CommonFields; + } + } + + private static bool IsDerivedName(string derived, string basename) + { + int left, right; + if (basename.Length >= derived.Length) return false; + for (left = 0; left < basename.Length; left++) + if (basename[left] != derived[left]) + break; + if (left == 0) return false; + for (right = 1; left + right <= basename.Length; right++) + if (basename[^right] != derived[^right]) + break; + return left + right > basename.Length; + } + + private void WriteTypeAsEnum(StreamWriter sw, TypeInfo typeInfo) + { + enumTypes.Add(typeInfo.ReturnName); + bool lowercase = typeInfo.ReturnName == "Storage_FileType"; + sw.WriteLine($"{tabIndent}public enum {typeInfo.ReturnName} : uint"); + sw.WriteLine($"{tabIndent}{{"); + string prefix = ""; + while ((prefix += typeInfo.Structs[1].predicate[prefix.Length]) != null) + if (!typeInfo.Structs.All(ctor => ctor.id == null || ctor.predicate.StartsWith(prefix))) + break; + int prefixLen = CSharpName(prefix).Length - 1; + foreach (var ctor in typeInfo.Structs) + { + if (ctor.id == null) continue; + string className = CSharpName(ctor.predicate); + if (!allTypes.Add(className)) continue; + if (lowercase) className = className.ToLowerInvariant(); + ctorToTypes.Remove(ctor.ID); + sw.WriteLine($"{tabIndent}\t///See "); + sw.WriteLine($"{tabIndent}\t{className[prefixLen..]} = 0x{ctor.ID:X8},"); + } + sw.WriteLine($"{tabIndent}}}"); + } + + + private static string MapName(string name) => name switch + { + "out" => "out_", + "static" => "static_", + "long" => "long_", + "default" => "default_", + "public" => "public_", + "params" => "params_", + "private" => "private_", + _ => name + }; + + private string MapType(string type, string name) + { + if (type.StartsWith("Vector<", StringComparison.OrdinalIgnoreCase)) + return MapType(type[7..^1], name) + "[]"; + else if (type == "Bool") + return "bool"; + else if (type == "bytes") + return "byte[]"; + else if (type == "int128") + return "Int128"; + else if (type == "int256") + return "Int256"; + else if (type == "Object") + return "ITLObject"; + else if (type == "!X") + return "ITLFunction"; + else if (type == "int") + { + var name2 = '_' + name + '_'; + if (name2.EndsWith("_date_") || name2.EndsWith("_time_") || name2.StartsWith("_valid_") || + name2 == "_expires_" || name2 == "_expires_at_" || name2 == "_now_") + return "DateTime"; + else + return "int"; + } + else if (type == "string") + return name.StartsWith("md5") ? "byte[]" : "string"; + else if (type == "long" || type == "double" || type == "X") + return type; + else if (typeInfos.TryGetValue(type, out var typeInfo)) + return typeInfo.ReturnName; + else + { // try to find type in a lower layer + /*foreach (var layer in typeInfosByLayer.OrderByDescending(kvp => kvp.Key)) + if (layer.Value.TryGetValue(type, out typeInfo)) + return layer.Key == 0 ? typeInfo.ReturnName : $"Layer{layer.Key}.{typeInfo.ReturnName}";*/ + return CSharpName(type); + } + } + + private string MapOptionalType(string type, string name) + { + if (type == "Bool") + return "bool?"; + else if (type == "long") + return "long?"; + else if (type == "double") + return "double?"; + else if (type == "int128") + return "Int128?"; + else if (type == "int256") + return "Int256?"; + else if (type == "int") + { + var name2 = '_' + name + '_'; + if (name2.EndsWith("_date_") || name2.EndsWith("_time_") || name2 == "_expires_" || name2 == "_now_" || name2.StartsWith("_valid_")) + return "DateTime?"; + else + return "int?"; + } + else + return MapType(type, name); + } + + private void WriteMethod(StreamWriter sw, Method method) + { + int ctorNb = int.Parse(method.id); + var funcName = CSharpName(method.method); + string returnType = MapType(method.type, ""); + int style = knownStyles.GetValueOrDefault(funcName, 2); + // styles: 0 = static string, 1 = static ITLFunction<>, 2 = Task<>, -1 = skip method + if (style == -1) return; + sw.WriteLine(); + + var callAsync = "CallAsync"; + if (method.type.Length == 1 && style != 1) funcName += $"<{returnType}>"; + if (currentJson != "TL.MTProto") + sw.WriteLine($"{tabIndent}///See "); + else + { + if (method.type is not "FutureSalts" and not "Pong") callAsync = "CallBareAsync"; + sw.Write($"{tabIndent}//{method.method}#{ctorNb:x8} "); + if (method.type.Length == 1) sw.Write($"{{{method.type}:Type}} "); + foreach (var parm in method.@params) sw.Write($"{parm.name}:{parm.type} "); + sw.WriteLine($"= {method.type}"); + } + + if (style == 0) sw.WriteLine($"{tabIndent}public static Task<{returnType}> {funcName}(this Client client) => client.{callAsync}<{returnType}>({funcName});"); + if (style == 0) sw.Write($"{tabIndent}public static string {funcName}(BinaryWriter writer"); + if (style == 1) sw.Write($"{tabIndent}public static ITLFunction {funcName}("); + if (style == 2) sw.Write($"{tabIndent}public static Task<{returnType}> {funcName}(this Client client"); + bool first = style == 1; + foreach (var parm in method.@params) // output non-optional parameters + { + if (parm.type == "#" || parm.type.StartsWith("flags.")) continue; + if (first) first = false; else sw.Write(", "); + sw.Write($"{MapType(parm.type, parm.name)} {MapName(parm.name)}"); + } + string flagExpr = null; + foreach (var parm in method.@params) // output optional parameters + { + if (!parm.type.StartsWith("flags.")) continue; + var parmName = MapName(parm.name); + int qm = parm.type.IndexOf('?'); + int bit = int.Parse(parm.type[6..qm]); + if (first) first = false; else sw.Write(", "); + if (parm.type.EndsWith("?true")) + { + sw.Write($"bool {parmName} = false"); + flagExpr += $" | ({parmName} ? 0x{1 << bit:X} : 0)"; + } + else + { + sw.Write($"{MapOptionalType(parm.type[(qm + 1)..], parm.name)} {parmName} = null"); + flagExpr += $" | ({parmName} != null ? 0x{1 << bit:X} : 0)"; + } + } + if (flagExpr != null) flagExpr = flagExpr.IndexOf('|', 3) >= 0 ? flagExpr[3..] : flagExpr[4..^1]; + sw.WriteLine(")"); + if (style != 0) tabIndent += "\t"; + if (style == 1) sw.WriteLine($"{tabIndent}=> writer =>"); + if (style == 2) sw.WriteLine($"{tabIndent}=> client.{callAsync}<{returnType}>(writer =>"); + sw.WriteLine(tabIndent + "{"); + sw.WriteLine($"{tabIndent}\twriter.Write(0x{ctorNb:X8});"); + foreach (var parm in method.@params) // serialize request + { + var parmName = MapName(parm.name); + var parmType = parm.type; + if (parmType.StartsWith("flags.")) + { + if (parmType.EndsWith("?true")) continue; + int qm = parmType.IndexOf('?'); + parmType = parmType[(qm + 1)..]; + sw.WriteLine($"{tabIndent}\tif ({parmName} != null)"); + sw.Write('\t'); + if (MapOptionalType(parmType, parm.name).EndsWith("?")) + parmName += ".Value"; + } + switch (parmType) + { + case "Bool": + sw.WriteLine($"{tabIndent}\twriter.Write({parmName} ? 0x997275B5 : 0xBC799737);"); + break; + case "bytes": + sw.WriteLine($"{tabIndent}\twriter.WriteTLBytes({parmName});"); + break; + case "long": case "int128": case "int256": case "double": + sw.WriteLine($"{tabIndent}\twriter.Write({parmName});"); + break; + case "int": + if (MapType(parmType, parm.name) == "int") + sw.WriteLine($"{tabIndent}\twriter.Write({parmName});"); + else + sw.WriteLine($"{tabIndent}\twriter.WriteTLStamp({parmName});"); + break; + case "string": + if (parm.name.StartsWith("md5")) + sw.WriteLine($"{tabIndent}\twriter.WriteTLBytes({parmName});"); + else + sw.WriteLine($"{tabIndent}\twriter.WriteTLString({parmName});"); + break; + case "#": + sw.WriteLine($"{tabIndent}\twriter.Write({flagExpr});"); + break; + case "!X": + sw.WriteLine($"{tabIndent}\t{parmName}(writer);"); + break; + default: + if (parmType.StartsWith("Vector<", StringComparison.OrdinalIgnoreCase)) + sw.WriteLine($"{tabIndent}\twriter.WriteTLVector({parmName});"); + else if (enumTypes.Contains(parmType)) + sw.WriteLine($"{tabIndent}\twriter.Write((uint){parmName});"); + else + sw.WriteLine($"{tabIndent}\twriter.WriteTLObject({parmName});"); + break; + } + } + sw.WriteLine($"{tabIndent}\treturn \"{funcName}\";"); + if (style == 0) sw.WriteLine(tabIndent + "}"); + if (style == 1) sw.WriteLine(tabIndent + "};"); + if (style == 2) sw.WriteLine(tabIndent + "});"); + if (style != 0) tabIndent = tabIndent[0..^1]; + } + + void UpdateTable(string tableCs) + { + int tableId = 0; + var myTag = $"\t\t\t// from {currentJson}:"; + var seen_ids = new HashSet(); + var seen_nullables = new HashSet(); + using (var sr = new StreamReader(tableCs)) + using (var sw = new StreamWriter(tableCs + ".new", false, Encoding.UTF8)) + { + string line; + while ((line = sr.ReadLine()) != null) + { + if (currentLayer != 0 && line.StartsWith("\t\tpublic const int Layer")) + sw.WriteLine($"\t\tpublic const int Layer = {currentLayer};\t\t\t\t\t// fetched {DateTime.UtcNow}"); + else + sw.WriteLine(line); + if (line == myTag) + { + switch (++tableId) + { + case 1: + foreach (var ctor in ctorToTypes) + if (seen_ids.Add(ctor.Key)) + if (ctor.Value.EndsWith("=null")) + sw.WriteLine($"\t\t\t[0x{ctor.Key:X8}] = null,//{ctor.Value[..^5]}"); + else + sw.WriteLine($"\t\t\t[0x{ctor.Key:X8}] = typeof({ctor.Value}),"); + break; + case 2: + foreach (var typeInfo in typeInfos.Values) + if (typeInfo.Nullable != null && seen_nullables.Add(typeInfo.ReturnName)) + sw.WriteLine($"\t\t\t[typeof({typeInfo.ReturnName})]{new string(' ', 30 - typeInfo.ReturnName.Length)} = 0x{typeInfo.Nullable.ID:X8}, //{typeInfo.Nullable.predicate}"); + break; + } + while ((line = sr.ReadLine()) != null) + if (line.StartsWith("\t\t\t// ")) + break; + sw.WriteLine(line); + } + else if (line.StartsWith("\t\t\t[0x")) + seen_ids.Add(int.Parse(line[6..14], System.Globalization.NumberStyles.HexNumber)); + else if (line.StartsWith("\t\t\t[typeof(")) + seen_nullables.Add(line[11..line.IndexOf(')')]); + } + } + File.Replace(tableCs + ".new", tableCs, null); + } + + private static bool HasPrefix(Constructor ctor, IList prefixParams) + { + if (ctor.@params.Length < prefixParams.Count) return false; + for (int i = 0; i < prefixParams.Count; i++) + if (ctor.@params[i].name != prefixParams[i].name || ctor.@params[i].type != prefixParams[i].type) + return false; + return true; + } + + private static bool HasSuffix(Constructor ctor, IList prefixParams) + { + if (ctor.@params.Length < prefixParams.Count) return false; + for (int i = 1; i <= prefixParams.Count; i++) + if (ctor.@params[^i].name != prefixParams[^i].name || ctor.@params[^i].type != prefixParams[^i].type) + return false; + return true; + } + + private static string CSharpName(string name) + { + name = char.ToUpper(name[0]) + name[1..]; + int i; + while ((i = name.IndexOf('_')) > 0) + name = name[..i] + char.ToUpper(name[i + 1]) + name[(i + 2)..]; + while ((i = name.IndexOf('.')) > 0) + name = name[..i] + '_' + char.ToUpper(name[i + 1]) + name[(i + 2)..]; + return name; + } + + class TypeInfo + { + public string ReturnName; + public Constructor MainClass; + public Constructor Nullable; + public List Structs = new(); + internal int CommonFields; // n fields are common among all those classes + internal bool AsEnum; + } + +#pragma warning disable IDE1006 // Naming Styles + public class SchemaJson + { + public List constructors { get; set; } + public List methods { get; set; } + } + + public class Constructor + { + public string id { get; set; } + public string predicate { get; set; } + public Param[] @params { get; set; } + public string type { get; set; } + public int layer { get; set; } + + public int ID => string.IsNullOrEmpty(id) ? 0 : int.Parse(id); + } + + public class Param + { + public string name { get; set; } + public string type { get; set; } + } + + public class Method + { + public string id { get; set; } + public string method { get; set; } + public Param[] @params { get; set; } + public string type { get; set; } + } +#pragma warning restore IDE1006 // Naming Styles + } +} diff --git a/src/Helpers.TL.cs b/src/Helpers.TL.cs new file mode 100644 index 0000000..a7fc6b2 --- /dev/null +++ b/src/Helpers.TL.cs @@ -0,0 +1,276 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Web; + +namespace TL +{ + partial class InputPeer { public static InputPeerSelf Self => new(); } + partial class InputUser { public static InputUserSelf Self => new(); } + + partial class ChatBase + { + public abstract long ID { get; } + public abstract string Title { get; } + /// returns true if you're banned of any of these rights + public abstract bool IsBanned(ChatBannedRights.Flags flags = 0); + protected abstract InputPeer ToInputPeer(); + public static implicit operator InputPeer(ChatBase chat) => chat.ToInputPeer(); + } + partial class ChatEmpty + { + public override long ID => id; + public override string Title => null; + public override bool IsBanned(ChatBannedRights.Flags flags = 0) => true; + protected override InputPeer ToInputPeer() => null; + } + partial class Chat + { + public override long ID => id; + public override string Title => title; + public override bool IsBanned(ChatBannedRights.Flags flags = 0) => ((default_banned_rights?.flags ?? 0) & flags) != 0; + protected override InputPeer ToInputPeer() => new InputPeerChat { chat_id = id }; + } + partial class ChatForbidden + { + public override long ID => id; + public override string Title => title; + public override bool IsBanned(ChatBannedRights.Flags flags = 0) => true; + protected override InputPeer ToInputPeer() => new InputPeerChat { chat_id = id }; + } + partial class Channel + { + public override long ID => id; + public override string Title => title; + public override bool IsBanned(ChatBannedRights.Flags flags = 0) => ((banned_rights?.flags ?? 0) & flags) != 0 || ((default_banned_rights?.flags ?? 0) & flags) != 0; + protected override InputPeer ToInputPeer() => new InputPeerChannel { channel_id = id, access_hash = access_hash }; + public static implicit operator InputChannel(Channel channel) => new() { channel_id = channel.id, access_hash = channel.access_hash }; + } + partial class ChannelForbidden + { + public override long ID => id; + public override string Title => title; + public override bool IsBanned(ChatBannedRights.Flags flags = 0) => true; + protected override InputPeer ToInputPeer() => new InputPeerChannel { channel_id = id, access_hash = access_hash }; + } + + partial class UserBase + { + public abstract long ID { get; } + public abstract string DisplayName { get; } + protected abstract InputPeer ToInputPeer(); + protected abstract InputUserBase ToInputUser(); + public static implicit operator InputPeer(UserBase user) => user.ToInputPeer(); + public static implicit operator InputUserBase(UserBase user) => user.ToInputUser(); + } + partial class UserEmpty + { + public override long ID => id; + public override string DisplayName => null; + protected override InputPeer ToInputPeer() => null; + protected override InputUserBase ToInputUser() => null; + } + partial class User + { + public override long ID => id; + public override string DisplayName => username != null ? '@' + username : last_name == null ? first_name : $"{first_name} {last_name}"; + protected override InputPeer ToInputPeer() => new InputPeerUser { user_id = id, access_hash = access_hash }; + protected override InputUserBase ToInputUser() => new InputUser { user_id = id, access_hash = access_hash }; + } + + partial class MessageBase + { + public abstract long ID { get; } + public abstract Peer Peer { get; } + public abstract DateTime Date { get; } + } + partial class MessageEmpty + { + public override long ID => id; + public override Peer Peer => peer_id; + public override DateTime Date => default; + } + public partial class Message + { + public override long ID => id; + public override Peer Peer => peer_id; + public override DateTime Date => date; + } + public partial class MessageService + { + public override long ID => id; + public override Peer Peer => peer_id; + public override DateTime Date => date; + } + + partial class PhotoBase + { + public abstract long ID { get; } + protected abstract InputPhoto ToInputPhoto(); + public static implicit operator InputPhoto(PhotoBase photo) => photo.ToInputPhoto(); + } + partial class PhotoEmpty + { + public override long ID => id; + protected override InputPhoto ToInputPhoto() => null; + } + partial class Photo + { + public override long ID => id; + + protected override InputPhoto ToInputPhoto() => new() { id = id, access_hash = access_hash, file_reference = file_reference }; + public InputPhotoFileLocation ToFileLocation() => ToFileLocation(LargestPhotoSize); + public InputPhotoFileLocation ToFileLocation(PhotoSizeBase photoSize) => new() { id = id, access_hash = access_hash, file_reference = file_reference, thumb_size = photoSize.Type }; + public PhotoSizeBase LargestPhotoSize => sizes.Aggregate((agg, next) => (long)next.Width * next.Height > (long)agg.Width * agg.Height ? next : agg); + } + + partial class PhotoSizeBase + { + public abstract string Type { get; } + public abstract int Width { get; } + public abstract int Height { get; } + public abstract int FileSize { get; } + } + partial class PhotoSizeEmpty + { + public override string Type => type; + public override int Width => 0; + public override int Height => 0; + public override int FileSize => 0; + } + partial class PhotoSize + { + public override string Type => type; + public override int Width => w; + public override int Height => h; + public override int FileSize => size; + } + partial class PhotoCachedSize + { + public override string Type => type; + public override int Width => w; + public override int Height => h; + public override int FileSize => bytes.Length; + } + partial class PhotoStrippedSize + { + public override string Type => type; + public override int Width => bytes[2]; + public override int Height => bytes[1]; + public override int FileSize => bytes.Length; + } + partial class PhotoSizeProgressive + { + public override string Type => type; + public override int Width => w; + public override int Height => h; + public override int FileSize => sizes.Last(); + } + partial class PhotoPathSize + { + public override string Type => type; + public override int Width => -1; + public override int Height => -1; + public override int FileSize => bytes.Length; + } + namespace Layer23 + { + partial class PhotoSize + { + public override string Type => type; + public override int Width => w; + public override int Height => h; + public override int FileSize => size; + } + partial class PhotoCachedSize + { + public override string Type => type; + public override int Width => w; + public override int Height => h; + public override int FileSize => bytes.Length; + } + } + + partial class DocumentBase + { + public abstract long ID { get; } + protected abstract InputDocument ToInputDocument(); + public static implicit operator InputDocument(DocumentBase document) => document.ToInputDocument(); + } + partial class DocumentEmpty + { + public override long ID => id; + protected override InputDocument ToInputDocument() => null; + } + partial class Document + { + public override long ID => id; + protected override InputDocument ToInputDocument() => new() { id = id, access_hash = access_hash, file_reference = file_reference }; + public InputDocumentFileLocation ToFileLocation(PhotoSizeBase thumbSize = null) => new() { id = id, access_hash = access_hash, file_reference = file_reference, thumb_size = thumbSize?.Type }; + } + + partial class EncryptedFile + { + public static implicit operator InputEncryptedFile(EncryptedFile file) => file == null ? null : new InputEncryptedFile { id = file.id, access_hash = file.access_hash }; + public InputEncryptedFileLocation ToFileLocation() => new() { id = id, access_hash = access_hash }; + } + + partial class SecureFile + { + public static implicit operator InputSecureFile(SecureFile file) => new() { id = file.id, access_hash = file.access_hash }; + public InputSecureFileLocation ToFileLocation() => new() { id = id, access_hash = access_hash }; + } + + partial class InputFileBase + { + public abstract InputEncryptedFileBase ToInputEncryptedFile(int key_fingerprint); + public abstract InputSecureFileBase ToInputSecureFile(byte[] file_hash, byte[] secret); + } + partial class InputFile + { + public override InputEncryptedFileBase ToInputEncryptedFile(int key_fingerprint) => new InputEncryptedFileUploaded { id = id, parts = parts, md5_checksum = md5_checksum, key_fingerprint = key_fingerprint }; + public override InputSecureFileBase ToInputSecureFile(byte[] file_hash, byte[] secret) => new InputSecureFileUploaded { id = id, parts = parts, md5_checksum = md5_checksum, file_hash = file_hash, secret = secret }; + } + partial class InputFileBig + { + public override InputEncryptedFileBase ToInputEncryptedFile(int key_fingerprint) => new InputEncryptedFileBigUploaded { id = id, parts = parts, key_fingerprint = key_fingerprint }; + public override InputSecureFileBase ToInputSecureFile(byte[] file_hash, byte[] secret) => new InputSecureFileUploaded { id = id, parts = parts, file_hash = file_hash, secret = secret }; + } + + partial class StickerSet + { + public static implicit operator InputStickerSetID(StickerSet stickerSet) => new() { id = stickerSet.id, access_hash = stickerSet.access_hash }; + } + + partial class Peer { public abstract long ID { get; } } + partial class PeerUser { public override long ID => user_id; public override string ToString() => "user " + user_id; } + partial class PeerChat { public override long ID => chat_id; public override string ToString() => "chat " + chat_id; } + partial class PeerChannel { public override long ID => channel_id; public override string ToString() => "channel " + channel_id; } + + partial class JsonObjectValue { public override string ToString() => $"{HttpUtility.JavaScriptStringEncode(key, true)}:{value}"; } + partial class JsonNull { public override string ToString() => "null"; } + partial class JsonBool { public override string ToString() => value ? "true" : "false"; } + partial class JsonNumber { public override string ToString() => value.ToString(CultureInfo.InvariantCulture); } + partial class JsonString { public override string ToString() => HttpUtility.JavaScriptStringEncode(value, true); } + partial class JsonArray + { + public override string ToString() + { + var sb = new StringBuilder().Append('['); + for (int i = 0; i < value.Length; i++) + sb.Append(i == 0 ? "" : ",").Append(value[i]); + return sb.Append(']').ToString(); + } + } + partial class JsonObject + { + public override string ToString() + { + var sb = new StringBuilder().Append('{'); + for (int i = 0; i < value.Length; i++) + sb.Append(i == 0 ? "" : ",").Append(value[i]); + return sb.Append('}').ToString(); + } + } +} diff --git a/src/Helpers.cs b/src/Helpers.cs index ea7d0b5..0a39a5a 100644 --- a/src/Helpers.cs +++ b/src/Helpers.cs @@ -1,117 +1,23 @@ using System; using System.Collections.Generic; -using System.IO; using System.Numerics; -using System.Reflection; using System.Text.Json; using System.Text.Json.Serialization; -using System.Threading; -using System.Threading.Tasks; - -#if NET8_0_OR_GREATER -[JsonSerializable(typeof(WTelegram.Session))] -[JsonSerializable(typeof(Dictionary))] -[JsonSerializable(typeof(IDictionary))] -[JsonSerializable(typeof(System.Collections.Immutable.ImmutableDictionary))] -internal partial class WTelegramContext : JsonSerializerContext { } -#endif namespace WTelegram { public static class Helpers { - /// Callback for logging a line (string) with its associated severity level (int) + // int argument is the LogLevel: https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel public static Action Log { get; set; } = DefaultLogger; - /// For serializing indented Json with fields included - public static readonly JsonSerializerOptions JsonOptions = new() { IncludeFields = true, WriteIndented = true, -#if NET8_0_OR_GREATER - TypeInfoResolver = JsonSerializer.IsReflectionEnabledByDefault ? null : WTelegramContext.Default, - Converters = { new TLJsonConverter(), new JsonStringEnumConverter() }, -#endif - IgnoreReadOnlyProperties = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault }; + public static readonly JsonSerializerOptions JsonOptions = new() { IncludeFields = true, WriteIndented = true }; -#if NET8_0_OR_GREATER - public sealed class TLJsonConverter : JsonConverter - { - public override bool CanConvert(Type typeToConvert) - => typeToConvert.IsAbstract || typeToConvert == typeof(Dictionary) || typeToConvert == typeof(Dictionary); - public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (typeToConvert == typeof(Dictionary)) - { - if (reader.TokenType != JsonTokenType.StartArray) throw new JsonException("Expected array for users dictionary"); - var users = new Dictionary(); - while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) - { - var user = JsonSerializer.Deserialize(ref reader, options); - if (user != null) users[user.id] = user; - } - return users; - } - else if (typeToConvert == typeof(Dictionary)) - { - if (reader.TokenType != JsonTokenType.StartArray) throw new JsonException("Expected array for chats dictionary"); - var chats = new Dictionary(); - while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) - { - var chat = (TL.ChatBase)Read(ref reader, typeof(TL.ChatBase), options); - if (chat != null) chats[chat.ID] = chat; - } - return chats; - } - else if (reader.TokenType == JsonTokenType.Null) - return null; - else if (reader.TokenType == JsonTokenType.StartObject) - { - var typeReader = reader; - if (!typeReader.Read() || typeReader.TokenType != JsonTokenType.PropertyName || typeReader.GetString() != "$") - throw new JsonException("Expected $ type property"); - if (!typeReader.Read() || typeReader.TokenType != JsonTokenType.String) - throw new JsonException("Invalid $ type property"); - var type = typeReader.GetString(); - var actualType = typeToConvert.Assembly.GetType("TL." + type); - if (!typeToConvert.IsAssignableFrom(actualType)) - throw new JsonException($"Incompatible $ type: {type} -> {typeToConvert}"); - return JsonSerializer.Deserialize(ref reader, actualType, options); - } - throw new JsonException($"Unexpected token type: {reader.TokenType}"); - } - public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) - { - if (value is Dictionary users) - { - writer.WriteStartArray(); - foreach (var element in users.Values) - JsonSerializer.Serialize(writer, element, options); - writer.WriteEndArray(); - } - else if (value is Dictionary chats) - { - writer.WriteStartArray(); - foreach (var element in chats.Values) - Write(writer, element, options); - writer.WriteEndArray(); - } - else if (value is null) - writer.WriteNullValue(); - else - { - var actualType = value.GetType(); - var jsonObject = JsonSerializer.SerializeToElement(value, actualType, options); - writer.WriteStartObject(); - writer.WriteString("$", actualType.Name); - foreach (var property in jsonObject.EnumerateObject()) - if (char.IsLower(property.Name[0])) - property.WriteTo(writer); - writer.WriteEndObject(); - } - } - } -#endif + public static V GetOrCreate(this Dictionary dictionary, K key) where V : new() + => dictionary.TryGetValue(key, out V value) ? value : dictionary[key] = new V(); - private static readonly ConsoleColor[] LogLevelToColor = [ ConsoleColor.DarkGray, ConsoleColor.DarkCyan, - ConsoleColor.Cyan, ConsoleColor.Yellow, ConsoleColor.Red, ConsoleColor.Magenta, ConsoleColor.DarkBlue ]; + private static readonly ConsoleColor[] LogLevelToColor = new[] { ConsoleColor.DarkGray, ConsoleColor.DarkCyan, ConsoleColor.Cyan, + ConsoleColor.Yellow, ConsoleColor.Red, ConsoleColor.Magenta, ConsoleColor.DarkBlue }; private static void DefaultLogger(int level, string message) { Console.ForegroundColor = LogLevelToColor[level]; @@ -119,17 +25,47 @@ namespace WTelegram Console.ResetColor(); } - public static V GetOrCreate(this Dictionary dictionary, K key) where V : new() - => dictionary.TryGetValue(key, out V value) ? value : dictionary[key] = new V(); + internal class PolymorphicConverter : JsonConverter where T : class + { + public override bool HandleNull => true; + + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + { + if (value == null) + writer.WriteNullValue(); + else + { + writer.WriteStartObject(); + writer.WritePropertyName(value.GetType().FullName); + JsonSerializer.Serialize(writer, value, value.GetType(), JsonOptions); + writer.WriteEndObject(); + } + } + + public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + return null; + else if (reader.TokenType == JsonTokenType.StartObject) + { + if (!reader.Read() || reader.TokenType != JsonTokenType.PropertyName) throw new JsonException(); + var returnType = typeToConvert.Assembly.GetType(reader.GetString()); + if (!typeToConvert.IsAssignableFrom(returnType)) throw new JsonException(); + var result = (T)JsonSerializer.Deserialize(ref reader, returnType, JsonOptions); + if (!reader.Read() || reader.TokenType != JsonTokenType.EndObject) throw new JsonException(); + return result; + } + else + throw new JsonException(); + } + } - /// Get a cryptographic random 64-bit value public static long RandomLong() { #if NETCOREAPP2_1_OR_GREATER - long value = 0; - System.Security.Cryptography.RandomNumberGenerator.Fill(System.Runtime.InteropServices.MemoryMarshal.AsBytes( - System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref value, 1))); - return value; + Span span = stackalloc long[1]; + System.Security.Cryptography.RandomNumberGenerator.Fill(System.Runtime.InteropServices.MemoryMarshal.AsBytes(span)); + return span[0]; #else var span = new byte[8]; Encryption.RNG.GetBytes(span); @@ -137,30 +73,17 @@ namespace WTelegram #endif } - public static async Task FullReadAsync(this Stream stream, byte[] buffer, int length, CancellationToken ct) + public static byte[] ToBigEndian(ulong value) // variable-size buffer { - for (int offset = 0; offset < length;) - { -#pragma warning disable CA1835 - var read = await stream.ReadAsync(buffer, offset, length - offset, ct); -#pragma warning restore CA1835 - if (read == 0) return offset; - offset += read; - } - return length; - } - - internal static byte[] ToBigEndian(ulong value) // variable-size buffer - { - int i = 1; - for (ulong temp = value; (temp >>= 8) != 0; ) i++; + int i; + var temp = value; + for (i = 1; (temp >>= 8) != 0; i++) ; var result = new byte[i]; - for (; --i >= 0; value >>= 8) - result[i] = (byte)value; + while (--i >= 0) { result[i] = (byte)value; value >>= 8; } return result; } - internal static ulong FromBigEndian(byte[] bytes) // variable-size buffer + public static ulong FromBigEndian(byte[] bytes) // variable-size buffer { if (bytes.Length > 8) throw new ArgumentException($"expected bytes length <= 8 but got {bytes.Length}"); ulong result = 0; @@ -178,7 +101,7 @@ namespace WTelegram return result; } - internal static ulong PQFactorize(ulong pq) // ported from https://github.com/tdlib/td/blob/master/tdutils/td/utils/crypto.cpp#L103 + internal static ulong PQFactorize(ulong pq) // ported from https://github.com/tdlib/td/blob/master/tdutils/td/utils/crypto.cpp#L90 { if (pq < 2) return 1; var random = new Random(); @@ -192,16 +115,26 @@ namespace WTelegram for (int j = 1; j < lim; j++) { iter++; - // x = (q + x * x) % pq - ulong res = q, a = x; - while (x != 0) + ulong a = x; + ulong b = x; + ulong c = q; + + // c += a * b + while (b != 0) { - if ((x & 1) != 0) - res = (res + a) % pq; - a = (a + a) % pq; - x >>= 1; + if ((b & 1) != 0) + { + c += a; + if (c >= pq) + c -= pq; + } + a += a; + if (a >= pq) + a -= pq; + b >>= 1; } - x = res; + + x = c; ulong z = x < y ? pq + x - y : x - y; g = gcd(z, pq); if (g != 1) @@ -221,25 +154,43 @@ namespace WTelegram } return g; - static ulong gcd(ulong left, ulong right) + static ulong gcd(ulong a, ulong b) { - while (right != 0) + if (a == 0) return b; + if (b == 0) return a; + + int shift = 0; + while ((a & 1) == 0 && (b & 1) == 0) { - ulong num = left % right; - left = right; - right = num; + a >>= 1; + b >>= 1; + shift++; + } + + while (true) + { + while ((a & 1) == 0) + a >>= 1; + while ((b & 1) == 0) + b >>= 1; + if (a > b) + a -= b; + else if (b > a) + b -= a; + else + return a << shift; } - return left; } } public static int MillerRabinIterations { get; set; } = 64; // 64 is OpenSSL default for 2048-bits numbers - /// Miller–Rabin primality test - /// The number to check for primality + private static readonly HashSet GoodPrimes = new(); + // Miller–Rabin primality test public static bool IsProbablePrime(this BigInteger n) { var n_minus_one = n - BigInteger.One; if (n_minus_one.Sign <= 0) return false; + if (GoodPrimes.Contains(n)) return true; int s; var d = n_minus_one; @@ -274,80 +225,8 @@ namespace WTelegram } if (r == 0) return false; } + GoodPrimes.Add(n); return true; } - - internal static readonly byte[] StrippedThumbJPG = // see https://core.telegram.org/api/files#stripped-thumbnails - [ - 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, - 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x28, 0x1c, - 0x1e, 0x23, 0x1e, 0x19, 0x28, 0x23, 0x21, 0x23, 0x2d, 0x2b, 0x28, 0x30, 0x3c, 0x64, 0x41, 0x3c, 0x37, 0x37, - 0x3c, 0x7b, 0x58, 0x5d, 0x49, 0x64, 0x91, 0x80, 0x99, 0x96, 0x8f, 0x80, 0x8c, 0x8a, 0xa0, 0xb4, 0xe6, 0xc3, - 0xa0, 0xaa, 0xda, 0xad, 0x8a, 0x8c, 0xc8, 0xff, 0xcb, 0xda, 0xee, 0xf5, 0xff, 0xff, 0xff, 0x9b, 0xc1, 0xff, - 0xff, 0xff, 0xfa, 0xff, 0xe6, 0xfd, 0xff, 0xf8, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x2b, 0x2d, 0x2d, 0x3c, 0x35, - 0x3c, 0x76, 0x41, 0x41, 0x76, 0xf8, 0xa5, 0x8c, 0xa5, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, - 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, - 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, - 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x22, 0x00, - 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, - 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, - 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, - 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, - 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, - 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, - 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x00, 0x1f, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, - 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, - 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, - 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, - 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, - 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, - 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, - 0x3f, 0x00 - ]; - - internal static string GetSystemVersion() - { - var os = System.Runtime.InteropServices.RuntimeInformation.OSDescription; - int space = os.IndexOf(' ') + 1, dot = os.IndexOf('.'); - return os[(os.IndexOf(' ', space) < 0 ? 0 : space)..(dot < 0 ? os.Length : dot)]; - } - - internal static string GetAppVersion() - => (Assembly.GetEntryAssembly() ?? Array.Find(AppDomain.CurrentDomain.GetAssemblies(), a => a.EntryPoint != null))?.GetName().Version.ToString() ?? "0.0"; - - public class IndirectStream(Stream innerStream) : Stream - { - public long? ContentLength; - protected readonly Stream _innerStream = innerStream; - public override bool CanRead => _innerStream.CanRead; - public override bool CanSeek => ContentLength.HasValue || _innerStream.CanSeek; - public override bool CanWrite => _innerStream.CanWrite; - public override long Length => ContentLength ?? _innerStream.Length; - public override long Position { get => _innerStream.Position; set => _innerStream.Position = value; } - public override void Flush() => _innerStream.Flush(); - public override long Seek(long offset, SeekOrigin origin) => _innerStream.Seek(offset, origin); - public override void SetLength(long value) => _innerStream.SetLength(value); - public override void Write(byte[] buffer, int offset, int count) => _innerStream.Write(buffer, offset, count); - public override int Read(byte[] buffer, int offset, int count) => _innerStream.Read(buffer, offset, count); - protected override void Dispose(bool disposing) => _innerStream.Dispose(); - } - } - - public class WTException : ApplicationException - { - public WTException(string message) : base(message) { } - public WTException(string message, Exception innerException) : base(message, innerException) { } } } diff --git a/src/SecretChats.cs b/src/SecretChats.cs deleted file mode 100644 index 5773c8c..0000000 --- a/src/SecretChats.cs +++ /dev/null @@ -1,626 +0,0 @@ -using System; -using System.Buffers.Binary; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Numerics; -using System.Security.Cryptography; -using System.Text; -using System.Threading.Tasks; -using TL; -using static WTelegram.Compat; -using static WTelegram.Encryption; - -namespace WTelegram -{ - public interface ISecretChat - { - int ChatId { get; } - long RemoteUserId { get; } - InputEncryptedChat Peer { get; } - int RemoteLayer { get; } - } - - [TLDef(0xFEFEFEFE)] [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles")] - internal sealed partial class SecretChat : IObject, ISecretChat - { - [Flags] public enum Flags : uint { requestChat = 1, renewKey = 2, acceptKey = 4, originator = 8, commitKey = 16 } - public Flags flags; - public InputEncryptedChat peer = new(); - public byte[] salt; // contains future/discarded authKey during acceptKey/commitKey - public byte[] authKey; - public DateTime key_created; - public int key_useCount; - public long participant_id; - public int remoteLayer = 46; - public int in_seq_no = -2, out_seq_no = 0; - 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 = []; - internal void Discarded() // clear out fields for more security - { - Array.Clear(authKey, 0, authKey.Length); - key_fingerprint = participant_id = peer.access_hash = peer.chat_id = in_seq_no = out_seq_no = remoteLayer = 0; - } - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles")] - public sealed class SecretChats : IDisposable - { - public event Action OnChanged; - - private readonly Client client; - private readonly FileStream storage; - private readonly Dictionary chats = []; - private Messages_DhConfig dh; - private BigInteger dh_prime; - private readonly SHA256 sha256 = SHA256.Create(); - private readonly SHA1 sha1 = SHA1.Create(); - private readonly Random random = new(); - private const int ThresholdPFS = 100; - - /// Instantiate a Secret Chats manager - /// The Telegram client - /// File path to load/save secret chats keys/status (optional) - public SecretChats(Client client, string filename = null) - { - this.client = client; - if (filename != null) - { - storage = File.Open(filename, FileMode.OpenOrCreate); - if (storage.Length != 0) Load(storage); - OnChanged = () => { storage.SetLength(0); Save(storage); }; - } - } - public void Dispose() { OnChanged?.Invoke(); storage?.Dispose(); sha256.Dispose(); sha1.Dispose(); } - - public List Chats => [.. chats.Values]; - - public bool IsChatActive(int chat_id) => !(chats.GetValueOrDefault(chat_id)?.flags.HasFlag(SecretChat.Flags.requestChat) ?? true); - - public void Save(Stream output) - { - using var writer = new BinaryWriter(output, Encoding.UTF8, true); - writer.Write(0); - writer.WriteTLObject(dh); - writer.Write(chats.Count); - foreach (var chat in chats.Values) - writer.WriteTLObject(chat); - } - public void Load(Stream input) - { - using var reader = new BinaryReader(input, Encoding.UTF8, true); - if (reader.ReadInt32() != 0) throw new WTException("Unrecognized Secrets format"); - dh = (Messages_DhConfig)reader.ReadTLObject(); - if (dh?.p != null) dh_prime = BigEndianInteger(dh.p); - int count = reader.ReadInt32(); - for (int i = 0; i < count; i++) - { - var chat = (SecretChat)reader.ReadTLObject(); - if (chat.authKey?.Length > 0) chat.key_fingerprint = BinaryPrimitives.ReadInt64LittleEndian(sha1.ComputeHash(chat.authKey).AsSpan(12)); - chats[chat.ChatId] = chat; - } - } - - /// Terminate the secret chat - /// Secret Chat ID - /// Whether to delete the entire chat history for the other user as well - public async Task Discard(int chat_id, bool delete_history = false) - { - if (chats.TryGetValue(chat_id, out var chat)) - { - chats.Remove(chat_id); - chat.Discarded(); - } - try - { - await client.Messages_DiscardEncryption(chat_id, delete_history); - } - catch (RpcException ex) when (ex.Code == 400 && ex.Message == "ENCRYPTION_ALREADY_DECLINED") { } - } - - private async Task UpdateDHConfig() - { - var mdhcb = await client.Messages_GetDhConfig(dh?.version ?? 0, 256); - if (mdhcb is Messages_DhConfigNotModified { random: var random }) - _ = dh ?? throw new WTException("DhConfigNotModified on zero version"); - else if (mdhcb is Messages_DhConfig dhc) - { - var p = BigEndianInteger(dhc.p); - CheckGoodPrime(p, dhc.g); - (dh, dh_prime, random, dh.random) = (dhc, p, dhc.random, null); - } - else throw new WTException("Unexpected DHConfig response: " + mdhcb?.GetType().Name); - if (random.Length != 256) throw new WTException("Invalid DHConfig random"); - var salt = new byte[256]; - RNG.GetBytes(salt); - for (int i = 0; i < 256; i++) salt[i] ^= random[i]; - return salt; - } - - /// Initiate a secret chat with the given user.
(chat must be acknowledged by remote user before being active)
- /// The remote user - /// Secret Chat ID - /// - public async Task Request(InputUserBase user) - { - int chat_id; - do chat_id = (int)Helpers.RandomLong(); while (chats.ContainsKey(chat_id)); - var chat = chats[chat_id] = new SecretChat - { - flags = SecretChat.Flags.requestChat | SecretChat.Flags.originator, - peer = { chat_id = chat_id }, - participant_id = user.UserId ?? 0, - salt = await UpdateDHConfig(), - out_seq_no = 1, - }; - var a = BigEndianInteger(chat.salt); - var g_a = BigInteger.ModPow(dh.g, a, dh_prime); - CheckGoodGaAndGb(g_a, dh_prime); - var ecb = await client.Messages_RequestEncryption(user, chat_id, g_a.To256Bytes()); - if (ecb is not EncryptedChatWaiting ecw || ecw.id != chat_id || ecw.participant_id != chat.participant_id) - throw new WTException("Invalid " + ecb?.GetType().Name); - chat.peer.access_hash = ecw.access_hash; - return chat_id; - } - - /// Processes the you received from Telegram (). - /// If update.chat is , you might want to first make sure you want to accept this secret chat initiated by user - /// Incoming requests for secret chats are automatically: accepted (), rejected () or ignored () - /// if the update was handled successfully - /// - public async Task HandleUpdate(UpdateEncryption update, bool? acceptChatRequests = true) - { - try - { - if (chats.TryGetValue(update.chat.ID, out var chat)) - { - if (update.chat is EncryptedChat ec && chat.flags.HasFlag(SecretChat.Flags.requestChat)) // remote accepted our request - { - var a = BigEndianInteger(chat.salt); - var g_b = BigEndianInteger(ec.g_a_or_b); - CheckGoodGaAndGb(g_b, dh_prime); - var gab = BigInteger.ModPow(g_b, a, dh_prime); - chat.flags &= ~SecretChat.Flags.requestChat; - SetAuthKey(chat, gab.To256Bytes()); - if (ec.key_fingerprint != chat.key_fingerprint) throw new WTException("Invalid fingerprint on accepted secret chat"); - if (ec.access_hash != chat.peer.access_hash || ec.participant_id != chat.participant_id) throw new WTException("Invalid peer on accepted secret chat"); - await SendNotifyLayer(chat); - return true; - } - else if (update.chat is EncryptedChatDiscarded ecd) - { - chats.Remove(chat.ChatId); - chat.Discarded(); - return true; - } - Helpers.Log(3, $"Unexpected {update.chat.GetType().Name} for secret chat {chat.ChatId}"); - return false; - } - else if (update.chat is EncryptedChatRequested ecr) // incoming request - { - switch (acceptChatRequests) - { - case null: return false; - case false: await client.Messages_DiscardEncryption(ecr.id, false); return true; - case true: - var salt = await UpdateDHConfig(); - var b = BigEndianInteger(salt); - var g_b = BigInteger.ModPow(dh.g, b, dh_prime); - var g_a = BigEndianInteger(ecr.g_a); - CheckGoodGaAndGb(g_a, dh_prime); - CheckGoodGaAndGb(g_b, dh_prime); - var gab = BigInteger.ModPow(g_a, b, dh_prime); - chat = chats[ecr.id] = new SecretChat - { - flags = 0, - peer = { chat_id = ecr.id, access_hash = ecr.access_hash }, - participant_id = ecr.admin_id, - in_seq_no = -1, - }; - SetAuthKey(chat, gab.To256Bytes()); - var ecb = await client.Messages_AcceptEncryption(chat.peer, g_b.ToByteArray(true, true), chat.key_fingerprint); - if (ecb is not EncryptedChat ec || ec.id != ecr.id || ec.access_hash != ecr.access_hash || - ec.admin_id != ecr.admin_id || ec.key_fingerprint != chat.key_fingerprint) - throw new WTException("Inconsistent accepted secret chat"); - await SendNotifyLayer(chat); - return true; - } - } - else if (update.chat is EncryptedChatDiscarded) // unknown chat discarded - return true; - Helpers.Log(3, $"Unexpected {update.chat.GetType().Name} for unknown secret chat {update.chat.ID}"); - return false; - } - catch - { - await Discard(update.chat.ID); - throw; - } - finally - { - OnChanged?.Invoke(); - } - } - - private void SetAuthKey(SecretChat chat, byte[] key) - { - chat.authKey = key; - chat.key_fingerprint = BinaryPrimitives.ReadInt64LittleEndian(sha1.ComputeHash(key).AsSpan(12)); - chat.exchange_id = 0; - chat.key_useCount = 0; - chat.key_created = DateTime.UtcNow; - } - - private async Task SendNotifyLayer(SecretChat chat) - { - 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 - ///
Remember to fill random_id with , and the flags field if necessary
- /// Secret Chat ID - /// The pre-filled DecryptedMessage or DecryptedMessageService to send - /// Send encrypted message without a notification - /// Optional file attachment. See method UploadFile - /// Confirmation of sent message - public async Task SendMessage(int chatId, DecryptedMessageBase msg, bool silent = false, InputEncryptedFileBase file = null) - { - if (!chats.TryGetValue(chatId, out var chat)) throw new WTException("Secret chat not found"); - try - { - var dml = new TL.Layer23.DecryptedMessageLayer - { - layer = Math.Min(chat.remoteLayer, Layer.SecretChats), - random_bytes = new byte[15], - in_seq_no = chat.in_seq_no < 0 ? chat.in_seq_no + 2 : chat.in_seq_no, - out_seq_no = chat.out_seq_no, - message = msg - }; - //Debug.WriteLine($">\t\t\t\t{dml.in_seq_no}\t{dml.out_seq_no}"); - var result = await SendMessage(chat, dml, silent, file); - chat.out_seq_no += 2; - return result; - } - finally - { - OnChanged?.Invoke(); - } - } - - 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); - using var memStream = new MemoryStream(1024); - using var writer = new BinaryWriter(memStream); - - using var clearStream = new MemoryStream(1024); - using var clearWriter = new BinaryWriter(clearStream); - clearWriter.Write(chat.authKey, 88 + x, 32); - clearWriter.Write(0); // int32 message_data_length (to be patched) - clearWriter.WriteTLObject(dml); // bytes message_data - int clearLength = (int)clearStream.Length - 32; // length before padding (= 4 + message_data_length) - int padding = (0x7FFFFFF0 - clearLength) % 16; - padding += random.Next(2, 16) * 16; // MTProto 2.0 padding must be between 12..1024 with total length divisible by 16 - clearStream.SetLength(32 + clearLength + padding); - byte[] clearBuffer = clearStream.GetBuffer(); - BinaryPrimitives.WriteInt32LittleEndian(clearBuffer.AsSpan(32), clearLength - 4); // patch message_data_length - RNG.GetBytes(clearBuffer, 32 + clearLength, padding); - var msgKeyLarge = sha256.ComputeHash(clearBuffer, 0, 32 + clearLength + padding); - const int msgKeyOffset = 8; // msg_key = middle 128-bits of SHA256(authkey_part+plaintext+padding) - byte[] encrypted_data = EncryptDecryptMessage(clearBuffer.AsSpan(32, clearLength + padding), true, x, chat.authKey, msgKeyLarge, msgKeyOffset, sha256); - - writer.Write(chat.key_fingerprint); // int64 key_fingerprint - writer.Write(msgKeyLarge, msgKeyOffset, 16); // int128 msg_key - writer.Write(encrypted_data); // bytes encrypted_data - var data = memStream.ToArray(); - - CheckPFS(chat); - if (file != null) - return await client.Messages_SendEncryptedFile(chat.peer, dml.message.RandomId, data, file, silent); - 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); - } - - private IObject Decrypt(SecretChat chat, byte[] data, int dataLen) - { - if (dataLen < 32) // authKeyId+msgKey+(length+ctorNb) - throw new WTException($"Encrypted packet too small: {data.Length}"); - var authKey = chat.authKey; - long authKeyId = BinaryPrimitives.ReadInt64LittleEndian(data); - if (authKeyId == chat.key_fingerprint) - if (!chat.flags.HasFlag(SecretChat.Flags.commitKey)) CheckPFS(chat); - else { chat.flags &= ~SecretChat.Flags.commitKey; Array.Clear(chat.salt, 0, chat.salt.Length); } - else if (chat.flags.HasFlag(SecretChat.Flags.commitKey) && authKeyId == BinaryPrimitives.ReadInt64LittleEndian(sha1.ComputeHash(chat.salt).AsSpan(12))) authKey = chat.salt; - else throw new WTException($"Received a packet encrypted with unexpected key {authKeyId:X}"); - int x = (int)(chat.flags & SecretChat.Flags.originator); - byte[] decrypted_data = EncryptDecryptMessage(data.AsSpan(24, dataLen - 24), false, x, authKey, data, 8, sha256); - var length = BinaryPrimitives.ReadInt32LittleEndian(decrypted_data); - var success = length >= 4 && length <= decrypted_data.Length - 4; - if (success) - { - sha256.Initialize(); - sha256.TransformBlock(authKey, 88 + x, 32, null, 0); - sha256.TransformFinalBlock(decrypted_data, 0, decrypted_data.Length); - if (success = data.AsSpan(8, 16).SequenceEqual(sha256.Hash.AsSpan(8, 16))) - if (decrypted_data.Length - 4 - length is < 12 or > 1024) throw new WTException($"Invalid MTProto2 padding length: {decrypted_data.Length - 4}-{length}"); - else if (chat.remoteLayer < Layer.MTProto2) chat.remoteLayer = Layer.MTProto2; - } - if (!success) throw new WTException("Could not decrypt message"); - if (length % 4 != 0) throw new WTException($"Invalid message_data_length: {length}"); - using var reader = new BinaryReader(new MemoryStream(decrypted_data, 4, length)); - return reader.ReadTLObject(); - } - - /// 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.
- /// 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)
- /// - public ICollection DecryptMessage(EncryptedMessageBase msg, bool fillGaps = true) - { - if (!chats.TryGetValue(msg.ChatId, out var chat)) throw new WTException("Secret chat not found"); - try - { - var obj = Decrypt(chat, msg.Bytes, msg.Bytes.Length); - if (obj is not TL.Layer23.DecryptedMessageLayer dml) throw new WTException("Decrypted object is not DecryptedMessageLayer"); - if (dml.random_bytes.Length < 15) throw new WTException("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 WTException("Invalid seq_no parities"); - if (dml.layer > chat.remoteLayer) chat.remoteLayer = dml.layer; - //Debug.WriteLine($"<\t{dml.in_seq_no}\t{dml.out_seq_no}\t\t\t\t\t\texpected:{chat.out_seq_no}/{chat.in_seq_no + 2}"); - if (dml.out_seq_no <= chat.in_seq_no) return []; // already received message - var pendingMsgSeqNo = chat.pendingMsgs.Keys; - if (fillGaps && dml.out_seq_no > chat.in_seq_no + 2) - { - var lastPending = pendingMsgSeqNo.LastOrDefault(); - 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.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 []; - } - chat.in_seq_no = dml.out_seq_no; - if (pendingMsgSeqNo.Count == 0 || pendingMsgSeqNo[0] != dml.out_seq_no + 2) - if (HandleAction(chat, dml.message.Action)) return []; - else return [dml.message]; - else // we have pendingMsgs completing the sequence in order - { - var list = new List(); - if (!HandleAction(chat, dml.message.Action)) - list.Add(dml.message); - do - { - dml = chat.pendingMsgs.Values[0]; - chat.pendingMsgs.RemoveAt(0); - chat.in_seq_no += 2; - if (!HandleAction(chat, dml.message.Action)) - list.Add(dml.message); - } while (pendingMsgSeqNo.Count != 0 && pendingMsgSeqNo[0] == chat.in_seq_no + 2); - return list; - } - } - catch (Exception) - { - _ = Discard(msg.ChatId); - throw; - } - finally - { - OnChanged?.Invoke(); - } - } - - private bool HandleAction(SecretChat chat, DecryptedMessageAction action) - { - switch (action) - { - case TL.Layer23.DecryptedMessageActionNotifyLayer dmanl: - chat.remoteLayer = dmanl.layer; - return true; - 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.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], - in_seq_no = chat.in_seq_no, - message = msgSvc - }; - for (dml.out_seq_no = resend.start_seq_no; dml.out_seq_no <= resend.end_seq_no; dml.out_seq_no += 2) - { - msgSvc.random_id = Helpers.RandomLong(); - _ = SendMessage(chat, dml); - } - return true; - case TL.Layer23.DecryptedMessageActionNoop: - Helpers.Log(1, $"SC{(short)chat.ChatId:X4}> Noop"); - return true; - 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; - } - return false; - } - - private async void CheckPFS(SecretChat chat) - { - if (++chat.key_useCount < ThresholdPFS && chat.key_created >= DateTime.UtcNow.AddDays(-7)) return; - if (chat.key_useCount < ThresholdPFS) chat.key_useCount = ThresholdPFS; - if ((chat.flags & (SecretChat.Flags.requestChat | SecretChat.Flags.renewKey | SecretChat.Flags.acceptKey)) != 0) - if (chat.key_useCount < ThresholdPFS * 2) return; - 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.exchange_id = Helpers.RandomLong(); - 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) - { - Helpers.Log(4, "Error in CheckRenewKey: " + ex); - chat.flags &= ~SecretChat.Flags.renewKey; - } - } - - private async void HandlePFS(SecretChat chat, DecryptedMessageAction action) - { - try - { - switch (action) - { - case TL.Layer23.DecryptedMessageActionRequestKey request: - switch (chat.flags & (SecretChat.Flags.requestChat | SecretChat.Flags.renewKey | SecretChat.Flags.acceptKey)) - { - case SecretChat.Flags.renewKey: // Concurrent Re-Keying - if (chat.exchange_id > request.exchange_id) return; // we won, ignore the smaller exchange_id RequestKey - chat.flags &= ~SecretChat.Flags.renewKey; - if (chat.exchange_id == request.exchange_id) // equal => silent abort both re-keing - { - Array.Clear(chat.salt, 0, chat.salt.Length); - chat.exchange_id = 0; - return; - } - break; // we lost, process with the larger exchange_id RequestKey - case 0: break; - default: throw new WTException("Invalid RequestKey"); - } - var g_a = BigEndianInteger(request.g_a); - var salt = new byte[256]; - RNG.GetBytes(salt); - var b = BigEndianInteger(salt); - var g_b = BigInteger.ModPow(dh.g, b, dh_prime); - CheckGoodGaAndGb(g_a, dh_prime); - CheckGoodGaAndGb(g_b, dh_prime); - var gab = BigInteger.ModPow(g_a, b, dh_prime); - chat.flags |= SecretChat.Flags.acceptKey; - 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.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.Layer23.DecryptedMessageActionAcceptKey accept: - if ((chat.flags & (SecretChat.Flags.requestChat | SecretChat.Flags.renewKey | SecretChat.Flags.acceptKey)) != SecretChat.Flags.renewKey) - throw new WTException("Invalid AcceptKey"); - if (accept.exchange_id != chat.exchange_id) - throw new WTException("AcceptKey: exchange_id mismatch"); - var a = BigEndianInteger(chat.salt); - g_b = BigEndianInteger(accept.g_b); - CheckGoodGaAndGb(g_b, dh_prime); - gab = BigInteger.ModPow(g_b, a, dh_prime); - var authKey = gab.To256Bytes(); - key_fingerprint = BinaryPrimitives.ReadInt64LittleEndian(sha1.ComputeHash(authKey).AsSpan(12)); - if (accept.key_fingerprint != key_fingerprint) - throw new WTException("AcceptKey: key_fingerprint mismatch"); - _ = 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.Layer23.DecryptedMessageActionCommitKey commit: - if ((chat.flags & (SecretChat.Flags.requestChat | SecretChat.Flags.renewKey | SecretChat.Flags.acceptKey)) != SecretChat.Flags.acceptKey) - throw new WTException("Invalid RequestKey"); - key_fingerprint = BinaryPrimitives.ReadInt64LittleEndian(sha1.ComputeHash(chat.salt).AsSpan(12)); - if (commit.exchange_id != chat.exchange_id | commit.key_fingerprint != key_fingerprint) - throw new WTException("CommitKey: data mismatch"); - chat.flags &= ~SecretChat.Flags.acceptKey; - 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.Layer23.DecryptedMessageService { random_id = Helpers.RandomLong(), - action = new TL.Layer23.DecryptedMessageActionNoop() }); - break; - 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; - chat.flags &= ~(SecretChat.Flags.renewKey | SecretChat.Flags.acceptKey); - Array.Clear(chat.salt, 0, chat.salt.Length); - chat.exchange_id = 0; - break; - } - } - catch (Exception ex) - { - Helpers.Log(4, $"Error handling {action}: {ex}"); - _ = Discard(chat.ChatId); - } - } - - /// Upload a file to Telegram in encrypted form - /// Content of the file to upload. This method close/dispose the stream - /// The associated media structure that will be updated with file size and the random AES key/iv - /// (optional) Callback for tracking the progression of the transfer - /// the uploaded file info that should be passed to method SendMessage - public async Task UploadFile(Stream stream, DecryptedMessageMedia media, Client.ProgressCallback progress = null) - { - byte[] aes_key = new byte[32], aes_iv = new byte[32]; - RNG.GetBytes(aes_key); - RNG.GetBytes(aes_iv); - media.SizeKeyIV = (stream.Length, aes_key, aes_iv); - - using var md5 = MD5.Create(); - md5.TransformBlock(aes_key, 0, 32, null, 0); - var res = md5.TransformFinalBlock(aes_iv, 0, 32); - long fingerprint = BinaryPrimitives.ReadInt64LittleEndian(md5.Hash); - fingerprint ^= fingerprint >> 32; - - using var ige = new AES_IGE_Stream(stream, aes_key, aes_iv, true); - 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 - /// The encrypted file to download & decrypt - /// The associated message media structure - /// Stream to write the decrypted file content to. This method does not close/dispose the stream - /// (optional) Callback for tracking the progression of the transfer - /// The mime type of the decrypted file, if unknown - public async Task DownloadFile(EncryptedFile encryptedFile, DecryptedMessageMedia media, Stream outputStream, Client.ProgressCallback progress = null) - { - var (size, key, iv) = media.SizeKeyIV; - if (key == null || iv == null) throw new ArgumentException("Media has no information about encrypted file", nameof(media)); - using var md5 = MD5.Create(); - md5.TransformBlock(key, 0, 32, null, 0); - var res = md5.TransformFinalBlock(iv, 0, 32); - long fingerprint = BinaryPrimitives.ReadInt64LittleEndian(md5.Hash); - fingerprint ^= fingerprint >> 32; - if (encryptedFile.key_fingerprint != (int)fingerprint) throw new WTException("Encrypted file fingerprint mismatch"); - - using var decryptStream = new AES_IGE_Stream(outputStream, size, key, iv); - var fileLocation = encryptedFile.ToFileLocation(); - await client.DownloadFileAsync(fileLocation, decryptStream, encryptedFile.dc_id, encryptedFile.size, progress); - return media.MimeType; - } - } -} diff --git a/src/Services.cs b/src/Services.cs deleted file mode 100644 index ebf7733..0000000 --- a/src/Services.cs +++ /dev/null @@ -1,594 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Web; -using WTelegram; - -namespace TL -{ - public static class Services - { - public sealed partial class CollectorPeer(IDictionary _users, IDictionary _chats) : Peer, IPeerCollector - { - public override long ID => 0; - protected internal override IPeerInfo UserOrChat(Dictionary users, Dictionary chats) - { - if (users != null) Collect(users.Values); - if (chats != null) Collect(chats.Values); - return null; - } - - public void Collect(IEnumerable users) - { - lock (_users) - foreach (var user in users) - if (user != null) - if (!user.flags.HasFlag(User.Flags.min) || !_users.TryGetValue(user.id, out var prevUser) || prevUser.flags.HasFlag(User.Flags.min)) - _users[user.id] = user; - else - { // update previously full user from min user: - // see https://github.com/tdlib/td/blob/master/td/telegram/UserManager.cpp#L2689 - // and https://github.com/telegramdesktop/tdesktop/blob/dev/Telegram/SourceFiles/data/data_session.cpp#L515 - const User.Flags updated_flags = User.Flags.deleted | User.Flags.bot | User.Flags.bot_chat_history | - User.Flags.bot_nochats | User.Flags.verified | User.Flags.restricted | User.Flags.has_bot_inline_placeholder | - User.Flags.bot_inline_geo | User.Flags.support | User.Flags.scam | User.Flags.fake | User.Flags.bot_attach_menu | - User.Flags.premium | User.Flags.has_emoji_status; - const User.Flags2 updated_flags2 = User.Flags2.has_usernames | User.Flags2.stories_unavailable | - User.Flags2.has_color | User.Flags2.has_profile_color | User.Flags2.contact_require_premium | - User.Flags2.bot_business | User.Flags2.bot_has_main_app | User.Flags2.bot_forum_view; - // tdlib updated flags: deleted | bot | bot_chat_history | bot_nochats | verified | bot_inline_geo - // | support | scam | fake | bot_attach_menu | premium - // tdesktop non-updated flags: bot | bot_chat_history | bot_nochats | bot_attach_menu - // updated flags2: stories_unavailable | main_app | bot_business | bot_forum_view (tdlib) | contact_require_premium (tdesktop) - prevUser.flags = (prevUser.flags & ~updated_flags) | (user.flags & updated_flags); - prevUser.flags2 = (prevUser.flags2 & ~updated_flags2) | (user.flags2 & updated_flags2); - prevUser.first_name ??= user.first_name; // tdlib: not updated ; tdesktop: updated only if unknown - prevUser.last_name ??= user.last_name; // tdlib: not updated ; tdesktop: updated only if unknown - //prevUser.username ??= user.username; // tdlib/tdesktop: not updated - prevUser.phone ??= user.phone; // tdlib: updated only if unknown ; tdesktop: not updated - if (prevUser.flags.HasFlag(User.Flags.apply_min_photo) && user.photo != null) - { - prevUser.photo = user.photo; // tdlib/tdesktop: updated on apply_min_photo - prevUser.flags |= User.Flags.has_photo; - } - prevUser.bot_info_version = user.bot_info_version; // tdlib: updated ; tdesktop: not updated - prevUser.restriction_reason = user.restriction_reason; // tdlib: updated ; tdesktop: not updated - prevUser.bot_inline_placeholder = user.bot_inline_placeholder;// tdlib: updated ; tdesktop: ignored - if (user.lang_code != null) - prevUser.lang_code = user.lang_code; // tdlib: updated if present ; tdesktop: ignored - prevUser.emoji_status = user.emoji_status; // tdlib/tdesktop: updated - //prevUser.usernames = user.usernames; // tdlib/tdesktop: not updated - if (user.stories_max_id != null) - prevUser.stories_max_id = user.stories_max_id; // tdlib: updated if > 0 ; tdesktop: not updated - prevUser.color = user.color; // tdlib/tdesktop: updated - prevUser.profile_color = user.profile_color; // tdlib/tdesktop: unimplemented yet - _users[user.id] = prevUser; - } - } - - public void Collect(IEnumerable chats) - { - lock (_chats) - foreach (var chat in chats) - if (chat is not Channel channel) - _chats[chat.ID] = chat; - else if (!_chats.TryGetValue(channel.id, out var prevChat) || prevChat is not Channel prevChannel) - _chats[channel.id] = channel; - else if (!channel.flags.HasFlag(Channel.Flags.min) || prevChannel.flags.HasFlag(Channel.Flags.min)) - { - if (channel.participants_count == 0) channel.participants_count = prevChannel.participants_count; // non-min channel can lack this info - _chats[channel.id] = channel; - } - else - { // update previously full channel from min channel: - const Channel.Flags updated_flags = (Channel.Flags)0x7FDC0BE0; - const Channel.Flags2 updated_flags2 = (Channel.Flags2)0x781; - // tdesktop updated flags: broadcast | verified | megagroup | signatures | scam | has_link | slowmode_enabled - // | call_active | call_not_empty | fake | gigagroup | noforwards | join_to_send | join_request | forum - // tdlib nonupdated flags: broadcast | signatures | call_active | call_not_empty | noforwards - prevChannel.flags = (prevChannel.flags & ~updated_flags) | (channel.flags & updated_flags); - prevChannel.flags2 = (prevChannel.flags2 & ~updated_flags2) | (channel.flags2 & updated_flags2); - prevChannel.title = channel.title; // tdlib/tdesktop: updated - prevChannel.username = channel.username; // tdlib/tdesktop: updated - prevChannel.photo = channel.photo; // tdlib: updated if not banned ; tdesktop: updated - prevChannel.restriction_reason = channel.restriction_reason; // tdlib: updated ; tdesktop: not updated - prevChannel.default_banned_rights = channel.default_banned_rights; // tdlib/tdesktop: updated - if (channel.participants_count > 0) - prevChannel.participants_count = channel.participants_count; // tdlib/tdesktop: updated if present - prevChannel.usernames = channel.usernames; // tdlib/tdesktop: updated - prevChannel.color = channel.color; // tdlib: not updated ; tdesktop: updated - prevChannel.profile_color = channel.profile_color; // tdlib/tdesktop: ignored - prevChannel.emoji_status = channel.emoji_status; // tdlib: not updated ; tdesktop: updated - prevChannel.level = channel.level; // tdlib: not updated ; tdesktop: updated - _chats[channel.id] = prevChannel; - } - } - - public bool HasUser(long id) { lock (_users) return _users.ContainsKey(id); } - public bool HasChat(long id) { lock (_chats) return _chats.ContainsKey(id); } - } - - /// Accumulate users/chats found in this structure in your dictionaries, ignoring Min constructors when the full object is already stored - /// The structure having a users - public static void CollectUsersChats(this IPeerResolver structure, IDictionary users, IDictionary chats) - => structure.UserOrChat(new CollectorPeer(users, chats)); - - [EditorBrowsable(EditorBrowsableState.Never)][Obsolete("The method you're looking for is Messages_GetAllChats", true)] - public static Task Messages_GetChats(this Client _) => throw new WTException("The method you're looking for is Messages_GetAllChats"); - [EditorBrowsable(EditorBrowsableState.Never)][Obsolete("The method you're looking for is Messages_GetAllChats", true)] - public static Task Channels_GetChannels(this Client _) => throw new WTException("The method you're looking for is Messages_GetAllChats"); - [EditorBrowsable(EditorBrowsableState.Never)][Obsolete("The method you're looking for is Messages_GetAllDialogs", true)] - public static Task Users_GetUsers(this Client _) => throw new WTException("The method you're looking for is Messages_GetAllDialogs"); - [EditorBrowsable(EditorBrowsableState.Never)][Obsolete("If you want to get all messages from a chat, use method Messages_GetHistory", true)] - public static Task Messages_GetMessages(this Client _) => throw new WTException("If you want to get all messages from a chat, use method Messages_GetHistory"); - } - - public static class Markdown - { - /// Converts a Markdown text into the (plain text + entities) format used by Telegram messages - /// not used anymore, you can pass null - /// [in] The Markdown text
[out] The same (plain) text, stripped of all Markdown notation - /// 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 Client _, ref string text, IReadOnlyDictionary users = null) - { - var entities = new List(); - MessageEntityBlockquote lastBlockQuote = null; - int offset, inCode = 0; - var sb = new StringBuilder(text); - for (offset = 0; offset < sb.Length;) - { - switch (sb[offset]) - { - case '\r': sb.Remove(offset, 1); break; - case '\\': sb.Remove(offset++, 1); break; - case '*' when inCode == 0: ProcessEntity(); break; - case '~' when inCode == 0: ProcessEntity(); break; - case '_' when inCode == 0: - if (offset + 1 < sb.Length && sb[offset + 1] == '_') - { - sb.Remove(offset, 1); - ProcessEntity(); - } - else - ProcessEntity(); - break; - case '|': - if (inCode == 0 && offset + 1 < sb.Length && sb[offset + 1] == '|') - { - sb.Remove(offset, 1); - ProcessEntity(); - } - else - offset++; - break; - case '`': - int count = entities.Count; - if (offset + 2 < sb.Length && sb[offset + 1] == '`' && sb[offset + 2] == '`') - { - int len = 3; - if (entities.FindLast(e => e.length == -1) is MessageEntityPre pre) - pre.length = offset - pre.offset; - else - { - while (offset + len < sb.Length && !char.IsWhiteSpace(sb[offset + len])) - len++; - entities.Add(new MessageEntityPre { offset = offset, length = -1, language = sb.ToString(offset + 3, len - 3) }); - if (sb[offset + len] == '\n') len++; - } - sb.Remove(offset, len); - } - else - ProcessEntity(); - if (entities.Count > count) inCode++; else inCode--; - break; - case '>' when inCode == 0 && offset == 0 || sb[offset - 1] == '\n': - sb.Remove(offset, 1); - if (lastBlockQuote == null) - entities.Add(lastBlockQuote = new MessageEntityBlockquote { offset = offset, length = -1 }); - break; - case '\n' when lastBlockQuote != null: - if (offset + 1 >= sb.Length || sb[offset + 1] != '>') CloseBlockQuote(); - offset++; - break; - case '!' when inCode == 0 && offset + 1 < sb.Length && sb[offset + 1] == '[': - sb.Remove(offset, 1); - break; - case '[' when inCode == 0: - entities.Add(new MessageEntityTextUrl { offset = offset, length = -1 }); - sb.Remove(offset, 1); - break; - case ']': - if (inCode == 0 && offset + 2 < sb.Length && sb[offset + 1] == '(') - { - var lastIndex = entities.FindLastIndex(e => e.length == -1); - if (lastIndex >= 0 && entities[lastIndex] is MessageEntityTextUrl textUrl) - { - textUrl.length = offset - textUrl.offset; - int offset2 = offset + 2; - while (offset2 < sb.Length) - { - char c = sb[offset2++]; - if (c == '\\') sb.Remove(offset2 - 1, 1); - else if (c == ')') break; - } - textUrl.url = sb.ToString(offset + 2, offset2 - offset - 3); - sb.Remove(offset, offset2 - offset); - if (textUrl.url.StartsWith("tg://user?id=") && long.TryParse(textUrl.url[13..], out var id) && users?.GetValueOrDefault(id)?.access_hash is long hash) - entities[lastIndex] = new InputMessageEntityMentionName { offset = textUrl.offset, length = textUrl.length, user_id = new InputUser(id, hash) }; - else if (textUrl.url.StartsWith("tg://emoji?id=") && long.TryParse(textUrl.url[14..], out id)) - entities[lastIndex] = new MessageEntityCustomEmoji { offset = textUrl.offset, length = textUrl.length, document_id = id }; - else if (textUrl.url.StartsWith("tg://time?unix=") && textUrl.url.IndexOf("&format=", 15) is { } idxFormat) - entities[lastIndex] = new MessageEntityFormattedDate - { - offset = textUrl.offset, length = textUrl.length, - date = new DateTime((long.Parse(idxFormat < 0 ? textUrl.url[15..] : textUrl.url[15..idxFormat]) + 62135596800L) * 10000000, DateTimeKind.Utc), - flags = idxFormat < 0 ? 0 : HtmlText.DateFlags(textUrl.url[(idxFormat + 8)..]) - }; - break; - } - } - offset++; - break; - default: offset++; break; - } - - void ProcessEntity() where T : MessageEntity, new() - { - sb.Remove(offset, 1); - if (entities.LastOrDefault(e => e.length == -1) is T prevEntity) - if (offset == prevEntity.offset) - entities.Remove(prevEntity); - else - prevEntity.length = offset - prevEntity.offset; - else - entities.Add(new T { offset = offset, length = -1 }); - } - } - if (lastBlockQuote != null) CloseBlockQuote(); - HtmlText.FixUps(sb, entities); - text = sb.ToString(); - return entities.Count == 0 ? null : [.. entities]; - - void CloseBlockQuote() - { - if (entities[^1] is MessageEntitySpoiler { length: -1 } mes && mes.offset == offset) - { - entities.RemoveAt(entities.Count - 1); - lastBlockQuote.flags = MessageEntityBlockquote.Flags.collapsed; - } - lastBlockQuote.length = offset - lastBlockQuote.offset; - lastBlockQuote = null; - } - } - - /// 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 message text with MarkdownV2 formattings - public static string EntitiesToMarkdown(this Client client, string message, MessageEntity[] entities) - { - if (entities == null || entities.Length == 0) return Escape(message); - var closings = new List<(int offset, string md)>(); - var sb = new StringBuilder(message); - int entityIndex = 0; - var nextEntity = entities[entityIndex]; - bool inBlockQuote = false; - char lastCh = '\0'; - for (int offset = 0, i = 0; ; offset++, i++) - { - while (closings.Count != 0 && offset == closings[0].offset) - { - var md = closings[0].md; - closings.RemoveAt(0); - if (i > 0 && md[0] == '_' && sb[i - 1] == '_') md = '\r' + md; - if (md[0] == '>') { inBlockQuote = false; md = md[1..]; if (lastCh != '\n' && i < sb.Length && sb[i] != '\n') md += '\n'; } - sb.Insert(i, md); i += md.Length; - } - if (i == sb.Length) break; - if (lastCh == '\n' && inBlockQuote) sb.Insert(i++, '>'); - for (; offset == nextEntity?.offset; nextEntity = ++entityIndex < entities.Length ? entities[entityIndex] : null) - { - if (EntityToMD.TryGetValue(nextEntity.GetType(), out var md)) - { - var closing = (nextEntity.offset + nextEntity.length, md); - if (md[0] is '[' or '!') - { - if (nextEntity is MessageEntityTextUrl metu) - closing.md = $"]({metu.url.Replace("\\", "\\\\").Replace(")", "\\)").Replace(">", "%3E")})"; - else if (nextEntity is MessageEntityMentionName memn) - closing.md = $"](tg://user?id={memn.user_id})"; - else if (nextEntity is InputMessageEntityMentionName imemn) - closing.md = $"](tg://user?id={imemn.user_id.UserId ?? client.UserId})"; - else if (nextEntity is MessageEntityCustomEmoji mecu) - closing.md = $"](tg://emoji?id={mecu.document_id})"; - else if (nextEntity is MessageEntityFormattedDate mefd) - closing.md = $"](tg://time?unix={((DateTimeOffset)mefd.date).ToUnixTimeSeconds()}{(mefd.flags == 0 ? null : $"&format={HtmlText.DateFormat(mefd.flags)}")})"; - } - else if (nextEntity is MessageEntityBlockquote mebq) - { inBlockQuote = true; if (lastCh is not '\n' and not '\0') md = "\n>"; - if (mebq.flags == MessageEntityBlockquote.Flags.collapsed) closing.md = ">||"; } - else if (nextEntity is MessageEntityPre mep) - md = $"```{mep.language}\n"; - int index = ~closings.BinarySearch(closing, Comparer<(int, string)>.Create((x, y) => x.Item1.CompareTo(y.Item1) | 1)); - closings.Insert(index, closing); - if (i > 0 && md[0] == '_' && sb[i - 1] == '_') md = '\r' + md; - sb.Insert(i, md); i += md.Length; - } - } - switch (lastCh = sb[i]) - { - case '_': case '*': case '~': case '#': case '+': case '-': case '=': case '.': case '!': - case '[': case ']': case '(': case ')': case '{': case '}': case '>': case '|': case '\\': - if (closings.Count != 0 && closings[0].md[0] == '`') break; - goto case '`'; - case '`': - sb.Insert(i++, '\\'); - break; - } - } - return sb.ToString(); - } - - static readonly Dictionary EntityToMD = new() - { - [typeof(MessageEntityBold)] = "*", - [typeof(MessageEntityItalic)] = "_", - [typeof(MessageEntityCode)] = "`", - [typeof(MessageEntityPre)] = "```", - [typeof(MessageEntityTextUrl)] = "[", - [typeof(MessageEntityMentionName)] = "[", - [typeof(InputMessageEntityMentionName)] = "[", - [typeof(MessageEntityUnderline)] = "__", - [typeof(MessageEntityStrike)] = "~", - [typeof(MessageEntitySpoiler)] = "||", - [typeof(MessageEntityCustomEmoji)] = "![", - [typeof(MessageEntityBlockquote)] = ">", - [typeof(MessageEntityFormattedDate)] = "![", - }; - - /// Insert backslashes in front of Markdown reserved characters - /// The text to escape - /// The escaped text, ready to be used in MarkdownToEntities without problems - public static string Escape(string text) - { - if (text == null) return null; - StringBuilder sb = null; - for (int index = 0, added = 0; index < text.Length; index++) - { - switch (text[index]) - { - case '_': case '*': case '~': case '`': case '#': case '+': case '-': case '=': case '.': case '!': - case '[': case ']': case '(': case ')': case '{': case '}': case '>': case '|': case '\\': - sb ??= new StringBuilder(text, text.Length + 32); - sb.Insert(index + added++, '\\'); - break; - } - } - return sb?.ToString() ?? text; - } - } - - public static class HtmlText - { - /// Converts an HTML-formatted text into the (plain text + entities) format used by Telegram messages - /// not used anymore, you can pass null - /// [in] The HTML-formatted text
[out] The same (plain) text, stripped of all HTML tags - /// 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 Client _, ref string text, IReadOnlyDictionary users = null) - { - var entities = new List(); - var sb = new StringBuilder(text); - int end; - for (int offset = 0; offset < sb.Length;) - { - char c = sb[offset]; - if (c == '&') - { - end = offset + 1; - if (end < sb.Length && sb[end] == '#') end++; - while (end < sb.Length && sb[end] is >= 'a' and <= 'z' or >= 'A' and <= 'Z' or >= '0' and <= '9') end++; - var html = HttpUtility.HtmlDecode(end >= sb.Length || sb[end] != ';' - ? sb.ToString(offset, end - offset) + ";" : sb.ToString(offset, ++end - offset)); - if (html.Length == 1) - { - sb[offset] = html[0]; - sb.Remove(++offset, end - offset); - } - else - offset = end; - } - else if (c == '<') - { - for (end = ++offset; end < sb.Length; end++) - if (sb[end] == '>') break; - if (end >= sb.Length) break; - bool closing = sb[offset] == '/'; - var tag = closing ? sb.ToString(offset + 1, end - offset - 1) : sb.ToString(offset, end - offset); - sb.Remove(--offset, end + 1 - offset); - switch (tag) - { - case "b": case "strong": ProcessEntity(); break; - case "i": case "em": ProcessEntity(); break; - case "u": case "ins": ProcessEntity(); break; - case "s": case "strike": case "del": ProcessEntity(); break; - case "span class=\"tg-spoiler\"": - case "span class='tg-spoiler'": - case "span" when closing: - case "tg-spoiler": ProcessEntity(); break; - case "code": ProcessEntity(); break; - case "pre": ProcessEntity(); break; - case "tg-emoji" when closing: ProcessEntity(); break; - case "tg-time" when closing: ProcessEntity(); break; - case "blockquote": ProcessEntity(); break; - case "blockquote expandable": - entities.Add(new MessageEntityBlockquote { offset = offset, length = -1, flags = MessageEntityBlockquote.Flags.collapsed }); - break; - default: - if (closing) - { - if (tag == "a") - { - var prevEntity = entities.LastOrDefault(e => e.length == -1); - if (prevEntity is InputMessageEntityMentionName or MessageEntityTextUrl) - prevEntity.length = offset - prevEntity.offset; - } - } - else if ((tag[^1] == '"' && tag.StartsWith("a href=\"")) - || (tag[^1] == '\'' && tag.StartsWith("a href='"))) - { - tag = HttpUtility.HtmlDecode(tag[8..^1]); - if (tag.StartsWith("tg://user?id=") && long.TryParse(tag[13..], out var user_id) && users?.GetValueOrDefault(user_id)?.access_hash is long hash) - entities.Add(new InputMessageEntityMentionName { offset = offset, length = -1, user_id = new InputUser(user_id, hash) }); - else - entities.Add(new MessageEntityTextUrl { offset = offset, length = -1, url = tag }); - } - else if ((tag[^1] == '"' && tag.StartsWith("code class=\"language-")) - || (tag[^1] == '\'' && tag.StartsWith("code class='language-"))) - { - if (entities.LastOrDefault(e => e.length == -1) is MessageEntityPre prevEntity) - prevEntity.language = tag[21..^1]; - } - else if (tag.StartsWith("tg-emoji emoji-id=\"") || tag.StartsWith("tg-emoji emoji-id='")) - entities.Add(new MessageEntityCustomEmoji { offset = offset, length = -1, document_id = long.Parse(tag[19..^1]) }); - else if ((tag.StartsWith("tg-time unix=\"") || tag.StartsWith("tg-time unix='")) && (end = tag.IndexOf(tag[13], 14)) > 0) - entities.Add(new MessageEntityFormattedDate - { - offset = offset, length = -1, - date = new DateTime((long.Parse(tag[14..end]) + 62135596800L) * 10000000, DateTimeKind.Utc), - flags = string.Compare(tag, end + 1, " format=", 0, 8) == 0 ? DateFlags(tag[(end + 10)..^1]) : 0 - }); - break; - } - - void ProcessEntity() where T : MessageEntity, new() - { - if (!closing) - entities.Add(new T { offset = offset, length = -1 }); - else if (entities.LastOrDefault(e => e.length == -1) is T prevEntity) - prevEntity.length = offset - prevEntity.offset; - } - } - else - offset++; - } - FixUps(sb, entities); - text = sb.ToString(); - return entities.Count == 0 ? null : [.. entities]; - } - - internal static void FixUps(StringBuilder sb, List entities) - { - int newlen = sb.Length; - while (--newlen >= 0 && char.IsWhiteSpace(sb[newlen])); - if (++newlen != sb.Length) sb.Length = newlen; - for (int i = 0; i < entities.Count; i++) - { - var entity = entities[i]; - if (entity.offset + entity.length > newlen) entity.length = newlen - entity.offset; - if (entity.length == 0) entities.RemoveAt(i--); - } - } - - /// 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 message text with HTML formatting tags - public static string EntitiesToHtml(this Client client, string message, MessageEntity[] entities) - { - if (entities == null || entities.Length == 0) return Escape(message); - var closings = new List<(int offset, string tag)>(); - var sb = new StringBuilder(message); - int entityIndex = 0; - var nextEntity = entities[entityIndex]; - for (int offset = 0, i = 0; ; offset++, i++) - { - while (closings.Count != 0 && offset == closings[0].offset) - { - var tag = closings[0].tag; - sb.Insert(i, tag); i += tag.Length; - closings.RemoveAt(0); - } - if (i == sb.Length) break; - for (; offset == nextEntity?.offset; nextEntity = ++entityIndex < entities.Length ? entities[entityIndex] : null) - { - if (EntityToTag.TryGetValue(nextEntity.GetType(), out var tag)) - { - var closing = (nextEntity.offset + nextEntity.length, $""); - if (tag[0] == 'a') - { - if (nextEntity is MessageEntityTextUrl metu) - tag = $""; - else if (nextEntity is MessageEntityMentionName memn) - tag = $""; - else if (nextEntity is InputMessageEntityMentionName imemn) - tag = $""; - } - else if (nextEntity is MessageEntityCustomEmoji mecu) - tag = $""; - else if (nextEntity is MessageEntityPre mep && !string.IsNullOrEmpty(mep.language)) - { - closing.Item2 = ""; - tag = $"
";
-						}
-						else if (nextEntity is MessageEntityBlockquote { flags: MessageEntityBlockquote.Flags.collapsed })
-							tag = "
"; - else if (nextEntity is MessageEntityFormattedDate mefd) - tag = $""; - else - tag = $"<{tag}>"; - int index = ~closings.BinarySearch(closing, Comparer<(int, string)>.Create((x, y) => x.Item1.CompareTo(y.Item1) | 1)); - closings.Insert(index, closing); - sb.Insert(i, tag); i += tag.Length; - } - } - switch (sb[i]) - { - case '&': sb.Insert(i + 1, "amp;"); i += 4; break; - case '<': sb.Insert(i, "<"); sb[i += 3] = ';'; break; - case '>': sb.Insert(i, ">"); sb[i += 3] = ';'; break; - } - } - return sb.ToString(); - } - - static readonly Dictionary EntityToTag = new() - { - [typeof(MessageEntityBold)] = "b", - [typeof(MessageEntityItalic)] = "i", - [typeof(MessageEntityCode)] = "code", - [typeof(MessageEntityPre)] = "pre", - [typeof(MessageEntityTextUrl)] = "a", - [typeof(MessageEntityMentionName)] = "a", - [typeof(InputMessageEntityMentionName)] = "a", - [typeof(MessageEntityUnderline)] = "u", - [typeof(MessageEntityStrike)] = "s", - [typeof(MessageEntitySpoiler)] = "tg-spoiler", - [typeof(MessageEntityCustomEmoji)] = "tg-emoji", - [typeof(MessageEntityBlockquote)] = "blockquote", - [typeof(MessageEntityFormattedDate)] = "tg-time", - }; - - /// Replace special HTML characters with their &xx; equivalent - /// The text to make HTML-safe - /// The HTML-safe text, ready to be used in HtmlToEntities without problems - public static string Escape(string text) - => text?.Replace("&", "&").Replace("<", "<").Replace(">", ">"); - - internal static string DateFormat(MessageEntityFormattedDate.Flags flags) => flags.HasFlag(MessageEntityFormattedDate.Flags.relative) ? "r" : - ((flags & MessageEntityFormattedDate.Flags.day_of_week) != 0 ? "w" : "") + - ((flags & MessageEntityFormattedDate.Flags.short_date) != 0 ? "d" : "") + - ((flags & MessageEntityFormattedDate.Flags.long_date) != 0 ? "D" : "") + - ((flags & MessageEntityFormattedDate.Flags.short_time) != 0 ? "t" : "") + - ((flags & MessageEntityFormattedDate.Flags.long_time) != 0 ? "T" : ""); - - internal static MessageEntityFormattedDate.Flags DateFlags(string format) - => (MessageEntityFormattedDate.Flags)format.Sum(c => 1 << "rtTdDw".IndexOf(c)); - } -} diff --git a/src/Session.cs b/src/Session.cs index 321c319..861f527 100644 --- a/src/Session.cs +++ b/src/Session.cs @@ -1,210 +1,104 @@ using System; -using System.Buffers.Binary; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Security.Cryptography; using System.Text.Json; - -// Don't change this code to lower the security. It's following Telegram security recommendations https://corefork.telegram.org/mtproto/description +using System.Threading; namespace WTelegram { - internal sealed partial class Session : IDisposable + internal class Session { - public int ApiId; - public long UserId; + public TL.User User; public int MainDC; - public Dictionary DCSessions = []; - public TL.DcOption[] DcOptions; + public Dictionary DCSessions = new(); - public sealed class DCSession + public class DCSession { + public long Id; + public long AuthKeyID; public byte[] AuthKey; // 2048-bit = 256 bytes public long UserId; - public long OldSalt; // still accepted for a further 1800 seconds public long Salt; - public SortedList Salts; + public int Seqno; + public long ServerTicksOffset; + public long LastSentMsgId; public TL.DcOption DataCenter; - public int Layer; - internal long id = Helpers.RandomLong(); - internal long authKeyID; - internal int seqno; - internal long serverTicksOffset; - internal long lastSentMsgId; - internal bool withoutUpdates; internal Client Client; - internal int DcID => DataCenter == null ? 0 : DataCenter.flags.HasFlag(TL.DcOption.Flags.media_only) ? -DataCenter.id : DataCenter.id; + internal int DcID => DataCenter?.id ?? 0; internal IPEndPoint EndPoint => DataCenter == null ? null : new(IPAddress.Parse(DataCenter.ip_address), DataCenter.port); - internal void Renew() { Helpers.Log(3, $"Renewing session on DC {DcID}..."); id = Helpers.RandomLong(); seqno = 0; lastSentMsgId = 0; } - public void DisableUpdates(bool disable = true) { if (withoutUpdates != disable) { withoutUpdates = disable; Renew(); } } - - const int MsgIdsN = 512; - private long[] _msgIds; - private int _msgIdsHead; - internal bool CheckNewMsgId(long msg_id) - { - if (_msgIds == null) - { - _msgIds = new long[MsgIdsN]; - _msgIds[0] = msg_id; - msg_id -= 300L << 32; // until the array is filled with real values, allow ids up to 300 seconds in the past - for (int i = 1; i < MsgIdsN; i++) _msgIds[i] = msg_id; - return true; - } - int newHead = (_msgIdsHead + 1) % MsgIdsN; - if (msg_id > _msgIds[_msgIdsHead]) - _msgIds[_msgIdsHead = newHead] = msg_id; - else if (msg_id <= _msgIds[newHead]) - return false; - else - { - int min = 0, max = MsgIdsN - 1; - while (min <= max) // binary search (rotated at newHead) - { - int mid = (min + max) / 2; - int sign = msg_id.CompareTo(_msgIds[(mid + newHead) % MsgIdsN]); - if (sign == 0) return false; - else if (sign < 0) max = mid - 1; - else min = mid + 1; - } - _msgIdsHead = newHead; - for (min = (min + newHead) % MsgIdsN; newHead != min;) - _msgIds[newHead] = _msgIds[newHead = newHead == 0 ? MsgIdsN - 1 : newHead - 1]; - _msgIds[min] = msg_id; - } - return true; - } } public DateTime SessionStart => _sessionStart; + public readonly SemaphoreSlim _sem = new(1); private readonly DateTime _sessionStart = DateTime.UtcNow; private readonly SHA256 _sha256 = SHA256.Create(); - private Stream _store; - private byte[] _reuseKey; // used only if AES Encryptor.CanReuseTransform = false (Mono) - private byte[] _encrypted = new byte[16]; - private ICryptoTransform _encryptor; - private Utf8JsonWriter _jsonWriter; - private readonly MemoryStream _jsonStream = new(4096); + private string _pathname; + private byte[] _apiHash; // used as AES key for encryption of session file - public void Dispose() + private static readonly JsonSerializerOptions JsonOptions = new(Helpers.JsonOptions) { - _sha256.Dispose(); - _store.Dispose(); - _encryptor.Dispose(); - _jsonWriter.Dispose(); - _jsonStream.Dispose(); - } - - internal static Session LoadOrCreate(Stream store, byte[] rgbKey) - { - using var aes = Aes.Create(); - Session session = null; - try - { - var length = (int)store.Length; - if (length > 0) - { - var input = new byte[length]; - if (store.Read(input, 0, length) != length) - throw new WTException($"Can't read session block ({store.Position}, {length})"); - using var sha256 = SHA256.Create(); - using var decryptor = aes.CreateDecryptor(rgbKey, input[0..16]); - var utf8Json = decryptor.TransformFinalBlock(input, 16, input.Length - 16); - if (!sha256.ComputeHash(utf8Json, 32, utf8Json.Length - 32).SequenceEqual(utf8Json[0..32])) - throw new WTException("Integrity check failed in session loading"); - session = JsonSerializer.Deserialize(utf8Json.AsSpan(32), Helpers.JsonOptions); - Helpers.Log(2, "Loaded previous session"); - using var sha1 = SHA1.Create(); - foreach (var dcs in session.DCSessions.Values) - dcs.authKeyID = BinaryPrimitives.ReadInt64LittleEndian(sha1.ComputeHash(dcs.AuthKey).AsSpan(12)); - } - session ??= new Session(); - session._store = store; - Encryption.RNG.GetBytes(session._encrypted, 0, 16); - session._encryptor = aes.CreateEncryptor(rgbKey, session._encrypted); - if (!session._encryptor.CanReuseTransform) session._reuseKey = rgbKey; - session._jsonWriter = new Utf8JsonWriter(session._jsonStream, default); - return session; + Converters = { + new Helpers.PolymorphicConverter(), + new Helpers.PolymorphicConverter() } - catch (Exception ex) - { - store.Dispose(); - throw new WTException($"Exception while reading session file: {ex.Message}\nUse the correct api_hash/id/key, or delete the file to start a new session", ex); - } - } + }; - internal void Save() // must be called with lock(session) + internal static Session LoadOrCreate(string pathname, byte[] apiHash) { - JsonSerializer.Serialize(_jsonWriter, this, Helpers.JsonOptions); - var utf8Json = _jsonStream.GetBuffer(); - var utf8JsonLen = (int)_jsonStream.Position; - int encryptedLen = 64 + (utf8JsonLen & ~15); - lock (_store) // while updating _encrypted buffer and writing to store + if (File.Exists(pathname)) { - if (encryptedLen > _encrypted.Length) - Array.Copy(_encrypted, _encrypted = new byte[encryptedLen + 256], 16); - _encryptor.TransformBlock(_sha256.ComputeHash(utf8Json, 0, utf8JsonLen), 0, 32, _encrypted, 16); - _encryptor.TransformBlock(utf8Json, 0, encryptedLen - 64, _encrypted, 48); - _encryptor.TransformFinalBlock(utf8Json, encryptedLen - 64, utf8JsonLen & 15).CopyTo(_encrypted, encryptedLen - 16); - if (!_encryptor.CanReuseTransform) // under Mono, AES encryptor is not reusable - using (var aes = Aes.Create()) - _encryptor = aes.CreateEncryptor(_reuseKey, _encrypted[0..16]); try { - _store.Position = 0; - _store.Write(_encrypted, 0, encryptedLen); - _store.SetLength(encryptedLen); + var session = Load(pathname, apiHash); + session._pathname = pathname; + session._apiHash = apiHash; + Helpers.Log(2, "Loaded previous session"); + return session; } catch (Exception ex) { - Helpers.Log(4, $"{_store} raised {ex}"); + throw new ApplicationException($"Exception while reading session file: {ex.Message}\nDelete the file to start a new session", ex); } } - _jsonStream.Position = 0; - _jsonWriter.Reset(); + return new Session { _pathname = pathname, _apiHash = apiHash }; } - } - internal sealed class SessionStore : FileStream // This class is designed to be high-performance and failure-resilient with Writes (but when you're Andrei, you can't understand that) - { - public override long Length { get; } - public override long Position { get => base.Position; set { } } - public override void SetLength(long value) { } - private readonly byte[] _header = new byte[8]; - private int _nextPosition = 8; - - public SessionStore(string pathname) - : base(pathname, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None, 1) // no in-app buffering + internal static Session Load(string pathname, byte[] apiHash) { - if (base.Read(_header, 0, 8) == 8) - { - var position = BinaryPrimitives.ReadInt32LittleEndian(_header); - var length = BinaryPrimitives.ReadInt32LittleEndian(_header.AsSpan(4)); - base.Position = position; - Length = length; - _nextPosition = position + length; - } + var input = File.ReadAllBytes(pathname); + using var sha256 = SHA256.Create(); + using var aes = Aes.Create(); + using var decryptor = aes.CreateDecryptor(apiHash, input[0..16]); + var utf8Json = decryptor.TransformFinalBlock(input, 16, input.Length - 16); + if (!sha256.ComputeHash(utf8Json, 32, utf8Json.Length - 32).SequenceEqual(utf8Json[0..32])) + throw new ApplicationException("Integrity check failed in session loading"); + return JsonSerializer.Deserialize(utf8Json.AsSpan(32), JsonOptions); } - public override void Write(byte[] buffer, int offset, int count) + internal void Save() { - if (_nextPosition > count * 3) _nextPosition = 8; - base.Position = _nextPosition; - base.Write(buffer, offset, count); - BinaryPrimitives.WriteInt32LittleEndian(_header, _nextPosition); - BinaryPrimitives.WriteInt32LittleEndian(_header.AsSpan(4), count); - _nextPosition += count; - base.Position = 0; - base.Write(_header, 0, 8); + var utf8Json = JsonSerializer.SerializeToUtf8Bytes(this, JsonOptions); + var finalBlock = new byte[16]; + var output = new byte[(16 + 32 + utf8Json.Length + 16) & ~15]; + Encryption.RNG.GetBytes(output, 0, 16); + using var aes = Aes.Create(); + using var encryptor = aes.CreateEncryptor(_apiHash, output[0..16]); + encryptor.TransformBlock(_sha256.ComputeHash(utf8Json), 0, 32, output, 16); + encryptor.TransformBlock(utf8Json, 0, utf8Json.Length & ~15, output, 48); + utf8Json.AsSpan(utf8Json.Length & ~15).CopyTo(finalBlock); + encryptor.TransformFinalBlock(finalBlock, 0, utf8Json.Length & 15).CopyTo(output.AsMemory(48 + utf8Json.Length & ~15)); + if (!File.Exists(_pathname)) + File.WriteAllBytes(_pathname, output); + else lock (this) + { + string tempPathname = _pathname + ".tmp"; + File.WriteAllBytes(tempPathname, output); + File.Replace(tempPathname, _pathname, null); + } } } - - internal sealed class ActionStore(byte[] initial, Action save) : MemoryStream(initial ?? []) - { - public override void Write(byte[] buffer, int offset, int count) => save(buffer[offset..(offset + count)]); - public override void SetLength(long value) { } - } } \ No newline at end of file diff --git a/src/TL.MTProto.cs b/src/TL.MTProto.cs index de10b70..905390c 100644 --- a/src/TL.MTProto.cs +++ b/src/TL.MTProto.cs @@ -1,13 +1,14 @@ -using System; +// This file is generated automatically using the Generator class +using System; using System.Threading.Tasks; -using TL.Methods; -using Client = WTelegram.Client; namespace TL { - #pragma warning disable IDE1006, CS1574 + using BinaryWriter = System.IO.BinaryWriter; + using Client = WTelegram.Client; + [TLDef(0x05162463)] //resPQ#05162463 nonce:int128 server_nonce:int128 pq:bytes server_public_key_fingerprints:Vector = ResPQ - public sealed partial class ResPQ : IObject + public partial class ResPQ : ITLObject { public Int128 nonce; public Int128 server_nonce; @@ -16,7 +17,7 @@ namespace TL } [TLDef(0x83C95AEC)] //p_q_inner_data#83c95aec pq:bytes p:bytes q:bytes nonce:int128 server_nonce:int128 new_nonce:int256 = P_Q_inner_data - public partial class PQInnerData : IObject + public partial class PQInnerData : ITLObject { public byte[] pq; public byte[] p; @@ -25,25 +26,19 @@ namespace TL public Int128 server_nonce; public Int256 new_nonce; } - [TLDef(0xA9F55F95, inheritAt = 0)] //p_q_inner_data_dc#a9f55f95 pq:bytes p:bytes q:bytes nonce:int128 server_nonce:int128 new_nonce:int256 dc:int = P_Q_inner_data - public sealed partial class PQInnerDataDc : PQInnerData - { - public int dc; - } - [TLDef(0x3C6A84D4, inheritAt = 0)] //p_q_inner_data_temp#3c6a84d4 pq:bytes p:bytes q:bytes nonce:int128 server_nonce:int128 new_nonce:int256 expires_in:int = P_Q_inner_data - public sealed partial class PQInnerDataTemp : PQInnerData - { - public int expires_in; - } - [TLDef(0x56FDDF88, inheritAt = 0)] //p_q_inner_data_temp_dc#56fddf88 pq:bytes p:bytes q:bytes nonce:int128 server_nonce:int128 new_nonce:int256 dc:int expires_in:int = P_Q_inner_data - public sealed partial class PQInnerDataTempDc : PQInnerData + [TLDef(0xA9F55F95)] //p_q_inner_data_dc#a9f55f95 pq:bytes p:bytes q:bytes nonce:int128 server_nonce:int128 new_nonce:int256 dc:int = P_Q_inner_data + public partial class PQInnerDataDc : PQInnerData { public int dc; } + [TLDef(0x3C6A84D4)] //p_q_inner_data_temp#3c6a84d4 pq:bytes p:bytes q:bytes nonce:int128 server_nonce:int128 new_nonce:int256 expires_in:int = P_Q_inner_data + public partial class PQInnerDataTemp : PQInnerData { public int expires_in; } + [TLDef(0x56FDDF88)] //p_q_inner_data_temp_dc#56fddf88 pq:bytes p:bytes q:bytes nonce:int128 server_nonce:int128 new_nonce:int256 dc:int expires_in:int = P_Q_inner_data + public partial class PQInnerDataTempDc : PQInnerData { public int dc; public int expires_in; } [TLDef(0x75A3F765)] //bind_auth_key_inner#75a3f765 nonce:long temp_auth_key_id:long perm_auth_key_id:long temp_session_id:long expires_at:int = BindAuthKeyInner - public sealed partial class BindAuthKeyInner : IObject + public partial class BindAuthKeyInner : ITLObject { public long nonce; public long temp_auth_key_id; @@ -52,24 +47,18 @@ namespace TL public DateTime expires_at; } - public abstract partial class ServerDHParams : IObject + public abstract partial class ServerDHParams : ITLObject { public Int128 nonce; public Int128 server_nonce; } - [TLDef(0x79CB045D, inheritAt = 0)] //server_DH_params_fail#79cb045d nonce:int128 server_nonce:int128 new_nonce_hash:int128 = Server_DH_Params - public sealed partial class ServerDHParamsFail : ServerDHParams - { - public Int128 new_nonce_hash; - } - [TLDef(0xD0E8075C, inheritAt = 0)] //server_DH_params_ok#d0e8075c nonce:int128 server_nonce:int128 encrypted_answer:bytes = Server_DH_Params - public sealed partial class ServerDHParamsOk : ServerDHParams - { - public byte[] encrypted_answer; - } + [TLDef(0x79CB045D)] //server_DH_params_fail#79cb045d nonce:int128 server_nonce:int128 new_nonce_hash:int128 = Server_DH_Params + public partial class ServerDHParamsFail : ServerDHParams { public Int128 new_nonce_hash; } + [TLDef(0xD0E8075C)] //server_DH_params_ok#d0e8075c nonce:int128 server_nonce:int128 encrypted_answer:bytes = Server_DH_Params + public partial class ServerDHParamsOk : ServerDHParams { public byte[] encrypted_answer; } [TLDef(0xB5890DBA)] //server_DH_inner_data#b5890dba nonce:int128 server_nonce:int128 g:int dh_prime:bytes g_a:bytes server_time:int = Server_DH_inner_data - public sealed partial class ServerDHInnerData : IObject + public partial class ServerDHInnerData : ITLObject { public Int128 nonce; public Int128 server_nonce; @@ -80,7 +69,7 @@ namespace TL } [TLDef(0x6643B654)] //client_DH_inner_data#6643b654 nonce:int128 server_nonce:int128 retry_id:long g_b:bytes = Client_DH_Inner_Data - public sealed partial class ClientDHInnerData : IObject + public partial class ClientDHInnerData : ITLObject { public Int128 nonce; public Int128 server_nonce; @@ -88,124 +77,92 @@ namespace TL public byte[] g_b; } - public abstract partial class SetClientDHParamsAnswer : IObject + public abstract partial class SetClientDHParamsAnswer : ITLObject { public Int128 nonce; public Int128 server_nonce; } - [TLDef(0x3BCBF734, inheritAt = 0)] //dh_gen_ok#3bcbf734 nonce:int128 server_nonce:int128 new_nonce_hash1:int128 = Set_client_DH_params_answer - public sealed partial class DhGenOk : SetClientDHParamsAnswer - { - public Int128 new_nonce_hash1; - } - [TLDef(0x46DC1FB9, inheritAt = 0)] //dh_gen_retry#46dc1fb9 nonce:int128 server_nonce:int128 new_nonce_hash2:int128 = Set_client_DH_params_answer - public sealed partial class DhGenRetry : SetClientDHParamsAnswer - { - public Int128 new_nonce_hash2; - } - [TLDef(0xA69DAE02, inheritAt = 0)] //dh_gen_fail#a69dae02 nonce:int128 server_nonce:int128 new_nonce_hash3:int128 = Set_client_DH_params_answer - public sealed partial class DhGenFail : SetClientDHParamsAnswer - { - public Int128 new_nonce_hash3; - } + [TLDef(0x3BCBF734)] //dh_gen_ok#3bcbf734 nonce:int128 server_nonce:int128 new_nonce_hash1:int128 = Set_client_DH_params_answer + public partial class DhGenOk : SetClientDHParamsAnswer { public Int128 new_nonce_hash1; } + [TLDef(0x46DC1FB9)] //dh_gen_retry#46dc1fb9 nonce:int128 server_nonce:int128 new_nonce_hash2:int128 = Set_client_DH_params_answer + public partial class DhGenRetry : SetClientDHParamsAnswer { public Int128 new_nonce_hash2; } + [TLDef(0xA69DAE02)] //dh_gen_fail#a69dae02 nonce:int128 server_nonce:int128 new_nonce_hash3:int128 = Set_client_DH_params_answer + public partial class DhGenFail : SetClientDHParamsAnswer { public Int128 new_nonce_hash3; } - public abstract partial class DestroyAuthKeyRes : IObject { } - [TLDef(0xF660E1D4)] //destroy_auth_key_ok#f660e1d4 = DestroyAuthKeyRes - public sealed partial class DestroyAuthKeyOk : DestroyAuthKeyRes { } - [TLDef(0x0A9F2259)] //destroy_auth_key_none#0a9f2259 = DestroyAuthKeyRes - public sealed partial class DestroyAuthKeyNone : DestroyAuthKeyRes { } - [TLDef(0xEA109B13)] //destroy_auth_key_fail#ea109b13 = DestroyAuthKeyRes - public sealed partial class DestroyAuthKeyFail : DestroyAuthKeyRes { } + public enum DestroyAuthKeyRes : uint + { + ///See + Ok = 0xF660E1D4, + ///See + None = 0x0A9F2259, + ///See + Fail = 0xEA109B13, + } [TLDef(0x62D6B459)] //msgs_ack#62d6b459 msg_ids:Vector = MsgsAck - public sealed partial class MsgsAck : IObject - { - public long[] msg_ids; - } + public partial class MsgsAck : ITLObject { public long[] msg_ids; } [TLDef(0xA7EFF811)] //bad_msg_notification#a7eff811 bad_msg_id:long bad_msg_seqno:int error_code:int = BadMsgNotification - public partial class BadMsgNotification : IObject + public partial class BadMsgNotification : ITLObject { public long bad_msg_id; public int bad_msg_seqno; public int error_code; } - [TLDef(0xEDAB447B, inheritAt = 0)] //bad_server_salt#edab447b bad_msg_id:long bad_msg_seqno:int error_code:int new_server_salt:long = BadMsgNotification - public sealed partial class BadServerSalt : BadMsgNotification - { - public long new_server_salt; - } + [TLDef(0xEDAB447B)] //bad_server_salt#edab447b bad_msg_id:long bad_msg_seqno:int error_code:int new_server_salt:long = BadMsgNotification + public partial class BadServerSalt : BadMsgNotification { public long new_server_salt; } [TLDef(0xDA69FB52)] //msgs_state_req#da69fb52 msg_ids:Vector = MsgsStateReq - public sealed partial class MsgsStateReq : IObject - { - public long[] msg_ids; - } + public partial class MsgsStateReq : ITLObject { public long[] msg_ids; } [TLDef(0x04DEB57D)] //msgs_state_info#04deb57d req_msg_id:long info:bytes = MsgsStateInfo - public sealed partial class MsgsStateInfo : IObject + public partial class MsgsStateInfo : ITLObject { public long req_msg_id; public byte[] info; } [TLDef(0x8CC0D131)] //msgs_all_info#8cc0d131 msg_ids:Vector info:bytes = MsgsAllInfo - public sealed partial class MsgsAllInfo : IObject + public partial class MsgsAllInfo : ITLObject { public long[] msg_ids; public byte[] info; } - public abstract partial class MsgDetailedInfoBase : IObject - { - public virtual long AnswerMsgId => default; - public virtual int Bytes => default; - public virtual int Status => default; - } + public abstract partial class MsgDetailedInfoBase : ITLObject { } [TLDef(0x276D3EC6)] //msg_detailed_info#276d3ec6 msg_id:long answer_msg_id:long bytes:int status:int = MsgDetailedInfo - public sealed partial class MsgDetailedInfo : MsgDetailedInfoBase + public partial class MsgDetailedInfo : MsgDetailedInfoBase { public long msg_id; public long answer_msg_id; public int bytes; public int status; - - public override long AnswerMsgId => answer_msg_id; - public override int Bytes => bytes; - public override int Status => status; } [TLDef(0x809DB6DF)] //msg_new_detailed_info#809db6df answer_msg_id:long bytes:int status:int = MsgDetailedInfo - public sealed partial class MsgNewDetailedInfo : MsgDetailedInfoBase + public partial class MsgNewDetailedInfo : MsgDetailedInfoBase { public long answer_msg_id; public int bytes; public int status; - - public override long AnswerMsgId => answer_msg_id; - public override int Bytes => bytes; - public override int Status => status; } [TLDef(0x7D861A08)] //msg_resend_req#7d861a08 msg_ids:Vector = MsgResendReq - public sealed partial class MsgResendReq : IObject - { - public long[] msg_ids; - } + public partial class MsgResendReq : ITLObject { public long[] msg_ids; } [TLDef(0x2144CA19)] //rpc_error#2144ca19 error_code:int error_message:string = RpcError - public sealed partial class RpcError : IObject + public partial class RpcError : ITLObject { public int error_code; public string error_message; } - public abstract partial class RpcDropAnswer : IObject { } + public abstract partial class RpcDropAnswer : ITLObject { } [TLDef(0x5E2AD36E)] //rpc_answer_unknown#5e2ad36e = RpcDropAnswer - public sealed partial class RpcAnswerUnknown : RpcDropAnswer { } + public partial class RpcAnswerUnknown : RpcDropAnswer { } [TLDef(0xCD78E586)] //rpc_answer_dropped_running#cd78e586 = RpcDropAnswer - public sealed partial class RpcAnswerDroppedRunning : RpcDropAnswer { } + public partial class RpcAnswerDroppedRunning : RpcDropAnswer { } [TLDef(0xA43AD8B7)] //rpc_answer_dropped#a43ad8b7 msg_id:long seq_no:int bytes:int = RpcDropAnswer - public sealed partial class RpcAnswerDropped : RpcDropAnswer + public partial class RpcAnswerDropped : RpcDropAnswer { public long msg_id; public int seq_no; @@ -213,7 +170,7 @@ namespace TL } [TLDef(0x0949D9DC)] //future_salt#0949d9dc valid_since:int valid_until:int salt:long = FutureSalt - public sealed partial class FutureSalt : IObject + public partial class FutureSalt : ITLObject { public DateTime valid_since; public DateTime valid_until; @@ -221,7 +178,7 @@ namespace TL } [TLDef(0xAE500895)] //future_salts#ae500895 req_msg_id:long now:int salts:vector = FutureSalts - public sealed partial class FutureSalts : IObject + public partial class FutureSalts : ITLObject { public long req_msg_id; public DateTime now; @@ -229,24 +186,21 @@ namespace TL } [TLDef(0x347773C5)] //pong#347773c5 msg_id:long ping_id:long = Pong - public sealed partial class Pong : IObject + public partial class Pong : ITLObject { public long msg_id; public long ping_id; } - public abstract partial class DestroySessionRes : IObject - { - public long session_id; - } + public abstract partial class DestroySessionRes : ITLObject { public long session_id; } [TLDef(0xE22045FC)] //destroy_session_ok#e22045fc session_id:long = DestroySessionRes - public sealed partial class DestroySessionOk : DestroySessionRes { } + public partial class DestroySessionOk : DestroySessionRes { } [TLDef(0x62D350C9)] //destroy_session_none#62d350c9 session_id:long = DestroySessionRes - public sealed partial class DestroySessionNone : DestroySessionRes { } + public partial class DestroySessionNone : DestroySessionRes { } - public abstract partial class NewSession : IObject { } + public abstract partial class NewSession : ITLObject { } [TLDef(0x9EC20908)] //new_session_created#9ec20908 first_msg_id:long unique_id:long server_salt:long = NewSession - public sealed partial class NewSessionCreated : NewSession + public partial class NewSessionCreated : NewSession { public long first_msg_id; public long unique_id; @@ -254,7 +208,7 @@ namespace TL } [TLDef(0x9299359F)] //http_wait#9299359f max_delay:int wait_after:int max_wait:int = HttpWait - public sealed partial class HttpWait : IObject + public partial class HttpWait : ITLObject { public int max_delay; public int wait_after; @@ -262,19 +216,16 @@ namespace TL } [TLDef(0xD433AD73)] //ipPort#d433ad73 ipv4:int port:int = IpPort - public partial class IpPort : IObject + public partial class IpPort : ITLObject { public int ipv4; public int port; } - [TLDef(0x37982646, inheritAt = 0)] //ipPortSecret#37982646 ipv4:int port:int secret:bytes = IpPort - public sealed partial class IpPortSecret : IpPort - { - public byte[] secret; - } + [TLDef(0x37982646)] //ipPortSecret#37982646 ipv4:int port:int secret:bytes = IpPort + public partial class IpPortSecret : IpPort { public byte[] secret; } [TLDef(0x4679B65F)] //accessPointRule#4679b65f phone_prefix_rules:bytes dc_id:int ips:vector = AccessPointRule - public sealed partial class AccessPointRule : IObject + public partial class AccessPointRule : ITLObject { public byte[] phone_prefix_rules; public int dc_id; @@ -282,151 +233,115 @@ namespace TL } [TLDef(0x5A592A6C)] //help.configSimple#5a592a6c date:int expires:int rules:vector = help.ConfigSimple - public sealed partial class Help_ConfigSimple : IObject + public partial class Help_ConfigSimple : ITLObject { public DateTime date; public DateTime expires; public AccessPointRule[] rules; } + [TLDef(0x7ABE77EC)] //ping#7abe77ec ping_id:long = Pong + public partial class Ping : ITLObject { public long ping_id; } + // ---functions--- - public static class MTProtoExtensions + public static class MTProto { + //req_pq#60469778 nonce:int128 = ResPQ public static Task ReqPq(this Client client, Int128 nonce) - => client.InvokeBare(new ReqPq + => client.CallBareAsync(writer => { - nonce = nonce, + writer.Write(0x60469778); + writer.Write(nonce); + return "ReqPq"; }); + //req_pq_multi#be7e8ef1 nonce:int128 = ResPQ public static Task ReqPqMulti(this Client client, Int128 nonce) - => client.InvokeBare(new ReqPqMulti + => client.CallBareAsync(writer => { - nonce = nonce, + writer.Write(0xBE7E8EF1); + writer.Write(nonce); + return "ReqPqMulti"; }); + //req_DH_params#d712e4be nonce:int128 server_nonce:int128 p:bytes q:bytes public_key_fingerprint:long encrypted_data:bytes = Server_DH_Params public static Task ReqDHParams(this Client client, Int128 nonce, Int128 server_nonce, byte[] p, byte[] q, long public_key_fingerprint, byte[] encrypted_data) - => client.InvokeBare(new ReqDHParams + => client.CallBareAsync(writer => { - nonce = nonce, - server_nonce = server_nonce, - p = p, - q = q, - public_key_fingerprint = public_key_fingerprint, - encrypted_data = encrypted_data, + writer.Write(0xD712E4BE); + writer.Write(nonce); + writer.Write(server_nonce); + writer.WriteTLBytes(p); + writer.WriteTLBytes(q); + writer.Write(public_key_fingerprint); + writer.WriteTLBytes(encrypted_data); + return "ReqDHParams"; }); + //set_client_DH_params#f5045f1f nonce:int128 server_nonce:int128 encrypted_data:bytes = Set_client_DH_params_answer public static Task SetClientDHParams(this Client client, Int128 nonce, Int128 server_nonce, byte[] encrypted_data) - => client.InvokeBare(new SetClientDHParams + => client.CallBareAsync(writer => { - nonce = nonce, - server_nonce = server_nonce, - encrypted_data = encrypted_data, + writer.Write(0xF5045F1F); + writer.Write(nonce); + writer.Write(server_nonce); + writer.WriteTLBytes(encrypted_data); + return "SetClientDHParams"; }); + //destroy_auth_key#d1435160 = DestroyAuthKeyRes public static Task DestroyAuthKey(this Client client) - => client.Invoke(new DestroyAuthKey + => client.CallBareAsync(writer => { + writer.Write(0xD1435160); + return "DestroyAuthKey"; }); + //rpc_drop_answer#58e4a740 req_msg_id:long = RpcDropAnswer public static Task RpcDropAnswer(this Client client, long req_msg_id) - => client.Invoke(new Methods.RpcDropAnswer + => client.CallBareAsync(writer => { - req_msg_id = req_msg_id, + writer.Write(0x58E4A740); + writer.Write(req_msg_id); + return "RpcDropAnswer"; }); + //get_future_salts#b921bd04 num:int = FutureSalts public static Task GetFutureSalts(this Client client, int num) - => client.Invoke(new GetFutureSalts + => client.CallAsync(writer => { - num = num, + writer.Write(0xB921BD04); + writer.Write(num); + return "GetFutureSalts"; }); + //ping#7abe77ec ping_id:long = Pong public static Task Ping(this Client client, long ping_id) - => client.Invoke(new Ping + => client.CallAsync(writer => { - ping_id = ping_id, + writer.Write(0x7ABE77EC); + writer.Write(ping_id); + return "Ping"; }); + //ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong public static Task PingDelayDisconnect(this Client client, long ping_id, int disconnect_delay) - => client.Invoke(new PingDelayDisconnect + => client.CallAsync(writer => { - ping_id = ping_id, - disconnect_delay = disconnect_delay, + writer.Write(0xF3427B8C); + writer.Write(ping_id); + writer.Write(disconnect_delay); + return "PingDelayDisconnect"; }); + //destroy_session#e7512126 session_id:long = DestroySessionRes public static Task DestroySession(this Client client, long session_id) - => client.Invoke(new DestroySession + => client.CallBareAsync(writer => { - session_id = session_id, + writer.Write(0xE7512126); + writer.Write(session_id); + return "DestroySession"; }); } } - -namespace TL.Methods -{ - #pragma warning disable IDE1006 - [TLDef(0x60469778)] //req_pq#60469778 nonce:int128 = ResPQ - public sealed partial class ReqPq : IMethod - { - public Int128 nonce; - } - - [TLDef(0xBE7E8EF1)] //req_pq_multi#be7e8ef1 nonce:int128 = ResPQ - public sealed partial class ReqPqMulti : IMethod - { - public Int128 nonce; - } - - [TLDef(0xD712E4BE)] //req_DH_params#d712e4be nonce:int128 server_nonce:int128 p:bytes q:bytes public_key_fingerprint:long encrypted_data:bytes = Server_DH_Params - public sealed partial class ReqDHParams : IMethod - { - public Int128 nonce; - public Int128 server_nonce; - public byte[] p; - public byte[] q; - public long public_key_fingerprint; - public byte[] encrypted_data; - } - - [TLDef(0xF5045F1F)] //set_client_DH_params#f5045f1f nonce:int128 server_nonce:int128 encrypted_data:bytes = Set_client_DH_params_answer - public sealed partial class SetClientDHParams : IMethod - { - public Int128 nonce; - public Int128 server_nonce; - public byte[] encrypted_data; - } - - [TLDef(0xD1435160)] //destroy_auth_key#d1435160 = DestroyAuthKeyRes - public sealed partial class DestroyAuthKey : IMethod { } - - [TLDef(0x58E4A740)] //rpc_drop_answer#58e4a740 req_msg_id:long = RpcDropAnswer - public sealed partial class RpcDropAnswer : IMethod - { - public long req_msg_id; - } - - [TLDef(0xB921BD04)] //get_future_salts#b921bd04 num:int = FutureSalts - public sealed partial class GetFutureSalts : IMethod - { - public int num; - } - - [TLDef(0x7ABE77EC)] //ping#7abe77ec ping_id:long = Pong - public sealed partial class Ping : IMethod - { - public long ping_id; - } - - [TLDef(0xF3427B8C)] //ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong - public sealed partial class PingDelayDisconnect : IMethod - { - public long ping_id; - public int disconnect_delay; - } - - [TLDef(0xE7512126)] //destroy_session#e7512126 session_id:long = DestroySessionRes - public sealed partial class DestroySession : IMethod - { - public long session_id; - } -} diff --git a/src/TL.Schema.cs b/src/TL.Schema.cs index fde6d62..b965c6b 100644 --- a/src/TL.Schema.cs +++ b/src/TL.Schema.cs @@ -1,22588 +1,10705 @@ -using System; -using System.Collections.Generic; +// This file is generated automatically using the Generator class +using System; +using System.Threading.Tasks; namespace TL { - #pragma warning disable IDE1006, CS1574 - /// Boolean type. See + using BinaryWriter = System.IO.BinaryWriter; + using Client = WTelegram.Client; + + ///See public enum Bool : uint { - ///Constructor may be interpreted as a booleanfalse value. + ///See False = 0xBC799737, - ///The constructor can be interpreted as a booleantrue value. + ///See True = 0x997275B5, } - /// See predefined identifiers. See + ///See [TLDef(0x3FEDD339)] - public sealed partial class True : IObject { } + public partial class True : ITLObject { } - /// Error. See + ///See [TLDef(0xC4B9F9BB)] - public sealed partial class Error : IObject + public partial class Error : ITLObject { - /// Error code public int code; - /// Message public string text; } - /// Corresponds to an arbitrary empty object. See - /// a value means null + ///See + ///a null value means null [TLDef(0x56730BCC)] - public sealed partial class Null : IObject { } + public partial class Null : ITLObject { } - /// Peer See Derived classes: , , , , , - /// a value means inputPeerEmpty - public abstract partial class InputPeer : IObject { } - /// Defines the current user. See + ///See + ///a null value means inputPeerEmpty + public abstract partial class InputPeer : ITLObject { } + ///See [TLDef(0x7DA07EC9)] - public sealed partial class InputPeerSelf : InputPeer { } - /// Defines a chat for further interaction. See + public partial class InputPeerSelf : InputPeer { } + ///See [TLDef(0x35A95CB9)] - public sealed partial class InputPeerChat : InputPeer - { - /// Chat identifier - public long chat_id; - } - /// Defines a user for further interaction. See + public partial class InputPeerChat : InputPeer { public long chat_id; } + ///See [TLDef(0xDDE8A54C)] - public sealed partial class InputPeerUser : InputPeer + public partial class InputPeerUser : InputPeer { - /// User identifier public long user_id; - /// REQUIRED FIELD. See how to obtain it
access_hash value from the
public long access_hash; } - ///
Defines a channel for further interaction. See + ///See [TLDef(0x27BCBBFC)] - public sealed partial class InputPeerChannel : InputPeer + public partial class InputPeerChannel : InputPeer { - /// Channel identifier public long channel_id; - /// 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 + ///See [TLDef(0xA87B0A1C)] - public sealed partial class InputPeerUserFromMessage : InputPeer + public partial class InputPeerUserFromMessage : InputPeer { - /// The chat where the user was seen public InputPeer peer; - /// The message ID public int msg_id; - /// The identifier of the user that was seen public long user_id; } - /// Defines a min channel that was seen in a certain message of a certain chat. See + ///See [TLDef(0xBD2A0840)] - public sealed partial class InputPeerChannelFromMessage : InputPeer + public partial class InputPeerChannelFromMessage : InputPeer { - /// The chat where the channel's message was seen public InputPeer peer; - /// The message ID public int msg_id; - /// The identifier of the channel that was seen public long channel_id; } - /// Defines a user for subsequent interaction. See Derived classes: , , - /// a value means inputUserEmpty - public abstract partial class InputUserBase : IObject { } - /// Defines the current user. See + ///See + ///a null value means inputUserEmpty + public abstract partial class InputUserBase : ITLObject { } + ///See [TLDef(0xF7C1B13F)] - public sealed partial class InputUserSelf : InputUserBase { } - /// Defines a user for further interaction. See + public partial class InputUserSelf : InputUserBase { } + ///See [TLDef(0xF21158C6)] - public sealed partial class InputUser : InputUserBase + public partial class InputUser : InputUserBase { - /// User identifier public long user_id; - /// 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 + ///See [TLDef(0x1DA448E2)] - public sealed partial class InputUserFromMessage : InputUserBase + public partial class InputUserFromMessage : InputUserBase { - /// The chat where the user was seen public InputPeer peer; - /// The message ID public int msg_id; - /// The identifier of the user that was seen public long user_id; } - /// Object defines a contact from the user's phone book. See Derived classes: - public abstract partial class InputContact : IObject { } - /// Phone contact. See - [TLDef(0x6A1DC4BE)] - public sealed partial class InputPhoneContact : InputContact + ///See + public abstract partial class InputContact : ITLObject { } + ///See + [TLDef(0xF392B7F4)] + public partial class InputPhoneContact : InputContact { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// An arbitrary 64-bit integer: it should be set, for example, to an incremental number when using Contacts_ImportContacts, in order to retry importing only the contacts that weren't imported successfully, according to the client_ids returned in .retry_contacts. public long client_id; - /// Phone number public string phone; - /// Contact's first name public string first_name; - /// Contact's last name public string last_name; - [IfFlag(0)] public TextWithEntities note; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_note = 0x1, - } } - /// Defines a file uploaded by the client. See Derived classes: , , - public abstract partial class InputFileBase : IObject { } - /// Defines a file saved in parts using the method Upload_SaveFilePart. See + ///See + public abstract partial class InputFileBase : ITLObject { } + ///See [TLDef(0xF52FF27F)] - public sealed partial class InputFile : InputFileBase + public partial class InputFile : InputFileBase { - /// Random file identifier created by the client public long id; - /// Number of parts saved public int parts; - /// Full name of the file public string name; - /// In case the file's md5-hash was passed, contents of the file will be checked prior to use - public string md5_checksum; + public byte[] md5_checksum; } - /// Assigns a big file (over 10 MB in size), saved in part using the method Upload_SaveBigFilePart. See + ///See [TLDef(0xFA4F0BB5)] - public sealed partial class InputFileBig : InputFileBase + public partial class InputFileBig : InputFileBase { - /// Random file id, created by the client public long id; - /// Number of parts saved public int parts; - /// Full file name public string name; } - /// Used to edit the thumbnail/static preview of a story, see here » for more info on the full flow. See - [TLDef(0x62DC8B48)] - public sealed partial class InputFileStoryDocument : InputFileBase - { - /// The old story video. - public InputDocument id; - } - /// Defines media content of a message. See Derived classes: , , , , , , , , , , , , , , , , , , - /// a value means inputMediaEmpty - public abstract partial class InputMedia : IObject { } - /// Photo See + ///See + ///a null value means inputMediaEmpty + public abstract partial class InputMedia : ITLObject { } + ///See [TLDef(0x1E287D04)] - public sealed partial class InputMediaUploadedPhoto : InputMedia + public partial class InputMediaUploadedPhoto : InputMedia { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_stickers = 0x1, has_ttl_seconds = 0x2 } public Flags flags; - /// The uploaded file public InputFileBase file; - /// Attached mask stickers [IfFlag(0)] public InputDocument[] stickers; - /// Time to live in seconds of self-destructing photo [IfFlag(1)] public int ttl_seconds; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_stickers = 0x1, - /// Field has a value - has_ttl_seconds = 0x2, - /// Whether this media should be hidden behind a spoiler warning - spoiler = 0x4, - } } - /// Forwarded photo See + ///See [TLDef(0xB3BA0635)] - public sealed partial class InputMediaPhoto : InputMedia + public partial class InputMediaPhoto : InputMedia { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_ttl_seconds = 0x1 } public Flags flags; - /// Photo to be forwarded public InputPhoto id; - /// Time to live in seconds of self-destructing photo [IfFlag(0)] public int ttl_seconds; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_ttl_seconds = 0x1, - /// Whether this media should be hidden behind a spoiler warning - spoiler = 0x2, - } } - /// Map. See + ///See [TLDef(0xF9C44144)] - public sealed partial class InputMediaGeoPoint : InputMedia - { - /// GeoPoint - public InputGeoPoint geo_point; - } - /// Phone book contact See + public partial class InputMediaGeoPoint : InputMedia { public InputGeoPoint geo_point; } + ///See [TLDef(0xF8AB7DFB)] - public sealed partial class InputMediaContact : InputMedia + public partial class InputMediaContact : InputMedia { - /// Phone number public string phone_number; - /// Contact's first name public string first_name; - /// Contact's last name public string last_name; - /// Contact vcard public string vcard; } - /// New document See - [TLDef(0x037C9330)] - public sealed partial class InputMediaUploadedDocument : InputMedia + ///See + [TLDef(0x5B38C6C1)] + public partial class InputMediaUploadedDocument : InputMedia { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_stickers = 0x1, has_ttl_seconds = 0x2, has_thumb = 0x4, nosound_video = 0x8, force_file = 0x10 } public Flags flags; - /// The uploaded file public InputFileBase file; - /// Thumbnail of the document, uploaded as for the file [IfFlag(2)] public InputFileBase thumb; - /// MIME type of document public string mime_type; - /// Attributes that specify the type of the document (video, audio, voice, sticker, etc.) public DocumentAttribute[] attributes; - /// Attached stickers [IfFlag(0)] public InputDocument[] stickers; - /// Start playing the video at the specified timestamp (seconds). - [IfFlag(6)] public InputPhoto video_cover; - /// Start playing the video at the specified timestamp (seconds). - [IfFlag(7)] public int video_timestamp; - /// Time to live in seconds of self-destructing document [IfFlag(1)] public int ttl_seconds; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_stickers = 0x1, - /// Field has a value - has_ttl_seconds = 0x2, - /// Field has a value - has_thumb = 0x4, - /// Whether to send the file as a video even if it doesn't have an audio track (i.e. if set, the attribute will not be set even for videos without audio) - nosound_video = 0x8, - /// Force the media file to be uploaded as document - force_file = 0x10, - /// Whether this media should be hidden behind a spoiler warning - spoiler = 0x20, - /// Field has a value - has_video_cover = 0x40, - /// Field has a value - has_video_timestamp = 0x80, - } } - /// Forwarded document See - [TLDef(0xA8763AB5)] - public sealed partial class InputMediaDocument : InputMedia + ///See + [TLDef(0x33473058)] + public partial class InputMediaDocument : InputMedia { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_ttl_seconds = 0x1, has_query = 0x2 } public Flags flags; - /// The document to be forwarded. public InputDocument id; - /// Custom video cover. - [IfFlag(3)] public InputPhoto video_cover; - /// Start playing the video at the specified timestamp (seconds). - [IfFlag(4)] public int video_timestamp; - /// Time to live of self-destructing document [IfFlag(0)] public int ttl_seconds; - /// Text query or emoji that was used by the user to find this sticker or GIF: used to improve search result relevance. [IfFlag(1)] public string query; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_ttl_seconds = 0x1, - /// Field has a value - has_query = 0x2, - /// Whether this media should be hidden behind a spoiler warning - spoiler = 0x4, - /// Field has a value - has_video_cover = 0x8, - /// Field has a value - has_video_timestamp = 0x10, - } } - /// Can be used to send a venue geolocation. See + ///See [TLDef(0xC13D1C11)] - public sealed partial class InputMediaVenue : InputMedia + public partial class InputMediaVenue : InputMedia { - /// Geolocation public InputGeoPoint geo_point; - /// Venue name public string title; - /// Physical address of the venue public string address; - /// Venue provider: currently only "foursquare" and "gplaces" (Google Places) need to be supported public string provider; - /// Venue ID in the provider's database public string venue_id; - /// Venue type in the provider's database public string venue_type; } - /// New photo that will be uploaded by the server using the specified URL See + ///See [TLDef(0xE5BBFE1A)] - public sealed partial class InputMediaPhotoExternal : InputMedia + public partial class InputMediaPhotoExternal : InputMedia { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_ttl_seconds = 0x1 } public Flags flags; - /// URL of the photo public string url; - /// Self-destruct time to live of photo [IfFlag(0)] public int ttl_seconds; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_ttl_seconds = 0x1, - /// Whether this media should be hidden behind a spoiler warning - spoiler = 0x2, - } } - /// Document that will be downloaded by the telegram servers See - [TLDef(0x779600F9)] - public sealed partial class InputMediaDocumentExternal : InputMedia + ///See + [TLDef(0xFB52DC99)] + public partial class InputMediaDocumentExternal : InputMedia { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_ttl_seconds = 0x1 } public Flags flags; - /// URL of the document public string url; - /// Self-destruct time to live of document [IfFlag(0)] public int ttl_seconds; - /// Custom video cover. - [IfFlag(2)] public InputPhoto video_cover; - /// Start playing the video at the specified timestamp (seconds). - [IfFlag(3)] public int video_timestamp; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_ttl_seconds = 0x1, - /// Whether this media should be hidden behind a spoiler warning - spoiler = 0x2, - /// Field has a value - has_video_cover = 0x4, - /// Field has a value - has_video_timestamp = 0x8, - } } - /// A game See + ///See [TLDef(0xD33F43F3)] - public sealed partial class InputMediaGame : InputMedia + public partial class InputMediaGame : InputMedia { public InputGame id; } + ///See + [TLDef(0xD9799874)] + public partial class InputMediaInvoice : InputMedia { - /// The game to forward - public InputGame id; - } - /// Generated invoice of a bot payment See - [TLDef(0x405FEF0D)] - public sealed partial class InputMediaInvoice : InputMedia - { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_photo = 0x1, has_start_param = 0x2 } public Flags flags; - /// Product name, 1-32 characters public string title; - /// Product description, 1-255 characters public string description; - /// URL of the product photo for the invoice. Can be a photo of the goods or a marketing image for a service. People like it better when they see what they are paying for. [IfFlag(0)] public InputWebDocument photo; - /// The actual invoice public Invoice invoice; - /// Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user, use for your internal processes. public byte[] payload; - /// Payments provider token, obtained via Botfather - [IfFlag(3)] public string provider; - /// JSON-encoded data about the invoice, which will be shared with the payment provider. A detailed description of required fields should be provided by the payment provider. + public string provider; public DataJSON provider_data; - /// Unique bot deep links start parameter. If present, forwarded copies of the sent message will have a URL button with a deep link to the bot (instead of a Pay button), with the value used as the start parameter. If absent, forwarded copies of the sent message will have a Pay button, allowing multiple users to pay directly from the forwarded message, using the same invoice. [IfFlag(1)] public string start_param; - /// Deprecated - [IfFlag(2)] public InputMedia extended_media; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_photo = 0x1, - /// Field has a value - has_start_param = 0x2, - /// Field has a value - has_extended_media = 0x4, - /// Field has a value - has_provider = 0x8, - } } - /// Live geolocation See + ///See [TLDef(0x971FA843)] - public sealed partial class InputMediaGeoLive : InputMedia + public partial class InputMediaGeoLive : InputMedia { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { stopped = 0x1, has_period = 0x2, has_heading = 0x4, has_proximity_notification_radius = 0x8 } public Flags flags; - /// Current geolocation public InputGeoPoint geo_point; - /// For live locations, a direction in which the location moves, in degrees; 1-360. [IfFlag(2)] public int heading; - /// Validity period of the current location [IfFlag(1)] public int period; - /// For live locations, a maximum distance to another chat member for proximity alerts, in meters (0-100000) [IfFlag(3)] public int proximity_notification_radius; - - [Flags] public enum Flags : uint - { - /// Whether sending of the geolocation was stopped - stopped = 0x1, - /// Field has a value - has_period = 0x2, - /// Field has a value - has_heading = 0x4, - /// Field has a value - has_proximity_notification_radius = 0x8, - } } - /// A poll See + ///See [TLDef(0x0F94E5F1)] - public sealed partial class InputMediaPoll : InputMedia + public partial class InputMediaPoll : InputMedia { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_correct_answers = 0x1, has_solution = 0x2 } public Flags flags; - /// The poll to send public Poll poll; - /// Correct answer IDs (for quiz polls) [IfFlag(0)] public byte[][] correct_answers; - /// Explanation of quiz solution [IfFlag(1)] public string solution; - /// Message entities for styled text [IfFlag(1)] public MessageEntity[] solution_entities; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_correct_answers = 0x1, - /// Fields and have a value - has_solution = 0x2, - } } - /// Send a dice-based animated sticker See + ///See [TLDef(0xE66FBF7B)] - public sealed partial class InputMediaDice : InputMedia - { - /// The emoji, for now 🏀, 🎲 and 🎯 are supported - public string emoticon; - } - /// Forwarded story See - [TLDef(0x89FDD778)] - public sealed partial class InputMediaStory : InputMedia - { - /// Peer where the story was posted - public InputPeer peer; - /// Story ID - public int id; - } - /// Specifies options that will be used to generate the link preview for the caption, or even a standalone link preview without an attached message. See - [TLDef(0xC21B8849)] - public sealed partial class InputMediaWebPage : InputMedia - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The URL to use for the link preview. - public string url; + public partial class InputMediaDice : InputMedia { public string emoticon; } - [Flags] public enum Flags : uint - { - /// If set, specifies that a large media preview should be used. - force_large_media = 0x1, - /// If set, specifies that a small media preview should be used. - force_small_media = 0x2, - /// If not set, a WEBPAGE_NOT_FOUND RPC error will be emitted if a webpage preview cannot be generated for the specified url; otherwise, no error will be emitted (unless the provided message is also empty, in which case a MESSAGE_EMPTY will be emitted, instead). - optional = 0x4, - } - } - /// Paid media, see here » for more info. See - [TLDef(0xC4103386)] - public sealed partial class InputMediaPaidMedia : InputMedia + ///See + ///a null value means inputChatPhotoEmpty + public abstract partial class InputChatPhotoBase : ITLObject { } + ///See + [TLDef(0xC642724E)] + public partial class InputChatUploadedPhoto : InputChatPhotoBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_file = 0x1, has_video = 0x2, has_video_start_ts = 0x4 } public Flags flags; - /// The price of the media in Telegram Stars. - public long stars_amount; - /// Photos or videos. - public InputMedia[] extended_media; - /// Bots only, specifies a custom payload that will then be passed in when a payment is made (this field will not be visible to the user) - [IfFlag(0)] public string payload; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_payload = 0x1, - } - } - /// Creates a todo list ». See - [TLDef(0x9FC55FDE)] - public sealed partial class InputMediaTodo : InputMedia - { - /// The todo list. - public TodoList todo; - } - /// See - [TLDef(0xF3A9244A)] - public sealed partial class InputMediaStakeDice : InputMedia - { - public string game_hash; - public long ton_amount; - public byte[] client_seed; - } - - /// Defines a new group profile photo. See Derived classes: , - /// a value means inputChatPhotoEmpty - public abstract partial class InputChatPhotoBase : IObject { } - /// New photo to be set as group profile photo. See - [TLDef(0xBDCDAEC0)] - public sealed partial class InputChatUploadedPhoto : InputChatPhotoBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// 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; - /// Floating point UNIX timestamp in seconds, indicating the frame of the video/sticker that should be used as static preview; can only be used if video or video_emoji_markup is set. [IfFlag(2)] public double video_start_ts; - /// Animated sticker profile picture, must contain either a or a . - [IfFlag(3)] public VideoSizeBase video_emoji_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_file = 0x1, - /// Field has a value - has_video = 0x2, - /// Field has a value - has_video_start_ts = 0x4, - /// Field has a value - has_video_emoji_markup = 0x8, - } } - /// Existing photo to be set as a chat profile photo. See + ///See [TLDef(0x8953AD37)] - public sealed partial class InputChatPhoto : InputChatPhotoBase - { - /// Existing photo - public InputPhoto id; - } + public partial class InputChatPhoto : InputChatPhotoBase { public InputPhoto id; } - /// Defines a GeoPoint by its coordinates. See - /// a value means inputGeoPointEmpty + ///See + ///a null value means inputGeoPointEmpty [TLDef(0x48222FAF)] - public sealed partial class InputGeoPoint : IObject + public partial class InputGeoPoint : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_accuracy_radius = 0x1 } public Flags flags; - /// Latitude public double lat; - /// Longitude - public double lon; - /// The estimated horizontal accuracy of the location, in meters; as defined by the sender. + public double long_; [IfFlag(0)] public int accuracy_radius; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_accuracy_radius = 0x1, - } } - /// Defines a photo for further interaction. See - /// a value means inputPhotoEmpty + ///See + ///a null value means inputPhotoEmpty [TLDef(0x3BB3B94A)] - public sealed partial class InputPhoto : IObject + public partial class InputPhoto : ITLObject { - /// Photo identifier public long id; - /// REQUIRED FIELD. See how to obtain it
access_hash value from the
public long access_hash; - /// File reference public byte[] file_reference; } - /// Defines the location of a file for download. See Derived classes: , , , , , , , , , - public abstract partial class InputFileLocationBase : IObject { } - /// DEPRECATED location of a photo See + ///See + public abstract partial class InputFileLocationBase : ITLObject { } + ///See [TLDef(0xDFDAABE1)] - public sealed partial class InputFileLocation : InputFileLocationBase + public partial class InputFileLocation : InputFileLocationBase { - /// Server volume public long volume_id; - /// File identifier public int local_id; - /// Check sum to access the file public long secret; - /// File reference public byte[] file_reference; } - /// Location of encrypted secret chat file. See + ///See [TLDef(0xF5235D55)] - public sealed partial class InputEncryptedFileLocation : InputFileLocationBase + public partial class InputEncryptedFileLocation : InputFileLocationBase { - /// File ID, id parameter value from public long id; - /// 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 + ///See [TLDef(0xBAD07584)] - public sealed partial class InputDocumentFileLocation : InputFileLocationBase + public partial class InputDocumentFileLocation : InputFileLocationBase { - /// Document ID public long id; - /// REQUIRED FIELD. See how to obtain it
access_hash parameter from the
public long access_hash; - ///
File reference public byte[] file_reference; - /// Thumbnail size to download the thumbnail public string thumb_size; } - /// Location of encrypted telegram passport file. See + ///See [TLDef(0xCBC7EE28)] - public sealed partial class InputSecureFileLocation : InputFileLocationBase + public partial class InputSecureFileLocation : InputFileLocationBase { - /// File ID, id parameter value from public long id; - /// REQUIRED FIELD. See how to obtain it
Checksum, access_hash parameter value from
public long access_hash; } - ///
Used to download a JSON file that will contain all personal data related to features that do not have a specialized takeout method yet, see here » for more info on the takeout API. See + ///See [TLDef(0x29BE5899)] - public sealed partial class InputTakeoutFileLocation : InputFileLocationBase { } - /// Use this object to download a photo with Upload_GetFile method See + public partial class InputTakeoutFileLocation : InputFileLocationBase { } + ///See [TLDef(0x40181FFE)] - public sealed partial class InputPhotoFileLocation : InputFileLocationBase + public partial class InputPhotoFileLocation : InputFileLocationBase { - /// Photo ID, obtained from the object public long id; - /// 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; - /// The to download: must be set to the type field of the desired PhotoSize object of the public string thumb_size; } - /// DEPRECATED legacy photo file location See + ///See [TLDef(0xD83466F3)] - public sealed partial class InputPhotoLegacyFileLocation : InputFileLocationBase + public partial class InputPhotoLegacyFileLocation : InputFileLocationBase { - /// Photo ID public long id; - /// REQUIRED FIELD. See how to obtain it
Access hash
public long access_hash; - /// File reference public byte[] file_reference; - /// Volume ID public long volume_id; - /// Local ID public int local_id; - /// Secret public long secret; } - ///
Location of profile photo of channel/group/supergroup/user See + ///See [TLDef(0x37257E99)] - public sealed partial class InputPeerPhotoFileLocation : InputFileLocationBase + public partial class InputPeerPhotoFileLocation : InputFileLocationBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { big = 0x1 } public Flags flags; - /// The peer whose profile picture should be downloaded public InputPeer peer; - /// Photo ID public long photo_id; - - [Flags] public enum Flags : uint - { - /// Whether to download the high-quality version of the picture - big = 0x1, - } } - /// Location of stickerset thumbnail (see files) See + ///See [TLDef(0x9D84F3DB)] - public sealed partial class InputStickerSetThumb : InputFileLocationBase + public partial class InputStickerSetThumb : InputFileLocationBase { - /// Sticker set public InputStickerSet stickerset; - /// Thumbnail version public int thumb_version; } - /// Chunk of a livestream See + ///See [TLDef(0x0598A92A)] - public sealed partial class InputGroupCallStream : InputFileLocationBase + public partial class InputGroupCallStream : InputFileLocationBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_video_channel = 0x1 } public Flags flags; - /// Livestream info - public InputGroupCallBase call; - /// Timestamp in milliseconds + public InputGroupCall call; public long time_ms; - /// Specifies the duration of the video segment to fetch in milliseconds, by bitshifting 1000 to the right scale times: duration_ms := 1000 >> scale public int scale; - /// Selected video channel [IfFlag(0)] public int video_channel; - /// Selected video quality (0 = lowest, 1 = medium, 2 = best) [IfFlag(0)] public int video_quality; - - [Flags] public enum Flags : uint - { - /// Fields and have a value - has_video_channel = 0x1, - } } - /// Identifier of a private chat, basic group, group or channel (see here » for more info). See Derived classes: , , - public abstract partial class Peer : IObject { } - /// Chat partner See + ///See + public abstract partial class Peer : ITLObject { } + ///See [TLDef(0x59511722)] - public sealed partial class PeerUser : Peer - { - /// User identifier - public long user_id; - } - /// Group. See + public partial class PeerUser : Peer { public long user_id; } + ///See [TLDef(0x36C6019A)] - public sealed partial class PeerChat : Peer - { - /// Group identifier - public long chat_id; - } - /// Channel/supergroup See + public partial class PeerChat : Peer { public long chat_id; } + ///See [TLDef(0xA2A5371E)] - public sealed partial class PeerChannel : Peer - { - /// Channel ID - public long channel_id; - } + public partial class PeerChannel : Peer { public long channel_id; } - /// Object describes the file type. See + ///See public enum Storage_FileType : uint { - ///Unknown type. + ///See unknown = 0xAA963B05, - ///Part of a bigger file. + ///See partial = 0x40BC6F52, - ///JPEG image. MIME type: image/jpeg. + ///See jpeg = 0x007EFE0E, - ///GIF image. MIME type: image/gif. + ///See gif = 0xCAE1AADF, - ///PNG image. MIME type: image/png. + ///See png = 0x0A4F63C0, - ///PDF document image. MIME type: application/pdf. + ///See pdf = 0xAE1E508D, - ///Mp3 audio. MIME type: audio/mpeg. + ///See mp3 = 0x528A0677, - ///Quicktime video. MIME type: video/quicktime. + ///See mov = 0x4B09EBBC, - ///MPEG-4 video. MIME type: video/mp4. + ///See mp4 = 0xB3CEA0E4, - ///WEBP image. MIME type: image/webp. + ///See webp = 0x1081464C, } - /// Object defines a user. See Derived classes: , - public abstract partial class UserBase : IObject { } - /// Empty constructor, non-existent user. See + ///See + public abstract partial class UserBase : ITLObject { } + ///See [TLDef(0xD3BC4B7A)] - public sealed partial class UserEmpty : UserBase + public partial class UserEmpty : UserBase { public long id; } + ///See + [TLDef(0x3FF6ECB0)] + public partial class User : UserBase { - /// User identifier or 0 - public long id; - } - /// Indicates info about a certain user. See - [TLDef(0x31774388)] - public sealed partial class User : UserBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_access_hash = 0x1, has_first_name = 0x2, has_last_name = 0x4, has_username = 0x8, + has_phone = 0x10, has_photo = 0x20, has_status = 0x40, self = 0x400, contact = 0x800, mutual_contact = 0x1000, + deleted = 0x2000, bot = 0x4000, bot_chat_history = 0x8000, bot_nochats = 0x10000, verified = 0x20000, restricted = 0x40000, + has_bot_inline_placeholder = 0x80000, min = 0x100000, bot_inline_geo = 0x200000, has_lang_code = 0x400000, support = 0x800000, + scam = 0x1000000, apply_min_photo = 0x2000000, fake = 0x4000000 } public Flags flags; - /// Extra bits of information, use flags2.HasFlag(...) to test for those - public Flags2 flags2; - /// ID of the user, see here » for more info and the available ID range. public long id; - /// Access hash of the user, see here » for more info.
If this flag is set, when updating the local peer database, generate a virtual flag called min_access_hash, which is:
- Set to true if min is set AND
-- The phone flag is not set OR
-- The phone flag is set and the associated phone number string is non-empty
- Set to false otherwise.

Then, apply both access_hash and min_access_hash to the local database if:
- min_access_hash is false OR
- min_access_hash is true AND
-- There is no locally cached object for this user OR
-- There is no access_hash in the local cache OR
-- The cached object's min_access_hash is also true

If the final merged object stored to the database has the min_access_hash field set to true, the related access_hash is only suitable to use in inputPeerPhotoFileLocation », to directly download the profile pictures of users, everywhere else a inputPeer*FromMessage constructor will have to be generated as specified here ».
Bots can also use min access hashes in some conditions, by passing 0 instead of the min access hash.
[IfFlag(0)] public long access_hash; - /// First name.
When updating the local peer database, apply changes to this field only if:
- The min flag is not set OR
- The min flag is set AND
-- The min flag of the locally cached user entry is set.
[IfFlag(1)] public string first_name; - /// Last name.
When updating the local peer database, apply changes to this field only if:
- The min flag is not set OR
- The min flag is set AND
-- The min flag of the locally cached user entry is set.
[IfFlag(2)] public string last_name; - /// Main active username.
When updating the local peer database, apply changes to this field only if:
- The min flag is not set OR
- The min flag is set AND
-- The min flag of the locally cached user entry is set.
Changes to this flag should invalidate the local cache for this user ID if the above conditions are respected and the bot_can_edit flag is also set.
[IfFlag(3)] public string username; - /// Phone number.
When updating the local peer database, apply changes to this field only if:
- The min flag is not set OR
- The min flag is set AND
-- The min flag of the locally cached user entry is set.
[IfFlag(4)] public string phone; - /// Profile picture of user.
When updating the local peer database, apply changes to this field only if:
- The min flag is not set OR
- The min flag is set AND
-- The apply_min_photo flag is set OR
-- The min flag of the locally cached user entry is set.
[IfFlag(5)] public UserProfilePhoto photo; - /// Online status of user.
When updating the local peer database, apply changes to this field only if:
- The min flag is not set OR
- The min flag is set AND
-- The min flag of the locally cached user entry is set OR
-- The locally cached user entry is equal to .
[IfFlag(6)] public UserStatus status; - /// Version of the bot_info field in userFull, incremented every time it changes.
Changes to this flag should invalidate the local cache for this user ID, see here » for more info.
[IfFlag(14)] public int bot_info_version; - /// Contains the reason why access to this user must be restricted. [IfFlag(18)] public RestrictionReason[] restriction_reason; - /// Inline placeholder for this inline bot [IfFlag(19)] public string bot_inline_placeholder; - /// Language code of the user [IfFlag(22)] public string lang_code; - /// Emoji status - [IfFlag(30)] public EmojiStatusBase emoji_status; - /// Additional usernames.
When updating the local peer database, apply changes to this field only if:
- The min flag is not set OR
- The min flag is set AND
-- The min flag of the locally cached user entry is set.
Changes to this flag (if the above conditions are respected) should invalidate the local cache for this user ID.
- [IfFlag(32)] public Username[] usernames; - /// ID of the maximum read story.
When updating the local peer database, do not apply changes to this field if the min flag of the incoming constructor is set.
- [IfFlag(37)] public RecentStory stories_max_id; - /// The user's accent color. - [IfFlag(40)] public PeerColorBase color; - /// The user's profile color. - [IfFlag(41)] public PeerColorBase profile_color; - /// Monthly Active Users (MAU) of this bot (may be absent for small bots). - [IfFlag(44)] public int bot_active_users; - /// Describes a bot verification icon ». - [IfFlag(46)] public long bot_verification_icon; - /// If set, the user has enabled paid messages », we might need to pay the specified amount of Stars to send them messages, depending on the configured exceptions: check .send_paid_messages_stars or Users_GetRequirementsToContact to see if the currently logged in user actually has to pay or not, see here » for the full flow. - [IfFlag(47)] public long send_paid_messages_stars; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_access_hash = 0x1, - /// Field has a value - has_first_name = 0x2, - /// Field has a value - has_last_name = 0x4, - /// Field has a value - has_username = 0x8, - /// Field has a value - has_phone = 0x10, - /// Field has a value - has_photo = 0x20, - /// Field has a value - has_status = 0x40, - /// Whether this user indicates the currently logged in user - self = 0x400, - /// Whether this user is a contact
When updating the local peer database, do not apply changes to this field if the min flag is set.
- contact = 0x800, - /// Whether this user is a mutual contact.
When updating the local peer database, do not apply changes to this field if the min flag is set.
- mutual_contact = 0x1000, - /// Whether the account of this user was deleted.
Changes to this flag should invalidate the local cache for this user ID, see here » for more info.
- deleted = 0x2000, - /// Is this user a bot?
Changes to this flag should invalidate the local cache for this user ID, see here » for more info.
- bot = 0x4000, - /// Can the bot see all messages in groups? - bot_chat_history = 0x8000, - /// Can the bot be added to groups? - bot_nochats = 0x10000, - /// Whether this user is verified - verified = 0x20000, - /// Access to this user must be restricted for the reason specified in restriction_reason - restricted = 0x40000, - /// Field has a value - has_bot_inline_placeholder = 0x80000, - /// See min - min = 0x100000, - /// Whether the bot can request our geolocation in inline mode - bot_inline_geo = 0x200000, - /// Field has a value - has_lang_code = 0x400000, - /// Whether this is an official support user - support = 0x800000, - /// This may be a scam user - scam = 0x1000000, - /// If set and min is set, the value of photo can be used to update the local database, see the documentation of that flag for more info. - apply_min_photo = 0x2000000, - /// If set, this user was reported by many users as a fake or scam user: be careful when interacting with them. - fake = 0x4000000, - /// Whether this bot offers an attachment menu web app - bot_attach_menu = 0x8000000, - /// Whether this user is a Telegram Premium user
Changes to this flag should invalidate the local cache for this user ID, see here » for more info.
Changes to this flag if the self flag is set should also trigger the following calls, to refresh the respective caches:
- The Help_GetConfig cache
- The Messages_GetTopReactions cache if the bot flag is not set
- premium = 0x10000000, - /// Whether we installed the attachment menu web app offered by this bot.
When updating the local peer database, do not apply changes to this field if the min flag is set.
- attach_menu_enabled = 0x20000000, - /// Field has a value - has_emoji_status = 0x40000000, - } - - [Flags] public enum Flags2 : uint - { - /// Field has a value - has_usernames = 0x1, - /// Whether we can edit the profile picture, name, about text and description of this bot because we own it.
When updating the local peer database, do not apply changes to this field if the min flag is set.
Changes to this flag (if min is not set) should invalidate the local cache for this user ID.
- bot_can_edit = 0x2, - /// Whether we marked this user as a close friend, see here » for more info.
When updating the local peer database, do not apply changes to this field if the min flag is set.
- close_friend = 0x4, - /// Whether we have hidden » all active stories of this user.
When updating the local peer database, do not apply changes to this field if the min flag is set.
- stories_hidden = 0x8, - /// No stories from this user are visible. - stories_unavailable = 0x10, - /// Field has a value - has_stories_max_id = 0x20, - /// Field has a value - has_color = 0x100, - /// Field has a value - has_profile_color = 0x200, - /// See here for more info on this flag ». - contact_require_premium = 0x400, - /// Whether this bot can be connected to a user as specified here ». - bot_business = 0x800, - /// Field has a value - has_bot_active_users = 0x1000, - /// If set, this bot has configured a Main Mini App ». - bot_has_main_app = 0x2000, - /// Field has a value - has_bot_verification_icon = 0x4000, - /// Field has a value - has_send_paid_messages_stars = 0x8000, - bot_forum_view = 0x10000, - bot_forum_can_manage_topics = 0x20000, - } } - /// User profile photo. See - /// a value means userProfilePhotoEmpty + ///See + ///a null value means userProfilePhotoEmpty [TLDef(0x82D1F706)] - public sealed partial class UserProfilePhoto : IObject + public partial class UserProfilePhoto : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_video = 0x1, has_stripped_thumb = 0x2 } public Flags flags; - /// Identifier of the respective photo public long photo_id; - /// Stripped thumbnail [IfFlag(1)] public byte[] stripped_thumb; - /// DC ID where the photo is stored public int dc_id; - - [Flags] public enum Flags : uint - { - /// Whether an animated profile picture is available for this user - has_video = 0x1, - /// Field has a value - has_stripped_thumb = 0x2, - /// Whether this profile photo is only visible to us (i.e. it was set using Photos_UploadContactProfilePhoto). - personal = 0x4, - } } - /// User online status See Derived classes: , , , , - /// a value means userStatusEmpty - public abstract partial class UserStatus : IObject { } - /// Online status of the user. See + ///See + ///a null value means userStatusEmpty + public abstract partial class UserStatus : ITLObject { } + ///See [TLDef(0xEDB93949)] - public sealed partial class UserStatusOnline : UserStatus - { - /// Time to expiration of the current online status - public DateTime expires; - } - /// The user's offline status. See + public partial class UserStatusOnline : UserStatus { public DateTime expires; } + ///See [TLDef(0x008C703F)] - public sealed partial class UserStatusOffline : UserStatus - { - /// Time the user was last seen online - public DateTime was_online; - } - /// Online status: last seen recently See - [TLDef(0x7B197DC8)] - public sealed partial class UserStatusRecently : UserStatus - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; + public partial class UserStatusOffline : UserStatus { public int was_online; } + ///See + [TLDef(0xE26F42F1)] + public partial class UserStatusRecently : UserStatus { } + ///See + [TLDef(0x07BF09FC)] + public partial class UserStatusLastWeek : UserStatus { } + ///See + [TLDef(0x77EBC742)] + public partial class UserStatusLastMonth : UserStatus { } - [Flags] public enum Flags : uint - { - /// If set, the exact user status of this user is actually available to us, but to view it we must first purchase a Premium subscription, or allow this user to see our exact last online status. See here » for more info. - by_me = 0x1, - } - } - /// Online status: last seen last week See - [TLDef(0x541A1D1A)] - public sealed partial class UserStatusLastWeek : UserStatus - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - - [Flags] public enum Flags : uint - { - /// If set, the exact user status of this user is actually available to us, but to view it we must first purchase a Premium subscription, or allow this user to see our exact last online status. See here » for more info. - by_me = 0x1, - } - } - /// Online status: last seen last month See - [TLDef(0x65899777)] - public sealed partial class UserStatusLastMonth : UserStatus - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - - [Flags] public enum Flags : uint - { - /// If set, the exact user status of this user is actually available to us, but to view it we must first purchase a Premium subscription, or allow this user to see our exact last online status. See here » for more info. - by_me = 0x1, - } - } - - /// Object defines a group. See Derived classes: , , , , - public abstract partial class ChatBase : IObject - { - /// ID of the group, see here » for more info and the available ID range. - public virtual long ID => default; - /// Title - public virtual string Title => default; - } - /// Empty constructor, group doesn't exist See + ///See + public abstract partial class ChatBase : ITLObject { } + ///See [TLDef(0x29562865)] - public sealed partial class ChatEmpty : ChatBase - { - /// Group identifier - public long id; - - /// Group identifier - public override long ID => id; - } - /// Info about a group. See + public partial class ChatEmpty : ChatBase { public long id; } + ///See [TLDef(0x41CBF256)] - public sealed partial class Chat : ChatBase + public partial class Chat : ChatBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { creator = 0x1, kicked = 0x2, left = 0x4, deactivated = 0x20, has_migrated_to = 0x40, + has_admin_rights = 0x4000, has_default_banned_rights = 0x40000, call_active = 0x800000, call_not_empty = 0x1000000 } public Flags flags; - /// ID of the group, see here » for more info and the available ID range. public long id; - /// Title public string title; - /// Chat photo public ChatPhoto photo; - /// Participant count public int participants_count; - /// Date of creation of the group public DateTime date; - /// Used in basic groups to reorder updates and make sure that all of them were received. public int version; - /// Means this chat was upgraded to a supergroup [IfFlag(6)] public InputChannelBase migrated_to; - /// Admin rights of the user in the group [IfFlag(14)] public ChatAdminRights admin_rights; - /// Default banned rights of all users in the group [IfFlag(18)] public ChatBannedRights default_banned_rights; - - [Flags] public enum Flags : uint - { - /// Whether the current user is the creator of the group - creator = 0x1, - /// Whether the current user has left the group - left = 0x4, - /// Whether the group was migrated - deactivated = 0x20, - /// Field has a value - has_migrated_to = 0x40, - /// Field has a value - has_admin_rights = 0x4000, - /// Field has a value - has_default_banned_rights = 0x40000, - /// Whether a group call is currently active - call_active = 0x800000, - /// Whether there's anyone in the group call - call_not_empty = 0x1000000, - /// Whether this group is protected, thus does not allow forwarding messages from it - noforwards = 0x2000000, - } - - /// ID of the group, see here » for more info and the available ID range. - public override long ID => id; - /// Title - public override string Title => title; } - /// A group to which the user has no access. E.g., because the user was kicked from the group. See + ///See [TLDef(0x6592A1A7)] - public sealed partial class ChatForbidden : ChatBase + public partial class ChatForbidden : ChatBase { - /// User identifier public long id; - /// Group name public string title; - - /// User identifier - public override long ID => id; - /// Group name - public override string Title => title; } - /// Channel/supergroup info See - [TLDef(0x1C32B11C)] - public sealed partial class Channel : ChatBase + ///See + [TLDef(0x8261AC61)] + public partial class Channel : ChatBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { creator = 0x1, left = 0x4, broadcast = 0x20, has_username = 0x40, verified = 0x80, + megagroup = 0x100, restricted = 0x200, signatures = 0x800, min = 0x1000, has_access_hash = 0x2000, has_admin_rights = 0x4000, + has_banned_rights = 0x8000, has_participants_count = 0x20000, has_default_banned_rights = 0x40000, scam = 0x80000, + has_link = 0x100000, has_geo = 0x200000, slowmode_enabled = 0x400000, call_active = 0x800000, call_not_empty = 0x1000000, + fake = 0x2000000, gigagroup = 0x4000000 } public Flags flags; - /// Extra bits of information, use flags2.HasFlag(...) to test for those - public Flags2 flags2; - /// ID of the channel, see here » for more info and the available ID range. public long id; - /// Access hash, see here » for more info [IfFlag(13)] public long access_hash; - /// Title public string title; - /// Main active username. [IfFlag(6)] public string username; - /// Profile photo public ChatPhoto photo; - /// Date when the user joined the supergroup/channel, or if the user isn't a member, its creation date public DateTime date; - /// Contains the reason why access to this channel must be restricted.
Changes to this flag should invalidate the local cache for this channel/supergroup ID, see here » for more info.
[IfFlag(9)] public RestrictionReason[] restriction_reason; - /// Admin rights of the user in this channel (see rights) [IfFlag(14)] public ChatAdminRights admin_rights; - /// Banned rights of the user in this channel (see rights) [IfFlag(15)] public ChatBannedRights banned_rights; - /// Default chat rights (see rights) [IfFlag(18)] public ChatBannedRights default_banned_rights; - /// Participant count [IfFlag(17)] public int participants_count; - /// Additional usernames - [IfFlag(32)] public Username[] usernames; - /// ID of the maximum read story. - [IfFlag(36)] public RecentStory stories_max_id; - /// The channel's accent color. - [IfFlag(39)] public PeerColorBase color; - /// The channel's profile color. - [IfFlag(40)] public PeerColorBase profile_color; - /// Emoji status - [IfFlag(41)] public EmojiStatusBase emoji_status; - /// Boost level.
Changes to this flag should invalidate the local cache for this channel/supergroup ID, see here » for more info.
- [IfFlag(42)] public int level; - /// Expiration date of the Telegram Star subscription » the current user has bought to gain access to this channel. - [IfFlag(43)] public DateTime subscription_until_date; - /// Describes a bot verification icon ». - [IfFlag(45)] public long bot_verification_icon; - /// If set, this supergroup or monoforum has enabled paid messages », we might need to pay the specified amount of Stars to send messages to it, depending on the configured exceptions: check .send_paid_messages_stars to see if the currently logged in user actually has to pay or not, see here » for the full flow (only set for the monoforum, not the associated channel). - [IfFlag(46)] public long send_paid_messages_stars; - /// For channels with associated monoforums, the monoforum ID. For Monoforums, the ID of the associated channel. - [IfFlag(50)] public long linked_monoforum_id; - - [Flags] public enum Flags : uint - { - /// Whether the current user is the creator of this channel - creator = 0x1, - /// Whether the current user has left or is not a member of this channel - left = 0x4, - /// Is this a channel? - broadcast = 0x20, - /// Field has a value - has_username = 0x40, - /// Is this channel verified by telegram? - verified = 0x80, - /// Is this a supergroup?
Changes to this flag should invalidate the local cache for this channel/supergroup ID, see here » for more info.
- megagroup = 0x100, - /// Whether viewing/writing in this channel for a reason (see restriction_reason) - restricted = 0x200, - /// Whether signatures are enabled (channels) - signatures = 0x800, - /// See min - min = 0x1000, - /// Field has a value - has_access_hash = 0x2000, - /// Field has a value - has_admin_rights = 0x4000, - /// Field has a value - has_banned_rights = 0x8000, - /// Field has a value - has_participants_count = 0x20000, - /// Field has a value - has_default_banned_rights = 0x40000, - /// This channel/supergroup is probably a scam
Changes to this flag should invalidate the local cache for this channel/supergroup ID, see here » for more info.
- scam = 0x80000, - /// Whether this channel has a linked discussion group » (or this supergroup is a channel's discussion group). The actual ID of the linked channel/supergroup is contained in .linked_chat_id.
Changes to this flag should invalidate the local cache for this channel/supergroup ID, see here » for more info.
- has_link = 0x100000, - /// Whether this chanel has a geoposition - has_geo = 0x200000, - /// Whether slow mode is enabled for groups to prevent flood in chat.
Changes to this flag should invalidate the local cache for this channel/supergroup ID, see here » for more info.
- slowmode_enabled = 0x400000, - /// Whether a group call or livestream is currently active - call_active = 0x800000, - /// Whether there's anyone in the group call or livestream - call_not_empty = 0x1000000, - /// If set, this supergroup/channel was reported by many users as a fake or scam: be careful when interacting with it.
Changes to this flag should invalidate the local cache for this channel/supergroup ID, see here » for more info.
- fake = 0x2000000, - /// Whether this supergroup is a gigagroup
Changes to this flag should invalidate the local cache for this channel/supergroup ID, see here » for more info.
- 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
Changes to this flag should invalidate the local cache for this channel/supergroup ID, see here » for more info.
- join_to_send = 0x10000000, - /// Whether a user's join request will have to be approved by administrators, toggle using Channels_ToggleJoinRequest
Changes to this flag should invalidate the local cache for this channel/supergroup ID, see here » for more info.
- join_request = 0x20000000, - /// Whether this supergroup is a forum.
Changes to this flag should invalidate the local cache for this channel/supergroup ID, see here » for more info.
- forum = 0x40000000, - } - - [Flags] public enum Flags2 : uint - { - /// Field has a value - has_usernames = 0x1, - /// Whether we have hidden all stories posted by this channel ». - stories_hidden = 0x2, - /// If set, indicates that the stories_hidden flag was not populated, and its value must cannot be relied on; use the previously cached value, or re-fetch the constructor using Channels_GetChannels to obtain the latest value of the stories_hidden flag. - stories_hidden_min = 0x4, - /// No stories from the channel are visible. - stories_unavailable = 0x8, - /// Field has a value - has_stories_max_id = 0x10, - /// Field has a value - has_color = 0x80, - /// Field has a value - has_profile_color = 0x100, - /// Field has a value - has_emoji_status = 0x200, - /// Field has a value - has_level = 0x400, - /// Field has a value - has_subscription_until_date = 0x800, - /// If set, messages sent by admins to this channel will link to the admin's profile (just like with groups). - signature_profiles = 0x1000, - /// Field has a value - has_bot_verification_icon = 0x2000, - /// Field has a value - has_send_paid_messages_stars = 0x4000, - /// If set, autotranslation was enabled for all users by the admin of the channel, as specified here ». - autotranslation = 0x8000, - /// If set, this channel has an associated monoforum », and its ID is specified in the linked_monoforum_id flag. - broadcast_messages_allowed = 0x10000, - /// If set, this is a monoforum », and the ID of the associated channel is specified in the linked_monoforum_id. - monoforum = 0x20000, - /// Field has a value - has_linked_monoforum_id = 0x40000, - /// If set, enables the tabbed forum UI ». - forum_tabs = 0x80000, - } - - /// ID of the channel, see here » for more info and the available ID range. - public override long ID => id; - /// Title - public override string Title => title; } - /// Indicates a channel/supergroup we can't access because we were banned, or for some other reason. See + ///See [TLDef(0x17D493D5)] - public sealed partial class ChannelForbidden : ChatBase + public partial class ChannelForbidden : ChatBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { broadcast = 0x20, megagroup = 0x100, has_until_date = 0x10000 } public Flags flags; - /// Channel ID public long id; - /// Access hash public long access_hash; - /// Title public string title; - /// The ban is valid until the specified date [IfFlag(16)] public DateTime until_date; - - [Flags] public enum Flags : uint - { - /// Is this a channel - broadcast = 0x20, - /// Is this a supergroup - megagroup = 0x100, - monoforum = 0x400, - /// Field has a value - has_until_date = 0x10000, - } - - /// Channel ID - public override long ID => id; - /// Title - public override string Title => title; } - /// Full info about a channel, supergroup, gigagroup or basic group. See Derived classes: , - public abstract partial class ChatFullBase : IObject + ///See + public abstract partial class ChatFullBase : ITLObject { } + ///See + [TLDef(0x4DBDC099)] + public partial class ChatFull : ChatFullBase { - /// ID of the chat - public virtual long ID => default; - /// About string for this chat - public virtual string About => default; - /// Chat photo - public virtual PhotoBase ChatPhoto => default; - /// Notification settings - public virtual PeerNotifySettings NotifySettings => default; - /// Chat invite - public virtual ExportedChatInvite ExportedInvite => default; - /// Info about bots that are in this chat - public virtual BotInfo[] BotInfo => default; - /// Message ID of the last pinned message - public virtual int PinnedMsg => default; - /// Peer folder ID, for more info click here - public virtual int Folder => default; - /// Group call information - public virtual InputGroupCallBase Call => default; - /// Time-To-Live of messages sent by the current user to this chat - public virtual int TtlPeriod => 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 => default; - /// Emoji representing a specific chat theme - public virtual string ThemeEmoticon => default; - /// Pending join requests » - public virtual int RequestsPending => default; - /// IDs of users who requested to join recently - public virtual long[] RecentRequesters => default; - /// Allowed message reactions » - public virtual ChatReactions AvailableReactions => default; - /// This flag may be used to impose a custom limit of unique reactions (i.e. a customizable version of appConfig.reactions_uniq_max). - public virtual int ReactionsLimit => default; - } - /// Full info about a basic group. See - [TLDef(0x2633421B)] - public sealed partial class ChatFull : ChatFullBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_chat_photo = 0x4, has_bot_info = 0x8, has_pinned_msg_id = 0x40, can_set_username = 0x80, + has_scheduled = 0x100, has_folder_id = 0x800, has_call = 0x1000, has_exported_invite = 0x2000, has_ttl_period = 0x4000, + has_groupcall_default_join_as = 0x8000, has_theme_emoticon = 0x10000 } public Flags flags; - /// ID of the chat public long id; - /// About string for this chat public string about; - /// Participant list public ChatParticipantsBase participants; - /// Chat photo [IfFlag(2)] public PhotoBase chat_photo; - /// Notification settings public PeerNotifySettings notify_settings; - /// Chat invite [IfFlag(13)] public ExportedChatInvite exported_invite; - /// Info about bots that are in this chat [IfFlag(3)] public BotInfo[] bot_info; - /// Message ID of the last pinned message [IfFlag(6)] public int pinned_msg_id; - /// Peer folder ID, for more info click here [IfFlag(11)] public int folder_id; - /// Group call information - [IfFlag(12)] public InputGroupCallBase call; - /// Time-To-Live of messages sent by the current user to this chat + [IfFlag(12)] public InputGroupCall call; [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. [IfFlag(15)] public Peer groupcall_default_join_as; - /// Emoji representing a specific chat theme [IfFlag(16)] public string theme_emoticon; - /// Pending join requests » - [IfFlag(17)] public int requests_pending; - /// IDs of users who requested to join recently - [IfFlag(17)] public long[] recent_requesters; - /// Allowed message reactions » - [IfFlag(18)] public ChatReactions available_reactions; - /// This flag may be used to impose a custom limit of unique reactions (i.e. a customizable version of appConfig.reactions_uniq_max). - [IfFlag(20)] public int reactions_limit; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_chat_photo = 0x4, - /// Field has a value - has_bot_info = 0x8, - /// Field has a value - has_pinned_msg_id = 0x40, - /// Can we change the username of this chat - can_set_username = 0x80, - /// Whether scheduled messages are available - has_scheduled = 0x100, - /// Field has a value - has_folder_id = 0x800, - /// Field has a value - has_call = 0x1000, - /// Field has a value - has_exported_invite = 0x2000, - /// Field has a value - has_ttl_period = 0x4000, - /// Field has a value - has_groupcall_default_join_as = 0x8000, - /// Field has a value - has_theme_emoticon = 0x10000, - /// Fields and have a value - has_requests_pending = 0x20000, - /// Field has a value - has_available_reactions = 0x40000, - /// Whether the real-time chat translation popup should be hidden. - translations_disabled = 0x80000, - /// Field has a value - has_reactions_limit = 0x100000, - } - - /// ID of the chat - public override long ID => id; - /// About string for this chat - public override string About => about; - /// Chat photo - public override PhotoBase ChatPhoto => chat_photo; - /// Notification settings - public override PeerNotifySettings NotifySettings => notify_settings; - /// Chat invite - public override ExportedChatInvite ExportedInvite => exported_invite; - /// Info about bots that are in this chat - public override BotInfo[] BotInfo => bot_info; - /// Message ID of the last pinned message - public override int PinnedMsg => pinned_msg_id; - /// Peer folder ID, for more info click here - public override int Folder => folder_id; - /// Group call information - public override InputGroupCallBase 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. - public override Peer GroupcallDefaultJoinAs => groupcall_default_join_as; - /// Emoji representing a specific chat theme - public override string ThemeEmoticon => theme_emoticon; - /// Pending join requests » - public override int RequestsPending => requests_pending; - /// IDs of users who requested to join recently - public override long[] RecentRequesters => recent_requesters; - /// Allowed message reactions » - public override ChatReactions AvailableReactions => available_reactions; - /// This flag may be used to impose a custom limit of unique reactions (i.e. a customizable version of appConfig.reactions_uniq_max). - public override int ReactionsLimit => reactions_limit; } - /// Full info about a channel, supergroup or gigagroup. See - [TLDef(0xE4E0B29D)] - public sealed partial class ChannelFull : ChatFullBase + ///See + [TLDef(0xE9B27A17)] + public partial class ChannelFull : ChatFullBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_participants_count = 0x1, has_admins_count = 0x2, has_kicked_count = 0x4, + can_view_participants = 0x8, has_migrated_from_chat_id = 0x10, has_pinned_msg_id = 0x20, can_set_username = 0x40, + can_set_stickers = 0x80, has_stickerset = 0x100, has_available_min_id = 0x200, hidden_prehistory = 0x400, + has_folder_id = 0x800, has_stats_dc = 0x1000, has_online_count = 0x2000, has_linked_chat_id = 0x4000, has_location = 0x8000, + can_set_location = 0x10000, has_slowmode_seconds = 0x20000, has_slowmode_next_send_date = 0x40000, has_scheduled = 0x80000, + can_view_stats = 0x100000, has_call = 0x200000, blocked = 0x400000, has_exported_invite = 0x800000, + has_ttl_period = 0x1000000, has_pending_suggestions = 0x2000000, has_groupcall_default_join_as = 0x4000000, + has_theme_emoticon = 0x8000000 } public Flags flags; - /// Extra bits of information, use flags2.HasFlag(...) to test for those - public Flags2 flags2; - /// ID of the channel public long id; - /// Info about the channel public string about; - /// Number of participants of the channel [IfFlag(0)] public int participants_count; - /// Number of channel admins [IfFlag(1)] public int admins_count; - /// Number of users kicked from the channel [IfFlag(2)] public int kicked_count; - /// Number of users banned from the channel [IfFlag(2)] public int banned_count; - /// Number of users currently online [IfFlag(13)] public int online_count; - /// Position up to which all incoming messages are read. public int read_inbox_max_id; - /// Position up to which all outgoing messages are read. public int read_outbox_max_id; - /// Count of unread messages public int unread_count; - /// Channel picture public PhotoBase chat_photo; - /// Notification settings public PeerNotifySettings notify_settings; - /// Invite link [IfFlag(23)] public ExportedChatInvite exported_invite; - /// Info about bots in the channel/supergroup public BotInfo[] bot_info; - /// The chat ID from which this group was migrated [IfFlag(4)] public long migrated_from_chat_id; - /// The message ID in the original chat at which this group was migrated [IfFlag(4)] public int migrated_from_max_id; - /// Message ID of the last pinned message [IfFlag(5)] public int pinned_msg_id; - /// Associated stickerset [IfFlag(8)] public StickerSet stickerset; - /// Identifier of a maximum unavailable message in a channel due to hidden history. [IfFlag(9)] public int available_min_id; - /// Peer folder ID, for more info click here [IfFlag(11)] public int folder_id; - /// ID of the linked discussion chat for channels (and vice versa, the ID of the linked channel for discussion chats). [IfFlag(14)] public long linked_chat_id; - /// Location of the geogroup [IfFlag(15)] public ChannelLocation location; - /// If specified, users in supergroups will only be able to send one message every slowmode_seconds seconds [IfFlag(17)] public int slowmode_seconds; - /// Indicates when the user will be allowed to send another message in the supergroup (unixtime) [IfFlag(18)] public DateTime slowmode_next_send_date; - /// If set, specifies the DC to use for fetching channel statistics [IfFlag(12)] public int stats_dc; - /// Latest PTS for this channel public int pts; - /// Livestream or group call information - [IfFlag(21)] public InputGroupCallBase call; - /// Time-To-Live of messages in this channel or supergroup + [IfFlag(21)] public InputGroupCall call; [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. [IfFlag(26)] public Peer groupcall_default_join_as; - /// Emoji representing a specific chat theme [IfFlag(27)] public string theme_emoticon; - /// Pending join requests » - [IfFlag(28)] public int requests_pending; - /// IDs of users who requested to join recently - [IfFlag(28)] public long[] recent_requesters; - /// Default peer used for sending messages to this channel - [IfFlag(29)] public Peer default_send_as; - /// Allowed message reactions » - [IfFlag(30)] public ChatReactions available_reactions; - /// This flag may be used to impose a custom limit of unique reactions (i.e. a customizable version of appConfig.reactions_uniq_max). - [IfFlag(45)] public int reactions_limit; - /// Channel stories - [IfFlag(36)] public PeerStories stories; - /// Wallpaper - [IfFlag(39)] public WallPaperBase wallpaper; - /// The number of boosts the current user has applied to the current supergroup. - [IfFlag(40)] public int boosts_applied; - /// The number of boosts this supergroup requires to bypass slowmode and other restrictions, see here » for more info. - [IfFlag(41)] public int boosts_unrestrict; - /// Custom emoji stickerset associated to the current supergroup, set using Channels_SetEmojiStickers after reaching the appropriate boost level, see here » for more info. - [IfFlag(42)] public StickerSet emojiset; - /// Bot verification icon - [IfFlag(49)] public BotVerification bot_verification; - /// Admins with .post_messages rights will see the total number of received gifts, everyone else will see the number of gifts added to the channel's profile. - [IfFlag(50)] public int stargifts_count; - /// If set and bigger than 0, this supergroup, monoforum or the monoforum associated to this channel has enabled paid messages » and we must pay the specified amount of Stars to send messages to it, see here » for the full flow.
This flag will be set both for the monoforum and for of the associated channel).
If set and equal to 0, the monoforum requires payment in general but we were exempted from paying.
- [IfFlag(53)] public long send_paid_messages_stars; - /// The main tab for the channel's profile, see here » for more info. - [IfFlag(54)] public ProfileTab main_tab; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_participants_count = 0x1, - /// Field has a value - has_admins_count = 0x2, - /// Fields and have a value - has_kicked_count = 0x4, - /// Can we view the participant list? - can_view_participants = 0x8, - /// Fields and have a value - has_migrated_from_chat_id = 0x10, - /// Field has a value - has_pinned_msg_id = 0x20, - /// Can we set the channel's username? - can_set_username = 0x40, - /// Can we Channels_SetStickers a stickerpack to the supergroup? - can_set_stickers = 0x80, - /// Field has a value - has_stickerset = 0x100, - /// Field has a value - has_available_min_id = 0x200, - /// Is the history before we joined hidden to us? - hidden_prehistory = 0x400, - /// Field has a value - has_folder_id = 0x800, - /// Field has a value - has_stats_dc = 0x1000, - /// Field has a value - has_online_count = 0x2000, - /// Field has a value - has_linked_chat_id = 0x4000, - /// Field has a value - has_location = 0x8000, - /// Can we set the geolocation of this group (for geogroups) - can_set_location = 0x10000, - /// Field has a value - has_slowmode_seconds = 0x20000, - /// Field has a value - has_slowmode_next_send_date = 0x40000, - /// Whether scheduled messages are available - has_scheduled = 0x80000, - /// Can the user view channel/supergroup statistics - can_view_stats = 0x100000, - /// Field has a value - has_call = 0x200000, - /// Whether any anonymous admin of this supergroup was blocked: if set, you won't receive messages from anonymous group admins in discussion replies via @replies - blocked = 0x400000, - /// Field has a value - has_exported_invite = 0x800000, - /// Field has a value - has_ttl_period = 0x1000000, - /// Field has a value - has_pending_suggestions = 0x2000000, - /// Field has a value - has_groupcall_default_join_as = 0x4000000, - /// Field has a value - has_theme_emoticon = 0x8000000, - /// Fields and have a value - has_requests_pending = 0x10000000, - /// Field has a value - has_default_send_as = 0x20000000, - /// Field has a value - has_available_reactions = 0x40000000, - } - - [Flags] public enum Flags2 : uint - { - /// Can we delete this channel? - can_delete_channel = 0x1, - /// Whether native antispam functionality is enabled in this supergroup. - antispam = 0x2, - /// Whether the participant list is hidden. - participants_hidden = 0x4, - /// Whether the real-time chat translation popup should be hidden. - translations_disabled = 0x8, - /// Field has a value - has_stories = 0x10, - /// Whether this user has some pinned stories. - stories_pinned_available = 0x20, - /// Users may also choose to display messages from all topics of a forum as if they were sent to a normal group, using a "View as messages" setting in the local client.
This setting only affects the current account, and is synced to other logged in sessions using the Channels_ToggleViewForumAsMessages method; invoking this method will update the value of this flag.
- view_forum_as_messages = 0x40, - /// Field has a value - has_wallpaper = 0x80, - /// Field has a value - has_boosts_applied = 0x100, - /// Field has a value - has_boosts_unrestrict = 0x200, - /// Field has a value - has_emojiset = 0x400, - /// Whether ads on this channel were disabled as specified here » (this flag is only visible to the owner of the channel). - restricted_sponsored = 0x800, - /// If set, this user can view ad revenue statistics » for this channel. - can_view_revenue = 0x1000, - /// Field has a value - has_reactions_limit = 0x2000, - /// Whether the current user can send or forward paid media » to this channel. - paid_media_allowed = 0x4000, - /// If set, this user can view Telegram Star revenue statistics » for this channel. - can_view_stars_revenue = 0x8000, - /// If set, users may send paid Telegram Star reactions » to messages of this channel. - paid_reactions_available = 0x10000, - /// Field has a value - has_bot_verification = 0x20000, - /// Field has a value - has_stargifts_count = 0x40000, - /// If set, users may send Gifts » to this channel. - stargifts_available = 0x80000, - /// If set, admins may enable enable paid messages » in this supergroup. - paid_messages_available = 0x100000, - /// Field has a value - has_send_paid_messages_stars = 0x200000, - /// Field has a value - has_main_tab = 0x400000, - } - - /// ID of the channel - public override long ID => id; - /// Info about the channel - public override string About => about; - /// Channel picture - public override PhotoBase ChatPhoto => chat_photo; - /// Notification settings - public override PeerNotifySettings NotifySettings => notify_settings; - /// Invite link - public override ExportedChatInvite ExportedInvite => exported_invite; - /// Info about bots in the channel/supergroup - public override BotInfo[] BotInfo => bot_info; - /// Message ID of the last pinned message - public override int PinnedMsg => pinned_msg_id; - /// Peer folder ID, for more info click here - public override int Folder => folder_id; - /// Livestream or group call information - public override InputGroupCallBase 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. - public override Peer GroupcallDefaultJoinAs => groupcall_default_join_as; - /// Emoji representing a specific chat theme - public override string ThemeEmoticon => theme_emoticon; - /// Pending join requests » - public override int RequestsPending => requests_pending; - /// IDs of users who requested to join recently - public override long[] RecentRequesters => recent_requesters; - /// Allowed message reactions » - public override ChatReactions AvailableReactions => available_reactions; - /// This flag may be used to impose a custom limit of unique reactions (i.e. a customizable version of appConfig.reactions_uniq_max). - public override int ReactionsLimit => reactions_limit; } - /// Details of a group member. See Derived classes: , , - public abstract partial class ChatParticipantBase : IObject - { - /// Member user ID - public virtual long UserId => default; - public virtual string Rank => default; - } - /// Group member. See - [TLDef(0x38E79FDE)] + ///See + public abstract partial class ChatParticipantBase : ITLObject { } + ///See + [TLDef(0xC02D4007)] public partial class ChatParticipant : ChatParticipantBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Member user ID public long user_id; - /// ID of the user that added the member to the group public long inviter_id; - /// Date added to the group public DateTime date; - [IfFlag(0)] public string rank; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_rank = 0x1, - } - - /// Member user ID - public override long UserId => user_id; - public override string Rank => rank; } - /// Represents the creator of the group See - [TLDef(0xE1F867B8)] - public sealed partial class ChatParticipantCreator : ChatParticipantBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of the user that created the group - public long user_id; - [IfFlag(0)] public string rank; + ///See + [TLDef(0xE46BCEE4)] + public partial class ChatParticipantCreator : ChatParticipantBase { public long user_id; } + ///See + [TLDef(0xA0933F5B)] + public partial class ChatParticipantAdmin : ChatParticipant { } - [Flags] public enum Flags : uint - { - /// Field has a value - has_rank = 0x1, - } - - /// ID of the user that created the group - public override long UserId => user_id; - public override string Rank => rank; - } - /// Chat admin See - [TLDef(0x0360D5D2)] - public sealed partial class ChatParticipantAdmin : ChatParticipant - { - } - - /// Object contains info on group members. See Derived classes: , - public abstract partial class ChatParticipantsBase : IObject - { - /// Group ID - public virtual long ChatId => default; - } - /// Info on members is unavailable See + ///See + public abstract partial class ChatParticipantsBase : ITLObject { } + ///See [TLDef(0x8763D3E1)] - public sealed partial class ChatParticipantsForbidden : ChatParticipantsBase + public partial class ChatParticipantsForbidden : ChatParticipantsBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_self_participant = 0x1 } public Flags flags; - /// Group ID public long chat_id; - /// Info about the group membership of the current user [IfFlag(0)] public ChatParticipantBase self_participant; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_self_participant = 0x1, - } - - /// Group ID - public override long ChatId => chat_id; } - /// Group members. See + ///See [TLDef(0x3CBC93F8)] - public sealed partial class ChatParticipants : ChatParticipantsBase + public partial class ChatParticipants : ChatParticipantsBase { - /// Group identifier public long chat_id; - /// List of group members public ChatParticipantBase[] participants; - /// Group version number public int version; - - /// Group identifier - public override long ChatId => chat_id; } - /// Group profile photo. See - /// a value means chatPhotoEmpty + ///See + ///a null value means chatPhotoEmpty [TLDef(0x1C6E1C11)] - public sealed partial class ChatPhoto : IObject + public partial class ChatPhoto : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_video = 0x1, has_stripped_thumb = 0x2 } public Flags flags; - /// Photo ID public long photo_id; - /// Stripped thumbnail [IfFlag(1)] public byte[] stripped_thumb; - /// DC where this photo is stored public int dc_id; - - [Flags] public enum Flags : uint - { - /// Whether the user has an animated profile picture - has_video = 0x1, - /// Field has a value - has_stripped_thumb = 0x2, - } } - /// Object describing a message. See Derived classes: , , - public abstract partial class MessageBase : IObject - { - /// ID of the message - public virtual int ID => default; - /// ID of the sender of the message - public virtual Peer From => default; - /// Peer ID, the chat where this message was sent - public virtual Peer Peer => default; - /// Messages from a saved messages dialog » will have peer= and the saved_peer_id flag set to the ID of the saved dialog.
Messages from a monoforum » will have peer=ID of the monoforum and the saved_peer_id flag set to the ID of a topic.
- public virtual Peer SavedPeer => default; - /// Reply information - public virtual MessageReplyHeaderBase ReplyTo => default; - /// Date of the message - public virtual DateTime Date => default; - /// Reactions to this message - public virtual MessageReactions Reactions => default; - /// Time To Live of the message, once message.date+message.ttl_period === time(), the message will be deleted on the server, and must be deleted locally as well. - public virtual int TtlPeriod => default; - } - /// Empty constructor, non-existent message. See + ///See + public abstract partial class MessageBase : ITLObject { } + ///See [TLDef(0x90A6CA84)] - public sealed partial class MessageEmpty : MessageBase + public partial class MessageEmpty : MessageBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_peer_id = 0x1 } public Flags flags; - /// Message identifier public int id; - /// Peer ID, the chat where this message was sent [IfFlag(0)] public Peer peer_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_peer_id = 0x1, - } - - /// Message identifier - public override int ID => id; - /// Peer ID, the chat where this message was sent - public override Peer Peer => peer_id; } - /// A message See - [TLDef(0x3AE56482)] - public sealed partial class Message : MessageBase + ///See + [TLDef(0x85D6CBE2)] + public partial class Message : MessageBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { out_ = 0x2, has_fwd_from = 0x4, has_reply_to = 0x8, mentioned = 0x10, media_unread = 0x20, + has_reply_markup = 0x40, has_entities = 0x80, has_from_id = 0x100, has_media = 0x200, has_views = 0x400, + has_via_bot_id = 0x800, silent = 0x2000, post = 0x4000, has_edit_date = 0x8000, has_post_author = 0x10000, + has_grouped_id = 0x20000, from_scheduled = 0x40000, legacy = 0x80000, edit_hide = 0x200000, has_restriction_reason = 0x400000, + has_replies = 0x800000, pinned = 0x1000000, has_ttl_period = 0x2000000 } public Flags flags; - /// Extra bits of information, use flags2.HasFlag(...) to test for those - public Flags2 flags2; - /// ID of the message public int id; - /// ID of the sender of the message [IfFlag(8)] public Peer from_id; - /// Supergroups only, contains the number of boosts this user has given the current supergroup, and should be shown in the UI in the header of the message.
Only present for incoming messages from non-anonymous supergroup members that have boosted the supergroup.
Note that this counter should be locally overridden for non-anonymous outgoing messages, according to the current value of .boosts_applied, to ensure the value is correct even for messages sent by the current user before a supergroup was boosted (or after a boost has expired or the number of boosts has changed); do not update this value for incoming messages from other users, even if their boosts have changed.
- [IfFlag(29)] public int from_boosts_applied; - [IfFlag(44)] public string from_rank; - /// Peer ID, the chat where this message was sent public Peer peer_id; - /// Messages from a saved messages dialog » will have peer= and the saved_peer_id flag set to the ID of the saved dialog.
Messages from a monoforum » will have peer=ID of the monoforum and the saved_peer_id flag set to the ID of a topic.
- [IfFlag(28)] public Peer saved_peer_id; - /// Info about forwarded messages [IfFlag(2)] public MessageFwdHeader fwd_from; - /// ID of the inline bot that generated the message [IfFlag(11)] public long via_bot_id; - /// Whether the message was sent by the business bot specified in via_bot_id on behalf of the user. - [IfFlag(32)] public long via_business_bot_id; - /// Reply information - [IfFlag(3)] public MessageReplyHeaderBase reply_to; - /// Date of the message + [IfFlag(3)] public MessageReplyHeader reply_to; public DateTime date; - /// The message public string message; - /// Media attachment [IfFlag(9)] public MessageMedia media; - /// Reply markup (bot/inline keyboards) [IfFlag(6)] public ReplyMarkup reply_markup; - /// Message entities for styled text [IfFlag(7)] public MessageEntity[] entities; - /// View count for channel posts [IfFlag(10)] public int views; - /// Forward counter [IfFlag(10)] public int forwards; - /// Info about post comments (for channels) or message replies (for groups) [IfFlag(23)] public MessageReplies replies; - /// Last edit date of this message [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 [IfFlag(17)] public long grouped_id; - /// Reactions to this message - [IfFlag(20)] public MessageReactions reactions; - /// Contains the reason why access to this message must be restricted. [IfFlag(22)] public RestrictionReason[] restriction_reason; - /// Time To Live of the message, once message.date+message.ttl_period === time(), the message will be deleted on the server, and must be deleted locally as well. [IfFlag(25)] public int ttl_period; - /// If set, this message is a quick reply shortcut message » (note that quick reply shortcut messages sent to a private chat will not have this field set). - [IfFlag(30)] public int quick_reply_shortcut_id; - /// A message effect that should be played as specified here ». - [IfFlag(34)] public long effect; - /// Represents a fact-check ». - [IfFlag(35)] public FactCheck factcheck; - /// Used for Telegram Gateway verification messages: if set and the current unixtime is bigger than the specified unixtime, invoke Messages_ReportMessagesDelivery passing the ID and the peer of this message as soon as it is received by the client (optionally batching requests for the same peer). - [IfFlag(37)] public DateTime report_delivery_until_date; - /// The amount of stars the sender has paid to send the message, see here » for more info. - [IfFlag(38)] public long paid_message_stars; - /// Used to suggest a post to a channel, see here » for more info on the full flow. - [IfFlag(39)] public SuggestedPost suggested_post; - [IfFlag(42)] public int schedule_repeat_period; - [IfFlag(43)] public string summary_from_language; - - [Flags] public enum Flags : uint - { - /// Is this an outgoing message - out_ = 0x2, - /// Field has a value - has_fwd_from = 0x4, - /// Field has a value - has_reply_to = 0x8, - /// Whether we were mentioned in this message - mentioned = 0x10, - /// Whether there are unread media attachments in this message - media_unread = 0x20, - /// Field has a value - has_reply_markup = 0x40, - /// Field has a value - has_entities = 0x80, - /// Field has a value - has_from_id = 0x100, - /// Field has a value - has_media = 0x200, - /// Fields and have a value - has_views = 0x400, - /// Field has a value - has_via_bot_id = 0x800, - /// Whether this is a silent message (no notification triggered) - silent = 0x2000, - /// Whether this is a channel post - post = 0x4000, - /// Field has a value - has_edit_date = 0x8000, - /// Field has a value - has_post_author = 0x10000, - /// Field has a value - has_grouped_id = 0x20000, - /// Whether this is a scheduled message - from_scheduled = 0x40000, - /// This is a legacy message: it has to be refetched with the new layer - legacy = 0x80000, - /// Field has a value - has_reactions = 0x100000, - /// Whether the message should be shown as not modified to the user, even if an edit date is present - edit_hide = 0x200000, - /// Field has a value - has_restriction_reason = 0x400000, - /// Field has a value - has_replies = 0x800000, - /// Whether this message is pinned - pinned = 0x1000000, - /// Field has a value - has_ttl_period = 0x2000000, - /// Whether this message is protected and thus cannot be forwarded; clients should also prevent users from saving attached media (i.e. videos should only be streamed, photos should be kept in RAM, et cetera). - noforwards = 0x4000000, - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - invert_media = 0x8000000, - /// Field has a value - has_saved_peer_id = 0x10000000, - /// Field has a value - has_from_boosts_applied = 0x20000000, - /// Field has a value - has_quick_reply_shortcut_id = 0x40000000, - } - - [Flags] public enum Flags2 : uint - { - /// Field has a value - has_via_business_bot_id = 0x1, - /// If set, the message was sent because of a scheduled action by the message sender, for example, as away, or a greeting service message. - offline = 0x2, - /// Field has a value - has_effect = 0x4, - /// Field has a value - has_factcheck = 0x8, - /// The video contained in the message is currently being processed by the server (i.e. to generate alternative qualities, that will be contained in the final .alt_document), and will be sent once the video is processed, which will happen approximately at the specified date (i.e. messages with this flag set should be treated similarly to scheduled messages, but instead of the scheduled date, date contains the estimated conversion date).
See here » for more info.
- video_processing_pending = 0x10, - /// Field has a value - has_report_delivery_until_date = 0x20, - /// Field has a value - has_paid_message_stars = 0x40, - /// Field has a value - has_suggested_post = 0x80, - /// Set if this is a suggested channel post » that was paid using Telegram Stars. - paid_suggested_post_stars = 0x100, - /// Set if this is a suggested channel post » that was paid using Toncoins. - paid_suggested_post_ton = 0x200, - /// Field has a value - has_schedule_repeat_period = 0x400, - /// Field has a value - has_summary_from_language = 0x800, - /// Field has a value - has_from_rank = 0x1000, - } - - /// ID of the message - public override int ID => id; - /// ID of the sender of the message - public override Peer From => from_id; - /// Peer ID, the chat where this message was sent - public override Peer Peer => peer_id; - /// Messages from a saved messages dialog » will have peer= and the saved_peer_id flag set to the ID of the saved dialog.
Messages from a monoforum » will have peer=ID of the monoforum and the saved_peer_id flag set to the ID of a topic.
- public override Peer SavedPeer => saved_peer_id; - /// Reply information - public override MessageReplyHeaderBase ReplyTo => reply_to; - /// Date of the message - public override DateTime Date => date; - /// Reactions to this message - public override MessageReactions Reactions => reactions; - /// Time To Live of the message, once message.date+message.ttl_period === time(), the message will be deleted on the server, and must be deleted locally as well. - public override int TtlPeriod => ttl_period; } - /// Indicates a service message See - [TLDef(0x7A800E0A)] - public sealed partial class MessageService : MessageBase + ///See + [TLDef(0x2B085862)] + public partial class MessageService : MessageBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { out_ = 0x2, has_reply_to = 0x8, mentioned = 0x10, media_unread = 0x20, has_from_id = 0x100, + silent = 0x2000, post = 0x4000, legacy = 0x80000, has_ttl_period = 0x2000000 } public Flags flags; - /// Message ID public int id; - /// ID of the sender of this message [IfFlag(8)] public Peer from_id; - /// Sender of service message public Peer peer_id; - /// Will only be set for service messages within a monoforum topic »: peer will be equal to the ID of the monoforum and the saved_peer_id flag will be set to the ID of a topic. - [IfFlag(28)] public Peer saved_peer_id; - /// Reply (thread) information - [IfFlag(3)] public MessageReplyHeaderBase reply_to; - /// Message date + [IfFlag(3)] public MessageReplyHeader reply_to; public DateTime date; - /// Event connected with the service message public MessageAction action; - /// Reactions ». - [IfFlag(20)] public MessageReactions reactions; - /// Time To Live of the message, once message.date+message.ttl_period === time(), the message will be deleted on the server, and must be deleted locally as well. [IfFlag(25)] public int ttl_period; - - [Flags] public enum Flags : uint - { - /// Whether the message is outgoing - out_ = 0x2, - /// Field has a value - has_reply_to = 0x8, - /// Whether we were mentioned in the message - mentioned = 0x10, - /// Whether the message contains unread media - media_unread = 0x20, - /// Field has a value - has_from_id = 0x100, - /// Whether you can react to this message ». - reactions_are_possible = 0x200, - /// Whether the message is silent - silent = 0x2000, - /// Whether it's a channel post - post = 0x4000, - /// This is a legacy message: it has to be refetched with the new layer - legacy = 0x80000, - /// Field has a value - has_reactions = 0x100000, - /// Field has a value - has_ttl_period = 0x2000000, - /// Field has a value - has_saved_peer_id = 0x10000000, - } - - /// Message ID - public override int ID => id; - /// ID of the sender of this message - public override Peer From => from_id; - /// Sender of service message - public override Peer Peer => peer_id; - /// Will only be set for service messages within a monoforum topic »: peer will be equal to the ID of the monoforum and the saved_peer_id flag will be set to the ID of a topic. - public override Peer SavedPeer => saved_peer_id; - /// Reply (thread) information - public override MessageReplyHeaderBase ReplyTo => reply_to; - /// Message date - public override DateTime Date => date; - /// Reactions ». - public override MessageReactions Reactions => reactions; - /// Time To Live of the message, once message.date+message.ttl_period === time(), the message will be deleted on the server, and must be deleted locally as well. - public override int TtlPeriod => ttl_period; } - /// Media See Derived classes: , , , , , , , , , , , , , , , , , - /// a value means messageMediaEmpty - public abstract partial class MessageMedia : IObject { } - /// Attached photo. See + ///See + ///a null value means messageMediaEmpty + public abstract partial class MessageMedia : ITLObject { } + ///See [TLDef(0x695150D7)] - public sealed partial class MessageMediaPhoto : MessageMedia + public partial class MessageMediaPhoto : MessageMedia { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_photo = 0x1, has_ttl_seconds = 0x4 } public Flags flags; - /// Photo [IfFlag(0)] public PhotoBase photo; - /// Time to live in seconds of self-destructing photo [IfFlag(2)] public int ttl_seconds; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_photo = 0x1, - /// Field has a value - has_ttl_seconds = 0x4, - /// Whether this media should be hidden behind a spoiler warning - spoiler = 0x8, - } } - /// Attached map. See + ///See [TLDef(0x56E0D474)] - public partial class MessageMediaGeo : MessageMedia - { - /// GeoPoint - public GeoPoint geo; - } - /// Attached contact. See + public partial class MessageMediaGeo : MessageMedia { public GeoPoint geo; } + ///See [TLDef(0x70322949)] - public sealed partial class MessageMediaContact : MessageMedia + public partial class MessageMediaContact : MessageMedia { - /// Phone number public string phone_number; - /// Contact's first name public string first_name; - /// Contact's last name public string last_name; - /// VCARD of contact public string vcard; - /// User identifier or 0, if the user with the given phone number is not registered public long user_id; } - /// Current version of the client does not support this media type. See + ///See [TLDef(0x9F84F49E)] - public sealed partial class MessageMediaUnsupported : MessageMedia { } - /// Document (video, audio, voice, sticker, any media type except photo) See - [TLDef(0x52D8CCD9)] - public sealed partial class MessageMediaDocument : MessageMedia + public partial class MessageMediaUnsupported : MessageMedia { } + ///See + [TLDef(0x9CB070D7)] + public partial class MessageMediaDocument : MessageMedia { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_document = 0x1, has_ttl_seconds = 0x4 } public Flags flags; - /// Attached document [IfFlag(0)] public DocumentBase document; - /// Videos only, contains alternative qualities of the video. - [IfFlag(5)] public DocumentBase[] alt_documents; - /// Custom video cover. - [IfFlag(9)] public PhotoBase video_cover; - /// Start playing the video at the specified timestamp (seconds). - [IfFlag(10)] public int video_timestamp; - /// Time to live of self-destructing document [IfFlag(2)] public int ttl_seconds; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_document = 0x1, - /// Field has a value - 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, - /// Whether this media should be hidden behind a spoiler warning - spoiler = 0x10, - /// Field has a value - has_alt_documents = 0x20, - /// Whether this is a video. - video = 0x40, - /// Whether this is a round video. - round = 0x80, - /// Whether this is a voice message. - voice = 0x100, - /// Field has a value - has_video_cover = 0x200, - /// Field has a value - has_video_timestamp = 0x400, - } } - /// Preview of webpage See - [TLDef(0xDDF10C3B)] - public sealed partial class MessageMediaWebPage : MessageMedia - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Webpage preview - public WebPageBase webpage; - - [Flags] public enum Flags : uint - { - /// If set, specifies that a large media preview should be used. - force_large_media = 0x1, - /// If set, specifies that a small media preview should be used. - force_small_media = 0x2, - /// If set, indicates that the URL used for the webpage preview was specified manually using , and may not be related to any of the URLs specified in the message. - manual = 0x8, - /// If set, the webpage can be opened directly without user confirmation; otherwise, user confirmation is required, showing the exact URL that will be opened. - safe = 0x10, - } - } - /// Venue See + ///See + [TLDef(0xA32DD600)] + public partial class MessageMediaWebPage : MessageMedia { public WebPageBase webpage; } + ///See [TLDef(0x2EC0533F)] - public sealed partial class MessageMediaVenue : MessageMedia + public partial class MessageMediaVenue : MessageMedia { - /// Geolocation of venue public GeoPoint geo; - /// Venue name public string title; - /// Address public string address; - /// Venue provider: currently only "foursquare" and "gplaces" (Google Places) need to be supported public string provider; - /// Venue ID in the provider's database public string venue_id; - /// Venue type in the provider's database public string venue_type; } - /// Telegram game See + ///See [TLDef(0xFDB19008)] - public sealed partial class MessageMediaGame : MessageMedia + public partial class MessageMediaGame : MessageMedia { public Game game; } + ///See + [TLDef(0x84551347)] + public partial class MessageMediaInvoice : MessageMedia { - /// Game - public Game game; - } - /// Invoice See - [TLDef(0xF6A548D3)] - public sealed partial class MessageMediaInvoice : MessageMedia - { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_photo = 0x1, shipping_address_requested = 0x2, has_receipt_msg_id = 0x4, test = 0x8 } public Flags flags; - /// Product name, 1-32 characters public string title; - /// Product description, 1-255 characters public string description; - /// URL of the product photo for the invoice. Can be a photo of the goods or a marketing image for a service. People like it better when they see what they are paying for. [IfFlag(0)] public WebDocumentBase photo; - /// Message ID of receipt: if set, clients should change the text of the first button always attached to the to a localized version of the word Receipt [IfFlag(2)] public int receipt_msg_id; - /// Three-letter ISO 4217 currency code, or XTR for Telegram Stars. public string currency; - /// Total price 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). public long total_amount; - /// Unique bot deep-linking parameter that can be used to generate this invoice public string start_param; - /// Deprecated - [IfFlag(4)] public MessageExtendedMediaBase extended_media; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_photo = 0x1, - /// Whether the shipping address was requested - shipping_address_requested = 0x2, - /// Field has a value - has_receipt_msg_id = 0x4, - /// Whether this is an example invoice - test = 0x8, - /// Field has a value - has_extended_media = 0x10, - } } - /// Indicates a live geolocation See - [TLDef(0xB940C666, inheritAt = 1)] - public sealed partial class MessageMediaGeoLive : MessageMediaGeo + ///See + [TLDef(0xB940C666)] + public partial class MessageMediaGeoLive : MessageMedia { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_heading = 0x1, has_proximity_notification_radius = 0x2 } public Flags flags; - /// For live locations, a direction in which the location moves, in degrees; 1-360 + public GeoPoint geo; [IfFlag(0)] public int heading; - /// Validity period of provided geolocation public int period; - /// For live locations, a maximum distance to another chat member for proximity alerts, in meters (0-100000). [IfFlag(1)] public int proximity_notification_radius; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_heading = 0x1, - /// Field has a value - has_proximity_notification_radius = 0x2, - } } - /// Poll See + ///See [TLDef(0x4BD6E798)] - public sealed partial class MessageMediaPoll : MessageMedia + public partial class MessageMediaPoll : MessageMedia { - /// The poll public Poll poll; - /// The results of the poll public PollResults results; } - /// Dice-based animated sticker See - [TLDef(0x08CBEC07)] - public sealed partial class MessageMediaDice : MessageMedia + ///See + [TLDef(0x3F7EE58B)] + public partial class MessageMediaDice : MessageMedia { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Dice value public int value; - /// The emoji, for now 🏀, 🎲 and 🎯 are supported public string emoticon; - [IfFlag(0)] public Messages_EmojiGameOutcome game_outcome; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_game_outcome = 0x1, - } - } - /// Represents a forwarded story or a story mention. See - [TLDef(0x68CB6283)] - public sealed partial class MessageMediaStory : MessageMedia - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Peer that posted the story. - public Peer peer; - /// Story ID - public int id; - /// The story itself, if absent fetch it using Stories_GetStoriesByID and the peer/id parameters specified above. - [IfFlag(0)] public StoryItemBase story; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_story = 0x1, - /// If set, indicates that this someone has mentioned us in this story (i.e. by tagging us in the description) or vice versa, we have mentioned the other peer (if the message is outgoing). - via_mention = 0x2, - } - } - /// Contains info about a giveaway, see here » for more info. See - [TLDef(0xAA073BEB)] - public sealed partial class MessageMediaGiveaway : MessageMedia - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The channels that the user must join to participate in the giveaway. - public long[] channels; - /// If set, only users residing in these countries can participate in the giveaway, (specified as a list of two-letter ISO 3166-1 alpha-2 country codes); otherwise there are no country-based limitations. - [IfFlag(1)] public string[] countries_iso2; - /// Can contain a textual description of additional giveaway prizes. - [IfFlag(3)] public string prize_description; - /// Number of Telegram Premium subscriptions given away. - public int quantity; - /// Duration in months of each Telegram Premium subscription in the giveaway. - [IfFlag(4)] public int months; - /// For Telegram Star giveaways, the total number of Telegram Stars being given away. - [IfFlag(5)] public long stars; - /// The end date of the giveaway. - public DateTime until_date; - - [Flags] public enum Flags : uint - { - /// If set, only new subscribers starting from the giveaway creation date will be able to participate to the giveaway. - only_new_subscribers = 0x1, - /// Field has a value - has_countries_iso2 = 0x2, - /// If set, giveaway winners are public and will be listed in a message that will be automatically sent to the channel once the giveaway ends. - winners_are_visible = 0x4, - /// Field has a value - has_prize_description = 0x8, - /// Field has a value - has_months = 0x10, - /// Field has a value - has_stars = 0x20, - } - } - /// A giveaway with public winners has finished, this constructor contains info about the winners. See - [TLDef(0xCEAA3EA1)] - public sealed partial class MessageMediaGiveawayResults : MessageMedia - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of the channel/supergroup that was automatically boosted by the winners of the giveaway for duration of the Premium subscription. - public long channel_id; - /// Number of other channels that participated in the giveaway. - [IfFlag(3)] public int additional_peers_count; - /// Identifier of the message with the giveaway in channel_id. - public int launch_msg_id; - /// Total number of winners in the giveaway. - public int winners_count; - /// Number of not-yet-claimed prizes. - public int unclaimed_count; - /// Up to 100 user identifiers of the winners of the giveaway. - public long[] winners; - /// Duration in months of each Telegram Premium subscription in the giveaway. - [IfFlag(4)] public int months; - /// For Telegram Star giveaways, the total number of Telegram Stars being given away. - [IfFlag(5)] public long stars; - /// Can contain a textual description of additional giveaway prizes. - [IfFlag(1)] public string prize_description; - /// Point in time (Unix timestamp) when the winners were selected. May be bigger than winners selection date specified in initial parameters of the giveaway. - public DateTime until_date; - - [Flags] public enum Flags : uint - { - /// If set, only new subscribers starting from the giveaway creation date participated in the giveaway. - only_new_subscribers = 0x1, - /// Field has a value - has_prize_description = 0x2, - /// If set, the giveaway was canceled and was fully refunded. - refunded = 0x4, - /// Field has a value - has_additional_peers_count = 0x8, - /// Field has a value - has_months = 0x10, - /// Field has a value - has_stars = 0x20, - } - } - /// Paid media, see here » for more info. See - [TLDef(0xA8852491)] - public sealed partial class MessageMediaPaidMedia : MessageMedia - { - /// The price of the media in Telegram Stars. - public long stars_amount; - /// Either the paid-for media, or super low resolution media previews if the media wasn't purchased yet, see here » for more info. - public MessageExtendedMediaBase[] extended_media; - } - /// Represents a todo list ». See - [TLDef(0x8A53B014)] - public sealed partial class MessageMediaToDo : MessageMedia - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The todo list. - public TodoList todo; - /// Completed items. - [IfFlag(0)] public TodoCompletion[] completions; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_completions = 0x1, - } - } - /// See - [TLDef(0xCA5CAB89)] - public sealed partial class MessageMediaVideoStream : MessageMedia - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - public InputGroupCallBase call; - - [Flags] public enum Flags : uint - { - rtmp_stream = 0x1, - } } - /// Object describing actions connected to a service message. See Derived classes: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - /// a value means messageActionEmpty - public abstract partial class MessageAction : IObject { } - /// Group created See + ///See + ///a null value means messageActionEmpty + public abstract partial class MessageAction : ITLObject { } + ///See [TLDef(0xBD47CBAD)] - public sealed partial class MessageActionChatCreate : MessageAction + public partial class MessageActionChatCreate : MessageAction { - /// Group name public string title; - /// List of group members public long[] users; } - /// Group name changed. See + ///See [TLDef(0xB5A1CE5A)] - public sealed partial class MessageActionChatEditTitle : MessageAction - { - /// New group name - public string title; - } - /// Group profile changed See + public partial class MessageActionChatEditTitle : MessageAction { public string title; } + ///See [TLDef(0x7FCB13A8)] - public sealed partial class MessageActionChatEditPhoto : MessageAction - { - /// New group profile photo - public PhotoBase photo; - } - /// Group profile photo removed. See + public partial class MessageActionChatEditPhoto : MessageAction { public PhotoBase photo; } + ///See [TLDef(0x95E3FBEF)] - public sealed partial class MessageActionChatDeletePhoto : MessageAction { } - /// New member in the group See + public partial class MessageActionChatDeletePhoto : MessageAction { } + ///See [TLDef(0x15CEFD00)] - public sealed partial class MessageActionChatAddUser : MessageAction - { - /// Users that were invited to the chat - public long[] users; - } - /// User left the group. See + public partial class MessageActionChatAddUser : MessageAction { public long[] users; } + ///See [TLDef(0xA43F30CC)] - public sealed partial class MessageActionChatDeleteUser : MessageAction - { - /// Leaving user ID - public long user_id; - } - /// A user joined the chat via an invite link See + public partial class MessageActionChatDeleteUser : MessageAction { public long user_id; } + ///See [TLDef(0x031224C3)] - public sealed partial class MessageActionChatJoinedByLink : MessageAction - { - /// ID of the user that created the invite link - public long inviter_id; - } - /// The channel was created See + public partial class MessageActionChatJoinedByLink : MessageAction { public long inviter_id; } + ///See [TLDef(0x95D2AC92)] - public sealed partial class MessageActionChannelCreate : MessageAction - { - /// Original channel/supergroup title - public string title; - } - /// Indicates the chat was migrated to the specified supergroup See + public partial class MessageActionChannelCreate : MessageAction { public string title; } + ///See [TLDef(0xE1037F92)] - public sealed partial class MessageActionChatMigrateTo : MessageAction - { - /// The supergroup it was migrated to - public long channel_id; - } - /// Indicates the channel was migrated from the specified chat See + public partial class MessageActionChatMigrateTo : MessageAction { public long channel_id; } + ///See [TLDef(0xEA3948E9)] - public sealed partial class MessageActionChannelMigrateFrom : MessageAction + public partial class MessageActionChannelMigrateFrom : MessageAction { - /// The old chat title public string title; - /// The old chat ID public long chat_id; } - /// A message was pinned See + ///See [TLDef(0x94BD38ED)] - public sealed partial class MessageActionPinMessage : MessageAction { } - /// Chat history was cleared See + public partial class MessageActionPinMessage : MessageAction { } + ///See [TLDef(0x9FBAB604)] - public sealed partial class MessageActionHistoryClear : MessageAction { } - /// Someone scored in a game See + public partial class MessageActionHistoryClear : MessageAction { } + ///See [TLDef(0x92A72876)] - public sealed partial class MessageActionGameScore : MessageAction + public partial class MessageActionGameScore : MessageAction { - /// Game ID public long game_id; - /// Score public int score; } - /// A user just sent a payment to me (a bot) See - [TLDef(0xFFA00CCC)] - public sealed partial class MessageActionPaymentSentMe : MessageAction + ///See + [TLDef(0x8F31B327)] + public partial class MessageActionPaymentSentMe : MessageAction { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_info = 0x1, has_shipping_option_id = 0x2 } public Flags flags; - /// Three-letter ISO 4217 currency code, or XTR for Telegram Stars. public string currency; - /// Price of the product 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). public long total_amount; - /// Bot specified invoice payload public byte[] payload; - /// Order info provided by the user [IfFlag(0)] public PaymentRequestedInfo info; - /// Identifier of the shipping option chosen by the user [IfFlag(1)] public string shipping_option_id; - /// Provider payment identifier public PaymentCharge charge; - /// Expiration date of the Telegram Star subscription ». - [IfFlag(4)] public DateTime subscription_until_date; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_info = 0x1, - /// Field has a value - has_shipping_option_id = 0x2, - /// Whether this is the first payment of a recurring payment we just subscribed to - recurring_init = 0x4, - /// Whether this payment is part of a recurring payment - recurring_used = 0x8, - /// Field has a value - has_subscription_until_date = 0x10, - } } - /// A payment was sent See - [TLDef(0xC624B16E)] - public sealed partial class MessageActionPaymentSent : MessageAction + ///See + [TLDef(0x40699CD0)] + public partial class MessageActionPaymentSent : MessageAction { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Three-letter ISO 4217 currency code, or XTR for Telegram Stars. public string currency; - /// Price of the product 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). public long total_amount; - /// An invoice slug taken from an invoice deep link or from the premium_invoice_slug app config parameter » - [IfFlag(0)] public string invoice_slug; - /// Expiration date of the Telegram Star subscription ». - [IfFlag(4)] public DateTime subscription_until_date; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_invoice_slug = 0x1, - /// Whether this is the first payment of a recurring payment we just subscribed to - recurring_init = 0x4, - /// Whether this payment is part of a recurring payment - recurring_used = 0x8, - /// Field has a value - has_subscription_until_date = 0x10, - } } - /// A phone call See + ///See [TLDef(0x80E11A7F)] - public sealed partial class MessageActionPhoneCall : MessageAction + public partial class MessageActionPhoneCall : MessageAction { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_reason = 0x1, has_duration = 0x2, video = 0x4 } public Flags flags; - /// Call ID public long call_id; - /// If the call has ended, the reason why it ended [IfFlag(0)] public PhoneCallDiscardReason reason; - /// Duration of the call in seconds [IfFlag(1)] public int duration; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_reason = 0x1, - /// Field has a value - has_duration = 0x2, - /// Is this a video call? - video = 0x4, - } } - /// A screenshot of the chat was taken See + ///See [TLDef(0x4792929B)] - public sealed partial class MessageActionScreenshotTaken : MessageAction { } - /// Custom action (most likely not supported by the current layer, an upgrade might be needed) See + public partial class MessageActionScreenshotTaken : MessageAction { } + ///See [TLDef(0xFAE69F56)] - public sealed partial class MessageActionCustomAction : MessageAction - { - /// Action message - public string message; - } - /// We have given the bot permission to send us direct messages. See - [TLDef(0xC516D679)] - public sealed partial class MessageActionBotAllowed : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// We have authorized the bot to send us messages by logging into a website via Telegram Login »; this field contains the domain name of the website on which the user has logged in. - [IfFlag(0)] public string domain; - /// We have authorized the bot to send us messages by opening the specified bot mini app. - [IfFlag(2)] public BotApp app; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_domain = 0x1, - /// We have authorized the bot to send us messages by installing the bot's attachment menu. - attach_menu = 0x2, - /// Field has a value - has_app = 0x4, - /// We have allowed the bot to send us messages using Bots_AllowSendMessage. - from_request = 0x8, - } - } - /// Secure telegram passport values were received See + public partial class MessageActionCustomAction : MessageAction { public string message; } + ///See + [TLDef(0xABE9AFFE)] + public partial class MessageActionBotAllowed : MessageAction { public string domain; } + ///See [TLDef(0x1B287353)] - public sealed partial class MessageActionSecureValuesSentMe : MessageAction + public partial class MessageActionSecureValuesSentMe : MessageAction { - /// Vector with information about documents and other Telegram Passport elements that were shared with the bot public SecureValue[] values; - /// Encrypted credentials required to decrypt the data public SecureCredentialsEncrypted credentials; } - /// Request for secure telegram passport values was sent See + ///See [TLDef(0xD95C6154)] - public sealed partial class MessageActionSecureValuesSent : MessageAction - { - /// Secure value types - public SecureValueType[] types; - } - /// A contact just signed up to telegram See + public partial class MessageActionSecureValuesSent : MessageAction { public SecureValueType[] types; } + ///See [TLDef(0xF3F25F76)] - public sealed partial class MessageActionContactSignUp : MessageAction { } - /// A user of the chat is now in proximity of another user See + public partial class MessageActionContactSignUp : MessageAction { } + ///See [TLDef(0x98E0D697)] - public sealed partial class MessageActionGeoProximityReached : MessageAction + public partial class MessageActionGeoProximityReached : MessageAction { - /// The user or chat that is now in proximity of to_id public Peer from_id; - /// The user or chat that subscribed to live geolocation proximity alerts public Peer to_id; - /// Distance, in meters (0-100000) public int distance; } - /// The group call has ended See + ///See [TLDef(0x7A0D7F42)] - public sealed partial class MessageActionGroupCall : MessageAction + public partial class MessageActionGroupCall : MessageAction { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_duration = 0x1 } public Flags flags; - /// Group call - public InputGroupCallBase call; - /// Group call duration + public InputGroupCall call; [IfFlag(0)] public int duration; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_duration = 0x1, - } } - /// A set of users was invited to the group call See + ///See [TLDef(0x502F92F7)] - public sealed partial class MessageActionInviteToGroupCall : MessageAction + public partial class MessageActionInviteToGroupCall : MessageAction { - /// The group call - public InputGroupCallBase call; - /// The invited users + public InputGroupCall call; public long[] users; } - /// The Time-To-Live of messages in this chat was changed. See - [TLDef(0x3C134D7B)] - public sealed partial class MessageActionSetMessagesTTL : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// New Time-To-Live of all messages sent in this chat; if 0, autodeletion was disabled. - public int period; - /// If set, the chat TTL setting was set not due to a manual change by one of participants, but automatically because one of the participants has the Messages_SetDefaultHistoryTTL. For example, when a user writes to us for the first time and we have set a default messages TTL of 1 week, this service message (with auto_setting_from=our_userid) will be emitted before our first message. - [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 + ///See + [TLDef(0xAA1AFBFD)] + public partial class MessageActionSetMessagesTTL : MessageAction { public int period; } + ///See [TLDef(0xB3A07661)] - public sealed partial class MessageActionGroupCallScheduled : MessageAction + public partial class MessageActionGroupCallScheduled : MessageAction { - /// The group call - public InputGroupCallBase call; - /// When is this group call scheduled to start + public InputGroupCall call; public DateTime schedule_date; } - /// The chat theme was changed See - [TLDef(0xB91BBD3A)] - public sealed partial class MessageActionSetChatTheme : MessageAction - { - /// The new chat theme. - public ChatThemeBase theme; - } - /// A user was accepted into the group by an admin See - [TLDef(0xEBBCA3CB)] - public sealed partial class MessageActionChatJoinedByRequest : MessageAction { } - /// Data from an opened reply keyboard bot mini app was relayed to the bot that owns it (bot side service message). See - [TLDef(0x47DD8079, inheritAt = 0)] - public sealed partial class MessageActionWebViewDataSentMe : MessageActionWebViewDataSent - { - /// Relayed data. - public string data; - } - /// Data from an opened reply keyboard bot mini app was relayed to the bot that owns it (user side service message). See - [TLDef(0xB4C38CB5)] - public partial class MessageActionWebViewDataSent : MessageAction - { - /// Text of the that was pressed to open the web app. - public string text; - } - /// Info about a gifted Telegram Premium subscription See - [TLDef(0x48E91302)] - public sealed partial class MessageActionGiftPremium : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Three-letter ISO 4217 currency code - public string currency; - /// Price of the gift 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). - public long amount; - public int days; - /// If the gift was bought using a cryptocurrency, the cryptocurrency name. - [IfFlag(0)] public string crypto_currency; - /// If the gift was bought using a cryptocurrency, price of the gift in the smallest units of a cryptocurrency. - [IfFlag(0)] public long crypto_amount; - /// Message attached with the gift - [IfFlag(1)] public TextWithEntities message; + ///See + [TLDef(0xAA786345)] + public partial class MessageActionSetChatTheme : MessageAction { public string emoticon; } - [Flags] public enum Flags : uint - { - /// Fields and have a value - has_crypto_currency = 0x1, - /// Field has a value - has_message = 0x2, - } - } - /// A forum topic was created. See - [TLDef(0x0D999256)] - public sealed partial class MessageActionTopicCreate : MessageAction + ///See + public abstract partial class DialogBase : ITLObject { } + ///See + [TLDef(0x2C171F72)] + public partial class Dialog : DialogBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_pts = 0x1, has_draft = 0x2, pinned = 0x4, unread_mark = 0x8, has_folder_id = 0x10 } public Flags flags; - /// Topic name. - public string title; - /// If no custom emoji icon is specified, specifies the color of the fallback topic icon (RGB), one of 0x6FB9F0, 0xFFD67E, 0xCB86DB, 0x8EEE98, 0xFF93B2, or 0xFB6F5F. - public int icon_color; - /// ID of the custom emoji used as topic icon. - [IfFlag(0)] public long icon_emoji_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_icon_emoji_id = 0x1, - title_missing = 0x2, - } - } - /// Forum topic information was edited. See - [TLDef(0xC0944820)] - public sealed partial class MessageActionTopicEdit : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// New topic title. - [IfFlag(0)] public string title; - /// ID of the new custom emoji used as topic icon, or if it was removed. - [IfFlag(1)] public long icon_emoji_id; - /// Whether the topic was opened or closed. - [IfFlag(2)] public bool closed; - /// Whether the topic was hidden or unhidden (only valid for the "General" topic, id=1). - [IfFlag(3)] public bool hidden; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_title = 0x1, - /// Field has a value - has_icon_emoji_id = 0x2, - /// Field has a value - has_closed = 0x4, - /// Field has a value - has_hidden = 0x8, - } - } - /// A new profile picture was suggested using Photos_UploadContactProfilePhoto. See - [TLDef(0x57DE635E)] - public sealed partial class MessageActionSuggestProfilePhoto : MessageAction - { - /// The photo that the user suggested we set as profile picture. - public PhotoBase photo; - } - /// Contains info about one or more peers that the we (the user) shared with the bot after clicking on a button (service message sent by the user). See - [TLDef(0x31518E9B)] - public sealed partial class MessageActionRequestedPeer : MessageAction - { - /// button_id contained in the - public int button_id; - /// The shared peers - public Peer[] peers; - } - /// The wallpaper » of the current chat was changed. See - [TLDef(0x5060A3F4)] - public sealed partial class MessageActionSetChatWallPaper : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// New wallpaper - public WallPaperBase wallpaper; - - [Flags] public enum Flags : uint - { - /// If set, indicates the user applied a wallpaper » previously sent by the other user in a message. - same = 0x1, - /// If set, indicates the wallpaper was forcefully applied for both sides, without explicit confirmation from the other side.
If the message is incoming, and we did not like the new wallpaper the other user has chosen for us, we can re-set our previous wallpaper just on our side, by invoking Messages_SetChatWallPaper, providing only the revert flag (and obviously the peer parameter).
- for_both = 0x2, - } - } - /// Contains a Telegram Premium giftcode link. See - [TLDef(0x31C48347)] - public sealed partial class MessageActionGiftCode : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Identifier of the channel/supergroup that created the gift code either directly or through a giveaway: if we import this giftcode link, we will also automatically boost this channel/supergroup. - [IfFlag(1)] public Peer boost_peer; - public int days; - /// Slug of the Telegram Premium giftcode link - public string slug; - /// Three-letter ISO 4217 currency code - [IfFlag(2)] public string currency; - /// Total price 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). - [IfFlag(2)] public long amount; - /// If set, the gift was made using the specified cryptocurrency. - [IfFlag(3)] public string crypto_currency; - /// If crypto_currency is set, contains the paid amount, in the smallest units of the cryptocurrency. - [IfFlag(3)] public long crypto_amount; - /// Message attached with the gift - [IfFlag(4)] public TextWithEntities message; - - [Flags] public enum Flags : uint - { - /// If set, this gift code was received from a giveaway » started by a channel/supergroup we're subscribed to. - via_giveaway = 0x1, - /// Field has a value - has_boost_peer = 0x2, - /// Fields and have a value - has_currency = 0x4, - /// Fields and have a value - has_crypto_currency = 0x8, - /// Field has a value - has_message = 0x10, - /// If set, the link was not redeemed yet. - unclaimed = 0x20, - } - } - /// A giveaway was started. See - [TLDef(0xA80F51E4)] - public sealed partial class MessageActionGiveawayLaunch : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// For Telegram Star giveaways, the total number of Telegram Stars being given away. - [IfFlag(0)] public long stars; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_stars = 0x1, - } - } - /// A giveaway has ended. See - [TLDef(0x87E2F155)] - public sealed partial class MessageActionGiveawayResults : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Number of winners in the giveaway - public int winners_count; - /// Number of undistributed prizes - public int unclaimed_count; - - [Flags] public enum Flags : uint - { - /// If set, this is a Telegram Star giveaway - stars = 0x1, - } - } - /// Some boosts » were applied to the channel or supergroup. See - [TLDef(0xCC02AA6D)] - public sealed partial class MessageActionBoostApply : MessageAction - { - /// Number of applied boosts. - public int boosts; - } - /// Contains info about one or more peers that the a user shared with the me (the bot) after clicking on a button (service message received by the bot). See - [TLDef(0x93B31848)] - public sealed partial class MessageActionRequestedPeerSentMe : MessageAction - { - /// button_id contained in the - public int button_id; - /// Info about the shared peers. - public RequestedPeer[] peers; - } - /// Describes a payment refund (service message received by both users and bots). See - [TLDef(0x41B3E202)] - public sealed partial class MessageActionPaymentRefunded : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Identifier of the peer that returned the funds. public Peer peer; - /// Currency, XTR for Telegram Stars. - public string currency; - /// Total price 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). - public long total_amount; - /// Bot specified invoice payload (only received by bots). - [IfFlag(0)] public byte[] payload; - /// Provider payment identifier - public PaymentCharge charge; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_payload = 0x1, - } - } - /// You gifted or were gifted some Telegram Stars. See - [TLDef(0x45D5B021)] - public sealed partial class MessageActionGiftStars : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Three-letter ISO 4217 currency code - public string currency; - /// Price of the gift 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). - public long amount; - /// Amount of gifted stars - public long stars; - /// If the gift was bought using a cryptocurrency, the cryptocurrency name. - [IfFlag(0)] public string crypto_currency; - /// If the gift was bought using a cryptocurrency, price of the gift in the smallest units of a cryptocurrency. - [IfFlag(0)] public long crypto_amount; - /// Identifier of the transaction, only visible to the receiver of the gift. - [IfFlag(1)] public string transaction_id; - - [Flags] public enum Flags : uint - { - /// Fields and have a value - has_crypto_currency = 0x1, - /// Field has a value - has_transaction_id = 0x2, - } - } - /// You won some Telegram Stars in a Telegram Star giveaway ». See - [TLDef(0xB00C47A2)] - public sealed partial class MessageActionPrizeStars : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The number of Telegram Stars you won - public long stars; - /// ID of the telegram star transaction. - public string transaction_id; - /// Identifier of the peer that was automatically boosted by the winners of the giveaway. - public Peer boost_peer; - /// ID of the message containing the - public int giveaway_msg_id; - - [Flags] public enum Flags : uint - { - /// If set, this indicates the reverse transaction that refunds the remaining stars to the creator of a giveaway if, when the giveaway ends, the number of members in the channel is smaller than the number of winners in the giveaway. - unclaimed = 0x1, - } - } - /// You received a gift, see here » for more info. See - [TLDef(0xEA2C31D3)] - public sealed partial class MessageActionStarGift : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Info about the gift - public StarGiftBase gift; - /// Additional message from the sender of the gift - [IfFlag(1)] public TextWithEntities message; - /// The receiver of this gift may convert it to this many Telegram Stars, instead of displaying it on their profile page.
convert_stars will be equal to stars only if the gift was bought using recently bought Telegram Stars, otherwise it will be less than stars.
- [IfFlag(4)] public long convert_stars; - ///
If set, this gift was upgraded to a collectible gift, and the corresponding is available at the specified message ID. - [IfFlag(5)] public int upgrade_msg_id; - /// The number of Telegram Stars the user can pay to convert the gift into a collectible gift ». - [IfFlag(8)] public long upgrade_stars; - /// Sender of the gift (unset for anonymous gifts). - [IfFlag(11)] public Peer from_id; - /// Receiver of the gift. - [IfFlag(12)] public Peer peer; - /// For channel gifts, ID to use in s. - [IfFlag(12)] public long saved_id; - /// Hash to prepay for a gift upgrade separately ». - [IfFlag(14)] public string prepaid_upgrade_hash; - /// For separate upgrades, the identifier of the message with the gift whose upgrade was prepaid (only valid for the receiver of the service message). - [IfFlag(15)] public int gift_msg_id; - [IfFlag(18)] public Peer to_id; - [IfFlag(19)] public int gift_num; - - [Flags] public enum Flags : uint - { - /// If set, the name of the sender of the gift will be hidden if the destination user decides to display the gift on their profile - name_hidden = 0x1, - /// Field has a value - has_message = 0x2, - /// Whether this gift was added to the destination user's profile (may be toggled using Payments_SaveStarGift and fetched using Payments_GetSavedStarGifts) - saved = 0x4, - /// Whether this gift was converted to Telegram Stars and cannot be displayed on the profile anymore. - converted = 0x8, - /// Field has a value - has_convert_stars = 0x10, - /// This gift was upgraded to a collectible gift ». - upgraded = 0x20, - /// Field has a value - has_upgrade_stars = 0x100, - /// This gift is not available anymore because a request to refund the payment related to this gift was made, and the money was returned. - refunded = 0x200, - /// If set, this gift can be upgraded to a collectible gift; can only be set for the receiver of a gift. - can_upgrade = 0x400, - /// Field has a value - has_from_id = 0x800, - /// Fields and have a value - has_peer = 0x1000, - /// The sender has already pre-paid for the upgrade of this gift to a collectible gift. - prepaid_upgrade = 0x2000, - /// Field has a value - has_prepaid_upgrade_hash = 0x4000, - /// Field has a value - has_gift_msg_id = 0x8000, - /// This service message is the notification of a separate pre-payment for the upgrade of a gift we own. - upgrade_separate = 0x10000, - auction_acquired = 0x20000, - /// Field has a value - has_to_id = 0x40000, - /// Field has a value - has_gift_num = 0x80000, - } - } - /// A gift » was upgraded to a collectible gift ». See - [TLDef(0xE6C31522)] - public sealed partial class MessageActionStarGiftUnique : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The collectible gift. - public StarGiftBase gift; - /// If set, indicates that the current gift can't be exported to the TON blockchain » yet: the owner will be able to export it at the specified unixtime. - [IfFlag(3)] public DateTime can_export_at; - /// If set, indicates that the gift can be transferred » to another user by paying the specified amount of stars. - [IfFlag(4)] public long transfer_stars; - /// Sender of the gift (unset for anonymous gifts). - [IfFlag(6)] public Peer from_id; - /// Receiver of the gift. - [IfFlag(7)] public Peer peer; - /// For channel gifts, ID to use in s. - [IfFlag(7)] public long saved_id; - /// Resale price of the gift. - [IfFlag(8)] public StarsAmountBase resale_amount; - /// If set, indicates that the current gift can't be transferred » yet: the owner will be able to transfer it at the specified unixtime. - [IfFlag(9)] public DateTime can_transfer_at; - /// If set, indicates that the current gift can't be resold » yet: the owner will be able to put it up for sale at the specified unixtime. - [IfFlag(10)] public DateTime can_resell_at; - [IfFlag(12)] public long drop_original_details_stars; - [IfFlag(15)] public DateTime can_craft_at; - - [Flags] public enum Flags : uint - { - /// If set, this collectible was upgraded » to a collectible gift from a previously received or sent (depending on the out flag of the containing ) non-collectible gift. - upgrade = 0x1, - /// If set, this collectible was transferred (either to the current user or by the current user to the other user in the private chat, depending on the out flag of the containing ). - transferred = 0x2, - /// If set, this gift is visible on the user or channel's profile page; can only be set for the receiver of a gift. - saved = 0x4, - /// Field has a value - has_can_export_at = 0x8, - /// Field has a value - has_transfer_stars = 0x10, - /// This gift was upgraded to a collectible gift » and then re-downgraded to a regular gift because a request to refund the payment related to the upgrade was made, and the money was returned. - refunded = 0x20, - /// Field has a value - has_from_id = 0x40, - /// Fields and have a value - has_peer = 0x80, - /// Field has a value - has_resale_amount = 0x100, - /// Field has a value - has_can_transfer_at = 0x200, - /// Field has a value - has_can_resell_at = 0x400, - /// The sender has pre-paid for the upgrade of this gift to a collectible gift. - prepaid_upgrade = 0x800, - /// Field has a value - has_drop_original_details_stars = 0x1000, - assigned = 0x2000, - from_offer = 0x4000, - /// Field has a value - has_can_craft_at = 0x8000, - craft = 0x10000, - } - } - /// Sent from peer A to B, indicates that A refunded all stars B previously paid to send messages to A, see here » for more info on paid messages. See - [TLDef(0xAC1F1FCD)] - public sealed partial class MessageActionPaidMessagesRefunded : MessageAction - { - /// Number of paid messages affected by the refund. - public int count; - /// Number of refunded stars. - public long stars; - } - /// The price of paid messages » in this chat was changed. See - [TLDef(0x84B88578)] - public sealed partial class MessageActionPaidMessagesPrice : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The new price in Telegram Stars, can be 0 if messages are now free. - public long stars; - - [Flags] public enum Flags : uint - { - /// Can only be set for channels, if set indicates that direct messages were enabled », otherwise indicates that direct messages were disabled; the price of paid messages is related to the price of direct messages (aka those sent to the associated monoforum). - broadcast_messages_allowed = 0x1, - } - } - /// Represents a conference call (or an invitation to a conference call, if neither the missed nor active flags are set). See - [TLDef(0x2FFE2F7A)] - public sealed partial class MessageActionConferenceCall : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Call ID. - public long call_id; - /// Call duration, for left calls only. - [IfFlag(2)] public int duration; - /// Identifiers of some other call participants. - [IfFlag(3)] public Peer[] other_participants; - - [Flags] public enum Flags : uint - { - /// Whether the conference call has ended and the user hasn't joined. - missed = 0x1, - /// Whether the user is currently in the conference call. - active = 0x2, - /// Field has a value - has_duration = 0x4, - /// Field has a value - has_other_participants = 0x8, - /// Whether this is a video conference call. - video = 0x10, - } - } - /// Items were marked as completed or not completed in a todo list ». See - [TLDef(0xCC7C5C89)] - public sealed partial class MessageActionTodoCompletions : MessageAction - { - /// Items marked as completed. - public int[] completed; - /// Items marked as not completed. - public int[] incompleted; - } - /// Items were appended to the todo list ». See - [TLDef(0xC7EDBC83)] - public sealed partial class MessageActionTodoAppendTasks : MessageAction - { - /// Appended items. - public TodoItem[] list; - } - /// A suggested post » was approved or rejected. See - [TLDef(0xEE7A1596)] - public sealed partial class MessageActionSuggestedPostApproval : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// If the suggested post was rejected, can optionally contain a rejection comment. - [IfFlag(2)] public string reject_comment; - /// Scheduling date. - [IfFlag(3)] public DateTime schedule_date; - /// Price for the suggested post. - [IfFlag(4)] public StarsAmountBase price; - - [Flags] public enum Flags : uint - { - /// Whether the suggested post was rejected. - rejected = 0x1, - /// If set, the post was approved but the user's balance is too low to pay for the suggested post. - balance_too_low = 0x2, - /// Field has a value - has_reject_comment = 0x4, - /// Field has a value - has_schedule_date = 0x8, - /// Field has a value - has_price = 0x10, - } - } - /// A suggested post » was successfully posted, and payment for it was successfully received. See - [TLDef(0x95DDCF69)] - public sealed partial class MessageActionSuggestedPostSuccess : MessageAction - { - /// The price. - public StarsAmountBase price; - } - /// A suggested post » was accepted and posted or scheduled, but either the channel deleted the posted/scheduled post before stars_suggested_post_age_min seconds have elapsed, or the user refunded the payment for the stars used to pay for the suggested post. See - [TLDef(0x69F916F8)] - public sealed partial class MessageActionSuggestedPostRefund : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - - [Flags] public enum Flags : uint - { - /// If set, the user refunded the payment for the stars used to pay for the suggested post. - payer_initiated = 0x1, - } - } - /// You were gifted some toncoins. See - [TLDef(0xA8A3C699)] - public sealed partial class MessageActionGiftTon : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Name of a localized FIAT currency. - public string currency; - /// FIAT currency equivalent (in the currency specified in currency) of the amount specified in crypto_amount. - public long amount; - /// Name of the cryptocurrency. - public string crypto_currency; - /// Amount in the smallest unit of the cryptocurrency (for TONs, one billionth of a ton, AKA a nanoton). - public long crypto_amount; - /// Transaction ID. - [IfFlag(0)] public string transaction_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_transaction_id = 0x1, - } - } - /// See - [TLDef(0x2C8F2A25)] - public sealed partial class MessageActionSuggestBirthday : MessageAction - { - public Birthday birthday; - } - /// See - [TLDef(0x774278D4)] - public sealed partial class MessageActionStarGiftPurchaseOffer : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - public StarGiftBase gift; - public StarsAmountBase price; - public DateTime expires_at; - - [Flags] public enum Flags : uint - { - accepted = 0x1, - declined = 0x2, - } - } - /// See - [TLDef(0x73ADA76B)] - public sealed partial class MessageActionStarGiftPurchaseOfferDeclined : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - public StarGiftBase gift; - public StarsAmountBase price; - - [Flags] public enum Flags : uint - { - expired = 0x1, - } - } - /// See - [TLDef(0xB07ED085)] - public sealed partial class MessageActionNewCreatorPending : MessageAction - { - public long new_creator_id; - } - /// See - [TLDef(0xE188503B)] - public sealed partial class MessageActionChangeCreator : MessageAction - { - public long new_creator_id; - } - /// See - [TLDef(0xBF7D6572)] - public sealed partial class MessageActionNoForwardsToggle : MessageAction - { - public bool prev_value; - public bool new_value; - } - /// See - [TLDef(0x3E2793BA)] - public sealed partial class MessageActionNoForwardsRequest : MessageAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - public bool prev_value; - public bool new_value; - - [Flags] public enum Flags : uint - { - expired = 0x1, - } - } - - /// Chat info. See Derived classes: , - public abstract partial class DialogBase : IObject - { - /// The chat - public virtual Peer Peer => default; - /// The latest message ID - public virtual int TopMessage => default; - } - /// Chat See - [TLDef(0xD58A08C6)] - public sealed partial class Dialog : DialogBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The chat - public Peer peer; - /// The latest message ID public int top_message; - /// Position up to which all incoming messages are read. public int read_inbox_max_id; - /// Position up to which all outgoing messages are read. public int read_outbox_max_id; - /// Number of unread messages public int unread_count; - /// Number of unread mentions public int unread_mentions_count; - /// Number of unread reactions to messages you sent - public int unread_reactions_count; - /// Notification settings public PeerNotifySettings notify_settings; - /// PTS [IfFlag(0)] public int pts; - /// Message draft [IfFlag(1)] public DraftMessageBase draft; - /// Peer folder ID, for more info click here [IfFlag(4)] public int folder_id; - /// Time-to-live of all messages sent in this dialog - [IfFlag(5)] public int ttl_period; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_pts = 0x1, - /// Field has a value - has_draft = 0x2, - /// Is the dialog pinned - pinned = 0x4, - /// Whether the chat was manually marked as unread - unread_mark = 0x8, - /// Field has a value - has_folder_id = 0x10, - /// Field has a value - has_ttl_period = 0x20, - /// Users may also choose to display messages from all topics of a forum as if they were sent to a normal group, using a "View as messages" setting in the local client.
This setting only affects the current account, and is synced to other logged in sessions using the Channels_ToggleViewForumAsMessages method; invoking this method will update the value of this flag.
- view_forum_as_messages = 0x40, - } - - /// The chat - public override Peer Peer => peer; - /// The latest message ID - public override int TopMessage => top_message; } - /// Dialog in folder See + ///See [TLDef(0x71BD134C)] - public sealed partial class DialogFolder : DialogBase + public partial class DialogFolder : DialogBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { pinned = 0x4 } public Flags flags; - /// The folder public Folder folder; - /// Peer in folder public Peer peer; - /// Latest message ID of dialog public int top_message; - /// Number of unread muted peers in folder public int unread_muted_peers_count; - /// Number of unread unmuted peers in folder public int unread_unmuted_peers_count; - /// Number of unread messages from muted peers in folder public int unread_muted_messages_count; - /// Number of unread messages from unmuted peers in folder public int unread_unmuted_messages_count; - - [Flags] public enum Flags : uint - { - /// Is this folder pinned - pinned = 0x4, - } - - /// Peer in folder - public override Peer Peer => peer; - /// Latest message ID of dialog - public override int TopMessage => top_message; } - /// Object describes a photo. See Derived classes: , - public abstract partial class PhotoBase : IObject { } - /// Empty constructor, non-existent photo See + ///See + public abstract partial class PhotoBase : ITLObject { } + ///See [TLDef(0x2331B22D)] - public sealed partial class PhotoEmpty : PhotoBase - { - /// Photo identifier - public long id; - } - /// Photo See + public partial class PhotoEmpty : PhotoBase { public long id; } + ///See [TLDef(0xFB197A65)] - public sealed partial class Photo : PhotoBase + public partial class Photo : PhotoBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_stickers = 0x1, has_video_sizes = 0x2 } public Flags flags; - /// ID public long id; - /// Access hash public long access_hash; - /// file reference public byte[] file_reference; - /// Date of upload public DateTime date; - /// Available sizes for download public PhotoSizeBase[] sizes; - /// For animated profiles, the MPEG4 videos - [IfFlag(1)] public VideoSizeBase[] video_sizes; - /// DC ID to use for download + [IfFlag(1)] public VideoSize[] video_sizes; public int dc_id; - - [Flags] public enum Flags : uint - { - /// Whether the photo has mask stickers attached to it - has_stickers = 0x1, - /// Field has a value - has_video_sizes = 0x2, - } } - /// Location of a certain size of a picture See Derived classes: , , , , , - public abstract partial class PhotoSizeBase : IObject - { - /// Thumbnail type » - public virtual string Type => default; - } - /// Empty constructor. Image with this thumbnail is unavailable. See + ///See + public abstract partial class PhotoSizeBase : ITLObject { } + ///See [TLDef(0x0E17E23C)] - public sealed partial class PhotoSizeEmpty : PhotoSizeBase - { - /// Thumbnail type » - public string type; - - /// Thumbnail type » - public override string Type => type; - } - /// Image description. See + public partial class PhotoSizeEmpty : PhotoSizeBase { public string type; } + ///See [TLDef(0x75C78E60)] - public sealed partial class PhotoSize : PhotoSizeBase + public partial class PhotoSize : PhotoSizeBase { - /// Thumbnail type » public string type; - /// 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 + ///See [TLDef(0x021E1AD6)] - public sealed partial class PhotoCachedSize : PhotoSizeBase + public partial class PhotoCachedSize : PhotoSizeBase { - /// Thumbnail type public string type; - /// Image width public int w; - /// Image height public int h; - /// Binary data, file content public byte[] bytes; - - /// Thumbnail type - public override string Type => type; } - /// A low-resolution compressed JPG payload See + ///See [TLDef(0xE0B0BC2E)] - public sealed partial class PhotoStrippedSize : PhotoSizeBase + public partial class PhotoStrippedSize : PhotoSizeBase { - /// Thumbnail type public string type; - /// Thumbnail data, see here for more info on decompression » public byte[] bytes; - - /// Thumbnail type - public override string Type => type; } - /// Progressively encoded photosize See + ///See [TLDef(0xFA3EFB95)] - public sealed partial class PhotoSizeProgressive : PhotoSizeBase + public partial class PhotoSizeProgressive : PhotoSizeBase { - /// Photosize type » public string type; - /// Photo width public int w; - /// Photo height public int h; - /// Sizes of progressive JPEG file prefixes, which can be used to preliminarily show the image. public int[] sizes; - - /// 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 + ///See [TLDef(0xD8214D41)] - public sealed partial class PhotoPathSize : PhotoSizeBase + public partial class PhotoPathSize : PhotoSizeBase { - /// Always j public string type; - /// Compressed SVG path payload, see here for decompression instructions public byte[] bytes; - - /// Always j - public override string Type => type; } - /// GeoPoint. See - /// a value means geoPointEmpty + ///See + ///a null value means geoPointEmpty [TLDef(0xB2A2F663)] - public sealed partial class GeoPoint : IObject + public partial class GeoPoint : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_accuracy_radius = 0x1 } public Flags flags; - /// Longitude - public double lon; - /// Latitude + public double long_; public double lat; - /// Access hash public long access_hash; - /// The estimated horizontal accuracy of the location, in meters; as defined by the sender. [IfFlag(0)] public int accuracy_radius; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_accuracy_radius = 0x1, - } } - /// Contains info on a confirmation code message sent via SMS, phone call or Telegram. See Derived classes: , , - public abstract partial class Auth_SentCodeBase : IObject { } - /// Contains info about a sent verification code. See + ///See [TLDef(0x5E002502)] - public sealed partial class Auth_SentCode : Auth_SentCodeBase + public partial class Auth_SentCode : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_next_type = 0x2, has_timeout = 0x4 } public Flags flags; - /// Phone code type public Auth_SentCodeType type; - /// 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 [IfFlag(1)] public Auth_CodeType next_type; - /// Timeout for reception of the phone code [IfFlag(2)] public int timeout; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_type = 0x2, - /// Field has a value - has_timeout = 0x4, - } - } - /// The user successfully authorized using future auth tokens See - [TLDef(0x2390FE44)] - public sealed partial class Auth_SentCodeSuccess : Auth_SentCodeBase - { - /// Authorization info - public Auth_AuthorizationBase authorization; - } - /// Official apps may receive this constructor, indicating that due to the high cost of SMS verification codes for the user's country/provider, the user must purchase a Telegram Premium subscription in order to proceed with the login/signup. See - [TLDef(0xE0955A3C)] - public sealed partial class Auth_SentCodePaymentRequired : Auth_SentCodeBase - { - /// Store identifier of the Telegram Premium subscription. - public string store_product; - /// Phone code hash, to be stored and later re-used with Auth_SignIn - public string phone_code_hash; - /// An email address that can be contacted for more information about this request. - public string support_email_address; - /// The mandatory subject for the email. - public string support_email_subject; - public string currency; - public long amount; } - /// Object contains info on user authorization. See Derived classes: , - public abstract partial class Auth_AuthorizationBase : IObject { } - /// Contains user authorization info. See - [TLDef(0x2EA2C0D4)] - public sealed partial class Auth_Authorization : Auth_AuthorizationBase + ///See + public abstract partial class Auth_AuthorizationBase : ITLObject { } + ///See + [TLDef(0xCD050916)] + public partial class Auth_Authorization : Auth_AuthorizationBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_tmp_sessions = 0x1 } public Flags flags; - /// If and only if setup_password_required is set and the user declines to set a 2-step verification password, they will be able to log into their account via SMS again only after this many days pass. - [IfFlag(1)] public int otherwise_relogin_days; - /// Temporary passport sessions [IfFlag(0)] public int tmp_sessions; - /// A future auth token - [IfFlag(2)] public byte[] future_auth_token; - /// Info on authorized user public UserBase user; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_tmp_sessions = 0x1, - /// Suggests the user to set up a 2-step verification password to be able to log in again - setup_password_required = 0x2, - /// Field has a value - has_future_auth_token = 0x4, - } } - /// An account with this phone number doesn't exist on telegram: the user has to enter basic information and sign up See + ///See [TLDef(0x44747E9A)] - public sealed partial class Auth_AuthorizationSignUpRequired : Auth_AuthorizationBase + public partial class Auth_AuthorizationSignUpRequired : Auth_AuthorizationBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_terms_of_service = 0x1 } public Flags flags; - /// Telegram's terms of service: the user must read and accept the terms of service before signing up to telegram [IfFlag(0)] public Help_TermsOfService terms_of_service; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_terms_of_service = 0x1, - } } - /// Data for copying of authorization between data centers. See + ///See [TLDef(0xB434E2B8)] - public sealed partial class Auth_ExportedAuthorization : IObject + public partial class Auth_ExportedAuthorization : ITLObject { - /// current user identifier public long id; - /// authorizes key public byte[] bytes; } - /// Object defines the set of users and/or groups that generate notifications. See Derived classes: , , , , - public abstract partial class InputNotifyPeerBase : IObject { } - /// Notifications generated by a certain user or group. See + ///See + public abstract partial class InputNotifyPeerBase : ITLObject { } + ///See [TLDef(0xB8BC5B0C)] - public sealed partial class InputNotifyPeer : InputNotifyPeerBase - { - /// User or group - public InputPeer peer; - } - /// Notifications generated by all users. See + public partial class InputNotifyPeer : InputNotifyPeerBase { public InputPeer peer; } + ///See [TLDef(0x193B4417)] - public sealed partial class InputNotifyUsers : InputNotifyPeerBase { } - /// Notifications generated by all groups. See + public partial class InputNotifyUsers : InputNotifyPeerBase { } + ///See [TLDef(0x4A95E84E)] - public sealed partial class InputNotifyChats : InputNotifyPeerBase { } - /// All channels See + public partial class InputNotifyChats : InputNotifyPeerBase { } + ///See [TLDef(0xB1DB7C7E)] - public sealed partial class InputNotifyBroadcasts : InputNotifyPeerBase { } - /// Notifications generated by a topic in a forum. See - [TLDef(0x5C467992)] - public sealed partial class InputNotifyForumTopic : InputNotifyPeerBase - { - /// Forum ID - public InputPeer peer; - /// Topic ID - public int top_msg_id; - } + public partial class InputNotifyBroadcasts : InputNotifyPeerBase { } - /// Notification settings. See - [TLDef(0xCACB6AE2)] - public sealed partial class InputPeerNotifySettings : IObject + ///See + [TLDef(0x9C3D198E)] + public partial class InputPeerNotifySettings : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_show_previews = 0x1, has_silent = 0x2, has_mute_until = 0x4, has_sound = 0x8 } public Flags flags; - /// If the text of the message shall be displayed in notification [IfFlag(0)] public bool show_previews; - /// Peer was muted? [IfFlag(1)] public bool silent; - /// Date until which all notifications shall be switched off - [IfFlag(2)] public DateTime mute_until; - /// Identifier of an audio file to play for notifications. - [IfFlag(3)] public NotificationSound sound; - /// Whether story notifications should be disabled. - [IfFlag(6)] public bool stories_muted; - /// Whether the sender name should be displayed in story notifications. - [IfFlag(7)] public bool stories_hide_sender; - /// Identifier of an audio file to play for story notifications. - [IfFlag(8)] public NotificationSound stories_sound; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_show_previews = 0x1, - /// Field has a value - has_silent = 0x2, - /// Field has a value - has_mute_until = 0x4, - /// Field has a value - has_sound = 0x8, - /// Field has a value - has_stories_muted = 0x40, - /// Field has a value - has_stories_hide_sender = 0x80, - /// Field has a value - has_stories_sound = 0x100, - } + [IfFlag(2)] public int mute_until; + [IfFlag(3)] public string sound; } - /// Notification settings. See - [TLDef(0x99622C0C)] - public sealed partial class PeerNotifySettings : IObject + ///See + [TLDef(0xAF509D20)] + public partial class PeerNotifySettings : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_show_previews = 0x1, has_silent = 0x2, has_mute_until = 0x4, has_sound = 0x8 } public Flags flags; - /// (Ternary value) If set, indicates whether or not to display previews of messages in notifications; otherwise the default behavior should be used. [IfFlag(0)] public bool show_previews; - /// (Ternary value) If set, indicates whether to mute or unmute the peer; otherwise the default behavior should be used. [IfFlag(1)] public bool silent; - /// Mute all notifications until this date - [IfFlag(2)] public DateTime mute_until; - /// Notification sound for the official iOS application - [IfFlag(3)] public NotificationSound ios_sound; - /// Notification sound for the official android application - [IfFlag(4)] public NotificationSound android_sound; - /// Notification sound for other applications - [IfFlag(5)] public NotificationSound other_sound; - /// Whether story notifications should be disabled. - [IfFlag(6)] public bool stories_muted; - /// Whether the sender name should be displayed in story notifications. - [IfFlag(7)] public bool stories_hide_sender; - /// Sound for story notifications on the official iOS application - [IfFlag(8)] public NotificationSound stories_ios_sound; - /// Sound for story notifications on the official Android application - [IfFlag(9)] public NotificationSound stories_android_sound; - /// Sound for story notifications on other applications - [IfFlag(10)] public NotificationSound stories_other_sound; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_show_previews = 0x1, - /// Field has a value - has_silent = 0x2, - /// Field has a value - has_mute_until = 0x4, - /// Field has a value - has_ios_sound = 0x8, - /// Field has a value - has_android_sound = 0x10, - /// Field has a value - has_other_sound = 0x20, - /// Field has a value - has_stories_muted = 0x40, - /// Field has a value - has_stories_hide_sender = 0x80, - /// Field has a value - has_stories_ios_sound = 0x100, - /// Field has a value - has_stories_android_sound = 0x200, - /// Field has a value - has_stories_other_sound = 0x400, - } + [IfFlag(2)] public int mute_until; + [IfFlag(3)] public string sound; } - /// List of actions that are possible when interacting with this user, to be shown as suggested actions in the chat action bar », see here » for more info. See - [TLDef(0xF47741F7)] - public sealed partial class PeerSettings : IObject + ///See + [TLDef(0x733F2961)] + public partial class PeerSettings : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { report_spam = 0x1, add_contact = 0x2, block_contact = 0x4, share_contact = 0x8, + need_contacts_exception = 0x10, report_geo = 0x20, has_geo_distance = 0x40, autoarchived = 0x80, invite_members = 0x100 } public Flags flags; - /// Distance in meters between us and this peer [IfFlag(6)] public int geo_distance; - /// If set, this is a private chat with an administrator of a chat or channel to which the user sent a join request, and this field contains the chat/channel's title. - [IfFlag(9)] public string request_chat_title; - /// If set, this is a private chat with an administrator of a chat or channel to which the user sent a join request, and this field contains the timestamp when the join request » was sent. - [IfFlag(9)] public DateTime request_chat_date; - /// Contains the ID of the business bot » managing this chat, used to display info about the bot in the action bar. - [IfFlag(13)] public long business_bot_id; - /// Contains a deep link », used to open a management menu in the business bot. This flag is set if and only if business_bot_id is set. - [IfFlag(13)] public string business_bot_manage_url; - /// All users that must pay us » to send us private messages will have this flag set only for us, containing the amount of required stars, see here » for more info on paid messages. - [IfFlag(14)] public long charge_paid_message_stars; - /// Used to display the user's registration year and month, the string is in MM.YYYY format, where MM is the registration month (1-12), and YYYY is the registration year. - [IfFlag(15)] public string registration_month; - /// The country code of the user's phone number. - [IfFlag(16)] public string phone_country; - /// When was the user's name last changed. - [IfFlag(17)] public DateTime name_change_date; - /// When was the user's photo last changed. - [IfFlag(18)] public DateTime photo_change_date; - - [Flags] public enum Flags : uint - { - /// Whether we can still report the user for spam - report_spam = 0x1, - /// Whether we can add the user as contact - add_contact = 0x2, - /// Whether we can block the user - block_contact = 0x4, - /// Whether we can share the user's contact - share_contact = 0x8, - /// Whether a special exception for contacts is needed - need_contacts_exception = 0x10, - /// Whether we can report a geogroup as irrelevant for this location - report_geo = 0x20, - /// Field has a value - has_geo_distance = 0x40, - /// 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, - /// Fields and have a value - has_request_chat_title = 0x200, - /// This flag is set if request_chat_title and request_chat_date fields are set and the join request » is related to a channel (otherwise if only the request fields are set, the join request » is related to a chat). - request_chat_broadcast = 0x400, - /// This flag is set if both business_bot_id and business_bot_manage_url are set and all connected business bots » were paused in this chat using Account_ToggleConnectedBotPaused. - business_bot_paused = 0x800, - /// This flag is set if both business_bot_id and business_bot_manage_url are set and connected business bots » can reply to messages in this chat, as specified by the settings during initial configuration. - business_bot_can_reply = 0x1000, - /// Fields and have a value - has_business_bot_id = 0x2000, - /// Field has a value - has_charge_paid_message_stars = 0x4000, - /// Field has a value - has_registration_month = 0x8000, - /// Field has a value - has_phone_country = 0x10000, - /// Field has a value - has_name_change_date = 0x20000, - /// Field has a value - has_photo_change_date = 0x40000, - } } - /// Object contains info on a wallpaper. See Derived classes: , - public abstract partial class WallPaperBase : IObject - { - /// Identifier - public virtual long ID => default; - /// Info on how to generate the wallpaper, according to these instructions ». - public virtual WallPaperSettings Settings => default; - } - /// Represents a wallpaper based on an image. See + ///See + public abstract partial class WallPaperBase : ITLObject { } + ///See [TLDef(0xA437C3ED)] - public sealed partial class WallPaper : WallPaperBase + public partial class WallPaper : WallPaperBase { - /// Identifier + [Flags] public enum Flags { creator = 0x1, default_ = 0x2, has_settings = 0x4, pattern = 0x8, dark = 0x10 } public long id; - /// Extra bits of information, use flags.HasFlag(...) to test for those public Flags flags; - /// Access hash public long access_hash; - /// Unique wallpaper ID, used when generating wallpaper links or importing wallpaper links. public string slug; - /// The actual wallpaper public DocumentBase document; - /// Info on how to generate the wallpaper, according to these instructions ». [IfFlag(2)] public WallPaperSettings settings; - - [Flags] public enum Flags : uint - { - /// Whether we created this wallpaper - creator = 0x1, - /// Whether this is the default wallpaper - default_ = 0x2, - /// Field has a value - has_settings = 0x4, - /// Whether this is a pattern wallpaper » - pattern = 0x8, - /// Whether this wallpaper should be used in dark mode. - dark = 0x10, - } - - /// Identifier - public override long ID => id; - /// Info on how to generate the wallpaper, according to these instructions ». - public override WallPaperSettings Settings => settings; } - /// Represents a wallpaper only based on colors/gradients. See + ///See [TLDef(0xE0804116)] - public sealed partial class WallPaperNoFile : WallPaperBase + public partial class WallPaperNoFile : WallPaperBase { - /// Wallpaper ID + [Flags] public enum Flags { default_ = 0x2, has_settings = 0x4, dark = 0x10 } public long id; - /// Extra bits of information, use flags.HasFlag(...) to test for those public Flags flags; - /// Info on how to generate the wallpaper. [IfFlag(2)] public WallPaperSettings settings; - - [Flags] public enum Flags : uint - { - /// Whether this is the default wallpaper - default_ = 0x2, - /// Field has a value - has_settings = 0x4, - /// Whether this wallpaper should be used in dark mode. - dark = 0x10, - } - - /// Wallpaper ID - public override long ID => id; - /// Info on how to generate the wallpaper. - public override WallPaperSettings Settings => settings; } - /// Report reason See + ///See public enum ReportReason : uint { - ///Report for spam + ///See Spam = 0x58DBCAB8, - ///Report for violence + ///See Violence = 0x1E22C78D, - ///Report for pornography + ///See Pornography = 0x2E59D922, - ///Report for child abuse + ///See ChildAbuse = 0xADF44EE3, - ///Other + ///See Other = 0xC1E4A2B1, - ///Report for copyrighted content + ///See Copyright = 0x9B89F93A, - ///Report an irrelevant geogroup + ///See GeoIrrelevant = 0xDBD4FEED, - ///Report for impersonation + ///See Fake = 0xF5DDD6E7, - ///Report for illegal drugs - IllegalDrugs = 0x0A8EB2BE, - ///Report for divulgation of personal details - PersonalDetails = 0x9EC7863D, } - /// Extended user info See - [TLDef(0xA02BC13E)] - public sealed partial class UserFull : IObject + ///See + [TLDef(0xD697FF05)] + public partial class UserFull : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { blocked = 0x1, has_about = 0x2, has_profile_photo = 0x4, has_bot_info = 0x8, + phone_calls_available = 0x10, phone_calls_private = 0x20, has_pinned_msg_id = 0x40, can_pin_message = 0x80, + has_folder_id = 0x800, has_scheduled = 0x1000, video_calls_available = 0x2000, has_ttl_period = 0x4000, + has_theme_emoticon = 0x8000 } public Flags flags; - /// Extra bits of information, use flags2.HasFlag(...) to test for those - public Flags2 flags2; - /// User ID - public long id; - /// Bio of the user + public UserBase user; [IfFlag(1)] public string about; - /// Peer settings public PeerSettings settings; - /// Personal profile photo, to be shown instead of profile_photo. - [IfFlag(21)] public PhotoBase personal_photo; - /// Profile photo [IfFlag(2)] public PhotoBase profile_photo; - /// Fallback profile photo, displayed if no photo is present in profile_photo or personal_photo, due to privacy settings. - [IfFlag(22)] public PhotoBase fallback_photo; - /// Notification settings public PeerNotifySettings notify_settings; - /// For bots, info about the bot (bot commands, etc) [IfFlag(3)] public BotInfo bot_info; - /// Message ID of the last pinned message [IfFlag(6)] public int pinned_msg_id; - /// Chats in common with this user public int common_chats_count; - /// Peer folder ID, for more info click here [IfFlag(11)] public int folder_id; - /// Time To Live of all messages in this chat; once a message is this many seconds old, it must be deleted. [IfFlag(14)] public int ttl_period; - /// The chat theme associated with this user ». - [IfFlag(15)] public ChatThemeBase theme; - /// Anonymized text to be shown instead of the user's name on forwarded messages - [IfFlag(16)] public string private_forward_name; - /// A suggested set of administrator rights for the bot, to be shown when adding the bot as admin to a group, see here for more info on how to handle them ». - [IfFlag(17)] public ChatAdminRights bot_group_admin_rights; - /// A suggested set of administrator rights for the bot, to be shown when adding the bot as admin to a channel, see here for more info on how to handle them ». - [IfFlag(18)] public ChatAdminRights bot_broadcast_admin_rights; - /// Wallpaper to use in the private chat with the user. - [IfFlag(24)] public WallPaperBase wallpaper; - /// Active stories » - [IfFlag(25)] public PeerStories stories; - /// Telegram Business working hours ». - [IfFlag(32)] public BusinessWorkHours business_work_hours; - /// Telegram Business location ». - [IfFlag(33)] public BusinessLocation business_location; - /// Telegram Business greeting message ». - [IfFlag(34)] public BusinessGreetingMessage business_greeting_message; - /// Telegram Business away message ». - [IfFlag(35)] public BusinessAwayMessage business_away_message; - /// Specifies a custom Telegram Business profile introduction ». - [IfFlag(36)] public BusinessIntro business_intro; - /// Contains info about the user's birthday ». - [IfFlag(37)] public Birthday birthday; - /// ID of the associated personal channel », that should be shown in the profile page. - [IfFlag(38)] public long personal_channel_id; - /// ID of the latest message of the associated personal channel », that should be previewed in the profile page. - [IfFlag(38)] public int personal_channel_message; - /// Number of gifts the user has chosen to display on their profile - [IfFlag(40)] public int stargifts_count; - /// This bot has an active referral program » - [IfFlag(43)] public StarRefProgram starref_program; - /// Describes a bot verification icon ». - [IfFlag(44)] public BotVerification bot_verification; - /// If set and bigger than 0, this user has enabled paid messages » and we must pay the specified amount of Stars to send messages to them, see here » for the full flow.
If set and equal to 0, the user requires payment in general but we were exempted from paying for any of the reasons specified in the docs ».
- [IfFlag(46)] public long send_paid_messages_stars; - /// Disallows the reception of specific gift types. - [IfFlag(47)] public DisallowedGiftsSettings disallowed_gifts; - /// The user's star rating. - [IfFlag(49)] public StarsRating stars_rating; - /// Our pending star rating, only visible for ourselves. - [IfFlag(50)] public StarsRating stars_my_pending_rating; - /// When the pending star rating will be applied, only visible for ourselves. - [IfFlag(50)] public DateTime stars_my_pending_rating_date; - /// The main tab for the user's profile, see here » for more info. - [IfFlag(52)] public ProfileTab main_tab; - /// The first song on the music tab of the profile, see here » for more info on the music profile tab. - [IfFlag(53)] public DocumentBase saved_music; - [IfFlag(54)] public TextWithEntities note; - - [Flags] public enum Flags : uint - { - /// Whether you have blocked this user - blocked = 0x1, - /// Field has a value - has_about = 0x2, - /// Field has a value - has_profile_photo = 0x4, - /// Field has a value - has_bot_info = 0x8, - /// Whether this user can make VoIP calls - phone_calls_available = 0x10, - /// Whether this user's privacy settings allow you to call them - phone_calls_private = 0x20, - /// Field has a value - has_pinned_msg_id = 0x40, - /// Whether you can pin messages in the chat with this user, you can do this only for a chat with yourself - can_pin_message = 0x80, - /// Field has a value - has_folder_id = 0x800, - /// Whether scheduled messages are available - has_scheduled = 0x1000, - /// Whether the user can receive video calls - video_calls_available = 0x2000, - /// Field has a value - has_ttl_period = 0x4000, - /// Field has a value - has_theme = 0x8000, - /// Field has a value - has_private_forward_name = 0x10000, - /// Field has a value - has_bot_group_admin_rights = 0x20000, - /// Field has a value - has_bot_broadcast_admin_rights = 0x40000, - /// 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, - /// Whether the real-time chat translation popup should be hidden. - translations_disabled = 0x800000, - /// Field has a value - has_wallpaper = 0x1000000, - /// Field has a value - has_stories = 0x2000000, - /// Whether this user has some pinned stories. - stories_pinned_available = 0x4000000, - /// Whether we've blocked this user, preventing them from seeing our stories ». - blocked_my_stories_from = 0x8000000, - /// Whether the other user has chosen a custom wallpaper for us using Messages_SetChatWallPaper and the for_both flag, see here » for more info. - wallpaper_overridden = 0x10000000, - /// If set, we cannot write to this user: subscribe to Telegram Premium to get permission to write to this user.
To set this flag for ourselves invoke Account_SetGlobalPrivacySettings, setting the settings.new_noncontact_peers_require_premium flag, see here » for more info.
- contact_require_premium = 0x20000000, - /// If set, we cannot fetch the exact read date of messages we send to this user using Messages_GetOutboxReadDate.
The exact read date of messages might still be unavailable for other reasons, see Messages_GetOutboxReadDate for more info.
To set this flag for ourselves invoke Account_SetGlobalPrivacySettings, setting the settings.hide_read_marks flag.
- read_dates_private = 0x40000000, - } - - [Flags] public enum Flags2 : uint - { - /// Field has a value - has_business_work_hours = 0x1, - /// Field has a value - has_business_location = 0x2, - /// Field has a value - has_business_greeting_message = 0x4, - /// Field has a value - has_business_away_message = 0x8, - /// Field has a value - has_business_intro = 0x10, - /// Field has a value - has_birthday = 0x20, - /// Fields and have a value - has_personal_channel_id = 0x40, - /// Whether ads were re-enabled for the current account (only accessible to the currently logged-in user), see here » for more info. - sponsored_enabled = 0x80, - /// Field has a value - has_stargifts_count = 0x100, - /// If set, this user can view ad revenue statistics » for this bot. - can_view_revenue = 0x200, - /// If set, this is a bot that can change our emoji status » - bot_can_manage_emoji_status = 0x400, - /// Field has a value - has_starref_program = 0x800, - /// Field has a value - has_bot_verification = 0x1000, - /// Field has a value - has_send_paid_messages_stars = 0x4000, - /// Field has a value - has_disallowed_gifts = 0x8000, - /// If this flag is set for both us and another user (changed through ), a gift button should always be displayed in the text field in private chats with the other user: once clicked, the gift UI should be displayed, offering the user options to gift Telegram Premium » subscriptions or Telegram Gifts ». - display_gifts_button = 0x10000, - /// Field has a value - has_stars_rating = 0x20000, - /// Fields and have a value - has_stars_my_pending_rating = 0x40000, - /// Field has a value - has_main_tab = 0x100000, - /// Field has a value - has_saved_music = 0x200000, - /// Field has a value - has_note = 0x400000, - noforwards_my_enabled = 0x800000, - noforwards_peer_enabled = 0x1000000, - } + [IfFlag(15)] public string theme_emoticon; } - /// A contact of the current user that is registered in the system. See + ///See [TLDef(0x145ADE0B)] - public sealed partial class Contact : IObject + public partial class Contact : ITLObject { - /// User identifier public long user_id; - /// Current user is in the user's contact list public bool mutual; } - /// Successfully imported contact. See + ///See [TLDef(0xC13E3C50)] - public sealed partial class ImportedContact : IObject + public partial class ImportedContact : ITLObject { - /// User identifier public long user_id; - /// The contact's client identifier (passed to one of the constructors) public long client_id; } - /// Contact status: online / offline. See + ///See [TLDef(0x16D9703B)] - public sealed partial class ContactStatus : IObject + public partial class ContactStatus : ITLObject { - /// User identifier public long user_id; - /// Online status public UserStatus status; } - /// The current user's contact list and info on users. See - /// a value means contacts.contactsNotModified + ///See + ///a null value means contacts.contactsNotModified [TLDef(0xEAE87E42)] - public sealed partial class Contacts_Contacts : IObject + public partial class Contacts_Contacts : ITLObject { - /// Contact list public Contact[] contacts; - /// Number of contacts that were saved successfully public int saved_count; - /// User list - public Dictionary users; + public UserBase[] users; } - /// Info on successfully imported contacts. See + ///See [TLDef(0x77D01C3B)] - public sealed partial class Contacts_ImportedContacts : IObject + public partial class Contacts_ImportedContacts : ITLObject { - /// List of successfully imported contacts public ImportedContact[] imported; - /// Popular contacts public PopularContact[] popular_invites; - /// List of contact ids that could not be imported due to system limitation and will need to be imported at a later date. public long[] retry_contacts; - /// List of users - public Dictionary users; + public UserBase[] users; } - /// Full list of blocked users. See + ///See [TLDef(0x0ADE1591)] - public partial class Contacts_Blocked : IObject, IPeerResolver + public partial class Contacts_Blocked : ITLObject { - /// List of blocked users public PeerBlocked[] blocked; - /// Blocked chats - public Dictionary chats; - /// List of users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - /// Incomplete list of blocked users. See - [TLDef(0xE1664194)] - public sealed partial class Contacts_BlockedSlice : Contacts_Blocked - { - /// Total number of elements in the list - public int count; + public ChatBase[] chats; + public UserBase[] users; } + ///See + [TLDef(0xE1664194, inheritAfter = true)] + public partial class Contacts_BlockedSlice : Contacts_Blocked { public int count; } - /// 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 - public virtual DialogBase[] Dialogs => default; - /// List of last messages from each chat - public virtual MessageBase[] Messages => default; - /// returns a or for the given Peer - public abstract IPeerInfo UserOrChat(Peer peer); - } - /// Full list of chats with messages and auxiliary data. See + ///See + public abstract partial class Messages_DialogsBase : ITLObject { } + ///See [TLDef(0x15BA6C40)] - public partial class Messages_Dialogs : Messages_DialogsBase, IPeerResolver + public partial class Messages_Dialogs : Messages_DialogsBase { - /// List of chats public DialogBase[] dialogs; - /// List of last messages from each chat public MessageBase[] messages; - /// List of groups mentioned in the chats - public Dictionary chats; - /// List of users mentioned in messages and groups - public Dictionary users; - - /// List of chats - public override DialogBase[] Dialogs => dialogs; - /// List of last messages from each chat - public override MessageBase[] Messages => messages; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Incomplete list of dialogs with messages and auxiliary data. See - [TLDef(0x71E094F3)] - public sealed partial class Messages_DialogsSlice : Messages_Dialogs, IPeerResolver - { - /// Total number of dialogs - public int count; - } - /// Dialogs haven't changed See + ///See + [TLDef(0x71E094F3, inheritAfter = true)] + public partial class Messages_DialogsSlice : Messages_Dialogs { public int count; } + ///See [TLDef(0xF0E3E596)] - public sealed partial class Messages_DialogsNotModified : Messages_DialogsBase, IPeerResolver - { - /// Number of dialogs found server-side by the query - public int count; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => null; - } + public partial class Messages_DialogsNotModified : Messages_DialogsBase { public int count; } - /// Object contains information on list of messages with auxiliary data. See Derived classes: , , , - public abstract partial class Messages_MessagesBase : IObject, IPeerResolver + ///See + public abstract partial class Messages_MessagesBase : ITLObject { } + ///See + [TLDef(0x8C718E87)] + public partial class Messages_Messages : Messages_MessagesBase { - /// List of messages - public virtual MessageBase[] Messages => default; - public virtual ForumTopicBase[] Topics => default; - /// returns a or for the given Peer - public abstract IPeerInfo UserOrChat(Peer peer); - } - /// Full list of messages with auxiliary data. See - [TLDef(0x1D73E7EA)] - public partial class Messages_Messages : Messages_MessagesBase, IPeerResolver - { - /// List of messages public MessageBase[] messages; - public ForumTopicBase[] topics; - /// List of chats mentioned in dialogs - public Dictionary chats; - /// List of users mentioned in messages and chats - public Dictionary users; - - /// List of messages - public override MessageBase[] Messages => messages; - public override ForumTopicBase[] Topics => topics; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Incomplete list of messages and auxiliary data. See - [TLDef(0x5F206716)] - public sealed partial class Messages_MessagesSlice : Messages_Messages, IPeerResolver + ///See + [TLDef(0x3A54685E, inheritAfter = true)] + public partial class Messages_MessagesSlice : Messages_Messages { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_next_rate = 0x1, inexact = 0x2, has_offset_id_offset = 0x4 } 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 [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; - ///
For global post searches », the remaining amount of free searches, here query_is_free is related to the current call only, not to the next paginated call, and all subsequent pagination calls will always be free. - [IfFlag(3)] public SearchPostsFlood search_flood; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_rate = 0x1, - /// If set, indicates that the results may be inexact - inexact = 0x2, - /// Field has a value - has_offset_id_offset = 0x4, - /// Field has a value - has_search_flood = 0x8, - } } - /// Channel messages See - [TLDef(0xC776BA4E)] - public sealed partial class Messages_ChannelMessages : Messages_MessagesBase, IPeerResolver + ///See + [TLDef(0x64479808)] + public partial class Messages_ChannelMessages : Messages_MessagesBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { inexact = 0x2, has_offset_id_offset = 0x4 } public Flags flags; - /// Event count after generation public int pts; - /// Total number of results were found server-side (may not be all included here) public int count; - /// 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; - /// Found messages public MessageBase[] messages; - /// Forum topic information - public ForumTopicBase[] topics; - /// Chats - public Dictionary chats; - /// Users - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// If set, returned results may be inexact - inexact = 0x2, - /// Field has a value - has_offset_id_offset = 0x4, - } - - /// Found messages - public override MessageBase[] Messages => messages; - /// Forum topic information - public override ForumTopicBase[] Topics => topics; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// No new messages matching the query were found See + ///See [TLDef(0x74535F21)] - public sealed partial class Messages_MessagesNotModified : Messages_MessagesBase, IPeerResolver - { - /// Number of results found server-side by the given query - public int count; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => null; - } + public partial class Messages_MessagesNotModified : Messages_MessagesBase { public int count; } - /// List of chats with auxiliary data. See + ///See [TLDef(0x64FF9FD5)] - public partial class Messages_Chats : IObject - { - /// List of chats - public Dictionary chats; - } - /// Partial list of chats, more would have to be fetched with pagination See - [TLDef(0x9CD81144)] - public sealed partial class Messages_ChatsSlice : Messages_Chats - { - /// Total number of results that were found server-side (not all are included in chats) - public int count; - } + public partial class Messages_Chats : ITLObject { public ChatBase[] chats; } + ///See + [TLDef(0x9CD81144, inheritAfter = true)] + public partial class Messages_ChatsSlice : Messages_Chats { public int count; } - /// Full info about a channel, supergroup, gigagroup or basic group. See + ///See [TLDef(0xE5D7D19C)] - public sealed partial class Messages_ChatFull : IObject, IPeerResolver + public partial class Messages_ChatFull : ITLObject { - /// Full info public ChatFullBase full_chat; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Affected part of communication history with the user or in a chat. See - [TLDef(0xB45C69D1, inheritAt = 0)] - public partial class Messages_AffectedHistory : Messages_AffectedMessages + ///See + [TLDef(0xB45C69D1)] + public partial class Messages_AffectedHistory : ITLObject { - /// If a parameter contains positive value, it is necessary to repeat the method call using the given value; during the proceeding of all the history the value itself shall gradually decrease + public int pts; + public int pts_count; public int offset; } - /// Object describes message filter. See Derived classes: , , , , , , , , , , , , , , , - /// a value means inputMessagesFilterEmpty - public abstract partial class MessagesFilter : IObject { } - /// Filter for messages containing photos. See + ///See + ///a null value means inputMessagesFilterEmpty + public abstract partial class MessagesFilter : ITLObject { } + ///See [TLDef(0x9609A51C)] - public sealed partial class InputMessagesFilterPhotos : MessagesFilter { } - /// Filter for messages containing videos. See + public partial class InputMessagesFilterPhotos : MessagesFilter { } + ///See [TLDef(0x9FC00E65)] - public sealed partial class InputMessagesFilterVideo : MessagesFilter { } - /// Filter for messages containing photos or videos. See + public partial class InputMessagesFilterVideo : MessagesFilter { } + ///See [TLDef(0x56E9F0E4)] - public sealed partial class InputMessagesFilterPhotoVideo : MessagesFilter { } - /// Filter for messages containing documents. See + public partial class InputMessagesFilterPhotoVideo : MessagesFilter { } + ///See [TLDef(0x9EDDF188)] - public sealed partial class InputMessagesFilterDocument : MessagesFilter { } - /// Return only messages containing URLs See + public partial class InputMessagesFilterDocument : MessagesFilter { } + ///See [TLDef(0x7EF0DD87)] - public sealed partial class InputMessagesFilterUrl : MessagesFilter { } - /// Return only messages containing gifs See + public partial class InputMessagesFilterUrl : MessagesFilter { } + ///See [TLDef(0xFFC86587)] - public sealed partial class InputMessagesFilterGif : MessagesFilter { } - /// Return only messages containing voice notes See + public partial class InputMessagesFilterGif : MessagesFilter { } + ///See [TLDef(0x50F5C392)] - public sealed partial class InputMessagesFilterVoice : MessagesFilter { } - /// Return only messages containing audio files See + public partial class InputMessagesFilterVoice : MessagesFilter { } + ///See [TLDef(0x3751B49E)] - public sealed partial class InputMessagesFilterMusic : MessagesFilter { } - /// Return only chat photo changes See + public partial class InputMessagesFilterMusic : MessagesFilter { } + ///See [TLDef(0x3A20ECB8)] - public sealed partial class InputMessagesFilterChatPhotos : MessagesFilter { } - /// Return only phone calls See + public partial class InputMessagesFilterChatPhotos : MessagesFilter { } + ///See [TLDef(0x80C99768)] - public sealed partial class InputMessagesFilterPhoneCalls : MessagesFilter + public partial class InputMessagesFilterPhoneCalls : MessagesFilter { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { missed = 0x1 } public Flags flags; - - [Flags] public enum Flags : uint - { - /// Return only missed phone calls - missed = 0x1, - } } - /// Return only round videos and voice notes See + ///See [TLDef(0x7A7C17A4)] - public sealed partial class InputMessagesFilterRoundVoice : MessagesFilter { } - /// Return only round videos See + public partial class InputMessagesFilterRoundVoice : MessagesFilter { } + ///See [TLDef(0xB549DA53)] - public sealed partial class InputMessagesFilterRoundVideo : MessagesFilter { } - /// Return only messages where the current user was mentioned. See + public partial class InputMessagesFilterRoundVideo : MessagesFilter { } + ///See [TLDef(0xC1F8E69A)] - public sealed partial class InputMessagesFilterMyMentions : MessagesFilter { } - /// Return only messages containing geolocations See + public partial class InputMessagesFilterMyMentions : MessagesFilter { } + ///See [TLDef(0xE7026D0D)] - public sealed partial class InputMessagesFilterGeo : MessagesFilter { } - /// Return only messages containing contacts See + public partial class InputMessagesFilterGeo : MessagesFilter { } + ///See [TLDef(0xE062DB83)] - public sealed partial class InputMessagesFilterContacts : MessagesFilter { } - /// Fetch only pinned messages See + public partial class InputMessagesFilterContacts : MessagesFilter { } + ///See [TLDef(0x1BB00451)] - public sealed partial class InputMessagesFilterPinned : MessagesFilter { } + public partial class InputMessagesFilterPinned : MessagesFilter { } - /// Object contains info on events occurred. See Derived classes: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - public abstract partial class Update : IObject - { - public virtual (long mbox_id, int pts, int pts_count) GetMBox() => default; - public virtual void SetPTS(int new_pts, int new_pts_count) { } - } - /// New message in a private chat or in a basic group. See + ///See + public abstract partial class Update : ITLObject { } + ///See [TLDef(0x1F2B0AFD)] public partial class UpdateNewMessage : Update { - /// Message public MessageBase message; - /// New quantity of actions in a message box public int pts; - /// Number of generated events public int pts_count; - - public override (long, int, int) GetMBox() => (0, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_pts_count); } - /// Sent message with random_id client identifier was assigned an identifier. See + ///See [TLDef(0x4E90BFD6)] - public sealed partial class UpdateMessageID : Update + public partial class UpdateMessageID : Update { - /// id identifier of a respective public int id; - /// Previously transferred client random_id identifier public long random_id; } - /// Messages were deleted. See + ///See [TLDef(0xA20DB0E5)] public partial class UpdateDeleteMessages : Update { - /// List of identifiers of deleted messages public int[] messages; - /// New quality of actions in a message box public int pts; - /// Number of generated events public int pts_count; - - public override (long, int, int) GetMBox() => (0, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_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(0x2A17BF5C)] - public sealed partial class UpdateUserTyping : Update + ///See + [TLDef(0xC01E857F)] + public partial class UpdateUserTyping : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// User id public long user_id; - [IfFlag(0)] public int top_msg_id; - /// Action type public SendMessageAction action; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_top_msg_id = 0x1, - } } - /// The user is preparing a message in a group; 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(0x83487AF0, inheritAt = 0)] - public sealed partial class UpdateChatUserTyping : UpdateChat + ///See + [TLDef(0x83487AF0)] + public partial class UpdateChatUserTyping : UpdateChat { - /// Peer that started typing (can be the chat itself, in case of anonymous admins). public Peer from_id; - /// Type of action public SendMessageAction action; } - /// Composition of chat participants changed. See + ///See [TLDef(0x07761198)] - public sealed partial class UpdateChatParticipants : Update + public partial class UpdateChatParticipants : Update { public ChatParticipantsBase participants; } + ///See + [TLDef(0xE5BDF8DE)] + public partial class UpdateUserStatus : Update { - /// Updated chat participants - public ChatParticipantsBase participants; - } - /// Contact status update. See - [TLDef(0xE5BDF8DE, inheritAt = 0)] - public sealed partial class UpdateUserStatus : UpdateUser - { - /// New status + public long user_id; public UserStatus status; } - /// Changes the user's first name, last name and username. See - [TLDef(0xA7848924, inheritAt = 0)] - public sealed partial class UpdateUserName : UpdateUser + ///See + [TLDef(0xC3F202E0)] + public partial class UpdateUserName : Update { - /// New first name. Corresponds to the new value of real_first_name field of the . + public long user_id; public string first_name; - /// New last name. Corresponds to the new value of real_last_name field of the . public string last_name; - /// Usernames. - public Username[] usernames; + public string username; } - /// A new session logged into the current user's account through an unknown device. See - [TLDef(0x8951ABEF)] - public sealed partial class UpdateNewAuthorization : Update + ///See + [TLDef(0xF227868C)] + public partial class UpdateUserPhoto : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Hash used for caching, for more info click here - public long hash; - /// Authorization date - [IfFlag(0)] public DateTime date; - /// Name of device, for example Android - [IfFlag(0)] public string device; - /// Location, for example USA, NY (IP=1.2.3.4) - [IfFlag(0)] public string location; - - [Flags] public enum Flags : uint - { - /// Whether the session is unconfirmed, see here » for more info. - unconfirmed = 0x1, - } + public long user_id; + public DateTime date; + public UserProfilePhoto photo; + public bool previous; } - /// New encrypted message. See + ///See [TLDef(0x12BCBD9A)] - public sealed partial class UpdateNewEncryptedMessage : Update + public partial class UpdateNewEncryptedMessage : Update { - /// Message public EncryptedMessageBase message; - /// New qts value, see updates » for more info. public int qts; - - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; } - /// Interlocutor is typing a message in an encrypted chat. Update period is 6 second. If upon this time there is no repeated update, it shall be considered that the interlocutor stopped typing. See + ///See [TLDef(0x1710F156)] - public sealed partial class UpdateEncryptedChatTyping : Update - { - /// Chat ID - public int chat_id; - } - /// Change of state in an encrypted chat. See + public partial class UpdateEncryptedChatTyping : Update { public int chat_id; } + ///See [TLDef(0xB4A2E88D)] - public sealed partial class UpdateEncryption : Update + public partial class UpdateEncryption : Update { - /// Encrypted chat public EncryptedChatBase chat; - /// Date of change public DateTime date; } - /// Communication history in an encrypted chat was marked as read. See + ///See [TLDef(0x38FE25B7)] - public sealed partial class UpdateEncryptedMessagesRead : Update + public partial class UpdateEncryptedMessagesRead : Update { - /// Chat ID public int chat_id; - /// Maximum value of data for read messages public DateTime max_date; - /// Time when messages were read public DateTime date; } - /// New group member. See - [TLDef(0x3DDA5451, inheritAt = 0)] - public sealed partial class UpdateChatParticipantAdd : UpdateChat + ///See + [TLDef(0x3DDA5451)] + public partial class UpdateChatParticipantAdd : UpdateChat { - /// ID of the new member public long user_id; - /// ID of the user, who added member to the group public long inviter_id; - /// When was the participant added public DateTime date; - /// Chat version number public int version; } - /// A member has left the group. See - [TLDef(0xE32F3D77, inheritAt = 0)] - public sealed partial class UpdateChatParticipantDelete : UpdateChat + ///See + [TLDef(0xE32F3D77)] + public partial class UpdateChatParticipantDelete : UpdateChat { - /// ID of the user public long user_id; - /// Used in basic groups to reorder updates and make sure that all of them was received. public int version; } - /// Changes in the data center configuration options. See + ///See [TLDef(0x8E5E9873)] - public sealed partial class UpdateDcOptions : Update - { - /// New connection options - public DcOption[] dc_options; - } - /// Changes in notification settings. See + public partial class UpdateDcOptions : Update { public DcOption[] dc_options; } + ///See [TLDef(0xBEC268EF)] - public sealed partial class UpdateNotifySettings : Update + public partial class UpdateNotifySettings : Update { - /// Notification source public NotifyPeerBase peer; - /// New notification settings public PeerNotifySettings notify_settings; } - /// A service message for the user. See + ///See [TLDef(0xEBE46819)] - public sealed partial class UpdateServiceNotification : Update + public partial class UpdateServiceNotification : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { popup = 0x1, has_inbox_date = 0x2 } public Flags flags; - /// When was the notification received
The message must also be stored locally as part of the message history with the user id 777000 (Telegram Notifications).
[IfFlag(1)] public DateTime inbox_date; - ///
String, identical in format and contents to the type field in API errors. Describes type of service message. It is acceptable to ignore repeated messages of the same type within a short period of time (15 minutes). public string type; - /// Message text public string message; - /// Media content (optional) public MessageMedia media; - /// Message entities for styled text public MessageEntity[] entities; - - [Flags] public enum Flags : uint - { - /// If set, the message must be displayed in a popup. - popup = 0x1, - /// Field has a value - has_inbox_date = 0x2, - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - invert_media = 0x4, - } } - /// Privacy rules were changed See + ///See [TLDef(0xEE3B272A)] - public sealed partial class UpdatePrivacy : Update + public partial class UpdatePrivacy : Update { - /// Peers to which the privacy rules apply public PrivacyKey key; - /// New privacy rules public PrivacyRule[] rules; } - /// A user's phone number was changed See - [TLDef(0x05492A13, inheritAt = 0)] - public sealed partial class UpdateUserPhone : UpdateUser + ///See + [TLDef(0x05492A13)] + public partial class UpdateUserPhone : Update { - /// New phone number + public long user_id; public string phone; } - /// Incoming messages were read See - [TLDef(0x9E84BC99)] - public sealed partial class UpdateReadHistoryInbox : Update + ///See + [TLDef(0x9C974FDF)] + public partial class UpdateReadHistoryInbox : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_folder_id = 0x1 } public Flags flags; - /// Peer folder ID, for more info click here [IfFlag(0)] public int folder_id; - /// Peer public Peer peer; - [IfFlag(1)] public int top_msg_id; - /// Maximum ID of messages read public int max_id; - /// Number of messages that are still unread public int still_unread_count; - /// Event count after generation public int pts; - /// Number of events that were generated public int pts_count; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_folder_id = 0x1, - /// Field has a value - has_top_msg_id = 0x2, - } - - public override (long, int, int) GetMBox() => (0, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_pts_count); } - /// Outgoing messages were read See + ///See [TLDef(0x2F2F21BF)] - public sealed partial class UpdateReadHistoryOutbox : Update + public partial class UpdateReadHistoryOutbox : Update { - /// Peer public Peer peer; - /// Maximum ID of read outgoing messages public int max_id; - /// Event count after generation public int pts; - /// Number of events that were generated public int pts_count; - - public override (long, int, int) GetMBox() => (0, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_pts_count); } - /// An instant view webpage preview was generated See + ///See [TLDef(0x7F891213)] public partial class UpdateWebPage : Update { - /// Webpage preview public WebPageBase webpage; - /// Event count after generation public int pts; - /// Number of events that were generated public int pts_count; - - public override (long, int, int) GetMBox() => (0, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_pts_count); } - /// Contents of messages in the common message box were read (emitted specifically for messages like voice messages or video, only once the media is watched and marked as read using Messages_ReadMessageContents). See - [TLDef(0xF8227181)] - public sealed partial class UpdateReadMessagesContents : Update + ///See + [TLDef(0x68C13933)] + public partial class UpdateReadMessagesContents : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// IDs of read messages public int[] messages; - /// Event count after generation public int pts; - /// Number of events that were generated public int pts_count; - /// When was the last message in messages marked as read. - [IfFlag(0)] public DateTime date; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_date = 0x1, - } - - public override (long, int, int) GetMBox() => (0, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_pts_count); } - /// There are new updates in the specified channel, the client must fetch them.
If the difference is too long or if the channel isn't currently in the states, start fetching from the specified pts. See
+ ///See [TLDef(0x108D941F)] - public sealed partial class UpdateChannelTooLong : Update + public partial class UpdateChannelTooLong : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_pts = 0x1 } public Flags flags; - /// The channel public long channel_id; - /// The PTS. [IfFlag(0)] public int pts; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_pts = 0x1, - } - - public override (long, int, int) GetMBox() => (channel_id, pts, 0); - public override void SetPTS(int new_pts, int _) => pts = new_pts; } - /// Channel/supergroup ( and/or ) information was updated. See + ///See [TLDef(0x635B4C09)] - public partial class UpdateChannel : Update - { - /// Channel ID - public long channel_id; - } - /// A new message was sent in a channel/supergroup See + public partial class UpdateChannel : Update { public long channel_id; } + ///See [TLDef(0x62BA04D9)] - public sealed partial class UpdateNewChannelMessage : UpdateNewMessage - { - public override (long, int, int) GetMBox() => (message.Peer is PeerChannel pc ? pc.channel_id : 0, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_pts_count); - } - /// Incoming messages in a channel/supergroup were read See + public partial class UpdateNewChannelMessage : UpdateNewMessage { } + ///See [TLDef(0x922E6E10)] - public sealed partial class UpdateReadChannelInbox : Update + public partial class UpdateReadChannelInbox : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_folder_id = 0x1 } public Flags flags; - /// Peer folder ID, for more info click here [IfFlag(0)] public int folder_id; - /// Channel/supergroup ID public long channel_id; - /// Position up to which all incoming messages are read. public int max_id; - /// Count of messages weren't read yet public int still_unread_count; - /// Event count after generation public int pts; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_folder_id = 0x1, - } - - public override (long, int, int) GetMBox() => (channel_id, pts, 0); - public override void SetPTS(int new_pts, int _) => pts = new_pts; } - /// Some messages in a supergroup/channel were deleted See - [TLDef(0xC32D5B12)] - public sealed partial class UpdateDeleteChannelMessages : UpdateDeleteMessages + ///See + [TLDef(0xC32D5B12, inheritAfter = true)] + public partial class UpdateDeleteChannelMessages : UpdateDeleteMessages { public long channel_id; } + ///See + [TLDef(0xF226AC08)] + public partial class UpdateChannelMessageViews : UpdateChannel { - /// Channel ID - public long channel_id; - - public override (long, int, int) GetMBox() => (channel_id, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_pts_count); - } - /// The view counter of a message in a channel has changed See - [TLDef(0xF226AC08, inheritAt = 0)] - public sealed partial class UpdateChannelMessageViews : UpdateChannel - { - /// ID of the message public int id; - /// New view counter public int views; } - /// Admin permissions of a user in a basic group were changed See - [TLDef(0xD7CA61A2, inheritAt = 0)] - public sealed partial class UpdateChatParticipantAdmin : UpdateChat + ///See + [TLDef(0xD7CA61A2)] + public partial class UpdateChatParticipantAdmin : UpdateChat { - /// ID of the (de)admined user public long user_id; - /// Whether the user was rendered admin public bool is_admin; - /// Used in basic groups to reorder updates and make sure that all of them was received. public int version; } - /// A new stickerset was installed See + ///See [TLDef(0x688A30AA)] - public sealed partial class UpdateNewStickerSet : Update + public partial class UpdateNewStickerSet : Update { public Messages_StickerSet stickerset; } + ///See + [TLDef(0x0BB2D201)] + public partial class UpdateStickerSetsOrder : Update { - /// The installed stickerset - public Messages_StickerSet stickerset; - } - /// The order of stickersets was changed See - [TLDef(0x0BB2D201, inheritAt = 0)] - public sealed partial class UpdateStickerSetsOrder : UpdateStickerSets - { - /// New sticker order by sticker ID + [Flags] public enum Flags { masks = 0x1 } + public Flags flags; public long[] order; } - /// Installed stickersets have changed, the client should refetch them as described in the docs. See - [TLDef(0x31C24808)] - public partial class UpdateStickerSets : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - - [Flags] public enum Flags : uint - { - /// Whether mask stickersets have changed - masks = 0x1, - /// Whether the list of installed custom emoji stickersets has changed - emojis = 0x2, - } - } - /// The saved gif list has changed, the client should refetch it using Messages_GetSavedGifs See + ///See + [TLDef(0x43AE3DEC)] + public partial class UpdateStickerSets : Update { } + ///See [TLDef(0x9375341E)] - public sealed partial class UpdateSavedGifs : Update { } - /// An incoming inline query See + public partial class UpdateSavedGifs : Update { } + ///See [TLDef(0x496F379C)] - public sealed partial class UpdateBotInlineQuery : Update + public partial class UpdateBotInlineQuery : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_geo = 0x1, has_peer_type = 0x2 } public Flags flags; - /// Query ID public long query_id; - /// User that sent the query public long user_id; - /// Text of query public string query; - /// Attached geolocation [IfFlag(0)] public GeoPoint geo; - /// Type of the chat from which the inline query was sent. [IfFlag(1)] public InlineQueryPeerType peer_type; - /// Offset to navigate through results public string offset; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_geo = 0x1, - /// Field has a value - 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 + ///See [TLDef(0x12F12A07)] - public sealed partial class UpdateBotInlineSend : Update + public partial class UpdateBotInlineSend : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_geo = 0x1, has_msg_id = 0x2 } public Flags flags; - /// The user that chose the result public long user_id; - /// The query that was used to obtain the result public string query; - /// Optional. Sender location, only for bots that require user location [IfFlag(0)] public GeoPoint geo; - /// The unique identifier for the result that was chosen public string id; - /// Identifier of the sent inline message. Available only if there is an inline keyboard attached to the message. Will be also received in callback queries and can be used to edit the message. [IfFlag(1)] public InputBotInlineMessageIDBase msg_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_geo = 0x1, - /// Field has a value - has_msg_id = 0x2, - } } - /// A message was edited in a channel/supergroup See + ///See [TLDef(0x1B3F4DF7)] - public sealed partial class UpdateEditChannelMessage : UpdateEditMessage - { - public override (long, int, int) GetMBox() => (message.Peer is PeerChannel pc ? pc.channel_id : 0, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_pts_count); - } - /// A callback button was pressed, and the button data was sent to the bot that created the button See + public partial class UpdateEditChannelMessage : UpdateEditMessage { } + ///See [TLDef(0xB9CFC48D)] - public sealed partial class UpdateBotCallbackQuery : Update + public partial class UpdateBotCallbackQuery : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_data = 0x1, has_game_short_name = 0x2 } public Flags flags; - /// Query ID public long query_id; - /// ID of the user that pressed the button public long user_id; - /// Chat where the inline keyboard was sent public Peer peer; - /// Message ID public int msg_id; - /// Global identifier, uniquely corresponding to the chat to which the message with the callback button was sent. Useful for high scores in games. public long chat_instance; - /// Callback data [IfFlag(0)] public byte[] data; - /// Short name of a Game to be returned, serves as the unique identifier for the game [IfFlag(1)] public string game_short_name; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_data = 0x1, - /// Field has a value - has_game_short_name = 0x2, - } } - /// A message was edited See + ///See [TLDef(0xE40370A3)] public partial class UpdateEditMessage : Update { - /// The new edited message public MessageBase message; - /// PTS public int pts; - /// PTS count public int pts_count; - - public override (long, int, int) GetMBox() => (0, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_pts_count); } - /// This notification is received by bots when a button is pressed See + ///See [TLDef(0x691E9052)] - public sealed partial class UpdateInlineBotCallbackQuery : Update + public partial class UpdateInlineBotCallbackQuery : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_data = 0x1, has_game_short_name = 0x2 } public Flags flags; - /// Query ID public long query_id; - /// ID of the user that pressed the button public long user_id; - /// ID of the inline message with the button public InputBotInlineMessageIDBase msg_id; - /// Global identifier, uniquely corresponding to the chat to which the message with the callback button was sent. Useful for high scores in games. public long chat_instance; - /// Data associated with the callback button. Be aware that a bad client can send arbitrary data in this field. [IfFlag(0)] public byte[] data; - /// Short name of a Game to be returned, serves as the unique identifier for the game [IfFlag(1)] public string game_short_name; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_data = 0x1, - /// Field has a value - has_game_short_name = 0x2, - } } - /// Outgoing messages in a channel/supergroup were read See + ///See [TLDef(0xB75F99A9)] - public sealed partial class UpdateReadChannelOutbox : Update + public partial class UpdateReadChannelOutbox : Update { - /// Channel/supergroup ID public long channel_id; - /// Position up to which all outgoing messages are read. public int max_id; } - /// Notifies a change of a message draft. See - [TLDef(0xEDFC111E)] - public sealed partial class UpdateDraftMessage : Update + ///See + [TLDef(0xEE2BB969)] + public partial class UpdateDraftMessage : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The peer to which the draft is associated public Peer peer; - /// ID of the forum topic to which the draft is associated - [IfFlag(0)] public int top_msg_id; - /// If set, the draft is related to the specified monoforum topic ID ». - [IfFlag(1)] public Peer saved_peer_id; - /// The draft public DraftMessageBase draft; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_top_msg_id = 0x1, - /// Field has a value - has_saved_peer_id = 0x2, - } } - /// Some featured stickers were marked as read See + ///See [TLDef(0x571D2742)] - public sealed partial class UpdateReadFeaturedStickers : Update { } - /// The recent sticker list was updated See + public partial class UpdateReadFeaturedStickers : Update { } + ///See [TLDef(0x9A422C20)] - public sealed partial class UpdateRecentStickers : Update { } - /// The server-side configuration has changed; the client should re-fetch the config using Help_GetConfig and Help_GetAppConfig. See + public partial class UpdateRecentStickers : Update { } + ///See [TLDef(0xA229DD06)] - public sealed partial class UpdateConfig : Update { } - /// Common message box sequence PTS has changed, state has to be refetched using updates.getState See + public partial class UpdateConfig : Update { } + ///See [TLDef(0x3354678F)] - public sealed partial class UpdatePtsChanged : Update { } - /// A webpage preview of a link in a channel/supergroup message was generated See - [TLDef(0x2F2BA99F)] - public sealed partial class UpdateChannelWebPage : UpdateWebPage - { - /// Channel/supergroup ID - public long channel_id; - - public override (long, int, int) GetMBox() => (channel_id, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_pts_count); - } - /// A dialog was pinned/unpinned See + public partial class UpdatePtsChanged : Update { } + ///See + [TLDef(0x2F2BA99F, inheritAfter = true)] + public partial class UpdateChannelWebPage : UpdateWebPage { public long channel_id; } + ///See [TLDef(0x6E6FE51C)] - public sealed partial class UpdateDialogPinned : Update + public partial class UpdateDialogPinned : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { pinned = 0x1, has_folder_id = 0x2 } public Flags flags; - /// Peer folder ID, for more info click here [IfFlag(1)] public int folder_id; - /// The dialog public DialogPeerBase peer; - - [Flags] public enum Flags : uint - { - /// Whether the dialog was pinned - pinned = 0x1, - /// Field has a value - has_folder_id = 0x2, - } } - /// Pinned dialogs were updated See + ///See [TLDef(0xFA0F3CA2)] - public sealed partial class UpdatePinnedDialogs : Update + public partial class UpdatePinnedDialogs : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_order = 0x1, has_folder_id = 0x2 } public Flags flags; - /// Peer folder ID, for more info click here [IfFlag(1)] public int folder_id; - /// New order of pinned dialogs [IfFlag(0)] public DialogPeerBase[] order; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_order = 0x1, - /// Field has a value - has_folder_id = 0x2, - } } - /// A new incoming event; for bots only See + ///See [TLDef(0x8317C0C3)] - public sealed partial class UpdateBotWebhookJSON : Update - { - /// The event - public DataJSON data; - } - /// A new incoming query; for bots only See + public partial class UpdateBotWebhookJSON : Update { public DataJSON data; } + ///See [TLDef(0x9B9240A6)] - public sealed partial class UpdateBotWebhookJSONQuery : Update + public partial class UpdateBotWebhookJSONQuery : Update { - /// Query identifier public long query_id; - /// Query data public DataJSON data; - /// Query timeout public int timeout; } - /// This object contains information about an incoming shipping query. See + ///See [TLDef(0xB5AEFD7D)] - public sealed partial class UpdateBotShippingQuery : Update + public partial class UpdateBotShippingQuery : Update { - /// Unique query identifier public long query_id; - /// User who sent the query public long user_id; - /// Bot specified invoice payload public byte[] payload; - /// User specified shipping address public PostAddress shipping_address; } - /// This object contains information about an incoming pre-checkout query. See + ///See [TLDef(0x8CAA9A96)] - public sealed partial class UpdateBotPrecheckoutQuery : Update + public partial class UpdateBotPrecheckoutQuery : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_info = 0x1, has_shipping_option_id = 0x2 } public Flags flags; - /// Unique query identifier public long query_id; - /// User who sent the query public long user_id; - /// Bot specified invoice payload public byte[] payload; - /// Order info provided by the user [IfFlag(0)] public PaymentRequestedInfo info; - /// Identifier of the shipping option chosen by the user [IfFlag(1)] public string shipping_option_id; - /// Three-letter ISO 4217 currency code, or XTR for Telegram Stars. public string currency; - /// Total amount 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). public long total_amount; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_info = 0x1, - /// Field has a value - has_shipping_option_id = 0x2, - } } - /// An incoming phone call See + ///See [TLDef(0xAB0F6B1E)] - public sealed partial class UpdatePhoneCall : Update - { - /// Phone call - public PhoneCallBase phone_call; - } - /// A language pack has changed, the client should manually fetch the changed strings using Langpack_GetDifference See + public partial class UpdatePhoneCall : Update { public PhoneCallBase phone_call; } + ///See [TLDef(0x46560264)] - public sealed partial class UpdateLangPackTooLong : Update - { - /// Language code - public string lang_code; - } - /// Language pack updated See + public partial class UpdateLangPackTooLong : Update { public string lang_code; } + ///See [TLDef(0x56022F4D)] - public sealed partial class UpdateLangPack : Update - { - /// Changed strings - public LangPackDifference difference; - } - /// The list of favorited stickers was changed, the client should call Messages_GetFavedStickers to refetch the new list See + public partial class UpdateLangPack : Update { public LangPackDifference difference; } + ///See [TLDef(0xE511996D)] - public sealed partial class UpdateFavedStickers : Update { } - /// The specified channel/supergroup messages were read (emitted specifically for messages like voice messages or video, only once the media is watched and marked as read using Channels_ReadMessageContents) See - [TLDef(0x25F324F7)] - public sealed partial class UpdateChannelReadMessagesContents : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Channel/supergroup ID - public long channel_id; - /// Forum topic ID. - [IfFlag(0)] public int top_msg_id; - /// If set, the messages were read within the specified monoforum topic ». - [IfFlag(1)] public Peer saved_peer_id; - /// IDs of messages that were read - public int[] messages; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_top_msg_id = 0x1, - /// Field has a value - has_saved_peer_id = 0x2, - } - } - /// All contacts were deleted See + public partial class UpdateFavedStickers : Update { } + ///See + [TLDef(0x44BDD535)] + public partial class UpdateChannelReadMessagesContents : UpdateChannel { public int[] messages; } + ///See [TLDef(0x7084A7BE)] - public sealed partial class UpdateContactsReset : Update { } - /// The history of a channel/supergroup was hidden. See - [TLDef(0xB23FC698, inheritAt = 0)] - public sealed partial class UpdateChannelAvailableMessages : UpdateChannel + public partial class UpdateContactsReset : Update { } + ///See + [TLDef(0xB23FC698)] + public partial class UpdateChannelAvailableMessages : UpdateChannel { public int available_min_id; } + ///See + [TLDef(0xE16459C3)] + public partial class UpdateDialogUnreadMark : Update { - /// Identifier of a maximum unavailable message in a channel due to hidden history. - public int available_min_id; - } - /// The manual unread mark of a chat was changed See - [TLDef(0xB658F23E)] - public sealed partial class UpdateDialogUnreadMark : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { unread = 0x1 } public Flags flags; - /// The dialog public DialogPeerBase peer; - /// If set, the mark is related to the specified monoforum topic ID ». - [IfFlag(1)] public Peer saved_peer_id; - - [Flags] public enum Flags : uint - { - /// Was the chat marked or unmarked as read - unread = 0x1, - /// Field has a value - has_saved_peer_id = 0x2, - } } - /// The results of a poll have changed See + ///See [TLDef(0xACA1657B)] - public sealed partial class UpdateMessagePoll : Update + public partial class UpdateMessagePoll : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_poll = 0x1 } public Flags flags; - /// Poll ID public long poll_id; - /// If the server knows the client hasn't cached this poll yet, the poll itself [IfFlag(0)] public Poll poll; - /// New poll results public PollResults results; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_poll = 0x1, - } } - /// Default banned rights in a normal chat were updated See + ///See [TLDef(0x54C01850)] - public sealed partial class UpdateChatDefaultBannedRights : Update + public partial class UpdateChatDefaultBannedRights : Update { - /// The chat public Peer peer; - /// New default banned rights public ChatBannedRights default_banned_rights; - /// Version public int version; } - /// The peer list of a peer folder was updated See + ///See [TLDef(0x19360DC0)] - public sealed partial class UpdateFolderPeers : Update + public partial class UpdateFolderPeers : Update { - /// New peer list public FolderPeer[] folder_peers; - /// Event count after generation public int pts; - /// Number of events that were generated public int pts_count; - - public override (long, int, int) GetMBox() => (0, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_pts_count); } - /// Settings of a certain peer have changed See + ///See [TLDef(0x6A7E7366)] - public sealed partial class UpdatePeerSettings : Update + public partial class UpdatePeerSettings : Update { - /// The peer public Peer peer; - /// Associated peer settings public PeerSettings settings; } - /// List of peers near you was updated See + ///See [TLDef(0xB4AFCFB0)] - public sealed partial class UpdatePeerLocated : Update - { - /// Geolocated peer list update - public PeerLocatedBase[] peers; - } - /// A message was added to the schedule queue of a chat See + public partial class UpdatePeerLocated : Update { public PeerLocatedBase[] peers; } + ///See [TLDef(0x39A51DFB)] - public sealed partial class UpdateNewScheduledMessage : Update + public partial class UpdateNewScheduledMessage : Update { public MessageBase message; } + ///See + [TLDef(0x90866CEE)] + public partial class UpdateDeleteScheduledMessages : Update { - /// Message - public MessageBase message; - } - /// Some scheduled messages were deleted (or sent) from the schedule queue of a chat See - [TLDef(0xF2A71983)] - public sealed partial class UpdateDeleteScheduledMessages : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Peer public Peer peer; - /// Deleted scheduled messages public int[] messages; - /// If set, this update indicates that some scheduled messages were sent (not simply deleted from the schedule queue).
In this case, the messages field will contain the scheduled message IDs for the sent messages (initially returned in ), and sent_messages will contain the real message IDs for the sent messages.
- [IfFlag(0)] public int[] sent_messages; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_sent_messages = 0x1, - } } - ///
A cloud theme was updated See + ///See [TLDef(0x8216FBA3)] - public sealed partial class UpdateTheme : Update - { - /// Theme - public Theme theme; - } - /// Live geoposition message was viewed See + public partial class UpdateTheme : Update { public Theme theme; } + ///See [TLDef(0x871FB939)] - public sealed partial class UpdateGeoLiveViewed : Update + public partial class UpdateGeoLiveViewed : Update { - /// The user that viewed the live geoposition public Peer peer; - /// Message ID of geoposition message public int msg_id; } - /// A login token (for login via QR code) was accepted. See + ///See [TLDef(0x564FE691)] - public sealed partial class UpdateLoginToken : Update { } - /// A specific peer has voted in a poll See - [TLDef(0x24F40E77)] - public sealed partial class UpdateMessagePollVote : Update + public partial class UpdateLoginToken : Update { } + ///See + [TLDef(0x106395C9)] + public partial class UpdateMessagePollVote : Update { - /// Poll ID public long poll_id; - /// The peer that voted in the poll - public Peer peer; - /// Chosen option(s) + public long user_id; public byte[][] options; - /// New qts value, see updates » for more info. public int qts; - - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; } - /// A new folder was added See + ///See [TLDef(0x26FFDE7D)] - public sealed partial class UpdateDialogFilter : Update + public partial class UpdateDialogFilter : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_filter = 0x1 } public Flags flags; - /// Folder ID public int id; - /// Folder info - [IfFlag(0)] public DialogFilterBase filter; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_filter = 0x1, - } + [IfFlag(0)] public DialogFilter filter; } - /// New folder order See + ///See [TLDef(0xA5D72105)] - public sealed partial class UpdateDialogFilterOrder : Update - { - /// Ordered folder IDs - public int[] order; - } - /// Clients should update folder info See + public partial class UpdateDialogFilterOrder : Update { public int[] order; } + ///See [TLDef(0x3504914F)] - public sealed partial class UpdateDialogFilters : Update { } - /// Incoming phone call signaling payload See + public partial class UpdateDialogFilters : Update { } + ///See [TLDef(0x2661BF09)] - public sealed partial class UpdatePhoneCallSignalingData : Update + public partial class UpdatePhoneCallSignalingData : Update { - /// Phone call ID public long phone_call_id; - /// Signaling payload public byte[] data; } - /// The forward counter of a message in a channel has changed See - [TLDef(0xD29A27F4, inheritAt = 0)] - public sealed partial class UpdateChannelMessageForwards : UpdateChannel + ///See + [TLDef(0xD29A27F4)] + public partial class UpdateChannelMessageForwards : UpdateChannel { - /// ID of the message public int id; - /// New forward counter public int forwards; } - /// Incoming comments in a discussion thread were marked as read See + ///See [TLDef(0xD6B19546)] - public sealed partial class UpdateReadChannelDiscussionInbox : Update + public partial class UpdateReadChannelDiscussionInbox : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_broadcast_id = 0x1 } public Flags flags; - /// Discussion group ID public long channel_id; - /// ID of the group message that started the thread (message in linked discussion group) public int top_msg_id; - /// Message ID of latest read incoming message for this thread public int read_max_id; - /// If set, contains the ID of the channel that contains the post that started the comment thread in the discussion group (channel_id) [IfFlag(0)] public long broadcast_id; - /// If set, contains the ID of the channel post that started the comment thread [IfFlag(0)] public int broadcast_post; - - [Flags] public enum Flags : uint - { - /// Fields and have a value - has_broadcast_id = 0x1, - } } - /// Outgoing comments in a discussion thread were marked as read See + ///See [TLDef(0x695C9E7C)] - public sealed partial class UpdateReadChannelDiscussionOutbox : Update + public partial class UpdateReadChannelDiscussionOutbox : Update { - /// Supergroup ID public long channel_id; - /// ID of the group message that started the thread public int top_msg_id; - /// Message ID of latest read outgoing message for this thread public int read_max_id; } - /// We blocked a peer, see here » for more info on blocklists. See - [TLDef(0xEBE07752)] - public sealed partial class UpdatePeerBlocked : Update + ///See + [TLDef(0x246A4B22)] + public partial class UpdatePeerBlocked : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The (un)blocked peer public Peer peer_id; - - [Flags] public enum Flags : uint - { - /// Whether the peer was blocked or unblocked - blocked = 0x1, - /// Whether the peer was added/removed to/from the story blocklist; if not set, this update affects the main blocklist, see here » for more info. - blocked_my_stories_from = 0x2, - } + public bool blocked; } - /// A user is typing in a supergroup, channel or message thread See + ///See [TLDef(0x8C88C923)] - public sealed partial class UpdateChannelUserTyping : Update + public partial class UpdateChannelUserTyping : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_top_msg_id = 0x1 } public Flags flags; - /// Channel ID public long channel_id; - /// Thread ID [IfFlag(0)] public int top_msg_id; - /// The peer that is typing public Peer from_id; - /// Whether the user is typing, sending a media or doing something else public SendMessageAction action; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_top_msg_id = 0x1, - } } - /// Some messages were pinned in a chat See + ///See [TLDef(0xED85EAB5)] - public sealed partial class UpdatePinnedMessages : Update + public partial class UpdatePinnedMessages : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { pinned = 0x1 } public Flags flags; - /// Peer public Peer peer; - /// Message IDs public int[] messages; - /// Event count after generation public int pts; - /// Number of events that were generated public int pts_count; - - [Flags] public enum Flags : uint - { - /// Whether the messages were pinned or unpinned - pinned = 0x1, - } - - public override (long, int, int) GetMBox() => (0, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_pts_count); } - /// Messages were pinned/unpinned in a channel/supergroup See + ///See [TLDef(0x5BB98608)] - public sealed partial class UpdatePinnedChannelMessages : Update + public partial class UpdatePinnedChannelMessages : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { pinned = 0x1 } public Flags flags; - /// Channel ID public long channel_id; - /// Messages public int[] messages; - /// Event count after generation public int pts; - /// Number of events that were generated public int pts_count; - - [Flags] public enum Flags : uint - { - /// Whether the messages were pinned or unpinned - pinned = 0x1, - } - - public override (long, int, int) GetMBox() => (channel_id, pts, pts_count); - public override void SetPTS(int new_pts, int new_pts_count) => (pts, pts_count) = (new_pts, new_pts_count); } - /// Chat ( and/or ) information was updated. See + ///See [TLDef(0xF89A6A4E)] - public partial class UpdateChat : Update - { - /// Chat ID - public long chat_id; - } - /// The participant list of a certain group call has changed See + public partial class UpdateChat : Update { public long chat_id; } + ///See [TLDef(0xF2EBDB4E)] - public sealed partial class UpdateGroupCallParticipants : Update + public partial class UpdateGroupCallParticipants : Update { - /// Group call - public InputGroupCallBase call; - /// New participant list + public InputGroupCall call; public GroupCallParticipant[] participants; - /// Version public int version; } - /// A new groupcall was started See - [TLDef(0x9D2216E0)] - public sealed partial class UpdateGroupCall : Update + ///See + [TLDef(0x14B24500)] + public partial class UpdateGroupCall : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - [IfFlag(1)] public Peer peer; - /// Info about the group call or livestream - public GroupCallBase call; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_peer = 0x2, - live_story = 0x4, - } - } - /// The Time-To-Live for messages sent by the current user in a specific chat has changed See - [TLDef(0xBB9BB9A5)] - public sealed partial class UpdatePeerHistoryTTL : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The chat - public Peer peer; - /// The new Time-To-Live - [IfFlag(0)] public int ttl_period; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_ttl_period = 0x1, - } - } - /// A user has joined or left a specific chat See - [TLDef(0xD087663A)] - public sealed partial class UpdateChatParticipant : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Chat ID public long chat_id; - /// When did this event occur - public DateTime date; - /// User that triggered the change (inviter, admin that kicked the user, or the even the user_id itself) - public long actor_id; - /// User that was affected by the change - public long user_id; - /// Previous participant info (empty if this participant just joined) - [IfFlag(0)] public ChatParticipantBase prev_participant; - /// New participant info (empty if this participant just left) - [IfFlag(1)] public ChatParticipantBase new_participant; - /// The invite that was used to join the group - [IfFlag(2)] public ExportedChatInvite invite; - /// New qts value, see updates » for more info. - public int qts; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_prev_participant = 0x1, - /// Field has a value - has_new_participant = 0x2, - /// Field has a value - has_invite = 0x4, - } - - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; + public GroupCallBase call; } - /// A participant has left, joined, was banned or admined in a channel or supergroup. See - [TLDef(0x985D3ABB)] - public sealed partial class UpdateChannelParticipant : Update + ///See + [TLDef(0xBB9BB9A5)] + public partial class UpdatePeerHistoryTTL : Update { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_ttl_period = 0x1 } public Flags flags; - /// Channel ID - public long channel_id; - /// Date of the event - public DateTime date; - /// User that triggered the change (inviter, admin that kicked the user, or the even the user_id itself) - public long actor_id; - /// User that was affected by the change - public long user_id; - /// Previous participant status - [IfFlag(0)] public ChannelParticipantBase prev_participant; - /// New participant status - [IfFlag(1)] public ChannelParticipantBase new_participant; - /// Chat invite used to join the channel/supergroup - [IfFlag(2)] public ExportedChatInvite invite; - /// New qts value, see updates » for more info. - public int qts; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_prev_participant = 0x1, - /// Field has a value - has_new_participant = 0x2, - /// Field has a value - has_invite = 0x4, - /// Whether the participant joined using a chat folder deep link ». - via_chatlist = 0x8, - } - - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; - } - /// A bot was stopped or re-started. See - [TLDef(0xC4870A49)] - public sealed partial class UpdateBotStopped : Update - { - /// The user ID - public long user_id; - /// When did this action occur - public DateTime date; - /// Whether the bot was stopped or started - public bool stopped; - /// New qts value, see updates » for more info. - public int qts; - - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; - } - /// New WebRTC parameters See - [TLDef(0x0B783982)] - public sealed partial class UpdateGroupCallConnection : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// WebRTC parameters - public DataJSON params_; - - [Flags] public enum Flags : uint - { - /// Are these parameters related to the screen capture session currently in progress? - presentation = 0x1, - } - } - /// The command set of a certain bot in a certain chat has changed. See - [TLDef(0x4D712F2E)] - public sealed partial class UpdateBotCommands : Update - { - /// The affected chat public Peer peer; - /// ID of the bot that changed its command set + [IfFlag(0)] public int ttl_period; + } + ///See + [TLDef(0xD087663A)] + public partial class UpdateChatParticipant : Update + { + [Flags] public enum Flags { has_prev_participant = 0x1, has_new_participant = 0x2, has_invite = 0x4 } + public Flags flags; + public long chat_id; + public DateTime date; + public long actor_id; + public long user_id; + [IfFlag(0)] public ChatParticipantBase prev_participant; + [IfFlag(1)] public ChatParticipantBase new_participant; + [IfFlag(2)] public ExportedChatInvite invite; + public int qts; + } + ///See + [TLDef(0x985D3ABB)] + public partial class UpdateChannelParticipant : Update + { + [Flags] public enum Flags { has_prev_participant = 0x1, has_new_participant = 0x2, has_invite = 0x4 } + public Flags flags; + public long channel_id; + public DateTime date; + public long actor_id; + public long user_id; + [IfFlag(0)] public ChannelParticipantBase prev_participant; + [IfFlag(1)] public ChannelParticipantBase new_participant; + [IfFlag(2)] public ExportedChatInvite invite; + public int qts; + } + ///See + [TLDef(0xC4870A49)] + public partial class UpdateBotStopped : Update + { + public long user_id; + public DateTime date; + public bool stopped; + public int qts; + } + ///See + [TLDef(0x0B783982)] + public partial class UpdateGroupCallConnection : Update + { + [Flags] public enum Flags { presentation = 0x1 } + public Flags flags; + public DataJSON params_; + } + ///See + [TLDef(0x4D712F2E)] + public partial class UpdateBotCommands : Update + { + public Peer peer; public long bot_id; - /// New bot commands public BotCommand[] commands; } - /// Someone has requested to join a chat or channel See - [TLDef(0x7063C3DB)] - public sealed partial class UpdatePendingJoinRequests : Update - { - /// Chat or channel - public Peer peer; - /// Number of pending join requests » for the chat or channel - public int requests_pending; - /// IDs of users that have recently requested to join - public long[] recent_requesters; - } - /// Someone has requested to join a chat or channel (bots only, users will receive an , instead) See - [TLDef(0x11DFA986)] - public sealed partial class UpdateBotChatInviteRequester : Update - { - /// The chat or channel in question - public Peer peer; - /// When was the join request » made - public DateTime date; - /// The user ID that is asking to join the chat or channel - public long user_id; - /// Bio of the user - public string about; - /// Chat invite link that was used by the user to send the join request » - public ExportedChatInvite invite; - /// QTS event sequence identifier - public int qts; - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; - } - /// New message reactions » are available See - [TLDef(0x1E297BFA)] - public sealed partial class UpdateMessageReactions : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Peer - public Peer peer; - /// Message ID - public int msg_id; - /// Forum topic ID - [IfFlag(0)] public int top_msg_id; - /// If set, the reactions are in the specified monoforum topic ». - [IfFlag(1)] public Peer saved_peer_id; - /// Reactions - public MessageReactions reactions; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_top_msg_id = 0x1, - /// Field has a value - has_saved_peer_id = 0x2, - } - } - /// The list of installed attachment menu entries » has changed, use Messages_GetAttachMenuBots to fetch the updated list. See - [TLDef(0x17B7A20B)] - public sealed partial 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 - [TLDef(0x1592B79D)] - public sealed partial class UpdateWebViewResultSent : Update - { - /// Web app interaction ID - public long query_id; - } - /// The menu button behavior for the specified bot has changed See - [TLDef(0x14B85813)] - public sealed partial class UpdateBotMenuButton : Update - { - /// Bot ID - public long bot_id; - /// New menu button - public BotMenuButtonBase button; - } - /// The list of saved notification sounds has changed, use Account_GetSavedRingtones to fetch the new list. See - [TLDef(0x74D8BE99)] - public sealed partial class UpdateSavedRingtones : Update { } - /// A pending voice message transcription » initiated with Messages_TranscribeAudio was updated. See - [TLDef(0x0084CD5A)] - public sealed partial class UpdateTranscribedAudio : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Peer of the transcribed message - public Peer peer; - /// Transcribed message ID - public int msg_id; - /// Transcription ID - public long transcription_id; - /// Transcribed text - public string text; - - [Flags] public enum Flags : uint - { - /// Whether this transcription is still pending and further about it will be sent in the future. - pending = 0x1, - } - } - /// Some featured custom emoji stickers were marked as read See - [TLDef(0xFB4C496C)] - public sealed partial class UpdateReadFeaturedEmojiStickers : Update { } - /// The emoji status of a certain user has changed See - [TLDef(0x28373599, inheritAt = 0)] - public sealed partial class UpdateUserEmojiStatus : UpdateUser - { - /// New emoji status - public EmojiStatusBase emoji_status; - } - /// The list of recent emoji statuses has changed See - [TLDef(0x30F443DB)] - public sealed partial class UpdateRecentEmojiStatuses : Update { } - /// The list of recent message reactions has changed See - [TLDef(0x6F7863F4)] - public sealed partial class UpdateRecentReactions : Update { } - /// A stickerset was just moved to top, see here for more info » See - [TLDef(0x86FCCF85)] - public sealed partial class UpdateMoveStickerSetToTop : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Stickerset ID - public long stickerset; - - [Flags] public enum Flags : uint - { - /// This update is referring to a mask stickerset - masks = 0x1, - /// This update is referring to a custom emoji stickerset - emojis = 0x2, - } - } - /// You bought a paid media »: this update contains the revealed media. See - [TLDef(0xD5A41724)] - public sealed partial class UpdateMessageExtendedMedia : Update - { - /// Peer where the paid media was posted - public Peer peer; - /// ID of the message containing the paid media - public int msg_id; - /// Revealed media, contains only s. - public MessageExtendedMediaBase[] extended_media; - } - /// User ( and/or ) information was updated. See - [TLDef(0x20529438)] - public partial class UpdateUser : Update - { - /// User ID - public long user_id; - } - /// Media autosave settings have changed and must be refetched using Account_GetAutoSaveSettings. See - [TLDef(0xEC05B097)] - public sealed partial class UpdateAutoSaveSettings : Update { } - /// A new story was posted. See - [TLDef(0x75B3B798)] - public sealed partial class UpdateStory : Update - { - /// ID of the poster. - public Peer peer; - /// The story that was posted. - public StoryItemBase story; - } - /// Stories of a specific peer were marked as read. See - [TLDef(0xF74E932B)] - public sealed partial class UpdateReadStories : Update - { - /// The peer - public Peer peer; - /// ID of the last story that was marked as read - public int max_id; - } - /// A story was successfully uploaded. See - [TLDef(0x1BF335B9)] - public sealed partial class UpdateStoryID : Update - { - /// The id that was attributed to the story. - public int id; - /// The random_id that was passed to Stories_SendStory. - public long random_id; - } - /// Indicates that stories stealth mode was activated. See - [TLDef(0x2C084DC1)] - public sealed partial class UpdateStoriesStealthMode : Update - { - /// Information about the current stealth mode session. - public StoriesStealthMode stealth_mode; - } - /// Indicates we reacted to a story ». See - [TLDef(0x7D627683)] - public sealed partial class UpdateSentStoryReaction : Update - { - /// The peer that sent the story - public Peer peer; - /// ID of the story we reacted to - public int story_id; - /// The reaction that was sent - public Reaction reaction; - } - /// A channel/supergroup boost has changed (bots only) See - [TLDef(0x904DD49C)] - public sealed partial class UpdateBotChatBoost : Update - { - /// Channel - public Peer peer; - /// New boost information - public Boost boost; - /// QTS event sequence identifier - public int qts; - - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; - } - /// Users may also choose to display messages from all topics as if they were sent to a normal group, using a "View as messages" setting in the local client.
This setting only affects the current account, and is synced to other logged in sessions using the Channels_ToggleViewForumAsMessages method; invoking this method will update the value of the view_forum_as_messages flag of or and emit an . See
- [TLDef(0x07B68920, inheritAt = 0)] - public sealed partial class UpdateChannelViewForumAsMessages : UpdateChannel - { - /// The new value of the toggle. - public bool enabled; - } - /// The wallpaper » of a given peer has changed. See - [TLDef(0xAE3F101D)] - public sealed partial class UpdatePeerWallpaper : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The peer where the wallpaper has changed. - public Peer peer; - /// The new wallpaper, if none the wallpaper was removed and the default wallpaper should be used. - [IfFlag(0)] public WallPaperBase wallpaper; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_wallpaper = 0x1, - /// Whether the other user has chosen a custom wallpaper for us using Messages_SetChatWallPaper and the for_both flag, see here » for more info. - wallpaper_overridden = 0x2, - } - } - /// Bots only: a user has changed their reactions on a message with public reactions. See - [TLDef(0xAC21D3CE)] - public sealed partial class UpdateBotMessageReaction : Update - { - /// Peer of the reacted-to message. - public Peer peer; - /// ID of the reacted-to message. - public int msg_id; - /// Date of the change. - public DateTime date; - /// The user that (un)reacted to the message. - public Peer actor; - /// Old reactions - public Reaction[] old_reactions; - /// New reactions - public Reaction[] new_reactions; - /// QTS event sequence identifier - public int qts; - - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; - } - /// Bots only: the number of reactions on a message with anonymous reactions has changed. See - [TLDef(0x09CB7759)] - public sealed partial class UpdateBotMessageReactions : Update - { - /// Peer of the reacted-to message. - public Peer peer; - /// ID of the reacted-to message. - public int msg_id; - /// Date of the change. - public DateTime date; - /// New reaction counters. - public ReactionCount[] reactions; - /// QTS event sequence identifier - public int qts; - - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; - } - /// A saved message dialog was pinned/unpinned See - [TLDef(0xAEAF9E74)] - public sealed partial class UpdateSavedDialogPinned : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The dialog - public DialogPeerBase peer; - - [Flags] public enum Flags : uint - { - /// Whether the dialog was pinned - pinned = 0x1, - } - } - /// Pinned saved dialogs » were updated See - [TLDef(0x686C85A6)] - public sealed partial class UpdatePinnedSavedDialogs : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// New order of pinned saved dialogs - [IfFlag(0)] public DialogPeerBase[] order; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_order = 0x1, - } - } - /// The list of reaction tag » names assigned by the user has changed and should be refetched using Messages_GetSavedReactionTags. See - [TLDef(0x39C67432)] - public sealed partial class UpdateSavedReactionTags : Update { } - /// A new SMS job was received See - [TLDef(0xF16269D4)] - public sealed partial class UpdateSmsJob : Update - { - /// SMS job ID - public string job_id; - } - /// Info about or the order of quick reply shortcuts » was changed. See - [TLDef(0xF9470AB2)] - public sealed partial class UpdateQuickReplies : Update - { - /// New quick reply shortcut order and information. - public QuickReply[] quick_replies; - } - /// A new quick reply shortcut » was created. See - [TLDef(0xF53DA717)] - public sealed partial class UpdateNewQuickReply : Update - { - /// Quick reply shortcut. - public QuickReply quick_reply; - } - /// A quick reply shortcut » was deleted. This will not emit updates, even if all the messages in the shortcut are also deleted by this update. See - [TLDef(0x53E6F1EC)] - public partial class UpdateDeleteQuickReply : Update - { - /// ID of the quick reply shortcut that was deleted. - public int shortcut_id; - } - /// A new message was added to a quick reply shortcut ». See - [TLDef(0x3E050D0F)] - public sealed partial class UpdateQuickReplyMessage : Update - { - /// The message that was added (the .quick_reply_shortcut_id field will contain the shortcut ID). - public MessageBase message; - } - /// One or more messages in a quick reply shortcut » were deleted. See - [TLDef(0x566FE7CD, inheritAt = 0)] - public sealed partial class UpdateDeleteQuickReplyMessages : UpdateDeleteQuickReply - { - /// IDs of the deleted messages. - public int[] messages; - } - /// Connecting or disconnecting a business bot or changing the connection settings will emit an update to the bot, with the new settings and a connection_id that will be used by the bot to handle updates from and send messages as the user. See - [TLDef(0x8AE5C97A)] - public sealed partial class UpdateBotBusinessConnect : Update - { - /// Business connection settings - public BotBusinessConnection connection; - /// New qts value, see updates » for more info. - public int qts; - - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; - } - /// A message was received via a connected business chat ». See - [TLDef(0x9DDB347C)] - public sealed partial class UpdateBotNewBusinessMessage : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Connection ID. - public string connection_id; - /// New message. - public MessageBase message; - /// The message that message is replying to. - [IfFlag(0)] public MessageBase reply_to_message; - /// New qts value, see updates » for more info. - public int qts; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_reply_to_message = 0x1, - } - - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; - } - /// A message was edited in a connected business chat ». See - [TLDef(0x07DF587C)] - public sealed partial class UpdateBotEditBusinessMessage : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Business connection ID - public string connection_id; - /// New message. - public MessageBase message; - /// The message that message is replying to. - [IfFlag(0)] public MessageBase reply_to_message; - /// New qts value, see updates » for more info. - public int qts; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_reply_to_message = 0x1, - } - - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; - } - /// A message was deleted in a connected business chat ». See - [TLDef(0xA02A982E)] - public sealed partial class UpdateBotDeleteBusinessMessage : Update - { - /// Business connection ID. - public string connection_id; - /// Peer where the messages were deleted. - public Peer peer; - /// IDs of the messages that were deleted. - public int[] messages; - /// New qts value, see updates » for more info. - public int qts; - - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; - } - /// Represents a new reaction to a story. See - [TLDef(0x1824E40B)] - public sealed partial class UpdateNewStoryReaction : Update - { - /// Story ID. - public int story_id; - /// The peer where the story was posted. - public Peer peer; - /// The reaction. - public Reaction reaction; - } - /// The current account's Telegram Stars balance » has changed. See - [TLDef(0x4E80A379)] - public sealed partial class UpdateStarsBalance : Update - { - /// New balance. - public StarsAmountBase balance; - } - /// A callback button sent via a business connection was pressed, and the button data was sent to the bot that created the button. See - [TLDef(0x1EA2FDA7)] - public sealed partial class UpdateBusinessBotCallbackQuery : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Query ID - public long query_id; - /// ID of the user that pressed the button - public long user_id; - /// Business connection ID - public string connection_id; - /// Message that contains the keyboard (also contains info about the chat where the message was sent). - public MessageBase message; - /// The message that message is replying to. - [IfFlag(2)] public MessageBase reply_to_message; - /// Global identifier, uniquely corresponding to the chat to which the message with the callback button was sent. Useful for high scores in games. - public long chat_instance; - /// Callback data - [IfFlag(0)] public byte[] data; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_data = 0x1, - /// Field has a value - has_reply_to_message = 0x4, - } - } - /// The Telegram Star balance of a channel/bot we own has changed ». See - [TLDef(0xA584B019)] - public sealed partial class UpdateStarsRevenueStatus : Update - { - /// Channel/bot - public Peer peer; - /// New Telegram Star balance. - public StarsRevenueStatus status; - } - /// Bots only: a user has purchased a paid media. See - [TLDef(0x283BD312)] - public sealed partial class UpdateBotPurchasedPaidMedia : Update - { - /// The user that bought the media - public long user_id; - /// Payload passed by the bot in .payload - public string payload; - /// New qts value, see updates » for more info. - public int qts; - - public override (long, int, int) GetMBox() => (-1, qts, 1); - public override void SetPTS(int new_qts, int _) => qts = new_qts; - } - /// Contains the current default paid reaction privacy, see here » for more info. See - [TLDef(0x8B725FCE)] - public sealed partial class UpdatePaidReactionPrivacy : Update - { - /// Paid reaction privacy settings. - public PaidReactionPrivacy private_; - } - /// A paid login SMS code was successfully sent. See - [TLDef(0x504AA18F)] - public sealed partial class UpdateSentPhoneCode : Update - { - /// Info about the sent code. - public Auth_SentCodeBase sent_code; - } - /// Contains updates to the blockchain of a conference call, see here » for more info. See - [TLDef(0xA477288F)] - public sealed partial class UpdateGroupCallChainBlocks : Update - { - /// The conference call. - public InputGroupCallBase call; - /// Subchain ID. - public int sub_chain_id; - /// Blocks. - public byte[][] blocks; - /// Offset of the next block. - public int next_offset; - } - /// Incoming messages in a monoforum topic were read See - [TLDef(0x77B0E372)] - public sealed partial class UpdateReadMonoForumInbox : Update - { - /// ID of the monoforum. - public long channel_id; - /// Topic ID. - public Peer saved_peer_id; - /// Position up to which all incoming messages are read. - public int read_max_id; - } - /// Outgoing messages in a monoforum were read. See - [TLDef(0xA4A79376)] - public sealed partial class UpdateReadMonoForumOutbox : Update - { - /// ID of the monoforum. - public long channel_id; - /// Topic ID. - public Peer saved_peer_id; - /// Position up to which all outgoing messages are read. - public int read_max_id; - } - /// An admin has (un)exempted this monoforum topic » from payment to send messages using Account_ToggleNoPaidMessagesException. See - [TLDef(0x9F812B08)] - public sealed partial class UpdateMonoForumNoPaidException : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The monoforum ID. - public long channel_id; - /// The peer/topic ID. - public Peer saved_peer_id; - - [Flags] public enum Flags : uint - { - /// If set, an admin has exempted this peer, otherwise the peer was unexempted. - exception = 0x1, - } - } - /// See - [TLDef(0xD8326F0D)] - public sealed partial class UpdateGroupCallMessage : Update - { - public InputGroupCallBase call; - public GroupCallMessage message; - } - /// See - [TLDef(0xC957A766)] - public sealed partial class UpdateGroupCallEncryptedMessage : Update - { - public InputGroupCallBase call; - public Peer from_id; - public byte[] encrypted_message; - } - /// See - [TLDef(0x683B2C52)] - public sealed partial class UpdatePinnedForumTopic : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - public Peer peer; - public int topic_id; - - [Flags] public enum Flags : uint - { - pinned = 0x1, - } - } - /// See - [TLDef(0xDEF143D0)] - public sealed partial class UpdatePinnedForumTopics : Update - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - public Peer peer; - [IfFlag(0)] public int[] order; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_order = 0x1, - } - } - /// See - [TLDef(0x3E85E92C)] - public sealed partial class UpdateDeleteGroupCallMessages : Update - { - public InputGroupCallBase call; - public int[] messages; - } - /// See - [TLDef(0x48E246C2)] - public sealed partial class UpdateStarGiftAuctionState : Update - { - public long gift_id; - public StarGiftAuctionStateBase state; - } - /// See - [TLDef(0xDC58F31E)] - public sealed partial class UpdateStarGiftAuctionUserState : Update - { - public long gift_id; - public StarGiftAuctionUserState user_state; - } - /// See - [TLDef(0xFB9C547A)] - public sealed partial class UpdateEmojiGameInfo : Update - { - public Messages_EmojiGameInfo info; - } - /// See - [TLDef(0xAC072444)] - public sealed partial class UpdateStarGiftCraftFail : Update { } - /// See - [TLDef(0xBD8367B9, inheritAt = 0)] - public sealed partial class UpdateChatParticipantRank : UpdateChat - { - public long user_id; - public string rank; - public int version; - } - - /// Updates state. See + ///See [TLDef(0xA56C2A3E)] - public sealed partial class Updates_State : IObject + public partial class Updates_State : ITLObject { - /// Number of events occurred in a text box public int pts; - /// Position in a sequence of updates in secret chats. For further details refer to article secret chats public int qts; - /// Date of condition public DateTime date; - /// Number of sent updates public int seq; - /// Number of unread messages public int unread_count; } - /// Occurred changes. See Derived classes: , , , - public abstract partial class Updates_DifferenceBase : IObject, IPeerResolver - { - /// List of new messages - public virtual MessageBase[] NewMessages => default; - /// List of new encrypted secret chat messages - public virtual EncryptedMessageBase[] NewEncryptedMessages => default; - /// List of updates - public virtual Update[] OtherUpdates => default; - /// returns a or for the given Peer - public abstract IPeerInfo UserOrChat(Peer peer); - } - /// No events. See + ///See + public abstract partial class Updates_DifferenceBase : ITLObject { } + ///See [TLDef(0x5D75A138)] - public sealed partial class Updates_DifferenceEmpty : Updates_DifferenceBase, IPeerResolver + public partial class Updates_DifferenceEmpty : Updates_DifferenceBase { - /// Current date public DateTime date; - /// Number of sent updates public int seq; - - public override MessageBase[] NewMessages => []; - public override EncryptedMessageBase[] NewEncryptedMessages => []; - public override Update[] OtherUpdates => []; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => null; } - /// Full list of occurred events. See + ///See [TLDef(0x00F49CA0)] - public sealed partial class Updates_Difference : Updates_DifferenceBase, IPeerResolver + public partial class Updates_Difference : Updates_DifferenceBase { - /// List of new messages public MessageBase[] new_messages; - /// List of new encrypted secret chat messages public EncryptedMessageBase[] new_encrypted_messages; - /// List of updates public Update[] other_updates; - /// List of chats mentioned in events - public Dictionary chats; - /// List of users mentioned in events - public Dictionary users; - /// Current state + public ChatBase[] chats; + public UserBase[] users; public Updates_State state; - - /// List of new messages - public override MessageBase[] NewMessages => new_messages; - /// List of new encrypted secret chat messages - public override EncryptedMessageBase[] NewEncryptedMessages => new_encrypted_messages; - /// List of updates - public override Update[] OtherUpdates => other_updates; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); } - /// Incomplete list of occurred events. See + ///See [TLDef(0xA8FB1981)] - public sealed partial class Updates_DifferenceSlice : Updates_DifferenceBase, IPeerResolver + public partial class Updates_DifferenceSlice : Updates_DifferenceBase { - /// List of new messages public MessageBase[] new_messages; - /// New messages from the encrypted event sequence public EncryptedMessageBase[] new_encrypted_messages; - /// List of updates public Update[] other_updates; - /// List of chats mentioned in events - public Dictionary chats; - /// List of users mentioned in events - public Dictionary users; - /// Intermediary state + public ChatBase[] chats; + public UserBase[] users; public Updates_State intermediate_state; - - /// List of new messages - public override MessageBase[] NewMessages => new_messages; - /// New messages from the encrypted event sequence - public override EncryptedMessageBase[] NewEncryptedMessages => new_encrypted_messages; - /// List of updates - public override Update[] OtherUpdates => other_updates; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); } - /// The difference is too long, and the specified state must be used to refetch updates. See + ///See [TLDef(0x4AFE8F6D)] - public sealed partial class Updates_DifferenceTooLong : Updates_DifferenceBase, IPeerResolver - { - /// The new state to use. - public int pts; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => null; - } + public partial class Updates_DifferenceTooLong : Updates_DifferenceBase { public int pts; } - /// 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 - public virtual DateTime Date => default; - /// returns a or for the given Peer - public abstract IPeerInfo UserOrChat(Peer peer); - } - /// Too many updates, it is necessary to execute Updates_GetDifference. See + ///See + public abstract partial class UpdatesBase : ITLObject { } + ///See [TLDef(0xE317AF7E)] - public sealed partial class UpdatesTooLong : UpdatesBase, IPeerResolver - { - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => null; - } - /// Info about a message sent to (received from) another user See + public partial class UpdatesTooLong : UpdatesBase { } + ///See [TLDef(0x313BC7F8)] - public sealed partial class UpdateShortMessage : UpdatesBase, IPeerResolver + public partial class UpdateShortMessage : UpdatesBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { out_ = 0x2, has_fwd_from = 0x4, has_reply_to = 0x8, mentioned = 0x10, media_unread = 0x20, + has_entities = 0x80, has_via_bot_id = 0x800, silent = 0x2000, has_ttl_period = 0x2000000 } public Flags flags; - /// The message ID public int id; - /// The ID of the sender (if outgoing will be the ID of the destination) of the message public long user_id; - /// The message public string message; - /// PTS public int pts; - /// PTS count public int pts_count; - /// date public DateTime date; - /// Info about a forwarded message [IfFlag(2)] public MessageFwdHeader fwd_from; - /// Info about the inline bot used to generate this message [IfFlag(11)] public long via_bot_id; - /// Reply and thread information - [IfFlag(3)] public MessageReplyHeaderBase reply_to; - /// Entities for styled text + [IfFlag(3)] public MessageReplyHeader reply_to; [IfFlag(7)] public MessageEntity[] entities; - /// Time To Live of the message, once message.date+message.ttl_period === time(), the message will be deleted on the server, and must be deleted locally as well. [IfFlag(25)] public int ttl_period; - - [Flags] public enum Flags : uint - { - /// Whether the message is outgoing - out_ = 0x2, - /// Field has a value - has_fwd_from = 0x4, - /// Field has a value - has_reply_to = 0x8, - /// Whether we were mentioned in the message - mentioned = 0x10, - /// Whether there are some unread mentions in this message - media_unread = 0x20, - /// Field has a value - has_entities = 0x80, - /// Field has a value - has_via_bot_id = 0x800, - /// If true, the message is a silent message, no notifications should be triggered - silent = 0x2000, - /// Field has a value - has_ttl_period = 0x2000000, - } - - /// date - public override DateTime Date => date; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => null; } - /// Shortened constructor containing info on one new incoming text message from a chat See + ///See [TLDef(0x4D6DEEA5)] - public sealed partial class UpdateShortChatMessage : UpdatesBase, IPeerResolver + public partial class UpdateShortChatMessage : UpdatesBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { out_ = 0x2, has_fwd_from = 0x4, has_reply_to = 0x8, mentioned = 0x10, media_unread = 0x20, + has_entities = 0x80, has_via_bot_id = 0x800, silent = 0x2000, has_ttl_period = 0x2000000 } public Flags flags; - /// ID of the message public int id; - /// ID of the sender of the message public long from_id; - /// ID of the chat where the message was sent public long chat_id; - /// Message public string message; - /// PTS public int pts; - /// PTS count public int pts_count; - /// date public DateTime date; - /// Info about a forwarded message [IfFlag(2)] public MessageFwdHeader fwd_from; - /// Info about the inline bot used to generate this message [IfFlag(11)] public long via_bot_id; - /// Reply (thread) information - [IfFlag(3)] public MessageReplyHeaderBase reply_to; - /// Entities for styled text + [IfFlag(3)] public MessageReplyHeader reply_to; [IfFlag(7)] public MessageEntity[] entities; - /// Time To Live of the message, once updateShortChatMessage.date+updateShortChatMessage.ttl_period === time(), the message will be deleted on the server, and must be deleted locally as well. [IfFlag(25)] public int ttl_period; - - [Flags] public enum Flags : uint - { - /// Whether the message is outgoing - out_ = 0x2, - /// Field has a value - has_fwd_from = 0x4, - /// Field has a value - has_reply_to = 0x8, - /// Whether we were mentioned in this message - mentioned = 0x10, - /// Whether the message contains some unread mentions - media_unread = 0x20, - /// Field has a value - has_entities = 0x80, - /// Field has a value - has_via_bot_id = 0x800, - /// If true, the message is a silent message, no notifications should be triggered - silent = 0x2000, - /// Field has a value - has_ttl_period = 0x2000000, - } - - /// date - public override DateTime Date => date; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => null; } - /// Shortened constructor containing info on one update not requiring auxiliary data See + ///See [TLDef(0x78D4DEC1)] - public sealed partial class UpdateShort : UpdatesBase, IPeerResolver + public partial class UpdateShort : UpdatesBase { - /// Update public Update update; - /// Date of event public DateTime date; - - /// Date of event - public override DateTime Date => date; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => null; } - /// Constructor for a group of updates. See + ///See [TLDef(0x725B04C3)] - public sealed partial class UpdatesCombined : UpdatesBase, IPeerResolver + public partial class UpdatesCombined : UpdatesBase { - /// List of updates public Update[] updates; - /// List of users mentioned in updates - public Dictionary users; - /// List of chats mentioned in updates - public Dictionary chats; - /// Current date + public UserBase[] users; + public ChatBase[] chats; public DateTime date; - /// Value seq for the earliest update in a group public int seq_start; - /// Value seq for the latest update in a group public int seq; - - /// Current date - public override DateTime Date => date; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); } - /// Full constructor of updates See + ///See [TLDef(0x74AE4240)] - public sealed partial class Updates : UpdatesBase, IPeerResolver + public partial class Updates : UpdatesBase { - /// List of updates public Update[] updates; - /// List of users mentioned in updates - public Dictionary users; - /// List of chats mentioned in updates - public Dictionary chats; - /// Current date + public UserBase[] users; + public ChatBase[] chats; public DateTime date; - /// Total number of sent updates public int seq; - - /// Current date - public override DateTime Date => date; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); } - /// Shortened constructor containing info on one outgoing message to a contact (the destination chat has to be extracted from the method call that returned this object). See + ///See [TLDef(0x9015E101)] - public sealed partial class UpdateShortSentMessage : UpdatesBase, IPeerResolver + public partial class UpdateShortSentMessage : UpdatesBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { out_ = 0x2, has_entities = 0x80, has_media = 0x200, has_ttl_period = 0x2000000 } public Flags flags; - /// ID of the sent message public int id; - /// PTS public int pts; - /// PTS count public int pts_count; - /// date public DateTime date; - /// Attached media [IfFlag(9)] public MessageMedia media; - /// Entities for styled text [IfFlag(7)] public MessageEntity[] entities; - /// Time To Live of the message, once message.date+message.ttl_period === time(), the message will be deleted on the server, and must be deleted locally as well. [IfFlag(25)] public int ttl_period; - - [Flags] public enum Flags : uint - { - /// Whether the message is outgoing - out_ = 0x2, - /// Field has a value - has_entities = 0x80, - /// Field has a value - has_media = 0x200, - /// Field has a value - has_ttl_period = 0x2000000, - } - - /// date - public override DateTime Date => date; - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => null; } - /// Full list of photos with auxiliary data. See + ///See [TLDef(0x8DCA6AA5)] - public partial class Photos_Photos : IObject + public partial class Photos_Photos : ITLObject { - /// List of photos public PhotoBase[] photos; - /// List of mentioned users - public Dictionary users; - } - /// Incomplete list of photos with auxiliary data. See - [TLDef(0x15051F54)] - public sealed partial class Photos_PhotosSlice : Photos_Photos - { - /// Total number of photos - public int count; + public UserBase[] users; } + ///See + [TLDef(0x15051F54, inheritAfter = true)] + public partial class Photos_PhotosSlice : Photos_Photos { public int count; } - /// Photo with auxiliary data. See + ///See [TLDef(0x20212CA8)] - public sealed partial class Photos_Photo : IObject + public partial class Photos_Photo : ITLObject { - /// Photo public PhotoBase photo; - /// Users - public Dictionary users; + public UserBase[] users; } - /// Contains info on file. See Derived classes: , - public abstract partial class Upload_FileBase : IObject { } - /// File content. See + ///See + public abstract partial class Upload_FileBase : ITLObject { } + ///See [TLDef(0x096A18D5)] - public sealed partial class Upload_File : Upload_FileBase + public partial class Upload_File : Upload_FileBase { - /// File type public Storage_FileType type; - /// Modification time public int mtime; - /// Binary data, file content public byte[] bytes; } - /// The file must be downloaded from a CDN DC. See + ///See [TLDef(0xF18CDA44)] - public sealed partial class Upload_FileCdnRedirect : Upload_FileBase + public partial class Upload_FileCdnRedirect : Upload_FileBase { - /// CDN DC ID public int dc_id; - /// File token (see CDN files) public byte[] file_token; - /// Encryption key (see CDN files) public byte[] encryption_key; - /// Encryption IV (see CDN files) public byte[] encryption_iv; - /// File hashes (see CDN files) public FileHash[] file_hashes; } - /// Data center See + ///See [TLDef(0x18B7A10D)] - public sealed partial class DcOption : IObject + public partial class DcOption : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { ipv6 = 0x1, media_only = 0x2, tcpo_only = 0x4, cdn = 0x8, static_ = 0x10, has_secret = 0x400 } public Flags flags; - /// DC ID public int id; - /// IP address of DC public string ip_address; - /// Port public int port; - /// If the tcpo_only flag is set, specifies the secret to use when connecting using transport obfuscation [IfFlag(10)] public byte[] secret; - - [Flags] public enum Flags : uint - { - /// Whether the specified IP is an IPv6 address - ipv6 = 0x1, - /// Whether this DC should only be used to download or upload files - media_only = 0x2, - /// Whether this DC only supports connection with transport obfuscation - tcpo_only = 0x4, - /// Whether this is a CDN DC. - cdn = 0x8, - /// If set, this IP should be used when connecting through a proxy - static_ = 0x10, - /// If set, clients must connect using only the specified port, without trying any other port. - this_port_only = 0x20, - /// Field has a value - has_secret = 0x400, - } } - /// Current configuration See - [TLDef(0xCC1A241E)] - public sealed partial class Config : IObject + ///See + [TLDef(0x330B4067)] + public partial class Config : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_tmp_sessions = 0x1, phonecalls_enabled = 0x2, has_suggested_lang_code = 0x4, + default_p2p_contacts = 0x8, preload_featured_stickers = 0x10, ignore_phone_entities = 0x20, revoke_pm_inbox = 0x40, + has_autoupdate_url_prefix = 0x80, blocked_mode = 0x100, has_gif_search_username = 0x200, has_venue_search_username = 0x400, + has_img_search_username = 0x800, has_static_maps_provider = 0x1000, pfs_enabled = 0x2000 } 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 public DateTime expires; - /// Whether we're connected to the test DCs public bool test_mode; - /// ID of the DC that returned the reply public int this_dc; - /// DC IP list public DcOption[] dc_options; - /// Domain name for fetching encrypted DC list from DNS TXT record public string dc_txt_domain_name; - /// Maximum member count for normal groups 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. public int forwarded_count_max; - /// 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; - /// Time without any user activity after which it should be treated offline public int offline_idle_timeout_ms; - /// If we are offline, but were online from some other client in last online_cloud_timeout_ms milliseconds after we had gone offline, then delay offline notification for notify_cloud_delay_ms milliseconds. public int online_cloud_timeout_ms; - /// If we are offline, but online from some other client then delay sending the offline notification for notify_cloud_delay_ms milliseconds. public int notify_cloud_delay_ms; - /// If some other client is online, then delay notification for notification_default_delay_ms milliseconds public int notify_default_delay_ms; - /// Not for client use public int push_chat_period_ms; - /// Not for client use public int push_chat_limit; - /// Only messages with age smaller than the one specified can be edited + public int saved_gifs_limit; public int edit_time_limit; - /// Only channel/supergroup messages with age smaller than the specified can be deleted public int revoke_time_limit; - /// Only private messages with age smaller than the specified can be deleted public int revoke_pm_time_limit; - /// Exponential decay rate for computing top peer rating public int rating_e_decay; - /// Maximum number of recent stickers public int stickers_recent_limit; - /// Indicates that round videos (video notes) and voice messages sent in channels and older than the specified period must be marked as read + public int stickers_faved_limit; public int channels_read_media_period; - /// Temporary passport sessions [IfFlag(0)] public int tmp_sessions; - /// Maximum allowed outgoing ring time in VoIP calls: if the user we're calling doesn't reply within the specified time (in milliseconds), we should hang up the call + public int pinned_dialogs_count_max; + public int pinned_infolder_count_max; public int call_receive_timeout_ms; - /// Maximum allowed incoming ring time in VoIP calls: if the current user doesn't reply within the specified time (in milliseconds), the call will be automatically refused public int call_ring_timeout_ms; - /// VoIP connection timeout: if the instance of libtgvoip on the other side of the call doesn't connect to our instance of libtgvoip within the specified time (in milliseconds), the call must be aborted public int call_connect_timeout_ms; - /// If during a VoIP call a packet isn't received for the specified period of time, the call must be aborted public int call_packet_timeout_ms; - /// The domain to use to parse deep links ». public string me_url_prefix; - /// URL to use to auto-update the current app [IfFlag(7)] public string autoupdate_url_prefix; - /// Username of the bot to use to search for GIFs [IfFlag(9)] public string gif_search_username; - /// Username of the bot to use to search for venues [IfFlag(10)] public string venue_search_username; - /// Username of the bot to use for image search [IfFlag(11)] public string img_search_username; - /// ID of the map provider to use for venues [IfFlag(12)] public string static_maps_provider; - /// Maximum length of caption (length in utf8 codepoints) public int caption_length_max; - /// Maximum length of messages (length in utf8 codepoints) public int message_length_max; - /// DC ID to use to download webfiles public int webfile_dc_id; - /// Suggested language code [IfFlag(2)] public string suggested_lang_code; - /// Language pack version [IfFlag(2)] public int lang_pack_version; - /// Basic language pack version [IfFlag(2)] public int base_lang_pack_version; - /// Default message reaction - [IfFlag(15)] public Reaction reactions_default; - /// Autologin token, click here for more info on URL authorization ». - [IfFlag(16)] public string autologin_token; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_tmp_sessions = 0x1, - /// Fields , and have a value - has_suggested_lang_code = 0x4, - /// Whether the client should use P2P by default for phone calls with contacts - default_p2p_contacts = 0x8, - /// Whether the client should preload featured stickers - preload_featured_stickers = 0x10, - /// Whether incoming private messages can be deleted for both participants - revoke_pm_inbox = 0x40, - /// Field has a value - has_autoupdate_url_prefix = 0x80, - /// Indicates that telegram is probably censored by governments/ISPs in the current region - blocked_mode = 0x100, - /// Field has a value - has_gif_search_username = 0x200, - /// Field has a value - has_venue_search_username = 0x400, - /// Field has a value - has_img_search_username = 0x800, - /// Field has a value - has_static_maps_provider = 0x1000, - /// Whether to forcefully connect using IPv6 , even if the client knows that IPv4 is available. - force_try_ipv6 = 0x4000, - /// Field has a value - has_reactions_default = 0x8000, - /// Field has a value - has_autologin_token = 0x10000, - } } - /// Nearest data center, according to geo-ip. See + ///See [TLDef(0x8E1A1775)] - public sealed partial class NearestDc : IObject + public partial class NearestDc : ITLObject { - /// Country code determined by geo-ip public string country; - /// Number of current data center public int this_dc; - /// Number of nearest data center public int nearest_dc; } - /// An update is available for the application. See - /// a value means help.noAppUpdate + ///See + ///a null value means help.noAppUpdate [TLDef(0xCCBBCE30)] - public sealed partial class Help_AppUpdate : IObject + public partial class Help_AppUpdate : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { can_not_skip = 0x1, has_document = 0x2, has_url = 0x4, has_sticker = 0x8 } public Flags flags; - /// Update ID public int id; - /// New version name public string version; - /// Text description of the update public string text; - /// Message entities for styled text public MessageEntity[] entities; - /// Application binary [IfFlag(1)] public DocumentBase document; - /// Application download URL [IfFlag(2)] public string url; - /// Associated sticker [IfFlag(3)] public DocumentBase sticker; - - [Flags] public enum Flags : uint - { - /// Unskippable, the new info must be shown to the user (with a popup or something else) - can_not_skip = 0x1, - /// Field has a value - has_document = 0x2, - /// Field has a value - has_url = 0x4, - /// Field has a value - has_sticker = 0x8, - } } - /// Text of a text message with an invitation to install Telegram. See + ///See [TLDef(0x18CB9F78)] - public sealed partial class Help_InviteText : IObject - { - /// Text of the message - public string message; - } + public partial class Help_InviteText : ITLObject { public string message; } - /// Object contains info on an encrypted chat. See Derived classes: , , , , - public abstract partial class EncryptedChatBase : IObject - { - /// Chat ID - public virtual int ID => default; - /// Checking sum depending on user ID - public virtual long AccessHash => default; - /// Date of chat creation - public virtual DateTime Date => default; - /// Chat creator ID - public virtual long AdminId => default; - /// ID of second chat participant - public virtual long ParticipantId => default; - } - /// Empty constructor. See + ///See + public abstract partial class EncryptedChatBase : ITLObject { } + ///See [TLDef(0xAB7EC0A0)] - public sealed partial class EncryptedChatEmpty : EncryptedChatBase - { - /// Chat ID - public int id; - - /// Chat ID - public override int ID => id; - } - /// Chat waiting for approval of second participant. See + public partial class EncryptedChatEmpty : EncryptedChatBase { public int id; } + ///See [TLDef(0x66B25953)] - public sealed partial class EncryptedChatWaiting : EncryptedChatBase + public partial class EncryptedChatWaiting : EncryptedChatBase { - /// Chat ID public int id; - /// Checking sum depending on user ID public long access_hash; - /// Date of chat creation public DateTime date; - /// Chat creator ID public long admin_id; - /// ID of second chat participant public long participant_id; - - /// 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 + ///See [TLDef(0x48F1D94C)] - public sealed partial class EncryptedChatRequested : EncryptedChatBase + public partial class EncryptedChatRequested : EncryptedChatBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_folder_id = 0x1 } public Flags flags; - /// Peer folder ID, for more info click here [IfFlag(0)] public int folder_id; - /// Chat ID public int id; - /// Check sum depending on user ID public long access_hash; - /// Chat creation date public DateTime date; - /// Chat creator ID public long admin_id; - /// ID of second chat participant public long participant_id; - /// A = g ^ a mod p, see Wikipedia public byte[] g_a; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_folder_id = 0x1, - } - - /// 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 + ///See [TLDef(0x61F0D4C7)] - public sealed partial class EncryptedChat : EncryptedChatBase + public partial class EncryptedChat : EncryptedChatBase { - /// Chat ID public int id; - /// Check sum dependent on the user ID public long access_hash; - /// Date chat was created public DateTime date; - /// Chat creator ID public long admin_id; - /// ID of the second chat participant public long participant_id; - /// B = g ^ b mod p, if the currently authorized user is the chat's creator,
or A = g ^ a mod p otherwise
See
Wikipedia for more info
public byte[] g_a_or_b; - /// 64-bit fingerprint of received key public long key_fingerprint; - - /// 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 + ///See [TLDef(0x1E1C7C45)] - public sealed partial class EncryptedChatDiscarded : EncryptedChatBase + public partial class EncryptedChatDiscarded : EncryptedChatBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { history_deleted = 0x1 } public Flags flags; - /// Chat ID public int id; - - [Flags] public enum Flags : uint - { - /// Whether both users of this secret chat should also remove all of its messages - history_deleted = 0x1, - } - - /// Chat ID - public override int ID => id; } - /// Creates an encrypted chat. See + ///See [TLDef(0xF141B5E1)] - public sealed partial class InputEncryptedChat : IObject + public partial class InputEncryptedChat : ITLObject { - /// Chat ID public int chat_id; - /// REQUIRED FIELD. See how to obtain it
Checking sum from constructor , or
public long access_hash; } - ///
Encrypted file. See - /// a value means encryptedFileEmpty - [TLDef(0xA8008CD8)] - public sealed partial class EncryptedFile : IObject + ///See + ///a null value means encryptedFileEmpty + [TLDef(0x4A70994C)] + public partial class EncryptedFile : ITLObject { - /// File ID public long id; - /// Checking sum depending on user ID public long access_hash; - /// File size in bytes - public long size; - /// Number of data center + public int size; public int dc_id; - /// 32-bit fingerprint of key used for file encryption public int key_fingerprint; } - /// Object sets encrypted file for attachment See Derived classes: , , - /// a value means inputEncryptedFileEmpty - public abstract partial class InputEncryptedFileBase : IObject - { - /// Random file ID created by client - public abstract long ID { get; set; } - } - /// Sets new encrypted file saved by parts using upload.saveFilePart method. See + ///See + ///a null value means inputEncryptedFileEmpty + public abstract partial class InputEncryptedFileBase : ITLObject { } + ///See [TLDef(0x64BD0306)] - public sealed partial class InputEncryptedFileUploaded : InputEncryptedFileBase + public partial class InputEncryptedFileUploaded : InputEncryptedFileBase { - /// Random file ID created by client public long id; - /// Number of saved parts public int parts; - /// In case md5-HASH of the (already encrypted) file was transmitted, file content will be checked prior to use - public string md5_checksum; - /// 32-bit fingerprint of the key used to encrypt a file + public byte[] md5_checksum; public int key_fingerprint; - - /// Random file ID created by client - public override long ID { get => id; set => id = value; } } - /// Sets forwarded encrypted file for attachment. See + ///See [TLDef(0x5A17B5E5)] - public sealed partial class InputEncryptedFile : InputEncryptedFileBase + public partial class InputEncryptedFile : InputEncryptedFileBase { - /// 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
public long access_hash; - - /// File ID, value of id parameter from - public override long ID { get => id; set => id = value; } } - ///
Assigns a new big encrypted file (over 10 MB in size), saved in parts using the method Upload_SaveBigFilePart. See + ///See [TLDef(0x2DC173C8)] - public sealed partial class InputEncryptedFileBigUploaded : InputEncryptedFileBase + public partial class InputEncryptedFileBigUploaded : InputEncryptedFileBase { - /// Random file id, created by the client public long id; - /// Number of saved parts public int parts; - /// 32-bit imprint of the key used to encrypt the file public int key_fingerprint; - - /// Random file id, created by the client - public override long ID { get => id; set => id = value; } } - /// Object contains encrypted message. See Derived classes: , - public abstract partial class EncryptedMessageBase : IObject - { - /// Random message ID, assigned by the author of message - public virtual long RandomId => default; - /// ID of encrypted chat - public virtual int ChatId => default; - /// Date of sending - public virtual DateTime Date => default; - /// TL-serialization of type, encrypted with the key created at chat initialization - public virtual byte[] Bytes => default; - } - /// Encrypted message. See + ///See + public abstract partial class EncryptedMessageBase : ITLObject { } + ///See [TLDef(0xED18C118)] - public sealed partial class EncryptedMessage : EncryptedMessageBase + public partial class EncryptedMessage : EncryptedMessageBase { - /// Random message ID, assigned by the author of message public long random_id; - /// ID of encrypted chat public int chat_id; - /// Date of sending public DateTime date; - /// TL-serialization of type, encrypted with the key created at chat initialization public byte[] bytes; - /// Attached encrypted file public EncryptedFile file; - - /// Random message ID, assigned by the author of message - public override long RandomId => random_id; - /// ID of encrypted chat - public override int ChatId => chat_id; - /// Date of sending - public override DateTime Date => date; - /// TL-serialization of type, encrypted with the key created at chat initialization - public override byte[] Bytes => bytes; } - /// Encrypted service message See + ///See [TLDef(0x23734B06)] - public sealed partial class EncryptedMessageService : EncryptedMessageBase + public partial class EncryptedMessageService : EncryptedMessageBase { - /// Random message ID, assigned by the author of message public long random_id; - /// ID of encrypted chat public int chat_id; - /// Date of sending public DateTime date; - /// TL-serialization of the type, encrypted with the key created at chat initialization public byte[] bytes; - - /// Random message ID, assigned by the author of message - public override long RandomId => random_id; - /// ID of encrypted chat - public override int ChatId => chat_id; - /// Date of sending - public override DateTime Date => date; - /// TL-serialization of the type, encrypted with the key created at chat initialization - public override byte[] Bytes => bytes; } - /// Contains Diffie-Hellman key generation protocol parameters. See Derived classes: , - public abstract partial class Messages_DhConfigBase : IObject { } - /// Configuring parameters did not change. See + ///See + public abstract partial class Messages_DhConfigBase : ITLObject { } + ///See [TLDef(0xC0E24635)] - public sealed partial class Messages_DhConfigNotModified : Messages_DhConfigBase - { - /// Random sequence of bytes of assigned length - public byte[] random; - } - /// New set of configuring parameters. See + public partial class Messages_DhConfigNotModified : Messages_DhConfigBase { public byte[] random; } + ///See [TLDef(0x2C221EDD)] - public sealed partial class Messages_DhConfig : Messages_DhConfigBase + public partial class Messages_DhConfig : Messages_DhConfigBase { - /// New value prime, see Wikipedia public int g; - /// New value primitive root, see Wikipedia public byte[] p; - /// Version of set of parameters public int version; - /// Random sequence of bytes of assigned length public byte[] random; } - /// Message without file attachments sent to an encrypted file. See + ///See [TLDef(0x560F8935)] - public partial class Messages_SentEncryptedMessage : IObject - { - /// Date of sending - public DateTime date; - } - /// Message with a file enclosure sent to a protected chat See - [TLDef(0x9493FF32, inheritAt = 0)] - public sealed partial class Messages_SentEncryptedFile : Messages_SentEncryptedMessage - { - /// Attached file - public EncryptedFile file; - } + public partial class Messages_SentEncryptedMessage : ITLObject { public DateTime date; } + ///See + [TLDef(0x9493FF32)] + public partial class Messages_SentEncryptedFile : Messages_SentEncryptedMessage { public EncryptedFile file; } - /// Defines a document for subsequent interaction. See - /// a value means inputDocumentEmpty + ///See + ///a null value means inputDocumentEmpty [TLDef(0x1ABFB575)] - public sealed partial class InputDocument : IObject + public partial class InputDocument : ITLObject { - /// Document ID public long id; - /// REQUIRED FIELD. See how to obtain it
access_hash parameter from the
public long access_hash; - /// File reference public byte[] file_reference; } - /// A document. See Derived classes: , - public abstract partial class DocumentBase : IObject { } - /// Empty constructor, document doesn't exist. See + ///See + public abstract partial class DocumentBase : ITLObject { } + ///See [TLDef(0x36F8C871)] - public sealed partial class DocumentEmpty : DocumentBase + public partial class DocumentEmpty : DocumentBase { public long id; } + ///See + [TLDef(0x1E87342B)] + public partial class Document : DocumentBase { - /// Document ID or 0 - public long id; - } - /// Document See - [TLDef(0x8FD4C4D8)] - public sealed partial class Document : DocumentBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_thumbs = 0x1, has_video_thumbs = 0x2 } public Flags flags; - /// Document ID public long id; - /// Check sum, dependent on document ID public long access_hash; - /// File reference public byte[] file_reference; - /// Creation date public DateTime date; - /// MIME type public string mime_type; - /// Size - public long size; - /// Thumbnails + public int size; [IfFlag(0)] public PhotoSizeBase[] thumbs; - /// Video thumbnails - [IfFlag(1)] public VideoSizeBase[] video_thumbs; - /// DC ID + [IfFlag(1)] public VideoSize[] video_thumbs; public int dc_id; - /// Attributes public DocumentAttribute[] attributes; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_thumbs = 0x1, - /// Field has a value - has_video_thumbs = 0x2, - } } - /// Info on support user. See + ///See [TLDef(0x17C6B5F6)] - public sealed partial class Help_Support : IObject + public partial class Help_Support : ITLObject { - /// Phone number public string phone_number; - /// User public UserBase user; } - /// Object defines the set of users and/or groups that generate notifications. See Derived classes: , , , , - public abstract partial class NotifyPeerBase : IObject { } - /// Notifications generated by a certain user or group. See + ///See + public abstract partial class NotifyPeerBase : ITLObject { } + ///See [TLDef(0x9FD40BD8)] - public sealed partial class NotifyPeer : NotifyPeerBase - { - /// user or group - public Peer peer; - } - /// Notifications generated by all users. See + public partial class NotifyPeer : NotifyPeerBase { public Peer peer; } + ///See [TLDef(0xB4C83B4C)] - public sealed partial class NotifyUsers : NotifyPeerBase { } - /// Notifications generated by all groups. See + public partial class NotifyUsers : NotifyPeerBase { } + ///See [TLDef(0xC007CEC3)] - public sealed partial class NotifyChats : NotifyPeerBase { } - /// Channel notification settings See + public partial class NotifyChats : NotifyPeerBase { } + ///See [TLDef(0xD612E8EF)] - public sealed partial class NotifyBroadcasts : NotifyPeerBase { } - /// Notifications generated by a topic in a forum. See - [TLDef(0x226E6308)] - public sealed partial class NotifyForumTopic : NotifyPeerBase - { - /// Forum ID - public Peer peer; - /// Topic ID - public int top_msg_id; - } + public partial 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. See Derived classes: , , , , , , , , , , , , , , , , , , - public abstract partial class SendMessageAction : IObject { } - /// User is typing. See + ///See + public abstract partial class SendMessageAction : ITLObject { } + ///See [TLDef(0x16BF744E)] - public sealed partial class SendMessageTypingAction : SendMessageAction { } - /// Invalidate all previous action updates. E.g. when user deletes entered text or aborts a video upload. See + public partial class SendMessageTypingAction : SendMessageAction { } + ///See [TLDef(0xFD5EC8F5)] - public sealed partial class SendMessageCancelAction : SendMessageAction { } - /// User is recording a video. See + public partial class SendMessageCancelAction : SendMessageAction { } + ///See [TLDef(0xA187D66F)] - public sealed partial class SendMessageRecordVideoAction : SendMessageAction { } - /// User is uploading a video. See + public partial class SendMessageRecordVideoAction : SendMessageAction { } + ///See [TLDef(0xE9763AEC)] - public sealed partial class SendMessageUploadVideoAction : SendMessageAction - { - /// Progress percentage - public int progress; - } - /// User is recording a voice message. See + public partial class SendMessageUploadVideoAction : SendMessageAction { public int progress; } + ///See [TLDef(0xD52F73F7)] - public sealed partial class SendMessageRecordAudioAction : SendMessageAction { } - /// User is uploading a voice message. See + public partial class SendMessageRecordAudioAction : SendMessageAction { } + ///See [TLDef(0xF351D7AB)] - public sealed partial class SendMessageUploadAudioAction : SendMessageAction - { - /// Progress percentage - public int progress; - } - /// User is uploading a photo. See + public partial class SendMessageUploadAudioAction : SendMessageAction { public int progress; } + ///See [TLDef(0xD1D34A26)] - public sealed partial class SendMessageUploadPhotoAction : SendMessageAction - { - /// Progress percentage - public int progress; - } - /// User is uploading a file. See + public partial class SendMessageUploadPhotoAction : SendMessageAction { public int progress; } + ///See [TLDef(0xAA0CD9E4)] - public sealed partial class SendMessageUploadDocumentAction : SendMessageAction - { - /// Progress percentage - public int progress; - } - /// User is selecting a location to share. See + public partial class SendMessageUploadDocumentAction : SendMessageAction { public int progress; } + ///See [TLDef(0x176F8BA1)] - public sealed partial class SendMessageGeoLocationAction : SendMessageAction { } - /// User is selecting a contact to share. See + public partial class SendMessageGeoLocationAction : SendMessageAction { } + ///See [TLDef(0x628CBC6F)] - public sealed partial class SendMessageChooseContactAction : SendMessageAction { } - /// User is playing a game See + public partial class SendMessageChooseContactAction : SendMessageAction { } + ///See [TLDef(0xDD6A8F48)] - public sealed partial class SendMessageGamePlayAction : SendMessageAction { } - /// User is recording a round video to share See + public partial class SendMessageGamePlayAction : SendMessageAction { } + ///See [TLDef(0x88F27FBC)] - public sealed partial class SendMessageRecordRoundAction : SendMessageAction { } - /// User is uploading a round video See + public partial class SendMessageRecordRoundAction : SendMessageAction { } + ///See [TLDef(0x243E1C66)] - public sealed partial class SendMessageUploadRoundAction : SendMessageAction - { - /// Progress percentage - public int progress; - } - /// User is currently speaking in the group call See + public partial class SendMessageUploadRoundAction : SendMessageAction { public int progress; } + ///See [TLDef(0xD92C2285)] - public sealed partial class SpeakingInGroupCallAction : SendMessageAction { } - /// Chat history is being imported See + public partial class SpeakingInGroupCallAction : SendMessageAction { } + ///See [TLDef(0xDBDA9246)] - public sealed partial class SendMessageHistoryImportAction : SendMessageAction - { - /// Progress percentage - public int progress; - } - /// User is choosing a sticker See + public partial class SendMessageHistoryImportAction : SendMessageAction { public int progress; } + ///See [TLDef(0xB05AC6B1)] - public sealed partial class SendMessageChooseStickerAction : SendMessageAction { } - /// User has clicked on an animated emoji triggering a reaction, click here for more info ». See - [TLDef(0x25972BCB)] - public sealed partial class SendMessageEmojiInteraction : SendMessageAction + public partial class SendMessageChooseStickerAction : SendMessageAction { } + ///See + [TLDef(0x6A3233B6)] + public partial class SendMessageEmojiInteraction : SendMessageAction { - /// Emoji public string emoticon; - /// Message ID of the animated emoji that was clicked - public int msg_id; - /// A JSON object with interaction info, click here for more info » public DataJSON interaction; } - /// User is watching an animated emoji reaction triggered by another user, click here for more info ». See + ///See [TLDef(0xB665902E)] - public sealed partial class SendMessageEmojiInteractionSeen : SendMessageAction - { - /// Emoji - public string emoticon; - } - /// See - [TLDef(0x376D975C)] - public sealed partial class SendMessageTextDraftAction : SendMessageAction - { - public long random_id; - public TextWithEntities text; - } + public partial class SendMessageEmojiInteractionSeen : SendMessageAction { public string emoticon; } - /// Users found by name substring and auxiliary data. See + ///See [TLDef(0xB3134D9D)] - public sealed partial class Contacts_Found : IObject, IPeerResolver + public partial class Contacts_Found : ITLObject { - /// Personalized results public Peer[] my_results; - /// List of found user identifiers public Peer[] results; - /// Found chats - public Dictionary chats; - /// List of users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Privacy keys together with privacy rules » indicate what can or can't someone do and are specified by a constructor, and its input counterpart . See + ///See public enum InputPrivacyKey : uint { - ///Whether people will be able to see our exact last online timestamp.

Note that if we decide to hide our exact last online timestamp to someone (i.e., users A, B, C, or all users) and we do not have a
Premium subscription, we won't be able to see the exact last online timestamp of those users (A, B, C, or all users), even if those users do share it with us.

If those users do share their exact online status with us, but we can't see it due to the reason mentioned above, the by_me flag of , , will be set.
+ ///See StatusTimestamp = 0x4F96CB18, - ///Whether people will be able to invite you to chats + ///See ChatInvite = 0xBDFB0426, - ///Whether you will accept phone calls + ///See PhoneCall = 0xFABADC5F, - ///Whether to allow P2P communication during VoIP calls + ///See PhoneP2P = 0xDB9E70D2, - ///Whether messages forwarded from you will be anonymous + ///See Forwards = 0xA4DD4C08, - ///Whether people will be able to see your profile picture + ///See ProfilePhoto = 0x5719BACC, - ///Whether people will be able to see your phone number + ///See PhoneNumber = 0x0352DAFA, - ///Whether people can add you to their contact list by your phone number + ///See AddedByPhone = 0xD1219BDD, - ///Whether people can send you voice messages or round videos (Premium users only). - VoiceMessages = 0xAEE69D68, - ///Whether people can see your bio - About = 0x3823CC40, - ///Whether the user can see our birthday. - Birthday = 0xD65A11CC, - ///Whether received gifts will be automatically displayed on our profile - StarGiftsAutoSave = 0xE1732341, - ///Who can send you messages without paying, if paid messages » are enabled. - NoPaidMessages = 0xBDC597B4, - ///See - SavedMusic = 0x4DBE9226, } - /// Privacy keys together with privacy rules » indicate what can or can't someone do and are specified by a constructor, and its input counterpart . See + ///See public enum PrivacyKey : uint { - ///Whether we can see the last online timestamp of this user.

Note that if we decide to hide our exact last online timestamp to someone (i.e., users A, B, C, or all users) and we do not have a
Premium subscription, we won't be able to see the exact last online timestamp of those users (A, B, C, or all users), even if those users do share it with us.

If those users do share their exact online status with us, but we can't see it due to the reason mentioned above, the by_me flag of , , will be set.
+ ///See StatusTimestamp = 0xBC2EAB30, - ///Whether the user can be invited to chats + ///See ChatInvite = 0x500E6DFA, - ///Whether the user accepts phone calls + ///See PhoneCall = 0x3D662B7B, - ///Whether P2P connections in phone calls with this user are allowed + ///See PhoneP2P = 0x39491CC8, - ///Whether messages forwarded from the user will be anonymously forwarded + ///See Forwards = 0x69EC56A3, - ///Whether the profile picture of the user is visible + ///See ProfilePhoto = 0x96151FED, - ///Whether the user allows us to see his phone number + ///See PhoneNumber = 0xD19AE46D, - ///Whether this user can be added to our contact list by their phone number + ///See AddedByPhone = 0x42FFD42B, - ///Whether the user accepts voice messages - VoiceMessages = 0x0697F414, - ///Whether people can see your bio - About = 0xA486B761, - ///Whether the user can see our birthday. - Birthday = 0x2000A518, - ///Whether received gifts will be automatically displayed on our profile - StarGiftsAutoSave = 0x2CA4FDF8, - ///Who can send you messages without paying, if paid messages » are enabled. - NoPaidMessages = 0x17D348D2, - ///See - SavedMusic = 0xFF7A571B, } - /// Privacy rules indicate who can or can't do something and are specified by a , and its input counterpart . See Derived classes: , , , , , , , , , , , - public abstract partial class InputPrivacyRule : IObject { } - /// Allow only contacts See + ///See + public abstract partial class InputPrivacyRule : ITLObject { } + ///See [TLDef(0x0D09E07B)] - public sealed partial class InputPrivacyValueAllowContacts : InputPrivacyRule { } - /// Allow all users See + public partial class InputPrivacyValueAllowContacts : InputPrivacyRule { } + ///See [TLDef(0x184B35CE)] - public sealed partial class InputPrivacyValueAllowAll : InputPrivacyRule { } - /// Allow only certain users See + public partial class InputPrivacyValueAllowAll : InputPrivacyRule { } + ///See [TLDef(0x131CC67F)] - public sealed partial class InputPrivacyValueAllowUsers : InputPrivacyRule - { - /// Allowed users - public InputUserBase[] users; - } - /// Disallow only contacts See + public partial class InputPrivacyValueAllowUsers : InputPrivacyRule { public InputUserBase[] users; } + ///See [TLDef(0x0BA52007)] - public sealed partial class InputPrivacyValueDisallowContacts : InputPrivacyRule { } - /// Disallow all See + public partial class InputPrivacyValueDisallowContacts : InputPrivacyRule { } + ///See [TLDef(0xD66B66C9)] - public sealed partial class InputPrivacyValueDisallowAll : InputPrivacyRule { } - /// Disallow only certain users See + public partial class InputPrivacyValueDisallowAll : InputPrivacyRule { } + ///See [TLDef(0x90110467)] - public sealed partial class InputPrivacyValueDisallowUsers : InputPrivacyRule - { - /// Users to disallow - public InputUserBase[] users; - } - /// Allow only participants of certain chats See + public partial class InputPrivacyValueDisallowUsers : InputPrivacyRule { public InputUserBase[] users; } + ///See [TLDef(0x840649CF)] - public sealed partial class InputPrivacyValueAllowChatParticipants : InputPrivacyRule - { - /// Allowed chat IDs (either a or a supergroup ID, verbatim the way it is received in the constructor (i.e. unlike with bot API IDs, here group and supergroup IDs should be treated in the same way)). - public long[] chats; - } - /// Disallow only participants of certain chats See + public partial class InputPrivacyValueAllowChatParticipants : InputPrivacyRule { public long[] chats; } + ///See [TLDef(0xE94F0F86)] - public sealed partial class InputPrivacyValueDisallowChatParticipants : InputPrivacyRule - { - /// Disallowed chat IDs (either a or a supergroup ID, verbatim the way it is received in the constructor (i.e. unlike with bot API IDs, here group and supergroup IDs should be treated in the same way)). - public long[] chats; - } - /// Allow only close friends » See - [TLDef(0x2F453E49)] - public sealed partial class InputPrivacyValueAllowCloseFriends : InputPrivacyRule { } - /// Allow only users with a Premium subscription », currently only usable for . See - [TLDef(0x77CDC9F1)] - public sealed partial class InputPrivacyValueAllowPremium : InputPrivacyRule { } - /// Allow bots and mini apps See - [TLDef(0x5A4FCCE5)] - public sealed partial class InputPrivacyValueAllowBots : InputPrivacyRule { } - /// Disallow bots and mini apps See - [TLDef(0xC4E57915)] - public sealed partial class InputPrivacyValueDisallowBots : InputPrivacyRule { } + public partial class InputPrivacyValueDisallowChatParticipants : InputPrivacyRule { public long[] chats; } - /// Privacy rules together with privacy keys indicate what can or can't someone do and are specified by a constructor, and its input counterpart . See Derived classes: , , , , , , , , , , , - public abstract partial class PrivacyRule : IObject { } - /// Allow all contacts See + ///See + public abstract partial class PrivacyRule : ITLObject { } + ///See [TLDef(0xFFFE1BAC)] - public sealed partial class PrivacyValueAllowContacts : PrivacyRule { } - /// Allow all users See + public partial class PrivacyValueAllowContacts : PrivacyRule { } + ///See [TLDef(0x65427B82)] - public sealed partial class PrivacyValueAllowAll : PrivacyRule { } - /// Allow only certain users See + public partial class PrivacyValueAllowAll : PrivacyRule { } + ///See [TLDef(0xB8905FB2)] - public sealed partial class PrivacyValueAllowUsers : PrivacyRule - { - /// Allowed users - public long[] users; - } - /// Disallow only contacts See + public partial class PrivacyValueAllowUsers : PrivacyRule { public long[] users; } + ///See [TLDef(0xF888FA1A)] - public sealed partial class PrivacyValueDisallowContacts : PrivacyRule { } - /// Disallow all users See + public partial class PrivacyValueDisallowContacts : PrivacyRule { } + ///See [TLDef(0x8B73E763)] - public sealed partial class PrivacyValueDisallowAll : PrivacyRule { } - /// Disallow only certain users See + public partial class PrivacyValueDisallowAll : PrivacyRule { } + ///See [TLDef(0xE4621141)] - public sealed partial class PrivacyValueDisallowUsers : PrivacyRule - { - /// Disallowed users - public long[] users; - } - /// Allow all participants of certain chats See + public partial class PrivacyValueDisallowUsers : PrivacyRule { public long[] users; } + ///See [TLDef(0x6B134E8E)] - public sealed partial class PrivacyValueAllowChatParticipants : PrivacyRule - { - /// Allowed chat IDs (either a or a supergroup ID, verbatim the way it is received in the constructor (i.e. unlike with bot API IDs, here group and supergroup IDs should be treated in the same way)). - public long[] chats; - } - /// Disallow only participants of certain chats See + public partial class PrivacyValueAllowChatParticipants : PrivacyRule { public long[] chats; } + ///See [TLDef(0x41C87565)] - public sealed partial class PrivacyValueDisallowChatParticipants : PrivacyRule - { - /// Disallowed chats IDs (either a or a supergroup ID, verbatim the way it is received in the constructor (i.e. unlike with bot API IDs, here group and supergroup IDs should be treated in the same way)). - public long[] chats; - } - /// Allow only close friends » See - [TLDef(0xF7E8D89B)] - public sealed partial class PrivacyValueAllowCloseFriends : PrivacyRule { } - /// Allow only users with a Premium subscription », currently only usable for . See - [TLDef(0xECE9814B)] - public sealed partial class PrivacyValueAllowPremium : PrivacyRule { } - /// Allow bots and mini apps See - [TLDef(0x21461B5D)] - public sealed partial class PrivacyValueAllowBots : PrivacyRule { } - /// Disallow bots and mini apps See - [TLDef(0xF6A5F82F)] - public sealed partial class PrivacyValueDisallowBots : PrivacyRule { } + public partial class PrivacyValueDisallowChatParticipants : PrivacyRule { public long[] chats; } - /// Privacy rules See + ///See [TLDef(0x50A04E45)] - public sealed partial class Account_PrivacyRules : IObject, IPeerResolver + public partial class Account_PrivacyRules : ITLObject { - /// Privacy rules public PrivacyRule[] rules; - /// Chats to which the rules apply - public Dictionary chats; - /// Users to which the rules apply - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Time to live in days of the current account See + ///See [TLDef(0xB8D0AFDF)] - public sealed partial class AccountDaysTTL : IObject - { - /// This account will self-destruct in the specified number of days - public int days; - } + public partial class AccountDaysTTL : ITLObject { 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) See Derived classes: , , , , , , , - public abstract partial class DocumentAttribute : IObject { } - /// Defines the width and height of an image uploaded as document See + ///See + public abstract partial class DocumentAttribute : ITLObject { } + ///See [TLDef(0x6C37C15C)] - public sealed partial class DocumentAttributeImageSize : DocumentAttribute + public partial class DocumentAttributeImageSize : DocumentAttribute { - /// Width of image public int w; - /// Height of image public int h; } - /// Defines an animated GIF See + ///See [TLDef(0x11B58939)] - public sealed partial class DocumentAttributeAnimated : DocumentAttribute { } - /// Defines a sticker See + public partial class DocumentAttributeAnimated : DocumentAttribute { } + ///See [TLDef(0x6319D612)] - public sealed partial class DocumentAttributeSticker : DocumentAttribute + public partial class DocumentAttributeSticker : DocumentAttribute { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_mask_coords = 0x1, mask = 0x2 } public Flags flags; - /// Alternative emoji representation of sticker public string alt; - /// Associated stickerset public InputStickerSet stickerset; - /// Mask coordinates (if this is a mask sticker, attached to a photo) [IfFlag(0)] public MaskCoords mask_coords; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_mask_coords = 0x1, - /// Whether this is a mask sticker - mask = 0x2, - } } - /// Defines a video See - [TLDef(0x43C57C48)] - public sealed partial class DocumentAttributeVideo : DocumentAttribute + ///See + [TLDef(0x0EF02CE6)] + public partial class DocumentAttributeVideo : DocumentAttribute { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { round_message = 0x1, supports_streaming = 0x2 } public Flags flags; - /// Duration in seconds - public double duration; - /// Video width - public int w; - /// Video height - public int h; - /// Number of bytes to preload when preloading videos (particularly video stories). - [IfFlag(2)] public int preload_prefix_size; - /// Floating point UNIX timestamp in seconds, indicating the frame of the video that should be used as static preview and thumbnail. - [IfFlag(4)] public double video_start_ts; - /// Codec used for the video, i.e. "h264", "h265", or "av1" - [IfFlag(5)] public string video_codec; - - [Flags] public enum Flags : uint - { - /// Whether this is a round video - round_message = 0x1, - /// Whether the video supports streaming - supports_streaming = 0x2, - /// Field has a value - has_preload_prefix_size = 0x4, - /// Whether the specified document is a video file with no audio tracks - nosound = 0x8, - /// Field has a value - has_video_start_ts = 0x10, - /// Field has a value - has_video_codec = 0x20, - } - } - /// Represents an audio file See - [TLDef(0x9852F9C6)] - public sealed partial class DocumentAttributeAudio : DocumentAttribute - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Duration in seconds public int duration; - /// Name of song - [IfFlag(0)] public string title; - /// Performer - [IfFlag(1)] public string performer; - /// Waveform: consists in a series of bitpacked 5-bit values.
Example implementation:
android.
- [IfFlag(2)] public byte[] waveform; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_title = 0x1, - /// Field has a value - has_performer = 0x2, - /// Field has a value - has_waveform = 0x4, - /// Whether this is a voice message - voice = 0x400, - } + public int w; + public int h; } - /// A simple document with a file name See - [TLDef(0x15590068)] - public sealed partial class DocumentAttributeFilename : DocumentAttribute + ///See + [TLDef(0x9852F9C6)] + public partial class DocumentAttributeAudio : DocumentAttribute { - /// The file name - public string file_name; - } - /// Whether the current document has stickers attached See - [TLDef(0x9801D2F7)] - public sealed partial class DocumentAttributeHasStickers : DocumentAttribute { } - /// Info about a custom emoji See - [TLDef(0xFD149899)] - public sealed partial class DocumentAttributeCustomEmoji : DocumentAttribute - { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_title = 0x1, has_performer = 0x2, has_waveform = 0x4, voice = 0x400 } public Flags flags; - /// The actual emoji - public string alt; - /// The emoji stickerset to which this emoji belongs. - public InputStickerSet stickerset; - - [Flags] public enum Flags : uint - { - /// Whether this custom emoji can be sent by non-Premium users - free = 0x1, - /// Whether the color of this TGS custom emoji should be changed to the text color when used in messages, the accent color if used as emoji status, white on chat photos, or another appropriate color based on context. - text_color = 0x2, - } + public int duration; + [IfFlag(0)] public string title; + [IfFlag(1)] public string performer; + [IfFlag(2)] public byte[] waveform; } + ///See + [TLDef(0x15590068)] + public partial class DocumentAttributeFilename : DocumentAttribute { public string file_name; } + ///See + [TLDef(0x9801D2F7)] + public partial class DocumentAttributeHasStickers : DocumentAttribute { } - /// Found stickers See - /// a value means messages.stickersNotModified + ///See + ///a null value means messages.stickersNotModified [TLDef(0x30A6EC7E)] - public sealed partial class Messages_Stickers : IObject + public partial class Messages_Stickers : ITLObject { - /// Hash used for caching, for more info click here public long hash; - /// Stickers public DocumentBase[] stickers; } - /// A stickerpack is a group of stickers associated to the same emoji.
It is not a sticker pack the way it is usually intended, you may be looking for a . See
+ ///See [TLDef(0x12B299D4)] - public sealed partial class StickerPack : IObject + public partial class StickerPack : ITLObject { - /// Emoji public string emoticon; - /// Stickers public long[] documents; } - /// Info about all installed stickers See - /// a value means messages.allStickersNotModified + ///See + ///a null value means messages.allStickersNotModified [TLDef(0xCDBBCEBB)] - public sealed partial class Messages_AllStickers : IObject + public partial class Messages_AllStickers : ITLObject { - /// Hash used for caching, for more info click here public long hash; - /// All stickersets public StickerSet[] sets; } - /// Events affected by operation See + ///See [TLDef(0x84D19185)] - public partial class Messages_AffectedMessages : IObject + public partial class Messages_AffectedMessages : ITLObject { - /// Event count after generation public int pts; - /// Number of events that were generated public int pts_count; } - /// Instant View webpage preview See Derived classes: , , , - public abstract partial class WebPageBase : IObject + ///See + public abstract partial class WebPageBase : ITLObject { } + ///See + [TLDef(0xEB1477E8)] + public partial class WebPageEmpty : WebPageBase { public long id; } + ///See + [TLDef(0xC586DA1C)] + public partial class WebPagePending : WebPageBase { - /// Preview ID - public virtual long ID => default; - /// URL of the webpage. - public virtual string Url => default; - } - /// No preview is available for the webpage See - [TLDef(0x211A1788)] - public sealed partial class WebPageEmpty : WebPageBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Preview ID public long id; - /// URL of the webpage. - [IfFlag(0)] public string url; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_url = 0x1, - } - - /// Preview ID - public override long ID => id; - /// URL of the webpage. - public override string Url => url; - } - /// A preview of the webpage is currently being generated See - [TLDef(0xB0D13E47)] - public sealed partial class WebPagePending : WebPageBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of preview - public long id; - /// URL of the webpage - [IfFlag(0)] public string url; - /// When was the processing started public DateTime date; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_url = 0x1, - } - - /// ID of preview - public override long ID => id; - /// URL of the webpage - public override string Url => url; } - /// Webpage preview See + ///See [TLDef(0xE89C45B2)] - public sealed partial class WebPage : WebPageBase + public partial class WebPage : WebPageBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_type = 0x1, has_site_name = 0x2, has_title = 0x4, has_description = 0x8, has_photo = 0x10, + has_embed_url = 0x20, has_embed_width = 0x40, has_duration = 0x80, has_author = 0x100, has_document = 0x200, + has_cached_page = 0x400, has_attributes = 0x1000 } public Flags flags; - /// Preview ID public long id; - /// URL of previewed webpage public string url; - /// Webpage URL to be displayed to the user public string display_url; - /// Hash used for caching, for more info click here public int hash; - /// Type of the web page. One of the following:

- app
- article
- document
- gif
- photo
- profile
- telegram_album
- telegram_auction
- telegram_background
- telegram_bot
- telegram_botapp
- telegram_call
- telegram_channel
- telegram_channel_boost
- telegram_channel_direct
- telegram_channel_request
- telegram_chat
- telegram_chat_request
- telegram_chatlist
- telegram_collection
- telegram_community
- telegram_giftcode
- telegram_group_boost
- telegram_livestream
- telegram_megagroup
- telegram_megagroup_request
- telegram_message
- telegram_nft
- telegram_stickerset
- telegram_story
- telegram_story_album
- telegram_theme
- telegram_user
- telegram_videochat
- telegram_voicechat
- video

[IfFlag(0)] public string type; - /// Short name of the site (e.g., Google Docs, App Store) [IfFlag(1)] public string site_name; - /// Title of the content [IfFlag(2)] public string title; - /// Content description [IfFlag(3)] public string description; - /// Image representing the content [IfFlag(4)] public PhotoBase photo; - /// URL to show in the embedded preview [IfFlag(5)] public string embed_url; - /// MIME type of the embedded preview, (e.g., text/html or video/mp4) [IfFlag(5)] public string embed_type; - /// Width of the embedded preview [IfFlag(6)] public int embed_width; - /// Height of the embedded preview [IfFlag(6)] public int embed_height; - /// Duration of the content, in seconds [IfFlag(7)] public int duration; - /// Author of the content [IfFlag(8)] public string author; - /// Preview of the content as a media file [IfFlag(9)] public DocumentBase document; - /// Page contents in instant view format [IfFlag(10)] public Page cached_page; - /// Webpage attributes [IfFlag(12)] public WebPageAttribute[] attributes; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_type = 0x1, - /// Field has a value - has_site_name = 0x2, - /// Field has a value - has_title = 0x4, - /// Field has a value - has_description = 0x8, - /// Field has a value - has_photo = 0x10, - /// Fields and have a value - has_embed_url = 0x20, - /// Fields and have a value - has_embed_width = 0x40, - /// Field has a value - has_duration = 0x80, - /// Field has a value - has_author = 0x100, - /// Field has a value - has_document = 0x200, - /// Field has a value - has_cached_page = 0x400, - /// Field has a value - has_attributes = 0x1000, - /// Whether the size of the media in the preview can be changed. - has_large_media = 0x2000, - /// Represents a custom video cover. - video_cover_photo = 0x4000, - } - - /// Preview ID - public override long ID => id; - /// URL of previewed webpage - public override string Url => url; } - /// The preview of the webpage hasn't changed See + ///See [TLDef(0x7311CA11)] - public sealed partial class WebPageNotModified : WebPageBase + public partial class WebPageNotModified : WebPageBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_cached_page_views = 0x1 } public Flags flags; - /// Page view count [IfFlag(0)] public int cached_page_views; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_cached_page_views = 0x1, - } } - /// Logged-in session See + ///See [TLDef(0xAD01D61D)] - public sealed partial class Authorization : IObject + public partial class Authorization : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { current = 0x1, official_app = 0x2, password_pending = 0x4 } public Flags flags; - /// Identifier public long hash; - /// Device model public string device_model; - /// Platform public string platform; - /// System version public string system_version; - /// API ID public int api_id; - /// App name public string app_name; - /// App version public string app_version; - /// When was the session created - public DateTime date_created; - /// When was the session last active - public DateTime date_active; - /// Last known IP + public int date_created; + public int date_active; public string ip; - /// Country determined from IP public string country; - /// Region determined from IP public string region; - - [Flags] public enum Flags : uint - { - /// Whether this is the current session - current = 0x1, - /// Whether the session is from an official app - official_app = 0x2, - /// Whether the session is still waiting for a 2FA password - password_pending = 0x4, - /// Whether this session will accept encrypted chats - encrypted_requests_disabled = 0x8, - /// Whether this session will accept phone calls - call_requests_disabled = 0x10, - /// Whether the session is unconfirmed, see here » for more info. - unconfirmed = 0x20, - } } - /// Logged-in sessions See - [TLDef(0x4BFF8EA0)] - public sealed partial class Account_Authorizations : IObject - { - /// Time-to-live of session - public int authorization_ttl_days; - /// Logged-in sessions - public Authorization[] authorizations; - } + ///See + [TLDef(0x1250ABDE)] + public partial class Account_Authorizations : ITLObject { public Authorization[] authorizations; } - /// Configuration for two-factor authorization See - [TLDef(0x957B50FB)] - public sealed partial class Account_Password : IObject + ///See + [TLDef(0x185B184F)] + public partial class Account_Password : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_recovery = 0x1, has_secure_values = 0x2, has_password = 0x4, has_hint = 0x8, + has_email_unconfirmed_pattern = 0x10, has_pending_reset_date = 0x20 } public Flags flags; - /// The KDF algorithm for SRP two-factor authentication of the current password [IfFlag(2)] public PasswordKdfAlgo current_algo; - /// Srp B param for SRP authorization [IfFlag(2)] public byte[] srp_B; - /// Srp ID param for SRP authorization [IfFlag(2)] public long srp_id; - /// Text hint for the password [IfFlag(3)] public string hint; - /// A password recovery email with the specified pattern is still awaiting verification [IfFlag(4)] public string email_unconfirmed_pattern; - /// The KDF algorithm for SRP two-factor authentication to use when creating new passwords public PasswordKdfAlgo new_algo; - /// The KDF algorithm for telegram passport public SecurePasswordKdfAlgo new_secure_algo; - /// Secure random string public byte[] secure_random; - /// The 2FA password will be automatically removed at this date, unless the user cancels the operation [IfFlag(5)] public DateTime pending_reset_date; - /// A verified login email with the specified pattern is configured - [IfFlag(6)] public string login_email_pattern; - - [Flags] public enum Flags : uint - { - /// Whether the user has a recovery method configured - has_recovery = 0x1, - /// Whether telegram passport is enabled - has_secure_values = 0x2, - /// Whether the user has a password - has_password = 0x4, - /// Field has a value - has_hint = 0x8, - /// Field has a value - has_email_unconfirmed_pattern = 0x10, - /// Field has a value - has_pending_reset_date = 0x20, - /// Field has a value - has_login_email_pattern = 0x40, - } } - /// Private info associated to the password info (recovery email, telegram passport info & so on) See + ///See [TLDef(0x9A5C33E5)] - public sealed partial class Account_PasswordSettings : IObject + public partial class Account_PasswordSettings : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_email = 0x1, has_secure_settings = 0x2 } public Flags flags; - /// 2FA Recovery email [IfFlag(0)] public string email; - /// Telegram passport settings [IfFlag(1)] public SecureSecretSettings secure_settings; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_email = 0x1, - /// Field has a value - has_secure_settings = 0x2, - } } - /// Settings for setting up a new password See + ///See [TLDef(0xC23727C9)] - public sealed partial class Account_PasswordInputSettings : IObject + public partial class Account_PasswordInputSettings : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_new_algo = 0x1, has_email = 0x2, has_new_secure_settings = 0x4 } public Flags flags; - /// The SRP algorithm to use [IfFlag(0)] public PasswordKdfAlgo new_algo; - /// The computed password hash [IfFlag(0)] public byte[] new_password_hash; - /// Text hint for the password [IfFlag(0)] public string hint; - /// Password recovery email [IfFlag(1)] public string email; - /// Telegram passport settings [IfFlag(2)] public SecureSecretSettings new_secure_settings; - - [Flags] public enum Flags : uint - { - /// Fields , and have a value - has_new_algo = 0x1, - /// Field has a value - has_email = 0x2, - /// Field has a value - has_new_secure_settings = 0x4, - } } - /// Recovery info of a 2FA password, only for accounts with a recovery email configured. See + ///See [TLDef(0x137948A5)] - public sealed partial class Auth_PasswordRecovery : IObject - { - /// The email to which the recovery code was sent must match this pattern. - public string email_pattern; - } + public partial class Auth_PasswordRecovery : ITLObject { public string email_pattern; } - /// Message ID, for which PUSH-notifications were cancelled. See + ///See [TLDef(0xA384B779)] - public sealed partial class ReceivedNotifyMessage : IObject + public partial class ReceivedNotifyMessage : ITLObject { - /// Message ID, for which PUSH-notifications were canceled public int id; - /// Reserved for future use public int flags; } - /// Exported chat invite See Derived classes: , - public abstract partial class ExportedChatInvite : IObject { } - /// Exported chat invite See - [TLDef(0xA22CBD96)] - public sealed partial class ChatInviteExported : ExportedChatInvite + ///See + public abstract partial class ExportedChatInvite : ITLObject { } + ///See + [TLDef(0xB18105E8)] + public partial class ChatInviteExported : ExportedChatInvite { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { revoked = 0x1, has_expire_date = 0x2, has_usage_limit = 0x4, has_usage = 0x8, + has_start_date = 0x10, permanent = 0x20 } public Flags flags; - /// Chat invitation link public string link; - /// ID of the admin that created this chat invite public long admin_id; - /// When was this chat invite created public DateTime date; - /// When was this chat invite last modified [IfFlag(4)] public DateTime start_date; - /// When does this chat invite expire [IfFlag(1)] public DateTime expire_date; - /// Maximum number of users that can join using this link [IfFlag(2)] public int usage_limit; - /// How many users joined using this link [IfFlag(3)] public int usage; - /// Number of users that have already used this link to join - [IfFlag(7)] public int requested; - /// For Telegram Star subscriptions », contains the number of chat members which have already joined the chat using the link, but have already left due to expiration of their subscription. - [IfFlag(10)] public int subscription_expired; - /// Custom description for the invite link, visible only to admins - [IfFlag(8)] public string title; - /// For Telegram Star subscriptions », contains the pricing of the subscription the user must activate to join the private channel. - [IfFlag(9)] public StarsSubscriptionPricing subscription_pricing; - - [Flags] public enum Flags : uint - { - /// Whether this chat invite was revoked - revoked = 0x1, - /// Field has a value - has_expire_date = 0x2, - /// Field has a value - has_usage_limit = 0x4, - /// Field has a value - has_usage = 0x8, - /// Field has a value - has_start_date = 0x10, - /// Whether this chat invite has no expiration - permanent = 0x20, - /// Whether users importing this invite link will have to be approved to join the channel or group - request_needed = 0x40, - /// Field has a value - has_requested = 0x80, - /// Field has a value - has_title = 0x100, - /// Field has a value - has_subscription_pricing = 0x200, - /// Field has a value - has_subscription_expired = 0x400, - } } - /// Used in updates and in the channel log to indicate when a user is requesting to join or has joined a discussion group See - [TLDef(0xED107AB7)] - public sealed partial class ChatInvitePublicJoinRequests : ExportedChatInvite { } - /// Chat invite See Derived classes: , , - public abstract partial class ChatInviteBase : IObject { } - /// The user has already joined this chat See + ///See + public abstract partial class ChatInviteBase : ITLObject { } + ///See [TLDef(0x5A686D7C)] - public sealed partial class ChatInviteAlready : ChatInviteBase + public partial class ChatInviteAlready : ChatInviteBase { public ChatBase chat; } + ///See + [TLDef(0xDFC2F58E)] + public partial class ChatInvite : ChatInviteBase { - /// The chat connected to the invite - public ChatBase chat; - } - /// Chat invite info See - [TLDef(0x5C9D3702)] - public sealed partial class ChatInvite : ChatInviteBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { channel = 0x1, broadcast = 0x2, public_ = 0x4, megagroup = 0x8, has_participants = 0x10 } public Flags flags; - /// Chat/supergroup/channel title public string title; - /// Description of the group of channel - [IfFlag(5)] public string about; - /// Chat/supergroup/channel photo public PhotoBase photo; - /// Participant count public int participants_count; - /// A few of the participants that are in the group [IfFlag(4)] public UserBase[] participants; - /// Profile color palette ID - public int color; - /// For Telegram Star subscriptions », contains the pricing of the subscription the user must activate to join the private channel. - [IfFlag(10)] public StarsSubscriptionPricing subscription_pricing; - /// For Telegram Star subscriptions », the ID of the payment form for the subscription. - [IfFlag(12)] public long subscription_form_id; - /// Describes a bot verification icon ». - [IfFlag(13)] public BotVerification bot_verification; - - [Flags] public enum Flags : uint - { - /// Whether this is a channel/supergroup or a normal group - channel = 0x1, - /// Whether this is a channel - broadcast = 0x2, - /// Whether this is a public channel/supergroup - public_ = 0x4, - /// Whether this is a supergroup - megagroup = 0x8, - /// Field has a value - has_participants = 0x10, - /// Field has a value - has_about = 0x20, - /// Whether the join request » must be first approved by an administrator - request_needed = 0x40, - /// Is this chat or channel verified by Telegram? - verified = 0x80, - /// This chat is probably a scam - scam = 0x100, - /// If set, this chat was reported by many users as a fake or scam: be careful when interacting with it. - fake = 0x200, - /// Field has a value - has_subscription_pricing = 0x400, - /// If set, indicates that the user has already paid for the associated Telegram Star subscriptions » and it hasn't expired yet, so they may re-join the channel using Messages_ImportChatInvite without repeating the payment. - can_refulfill_subscription = 0x800, - /// Field has a value - has_subscription_form_id = 0x1000, - /// Field has a value - has_bot_verification = 0x2000, - } } - /// A chat invitation that also allows peeking into the group to read messages without joining it. See + ///See [TLDef(0x61695CB0)] - public sealed partial class ChatInvitePeek : ChatInviteBase + public partial class ChatInvitePeek : ChatInviteBase { - /// Chat information public ChatBase chat; - /// Read-only anonymous access to this group will be revoked at this date public DateTime expires; } - /// Represents a stickerset See Derived classes: , , , , , , , , , , - /// a value means inputStickerSetEmpty - public abstract partial class InputStickerSet : IObject { } - /// Stickerset by ID See + ///See + ///a null value means inputStickerSetEmpty + public abstract partial class InputStickerSet : ITLObject { } + ///See [TLDef(0x9DE7A269)] - public sealed partial class InputStickerSetID : InputStickerSet + public partial class InputStickerSetID : InputStickerSet { - /// ID public long id; - /// REQUIRED FIELD. See how to obtain it
Access hash
public long access_hash; } - ///
Stickerset by short name, from a stickerset deep link » See + ///See [TLDef(0x861CC8A0)] - public sealed partial class InputStickerSetShortName : InputStickerSet - { - /// Short name from a stickerset deep link » - public string short_name; - } - /// Animated emojis stickerset See + public partial class InputStickerSetShortName : InputStickerSet { public string short_name; } + ///See [TLDef(0x028703C8)] - public sealed partial class InputStickerSetAnimatedEmoji : InputStickerSet { } - /// Used for fetching animated dice stickers See + public partial class InputStickerSetAnimatedEmoji : InputStickerSet { } + ///See [TLDef(0xE67F520E)] - public sealed partial class InputStickerSetDice : InputStickerSet - { - /// The emoji, for now 🏀, 🎲 and 🎯 are supported - public string emoticon; - } - /// Animated emoji reaction stickerset (contains animations to play when a user clicks on a given animated emoji) See - [TLDef(0x0CDE3739)] - public sealed partial class InputStickerSetAnimatedEmojiAnimations : InputStickerSet { } - /// Stickers to show when receiving a gifted Telegram Premium subscription See - [TLDef(0xC88B3B02)] - public sealed partial class InputStickerSetPremiumGifts : InputStickerSet { } - /// Generic animation stickerset containing animations to play when reacting to messages using a normal emoji without a custom animation See - [TLDef(0x04C4D4CE)] - public sealed partial class InputStickerSetEmojiGenericAnimations : InputStickerSet { } - /// Default custom emoji status stickerset See - [TLDef(0x29D0F5EE)] - public sealed partial class InputStickerSetEmojiDefaultStatuses : InputStickerSet { } - /// Default custom emoji stickerset for forum topic icons See - [TLDef(0x44C1F8E9)] - public sealed partial class InputStickerSetEmojiDefaultTopicIcons : InputStickerSet { } - /// Default custom emoji status stickerset for channel statuses See - [TLDef(0x49748553)] - public sealed partial class InputStickerSetEmojiChannelDefaultStatuses : InputStickerSet { } - /// TON gifts stickerset. See - [TLDef(0x1CF671A0)] - public sealed partial class InputStickerSetTonGifts : InputStickerSet { } + public partial class InputStickerSetDice : InputStickerSet { public string emoticon; } - /// Represents a stickerset (stickerpack) See - [TLDef(0x2DD14EDC)] - public sealed partial class StickerSet : IObject + ///See + [TLDef(0xD7DF217A)] + public partial class StickerSet : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_installed_date = 0x1, archived = 0x2, official = 0x4, masks = 0x8, has_thumbs = 0x10, + animated = 0x20 } public Flags flags; - /// When was this stickerset installed [IfFlag(0)] public DateTime installed_date; - /// ID of the stickerset public long id; - /// Access hash of stickerset public long access_hash; - /// Title of stickerset public string title; - /// Short name of stickerset, used when sharing stickerset using stickerset deep links. public string short_name; - /// Stickerset thumbnail [IfFlag(4)] public PhotoSizeBase[] thumbs; - /// DC ID of thumbnail [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 - [IfFlag(8)] public long thumb_document_id; - /// Number of stickers in pack public int count; - /// Hash public int hash; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_installed_date = 0x1, - /// Whether this stickerset was archived (due to too many saved stickers in the current account) - archived = 0x2, - /// Is this stickerset official - official = 0x4, - /// Is this a mask stickerset - masks = 0x8, - /// Fields , and have a value - has_thumbs = 0x10, - /// This is a custom emoji stickerset - emojis = 0x80, - /// Field has a value - has_thumb_document_id = 0x100, - /// Whether the color of this TGS custom emoji stickerset should be changed to the text color when used in messages, the accent color if used as emoji status, white on chat photos, or another appropriate color based on context. - text_color = 0x200, - /// If set, this custom emoji stickerset can be used in channel/supergroup emoji statuses. - channel_emoji_status = 0x400, - /// Whether we created this stickerset - creator = 0x800, - } } - /// Stickerset and stickers inside it See - /// a value means messages.stickerSetNotModified - [TLDef(0x6E153F16)] - public sealed partial class Messages_StickerSet : IObject + ///See + [TLDef(0xB60A24A6)] + public partial class Messages_StickerSet : ITLObject { - /// The stickerset public StickerSet set; - /// Emoji info for stickers public StickerPack[] packs; - /// Keywords for some or every sticker in the stickerset. - public StickerKeyword[] keywords; - /// Stickers in stickerset public DocumentBase[] documents; } - /// Describes a bot command that can be used in a chat See + ///See [TLDef(0xC27AC8C7)] - public sealed partial class BotCommand : IObject + public partial class BotCommand : ITLObject { - /// /command name public string command; - /// Description of the command public string description; } - /// Info about bots (available bot commands, etc) See - [TLDef(0x4D8A0299)] - public sealed partial class BotInfo : IObject + ///See + [TLDef(0x1B74B335)] + public partial class BotInfo : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of the bot - [IfFlag(0)] public long user_id; - /// Description of the bot - [IfFlag(1)] public string description; - /// Description photo - [IfFlag(4)] public PhotoBase description_photo; - /// Description animation in MPEG4 format - [IfFlag(5)] public DocumentBase description_document; - /// Bot commands that can be used in the chat - [IfFlag(2)] public BotCommand[] commands; - /// Indicates the action to execute when pressing the in-UI menu button for bots - [IfFlag(3)] public BotMenuButtonBase menu_button; - /// The HTTP link to the privacy policy of the bot. If not set, then the /privacy command must be used, if supported by the bot (i.e. if it's present in the commands vector). If it isn't supported, then https://telegram.org/privacy-tpa must be opened, instead. - [IfFlag(7)] public string privacy_policy_url; - /// Mini app » settings
- [IfFlag(8)] public BotAppSettings app_settings; - /// This bot can verify peers: this field contains more info about the verification the bot can assign to peers. - [IfFlag(9)] public BotVerifierSettings verifier_settings; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_user_id = 0x1, - /// Field has a value - has_description = 0x2, - /// Field has a value - has_commands = 0x4, - /// Field has a value - has_menu_button = 0x8, - /// Field has a value - has_description_photo = 0x10, - /// Field has a value - has_description_document = 0x20, - /// If set, the bot has some preview medias for the configured Main Mini App, see here » for more info on Main Mini App preview medias. - has_preview_medias = 0x40, - /// Field has a value - has_privacy_policy_url = 0x80, - /// Field has a value - has_app_settings = 0x100, - /// Field has a value - has_verifier_settings = 0x200, - } - } - - /// Bot or inline keyboard buttons See Derived classes: , , , , , , , , , , , , , , , , , - public abstract partial class KeyboardButtonBase : IObject - { - public virtual KeyboardButtonStyle Style => default; - /// Button text - public virtual string Text => default; - } - /// Bot keyboard button See - [TLDef(0x7D170CFF)] - public partial class KeyboardButton : KeyboardButtonBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - [IfFlag(10)] public KeyboardButtonStyle style; - /// Button text - public string text; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_style = 0x400, - } - - public override KeyboardButtonStyle Style => style; - /// Button text - public override string Text => text; - } - /// URL button See - [TLDef(0xD80C25EC, inheritAt = 0)] - public sealed partial class KeyboardButtonUrl : KeyboardButton - { - /// URL - public string url; - } - /// Callback button See - [TLDef(0xE62BC960)] - public sealed partial class KeyboardButtonCallback : KeyboardButtonBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - [IfFlag(10)] public KeyboardButtonStyle style; - /// Button text - public string text; - /// Callback data - public byte[] data; - - [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. - requires_password = 0x1, - /// Field has a value - has_style = 0x400, - } - - public override KeyboardButtonStyle Style => style; - /// Button text - public override string Text => text; - } - /// Button to request a user's phone number See - [TLDef(0x417EFD8F)] - public sealed partial class KeyboardButtonRequestPhone : KeyboardButton - { - } - /// Button to request a user's geolocation See - [TLDef(0xAA40F94D)] - public sealed partial class KeyboardButtonRequestGeoLocation : KeyboardButton - { - } - /// Button to force a user to switch to inline mode: pressing the button will prompt the user to select one of their chats, open that chat and insert the bot's username and the specified inline query in the input field. See - [TLDef(0x991399FC)] - public sealed partial class KeyboardButtonSwitchInline : KeyboardButtonBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - [IfFlag(10)] public KeyboardButtonStyle style; - /// Button label - public string text; - /// The inline query to use - public string query; - /// Filter to use when selecting chats. - [IfFlag(1)] public InlineQueryPeerType[] peer_types; - - [Flags] public enum Flags : uint - { - /// If set, pressing the button will insert the bot's username and the specified inline query in the current chat's input field. - same_peer = 0x1, - /// Field has a value - has_peer_types = 0x2, - /// Field has a value - has_style = 0x400, - } - - public override KeyboardButtonStyle Style => style; - /// Button label - public override string Text => text; - } - /// Button to start a game See - [TLDef(0x89C590F9)] - public sealed partial class KeyboardButtonGame : KeyboardButton - { - } - /// Button to buy a product See - [TLDef(0x3FA53905)] - public sealed partial 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 - [TLDef(0xF51006F9)] - public sealed partial class KeyboardButtonUrlAuth : KeyboardButtonBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - [IfFlag(10)] public KeyboardButtonStyle style; - /// Button label - public string text; - /// New text of the button in forwarded messages. - [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 - public int button_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_fwd_text = 0x1, - /// Field has a value - has_style = 0x400, - } - - public override KeyboardButtonStyle Style => style; - /// Button label - public override string Text => text; - } - /// Button to request a user to Messages_AcceptUrlAuth via URL using Seamless Telegram Login. See - [TLDef(0x68013E72)] - public sealed partial class InputKeyboardButtonUrlAuth : KeyboardButtonBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - [IfFlag(10)] public KeyboardButtonStyle style; - /// Button text - public string text; - /// New text of the button in forwarded messages. - [IfFlag(1)] 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: You 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; - /// Username of a bot, which will be used for user authorization. See Setting up a bot for more details. 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 InputUserBase bot; - - [Flags] public enum Flags : uint - { - /// Set this flag to request the permission for your bot to send messages to the user. - request_write_access = 0x1, - /// Field has a value - has_fwd_text = 0x2, - /// Field has a value - has_style = 0x400, - } - - public override KeyboardButtonStyle Style => style; - /// Button text - public override string Text => text; - } - /// A button that allows the user to create and send a poll when pressed; available only in private See - [TLDef(0x7A11D782)] - public sealed partial class KeyboardButtonRequestPoll : KeyboardButtonBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - [IfFlag(10)] public KeyboardButtonStyle style; - /// If set, only quiz polls can be sent - [IfFlag(0)] public bool quiz; - /// Button text - public string text; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_quiz = 0x1, - /// Field has a value - has_style = 0x400, - } - - public override KeyboardButtonStyle Style => style; - /// Button text - public override string Text => text; - } - /// Button that links directly to a user profile See - [TLDef(0x7D5E07C7)] - public sealed partial class InputKeyboardButtonUserProfile : KeyboardButtonBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - [IfFlag(10)] public KeyboardButtonStyle style; - /// Button text - public string text; - /// User ID - public InputUserBase user_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_style = 0x400, - } - - public override KeyboardButtonStyle Style => style; - /// Button text - public override string Text => text; - } - /// Button that links directly to a user profile See - [TLDef(0xC0FD5D09, inheritAt = 0)] - public sealed partial class KeyboardButtonUserProfile : KeyboardButton - { - /// User ID public long user_id; + public string description; + public BotCommand[] commands; } - /// Button to open a bot mini app using Messages_RequestWebView, sending over user information after user confirmation. See - [TLDef(0xE846B1A0, inheritAt = 0)] - public partial class KeyboardButtonWebView : KeyboardButton + + ///See + public abstract partial class KeyboardButtonBase : ITLObject { } + ///See + [TLDef(0xA2FA4880)] + public partial class KeyboardButton : KeyboardButtonBase { public string text; } + ///See + [TLDef(0x258AFF05)] + public partial class KeyboardButtonUrl : KeyboardButton { public string url; } + ///See + [TLDef(0x35BBDB6B)] + public partial class KeyboardButtonCallback : KeyboardButtonBase { - /// Web app url - public string url; - } - /// Button to open a bot mini app using Messages_RequestSimpleWebView, without sending user information to the web app. See - [TLDef(0xE15C4370)] - public sealed partial class KeyboardButtonSimpleWebView : KeyboardButtonWebView - { - } - /// Prompts the user to select and share one or more peers with the bot using Messages_SendBotRequestedPeer See - [TLDef(0x5B0F15F5, inheritAt = 0)] - public sealed partial class KeyboardButtonRequestPeer : KeyboardButton - { - /// Button ID, to be passed to Messages_SendBotRequestedPeer. - public int button_id; - /// Filtering criteria to use for the peer selection list shown to the user.
The list should display all existing peers of the specified type, and should also offer an option for the user to create and immediately use one or more (up to max_quantity) peers of the specified type, if needed.
- public RequestPeerType peer_type; - /// Maximum number of peers that can be chosen. - public int max_quantity; - } - ///
Prompts the user to select and share one or more peers with the bot using Messages_SendBotRequestedPeer. See - [TLDef(0x02B78156)] - public sealed partial class InputKeyboardButtonRequestPeer : KeyboardButtonBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { requires_password = 0x1 } public Flags flags; - [IfFlag(10)] public KeyboardButtonStyle style; - /// Button text public string text; - /// Button ID, to be passed to Messages_SendBotRequestedPeer. + public byte[] data; + } + ///See + [TLDef(0xB16A6C29)] + public partial class KeyboardButtonRequestPhone : KeyboardButton { } + ///See + [TLDef(0xFC796B3F)] + public partial class KeyboardButtonRequestGeoLocation : KeyboardButton { } + ///See + [TLDef(0x0568A748)] + public partial class KeyboardButtonSwitchInline : KeyboardButtonBase + { + [Flags] public enum Flags { same_peer = 0x1 } + public Flags flags; + public string text; + public string query; + } + ///See + [TLDef(0x50F41CCF)] + public partial class KeyboardButtonGame : KeyboardButton { } + ///See + [TLDef(0xAFD93FBB)] + public partial class KeyboardButtonBuy : KeyboardButton { } + ///See + [TLDef(0x10B78D29)] + public partial class KeyboardButtonUrlAuth : KeyboardButtonBase + { + [Flags] public enum Flags { has_fwd_text = 0x1 } + public Flags flags; + public string text; + [IfFlag(0)] public string fwd_text; + public string url; public int button_id; - /// Filtering criteria to use for the peer selection list shown to the user.
The list should display all existing peers of the specified type, and should also offer an option for the user to create and immediately use one or more (up to max_quantity) peers of the specified type, if needed.
- public RequestPeerType peer_type; - /// Maximum number of peers that can be chosen. - public int max_quantity; - - [Flags] public enum Flags : uint - { - /// Set this flag to request the peer's name. - name_requested = 0x1, - /// Set this flag to request the peer's @username (if any). - username_requested = 0x2, - /// Set this flag to request the peer's photo (if any). - photo_requested = 0x4, - /// Field has a value - has_style = 0x400, - } - - public override KeyboardButtonStyle Style => style; - /// Button text - public override string Text => text; } - ///
Clipboard button: when clicked, the attached text must be copied to the clipboard. See - [TLDef(0xBCC4AF10, inheritAt = 0)] - public sealed partial class KeyboardButtonCopy : KeyboardButton + ///See + [TLDef(0xD02E7FD4)] + public partial class InputKeyboardButtonUrlAuth : KeyboardButtonBase { - /// The text that will be copied to the clipboard - public string copy_text; + [Flags] public enum Flags { request_write_access = 0x1, has_fwd_text = 0x2 } + public Flags flags; + public string text; + [IfFlag(1)] public string fwd_text; + public string url; + public InputUserBase bot; + } + ///See + [TLDef(0xBBC7515D, inheritAfter = true)] + public partial class KeyboardButtonRequestPoll : KeyboardButton + { + [Flags] public enum Flags { has_quiz = 0x1 } + public Flags flags; + [IfFlag(0)] public bool quiz; } - /// Inline keyboard row See + ///See [TLDef(0x77608B83)] - public sealed partial class KeyboardButtonRow : IObject - { - /// Bot or inline keyboard buttons - public KeyboardButtonBase[] buttons; - } + public partial class KeyboardButtonRow : ITLObject { public KeyboardButtonBase[] buttons; } - /// Reply markup for bot and inline keyboards See Derived classes: , , , - public abstract partial class ReplyMarkup : IObject { } - /// Hide sent bot keyboard See + ///See + public abstract partial class ReplyMarkup : ITLObject { } + ///See [TLDef(0xA03E5B85)] - public sealed partial class ReplyKeyboardHide : ReplyMarkup + public partial class ReplyKeyboardHide : ReplyMarkup { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { selective = 0x4 } public Flags flags; - - [Flags] public enum Flags : uint - { - /// Use this flag if you want to remove the keyboard for specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message.

Example: A user votes in a poll, bot returns confirmation message in reply to the vote and removes the keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet
- selective = 0x4, - } } - ///
Force the user to send a reply See + ///See [TLDef(0x86B40B08)] - public sealed partial class ReplyKeyboardForceReply : ReplyMarkup + public partial class ReplyKeyboardForceReply : ReplyMarkup { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { single_use = 0x2, selective = 0x4, has_placeholder = 0x8 } public Flags flags; - /// The placeholder to be shown in the input field when the keyboard is active; 1-64 characters. [IfFlag(3)] public string placeholder; - - [Flags] public enum Flags : uint - { - /// Requests clients to hide the keyboard as soon as it's been used. The keyboard will still be available, but clients will automatically display the usual letter-keyboard in the chat – the user can press a special button in the input field to see the custom keyboard again. - single_use = 0x2, - /// Use this parameter if you want to show the keyboard to specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message.
Example: A user requests to change the bot's language, bot replies to the request with a keyboard to select the new language. Other users in the group don't see the keyboard.
- selective = 0x4, - /// Field has a value - has_placeholder = 0x8, - } } - ///
Bot keyboard See + ///See [TLDef(0x85DD99D1)] - public sealed partial class ReplyKeyboardMarkup : ReplyMarkup + public partial class ReplyKeyboardMarkup : ReplyMarkup { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { resize = 0x1, single_use = 0x2, selective = 0x4, has_placeholder = 0x8 } public Flags flags; - /// Button row public KeyboardButtonRow[] rows; - /// The placeholder to be shown in the input field when the keyboard is active; 1-64 characters. [IfFlag(3)] public string placeholder; - - [Flags] public enum Flags : uint - { - /// Requests clients to resize the keyboard vertically for optimal fit (e.g., make the keyboard smaller if there are just two rows of buttons). If not set, the custom keyboard is always of the same height as the app's standard keyboard. - resize = 0x1, - /// Requests clients to hide the keyboard as soon as it's been used. The keyboard will still be available, but clients will automatically display the usual letter-keyboard in the chat – the user can press a special button in the input field to see the custom keyboard again. - single_use = 0x2, - /// Use this parameter if you want to show the keyboard to specific users only. Targets: 1) users that are @mentioned in the text of the Message object; 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message.

Example: A user requests to change the bot's language, bot replies to the request with a keyboard to select the new language. Other users in the group don't see the keyboard.
- selective = 0x4, - /// Field has a value - has_placeholder = 0x8, - /// Requests clients to always show the keyboard when the regular keyboard is hidden. - persistent = 0x10, - } } - ///
Bot or inline keyboard See + ///See [TLDef(0x48A30254)] - public sealed partial class ReplyInlineMarkup : ReplyMarkup - { - /// Bot or inline keyboard rows - public KeyboardButtonRow[] rows; - } + public partial class ReplyInlineMarkup : ReplyMarkup { public KeyboardButtonRow[] rows; } - /// Message entities, representing styled text in a message See Derived classes: , , , , , , , , , , , , , , , , , , , , , - public abstract partial class MessageEntity : IObject + ///See + public abstract partial class MessageEntity : ITLObject { - /// Offset of message entity within message (in UTF-16 code units) public int offset; - /// Length of message entity within message (in UTF-16 code units) public int length; } - /// Unknown message entity See + ///See [TLDef(0xBB92BA95)] - public sealed partial class MessageEntityUnknown : MessageEntity { } - /// Message entity mentioning a user by @username; can also be used to mention users by their ID. See + public partial class MessageEntityUnknown : MessageEntity { } + ///See [TLDef(0xFA04579D)] - public sealed partial class MessageEntityMention : MessageEntity { } - /// #hashtag message entity See + public partial class MessageEntityMention : MessageEntity { } + ///See [TLDef(0x6F635B0D)] - public sealed partial class MessageEntityHashtag : MessageEntity { } - /// Message entity representing a bot /command See + public partial class MessageEntityHashtag : MessageEntity { } + ///See [TLDef(0x6CEF8AC7)] - public sealed partial class MessageEntityBotCommand : MessageEntity { } - /// Message entity representing an in-text url: https://google.com; for text urls, use . See + public partial class MessageEntityBotCommand : MessageEntity { } + ///See [TLDef(0x6ED02538)] - public sealed partial class MessageEntityUrl : MessageEntity { } - /// Message entity representing an email@example.com. See + public partial class MessageEntityUrl : MessageEntity { } + ///See [TLDef(0x64E475C2)] - public sealed partial class MessageEntityEmail : MessageEntity { } - /// Message entity representing bold text. See + public partial class MessageEntityEmail : MessageEntity { } + ///See [TLDef(0xBD610BC9)] - public sealed partial class MessageEntityBold : MessageEntity { } - /// Message entity representing italic text. See + public partial class MessageEntityBold : MessageEntity { } + ///See [TLDef(0x826F8B60)] - public sealed partial class MessageEntityItalic : MessageEntity { } - /// Message entity representing a codeblock. See + public partial class MessageEntityItalic : MessageEntity { } + ///See [TLDef(0x28A20571)] - public sealed partial class MessageEntityCode : MessageEntity { } - /// Message entity representing a preformatted codeblock, allowing the user to specify a programming language for the codeblock. See - [TLDef(0x73924BE0, inheritAt = 0)] - public sealed partial class MessageEntityPre : MessageEntity - { - /// Programming language of the code - public string language; - } - /// Message entity representing a text url: for in-text urls like https://google.com use . See - [TLDef(0x76A6D327, inheritAt = 0)] - public sealed partial class MessageEntityTextUrl : MessageEntity - { - /// The actual URL - public string url; - } - /// Message entity representing a user mention: for creating a mention use . See - [TLDef(0xDC7B1140, inheritAt = 0)] - public sealed partial class MessageEntityMentionName : MessageEntity - { - /// Identifier of the user that was mentioned - public long user_id; - } - /// Message entity that can be used to create a user user mention: received mentions use the , instead. See - [TLDef(0x208E68C9, inheritAt = 0)] - public sealed partial class InputMessageEntityMentionName : MessageEntity - { - /// Identifier of the user that was mentioned - public InputUserBase user_id; - } - /// Message entity representing a phone number. See + public partial class MessageEntityCode : MessageEntity { } + ///See + [TLDef(0x73924BE0)] + public partial class MessageEntityPre : MessageEntity { public string language; } + ///See + [TLDef(0x76A6D327)] + public partial class MessageEntityTextUrl : MessageEntity { public string url; } + ///See + [TLDef(0xDC7B1140)] + public partial class MessageEntityMentionName : MessageEntity { public long user_id; } + ///See + [TLDef(0x208E68C9)] + public partial class InputMessageEntityMentionName : MessageEntity { public InputUserBase user_id; } + ///See [TLDef(0x9B69E34B)] - public sealed partial class MessageEntityPhone : MessageEntity { } - /// Message entity representing a $cashtag. See + public partial class MessageEntityPhone : MessageEntity { } + ///See [TLDef(0x4C4E743F)] - public sealed partial class MessageEntityCashtag : MessageEntity { } - /// Message entity representing underlined text. See + public partial class MessageEntityCashtag : MessageEntity { } + ///See [TLDef(0x9C4E7E8B)] - public sealed partial class MessageEntityUnderline : MessageEntity { } - /// Message entity representing strikethrough text. See + public partial class MessageEntityUnderline : MessageEntity { } + ///See [TLDef(0xBF0693D4)] - public sealed partial class MessageEntityStrike : MessageEntity { } - /// Indicates a credit card number See + public partial class MessageEntityStrike : MessageEntity { } + ///See + [TLDef(0x020DF5D0)] + public partial class MessageEntityBlockquote : MessageEntity { } + ///See [TLDef(0x761E6AF4)] - public sealed partial class MessageEntityBankCard : MessageEntity { } - /// Message entity representing a spoiler See - [TLDef(0x32CA960F)] - public sealed partial class MessageEntitySpoiler : MessageEntity { } - /// 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, inheritAt = 0)] - public sealed partial class MessageEntityCustomEmoji : MessageEntity - { - /// Document ID of the custom emoji, use Messages_GetCustomEmojiDocuments to fetch the emoji animation and the actual emoji it represents. - public long document_id; - } - /// Message entity representing a block quote. See - [TLDef(0xF1CCAAAC)] - public sealed partial class MessageEntityBlockquote : MessageEntity - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; + public partial class MessageEntityBankCard : MessageEntity { } - [Flags] public enum Flags : uint - { - /// Whether the quote is collapsed by default. - collapsed = 0x1, - } - } - /// See - [TLDef(0x904AC7C7, inheritAt = 1)] - public sealed partial class MessageEntityFormattedDate : MessageEntity - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - public DateTime date; - - [Flags] public enum Flags : uint - { - relative = 0x1, - short_time = 0x2, - long_time = 0x4, - short_date = 0x8, - long_date = 0x10, - day_of_week = 0x20, - } - } - - /// Represents a channel See Derived classes: , - /// a value means inputChannelEmpty - public abstract partial class InputChannelBase : IObject - { - /// Channel ID - public abstract long ChannelId { get; set; } - } - /// Represents a channel See + ///See + ///a null value means inputChannelEmpty + public abstract partial class InputChannelBase : ITLObject { } + ///See [TLDef(0xF35AEC28)] - public sealed partial class InputChannel : InputChannelBase + public partial class InputChannel : InputChannelBase { - /// Channel ID public long channel_id; - /// REQUIRED FIELD. See how to obtain it
Access hash taken from the
public long access_hash; - - /// Channel ID - public override long ChannelId { get => channel_id; set => channel_id = value; } } - ///
Defines a min channel that was seen in a certain message of a certain chat. See + ///See [TLDef(0x5B934F9D)] - public sealed partial class InputChannelFromMessage : InputChannelBase + public partial class InputChannelFromMessage : InputChannelBase { - /// The chat where the channel was seen public InputPeer peer; - /// The message ID in the chat where the channel was seen public int msg_id; - /// The channel ID public long channel_id; - - /// The channel ID - public override long ChannelId { get => channel_id; set => channel_id = value; } } - /// Resolved peer See + ///See [TLDef(0x7F077AD9)] - public sealed partial class Contacts_ResolvedPeer : IObject + public partial class Contacts_ResolvedPeer : ITLObject { - /// The peer public Peer peer; - /// Chats - public Dictionary chats; - /// Users - public Dictionary users; - /// returns a or for the result - public IPeerInfo UserOrChat => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Indicates a range of chat messages See + ///See [TLDef(0x0AE30253)] - public sealed partial class MessageRange : IObject + public partial class MessageRange : ITLObject { - /// Start of range (message ID) public int min_id; - /// End of range (message ID) public int max_id; } - /// 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 - public abstract IPeerInfo UserOrChat(Peer peer); - } - /// There are no new updates See + ///See + public abstract partial class Updates_ChannelDifferenceBase : ITLObject { } + ///See [TLDef(0x3E11AFFB)] - public sealed partial class Updates_ChannelDifferenceEmpty : Updates_ChannelDifferenceBase, IPeerResolver + public partial class Updates_ChannelDifferenceEmpty : Updates_ChannelDifferenceBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { final = 0x1, has_timeout = 0x2 } public Flags flags; - /// The latest PTS public int pts; - /// Clients are supposed to refetch the channel difference after timeout seconds have elapsed, if the user is currently viewing the chat, see here » for more info. [IfFlag(1)] public int timeout; - - [Flags] public enum Flags : uint - { - /// Whether there are more updates that must be fetched (always false) - final = 0x1, - /// Field has a value - has_timeout = 0x2, - } - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => null; } - /// The provided pts + limit < remote pts. Simply, there are too many updates to be fetched (more than limit), the client has to resolve the update gap in one of the following ways (assuming the existence of a persistent database to locally store messages): See + ///See [TLDef(0xA4BCC6FE)] - public sealed partial class Updates_ChannelDifferenceTooLong : Updates_ChannelDifferenceBase, IPeerResolver + public partial class Updates_ChannelDifferenceTooLong : Updates_ChannelDifferenceBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { final = 0x1, has_timeout = 0x2 } public Flags flags; - /// Clients are supposed to refetch the channel difference after timeout seconds have elapsed [IfFlag(1)] public int timeout; - /// Dialog containing the latest PTS that can be used to reset the channel state public DialogBase dialog; - /// The latest messages public MessageBase[] messages; - /// Chats from messages - public Dictionary chats; - /// Users from messages - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Whether there are more updates that must be fetched (always false) - final = 0x1, - /// Field has a value - has_timeout = 0x2, - } - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// The new updates See + ///See [TLDef(0x2064674E)] - public sealed partial class Updates_ChannelDifference : Updates_ChannelDifferenceBase, IPeerResolver + public partial class Updates_ChannelDifference : Updates_ChannelDifferenceBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { final = 0x1, has_timeout = 0x2 } public Flags flags; - /// The PTS from which to start getting updates the next time public int pts; - /// Clients are supposed to refetch the channel difference after timeout seconds have elapsed, if the user is currently viewing the chat, see here » for more info. [IfFlag(1)] public int timeout; - /// New messages public MessageBase[] new_messages; - /// Other updates public Update[] other_updates; - /// Chats - public Dictionary chats; - /// Users - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Whether there are more updates to be fetched using getDifference, starting from the provided pts - final = 0x1, - /// Field has a value - has_timeout = 0x2, - } - /// returns a or for the given Peer - public override IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Filter for getting only certain types of channel messages See - /// a value means channelMessagesFilterEmpty + ///See + ///a null value means channelMessagesFilterEmpty [TLDef(0xCD77D957)] - public sealed partial class ChannelMessagesFilter : IObject + public partial class ChannelMessagesFilter : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { exclude_new_messages = 0x2 } public Flags flags; - /// A range of messages to fetch public MessageRange[] ranges; - - [Flags] public enum Flags : uint - { - /// Whether to exclude new messages from the search - exclude_new_messages = 0x2, - } } - /// Channel participant See Derived classes: , , , , , - public abstract partial class ChannelParticipantBase : IObject { } - /// Channel/supergroup participant See - [TLDef(0x1BD54456)] - public sealed partial class ChannelParticipant : ChannelParticipantBase + ///See + public abstract partial class ChannelParticipantBase : ITLObject { } + ///See + [TLDef(0xC00C07C0)] + public partial class ChannelParticipant : ChannelParticipantBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Participant user ID public long user_id; - /// Date joined public DateTime date; - /// If set, contains the expiration date of the current Telegram Star subscription period » for the specified participant. - [IfFlag(0)] public DateTime subscription_until_date; - [IfFlag(2)] public string rank; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_subscription_until_date = 0x1, - /// Field has a value - has_rank = 0x4, - } } - /// Myself See - [TLDef(0xA9478A1A)] - public sealed partial class ChannelParticipantSelf : ChannelParticipantBase + ///See + [TLDef(0x28A8BC67)] + public partial class ChannelParticipantSelf : ChannelParticipantBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// User ID public long user_id; - /// User that invited me to the channel/supergroup public long inviter_id; - /// When did I join the channel/supergroup public DateTime date; - /// If set, contains the expiration date of the current Telegram Star subscription period » for the specified participant. - [IfFlag(1)] public DateTime subscription_until_date; - [IfFlag(2)] public string rank; - - [Flags] public enum Flags : uint - { - /// Whether I joined upon specific approval of an admin - via_request = 0x1, - /// Field has a value - has_subscription_until_date = 0x2, - /// Field has a value - has_rank = 0x4, - } } - /// Channel/supergroup creator See + ///See [TLDef(0x2FE601D3)] - public sealed partial class ChannelParticipantCreator : ChannelParticipantBase + public partial class ChannelParticipantCreator : ChannelParticipantBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_rank = 0x1 } public Flags flags; - /// User ID public long user_id; - /// Creator admin rights public ChatAdminRights admin_rights; - /// The role (rank) of the group creator in the group: just an arbitrary string, admin by default [IfFlag(0)] public string rank; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_rank = 0x1, - } } - /// Admin See + ///See [TLDef(0x34C3BB53)] - public sealed partial class ChannelParticipantAdmin : ChannelParticipantBase + public partial class ChannelParticipantAdmin : ChannelParticipantBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { can_edit = 0x1, self = 0x2, has_rank = 0x4 } public Flags flags; - /// Admin user ID public long user_id; - /// User that invited the admin to the channel/group [IfFlag(1)] public long inviter_id; - /// User that promoted the user to admin public long promoted_by; - /// When did the user join public DateTime date; - /// Admin rights public ChatAdminRights admin_rights; - /// The role (rank) of the admin in the group: just an arbitrary string, admin by default [IfFlag(2)] public string rank; - - [Flags] public enum Flags : uint - { - /// Can this admin promote other admins with the same permissions? - can_edit = 0x1, - /// Is this the current user - self = 0x2, - /// Field has a value - has_rank = 0x4, - } } - /// Banned/kicked user See - [TLDef(0xD5F0AD91)] - public sealed partial class ChannelParticipantBanned : ChannelParticipantBase + ///See + [TLDef(0x6DF8014E)] + public partial class ChannelParticipantBanned : ChannelParticipantBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { left = 0x1 } public Flags flags; - /// The banned peer public Peer peer; - /// User was kicked by the specified admin public long kicked_by; - /// When did the user join the group public DateTime date; - /// Banned rights public ChatBannedRights banned_rights; - [IfFlag(2)] public string rank; - - [Flags] public enum Flags : uint - { - /// Whether the user has left the group - left = 0x1, - /// Field has a value - has_rank = 0x4, - } } - /// A participant that left the channel/supergroup See + ///See [TLDef(0x1B03F006)] - public sealed partial class ChannelParticipantLeft : ChannelParticipantBase - { - /// The peer that left - public Peer peer; - } + public partial class ChannelParticipantLeft : ChannelParticipantBase { public Peer peer; } - /// Filter for fetching channel participants See Derived classes: , , , , , , , - public abstract partial class ChannelParticipantsFilter : IObject { } - /// Fetch only recent participants See + ///See + public abstract partial class ChannelParticipantsFilter : ITLObject { } + ///See [TLDef(0xDE3F3C79)] - public sealed partial class ChannelParticipantsRecent : ChannelParticipantsFilter { } - /// Fetch only admin participants See + public partial class ChannelParticipantsRecent : ChannelParticipantsFilter { } + ///See [TLDef(0xB4608969)] - public sealed partial class ChannelParticipantsAdmins : ChannelParticipantsFilter { } - /// Fetch only kicked participants See + public partial class ChannelParticipantsAdmins : ChannelParticipantsFilter { } + ///See [TLDef(0xA3B54985)] - public sealed partial class ChannelParticipantsKicked : ChannelParticipantsFilter - { - /// Optional filter for searching kicked participants by name (otherwise empty) - public string q; - } - /// Fetch only bot participants See + public partial class ChannelParticipantsKicked : ChannelParticipantsFilter { public string q; } + ///See [TLDef(0xB0D1865B)] - public sealed partial class ChannelParticipantsBots : ChannelParticipantsFilter { } - /// Fetch only banned participants See + public partial class ChannelParticipantsBots : ChannelParticipantsFilter { } + ///See [TLDef(0x1427A5E1)] - public sealed partial class ChannelParticipantsBanned : ChannelParticipantsFilter - { - /// Optional filter for searching banned participants by name (otherwise empty) - public string q; - } - /// Query participants by name See + public partial class ChannelParticipantsBanned : ChannelParticipantsFilter { public string q; } + ///See [TLDef(0x0656AC4B)] - public sealed partial class ChannelParticipantsSearch : ChannelParticipantsFilter - { - /// Search query - public string q; - } - /// Fetch only participants that are also contacts See + public partial class ChannelParticipantsSearch : ChannelParticipantsFilter { public string q; } + ///See [TLDef(0xBB6AE88D)] - public sealed partial class ChannelParticipantsContacts : ChannelParticipantsFilter - { - /// Optional search query for searching contact participants by name - public string q; - } - /// This filter is used when looking for supergroup members to mention.
This filter will automatically remove anonymous admins, and return even non-participant users that replied to a specific
thread through the comment section of a channel. See
+ public partial class ChannelParticipantsContacts : ChannelParticipantsFilter { public string q; } + ///See [TLDef(0xE04B5CEB)] - public sealed partial class ChannelParticipantsMentions : ChannelParticipantsFilter + public partial class ChannelParticipantsMentions : ChannelParticipantsFilter { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_q = 0x1, has_top_msg_id = 0x2 } public Flags flags; - /// Filter by user name or username [IfFlag(0)] public string q; - /// Look only for users that posted in this thread [IfFlag(1)] public int top_msg_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_q = 0x1, - /// Field has a value - has_top_msg_id = 0x2, - } } - /// Represents multiple channel participants See - /// a value means channels.channelParticipantsNotModified + ///See + ///a null value means channels.channelParticipantsNotModified [TLDef(0x9AB0FEAF)] - public sealed partial class Channels_ChannelParticipants : IObject, IPeerResolver + public partial class Channels_ChannelParticipants : ITLObject { - /// Total number of participants that correspond to the given query public int count; - /// Participants public ChannelParticipantBase[] participants; - /// Mentioned chats - public Dictionary chats; - /// Users mentioned in participant info - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Represents a channel participant See + ///See [TLDef(0xDFB80317)] - public sealed partial class Channels_ChannelParticipant : IObject, IPeerResolver + public partial class Channels_ChannelParticipant : ITLObject { - /// The channel participant public ChannelParticipantBase participant; - /// Mentioned chats - public Dictionary chats; - /// Users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Info about the latest telegram Terms Of Service See + ///See [TLDef(0x780A0310)] - public sealed partial class Help_TermsOfService : IObject + public partial class Help_TermsOfService : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { popup = 0x1, has_min_age_confirm = 0x2 } public Flags flags; - /// ID of the new terms public DataJSON id; - /// Text of the new terms public string text; - /// Message entities for styled text public MessageEntity[] entities; - /// Minimum age required to sign up to telegram, the user must confirm that they is older than the minimum age. [IfFlag(1)] public int min_age_confirm; - - [Flags] public enum Flags : uint - { - /// Whether a prompt must be showed to the user, in order to accept the new terms. - popup = 0x1, - /// Field has a value - has_min_age_confirm = 0x2, - } } - /// Saved gifs See - /// a value means messages.savedGifsNotModified + ///See + ///a null value means messages.savedGifsNotModified [TLDef(0x84A02A0D)] - public sealed partial class Messages_SavedGifs : IObject + public partial class Messages_SavedGifs : ITLObject { - /// Hash used for caching, for more info click here public long hash; - /// List of saved gifs public DocumentBase[] gifs; } - /// Represents a sent inline message from the perspective of a bot See Derived classes: , , , , , , , - public abstract partial class InputBotInlineMessage : IObject { } - /// A media See + ///See + public abstract partial class InputBotInlineMessage : ITLObject { public int flags; } + ///See [TLDef(0x3380C786)] - public sealed partial class InputBotInlineMessageMediaAuto : InputBotInlineMessage + public partial class InputBotInlineMessageMediaAuto : InputBotInlineMessage { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Caption + [Flags] public enum Flags { has_entities = 0x2, has_reply_markup = 0x4 } public string message; - /// Message entities for styled text [IfFlag(1)] public MessageEntity[] entities; - /// Inline keyboard [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_entities = 0x2, - /// Field has a value - has_reply_markup = 0x4, - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - invert_media = 0x8, - } } - /// Simple text message See + ///See [TLDef(0x3DCD7A87)] - public sealed partial class InputBotInlineMessageText : InputBotInlineMessage + public partial class InputBotInlineMessageText : InputBotInlineMessage { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Message + [Flags] public enum Flags { no_webpage = 0x1, has_entities = 0x2, has_reply_markup = 0x4 } public string message; - /// Message entities for styled text [IfFlag(1)] public MessageEntity[] entities; - /// Inline keyboard [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Disable webpage preview - no_webpage = 0x1, - /// Field has a value - has_entities = 0x2, - /// Field has a value - has_reply_markup = 0x4, - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - invert_media = 0x8, - } } - /// Geolocation See + ///See [TLDef(0x96929A85)] - public sealed partial class InputBotInlineMessageMediaGeo : InputBotInlineMessage + public partial class InputBotInlineMessageMediaGeo : InputBotInlineMessage { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Geolocation + [Flags] public enum Flags { has_heading = 0x1, has_period = 0x2, has_reply_markup = 0x4, + has_proximity_notification_radius = 0x8 } public InputGeoPoint geo_point; - /// For live locations, a direction in which the location moves, in degrees; 1-360 [IfFlag(0)] public int heading; - /// Validity period [IfFlag(1)] public int period; - /// For live locations, a maximum distance to another chat member for proximity alerts, in meters (0-100000) [IfFlag(3)] public int proximity_notification_radius; - /// Reply markup for bot/inline keyboards [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_heading = 0x1, - /// Field has a value - has_period = 0x2, - /// Field has a value - has_reply_markup = 0x4, - /// Field has a value - has_proximity_notification_radius = 0x8, - } } - /// Venue See + ///See [TLDef(0x417BBF11)] - public sealed partial class InputBotInlineMessageMediaVenue : InputBotInlineMessage + public partial class InputBotInlineMessageMediaVenue : InputBotInlineMessage { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Geolocation + [Flags] public enum Flags { has_reply_markup = 0x4 } public InputGeoPoint geo_point; - /// Venue name public string title; - /// Address public string address; - /// Venue provider: currently only "foursquare" and "gplaces" (Google Places) need to be supported public string provider; - /// Venue ID in the provider's database public string venue_id; - /// Venue type in the provider's database public string venue_type; - /// Inline keyboard [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_reply_markup = 0x4, - } } - /// A contact See + ///See [TLDef(0xA6EDBFFD)] - public sealed partial class InputBotInlineMessageMediaContact : InputBotInlineMessage + public partial class InputBotInlineMessageMediaContact : InputBotInlineMessage { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Phone number + [Flags] public enum Flags { has_reply_markup = 0x4 } public string phone_number; - /// First name public string first_name; - /// Last name public string last_name; - /// VCard info public string vcard; - /// Inline keyboard [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_reply_markup = 0x4, - } } - /// A game See + ///See [TLDef(0x4B425864)] - public sealed partial class InputBotInlineMessageGame : InputBotInlineMessage + public partial class InputBotInlineMessageGame : InputBotInlineMessage { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Inline keyboard + [Flags] public enum Flags { has_reply_markup = 0x4 } [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_reply_markup = 0x4, - } } - /// An invoice See + ///See [TLDef(0xD7E78225)] - public sealed partial class InputBotInlineMessageMediaInvoice : InputBotInlineMessage + public partial class InputBotInlineMessageMediaInvoice : InputBotInlineMessage { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Product name, 1-32 characters + [Flags] public enum Flags { has_photo = 0x1, has_reply_markup = 0x4 } public string title; - /// Product description, 1-255 characters public string description; - /// Invoice photo [IfFlag(0)] public InputWebDocument photo; - /// The invoice public Invoice invoice; - /// Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user, use for your internal processes. public byte[] payload; - /// Payments provider token, obtained via Botfather public string provider; - /// A JSON-serialized object for data about the invoice, which will be shared with the payment provider. A detailed description of the required fields should be provided by the payment provider. public DataJSON provider_data; - /// Inline keyboard [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_photo = 0x1, - /// Field has a value - has_reply_markup = 0x4, - } - } - /// Specifies options that will be used to generate the link preview for the message, or even a standalone link preview without an attached message. See - [TLDef(0xBDDCC510)] - public sealed partial class InputBotInlineMessageMediaWebPage : InputBotInlineMessage - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The message, can be empty. - public string message; - /// Message entities for styled text - [IfFlag(1)] public MessageEntity[] entities; - /// The URL to use for the link preview. - public string url; - /// Inline keyboard - [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_entities = 0x2, - /// Field has a value - has_reply_markup = 0x4, - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - invert_media = 0x8, - /// If set, specifies that a large media preview should be used. - force_large_media = 0x10, - /// If set, specifies that a small media preview should be used. - force_small_media = 0x20, - /// If not set, a WEBPAGE_NOT_FOUND RPC error will be emitted if a webpage preview cannot be generated for the specified url; otherwise, no error will be emitted (unless the provided message is also empty, in which case a MESSAGE_EMPTY will be emitted, instead). - optional = 0x40, - } } - /// Inline bot result See Derived classes: , , , - public abstract partial class InputBotInlineResultBase : IObject - { - /// ID of result - public abstract string ID { get; set; } - /// Message to send when the result is selected - public abstract InputBotInlineMessage SendMessage { get; set; } - } - /// An inline bot result See + ///See + public abstract partial class InputBotInlineResultBase : ITLObject { } + ///See [TLDef(0x88BF9319)] - public sealed partial class InputBotInlineResult : InputBotInlineResultBase + public partial class InputBotInlineResult : InputBotInlineResultBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_title = 0x2, has_description = 0x4, has_url = 0x8, has_thumb = 0x10, has_content = 0x20 } public Flags flags; - /// ID of result public string id; - /// Result type (see bot API docs) public string type; - /// Result title [IfFlag(1)] public string title; - /// Result description [IfFlag(2)] public string description; - /// URL of result [IfFlag(3)] public string url; - /// Thumbnail for result [IfFlag(4)] public InputWebDocument thumb; - /// Result contents [IfFlag(5)] public InputWebDocument content; - /// Message to send when the result is selected public InputBotInlineMessage send_message; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_title = 0x2, - /// Field has a value - has_description = 0x4, - /// Field has a value - has_url = 0x8, - /// Field has a value - has_thumb = 0x10, - /// Field has a value - has_content = 0x20, - } - - /// ID of result - public override string ID { get => id; set => id = value; } - /// Message to send when the result is selected - public override InputBotInlineMessage SendMessage { get => send_message; set => send_message = value; } } - /// Photo See + ///See [TLDef(0xA8D864A7)] - public sealed partial class InputBotInlineResultPhoto : InputBotInlineResultBase + public partial class InputBotInlineResultPhoto : InputBotInlineResultBase { - /// Result ID public string id; - /// Result type (see bot API docs) public string type; - /// Photo to send public InputPhoto photo; - /// Message to send when the result is selected public InputBotInlineMessage send_message; - - /// Result ID - public override string ID { get => id; set => id = value; } - /// Message to send when the result is selected - public override InputBotInlineMessage SendMessage { get => send_message; set => send_message = value; } } - /// Document (media of any type except for photos) See + ///See [TLDef(0xFFF8FDC4)] - public sealed partial class InputBotInlineResultDocument : InputBotInlineResultBase + public partial class InputBotInlineResultDocument : InputBotInlineResultBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_title = 0x2, has_description = 0x4 } public Flags flags; - /// Result ID public string id; - /// Result type (see bot API docs) public string type; - /// Result title [IfFlag(1)] public string title; - /// Result description [IfFlag(2)] public string description; - /// Document to send public InputDocument document; - /// Message to send when the result is selected public InputBotInlineMessage send_message; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_title = 0x2, - /// Field has a value - has_description = 0x4, - } - - /// Result ID - public override string ID { get => id; set => id = value; } - /// Message to send when the result is selected - public override InputBotInlineMessage SendMessage { get => send_message; set => send_message = value; } } - /// Game See + ///See [TLDef(0x4FA417F2)] - public sealed partial class InputBotInlineResultGame : InputBotInlineResultBase + public partial class InputBotInlineResultGame : InputBotInlineResultBase { - /// Result ID public string id; - /// Game short name public string short_name; - /// Message to send when the result is selected public InputBotInlineMessage send_message; - - /// Result ID - public override string ID { get => id; set => id = value; } - /// Message to send when the result is selected - public override InputBotInlineMessage SendMessage { get => send_message; set => send_message = value; } } - /// Inline message See Derived classes: , , , , , , - public abstract partial class BotInlineMessage : IObject { } - /// Send whatever media is attached to the See + ///See + public abstract partial class BotInlineMessage : ITLObject { public int flags; } + ///See [TLDef(0x764CF810)] - public sealed partial class BotInlineMessageMediaAuto : BotInlineMessage + public partial class BotInlineMessageMediaAuto : BotInlineMessage { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Caption + [Flags] public enum Flags { has_entities = 0x2, has_reply_markup = 0x4 } public string message; - /// Message entities for styled text [IfFlag(1)] public MessageEntity[] entities; - /// Inline keyboard [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_entities = 0x2, - /// Field has a value - has_reply_markup = 0x4, - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - invert_media = 0x8, - } } - /// Send a simple text message See + ///See [TLDef(0x8C7F65E2)] - public sealed partial class BotInlineMessageText : BotInlineMessage + public partial class BotInlineMessageText : BotInlineMessage { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The message + [Flags] public enum Flags { no_webpage = 0x1, has_entities = 0x2, has_reply_markup = 0x4 } public string message; - /// Message entities for styled text [IfFlag(1)] public MessageEntity[] entities; - /// Inline keyboard [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Disable webpage preview - no_webpage = 0x1, - /// Field has a value - has_entities = 0x2, - /// Field has a value - has_reply_markup = 0x4, - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - invert_media = 0x8, - } } - /// Send a geolocation See + ///See [TLDef(0x051846FD)] - public sealed partial class BotInlineMessageMediaGeo : BotInlineMessage + public partial class BotInlineMessageMediaGeo : BotInlineMessage { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Geolocation + [Flags] public enum Flags { has_heading = 0x1, has_period = 0x2, has_reply_markup = 0x4, + has_proximity_notification_radius = 0x8 } public GeoPoint geo; - /// For live locations, a direction in which the location moves, in degrees; 1-360. [IfFlag(0)] public int heading; - /// Validity period [IfFlag(1)] public int period; - /// For live locations, a maximum distance to another chat member for proximity alerts, in meters (0-100000). [IfFlag(3)] public int proximity_notification_radius; - /// Inline keyboard [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_heading = 0x1, - /// Field has a value - has_period = 0x2, - /// Field has a value - has_reply_markup = 0x4, - /// Field has a value - has_proximity_notification_radius = 0x8, - } } - /// Send a venue See + ///See [TLDef(0x8A86659C)] - public sealed partial class BotInlineMessageMediaVenue : BotInlineMessage + public partial class BotInlineMessageMediaVenue : BotInlineMessage { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Geolocation of venue + [Flags] public enum Flags { has_reply_markup = 0x4 } public GeoPoint geo; - /// Venue name public string title; - /// Address public string address; - /// Venue provider: currently only "foursquare" and "gplaces" (Google Places) need to be supported public string provider; - /// Venue ID in the provider's database public string venue_id; - /// Venue type in the provider's database public string venue_type; - /// Inline keyboard [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_reply_markup = 0x4, - } } - /// Send a contact See + ///See [TLDef(0x18D1CDC2)] - public sealed partial class BotInlineMessageMediaContact : BotInlineMessage + public partial class BotInlineMessageMediaContact : BotInlineMessage { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Phone number + [Flags] public enum Flags { has_reply_markup = 0x4 } public string phone_number; - /// First name public string first_name; - /// Last name public string last_name; - /// VCard info public string vcard; - /// Inline keyboard [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_reply_markup = 0x4, - } } - /// Send an invoice See + ///See [TLDef(0x354A9B09)] - public sealed partial class BotInlineMessageMediaInvoice : BotInlineMessage + public partial class BotInlineMessageMediaInvoice : BotInlineMessage { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Product name, 1-32 characters + [Flags] public enum Flags { has_photo = 0x1, shipping_address_requested = 0x2, has_reply_markup = 0x4, test = 0x8 } public string title; - /// Product description, 1-255 characters public string description; - /// Product photo [IfFlag(0)] public WebDocumentBase photo; - /// Three-letter ISO 4217 currency code, or XTR for Telegram Stars. public string currency; - /// Total price 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). public long total_amount; - /// Inline keyboard [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_photo = 0x1, - /// Set this flag if you require the user's shipping address to complete the order - shipping_address_requested = 0x2, - /// Field has a value - has_reply_markup = 0x4, - /// Test invoice - test = 0x8, - } - } - /// Specifies options that must be used to generate the link preview for the message, or even a standalone link preview without an attached message. See - [TLDef(0x809AD9A6)] - public sealed partial class BotInlineMessageMediaWebPage : BotInlineMessage - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The message, can be empty. - public string message; - /// Message entities for styled text - [IfFlag(1)] public MessageEntity[] entities; - /// The URL to use for the link preview. - public string url; - /// Reply markup for sending bot buttons - [IfFlag(2)] public ReplyMarkup reply_markup; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_entities = 0x2, - /// Field has a value - has_reply_markup = 0x4, - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - invert_media = 0x8, - /// If set, specifies that a large media preview should be used. - force_large_media = 0x10, - /// If set, specifies that a small media preview should be used. - force_small_media = 0x20, - /// If set, indicates that the URL used for the webpage preview was specified manually using , and may not be related to any of the URLs specified in the message. - manual = 0x80, - /// If set, the link can be opened directly without user confirmation. - safe = 0x100, - } } - /// Results of an inline query See Derived classes: , - public abstract partial class BotInlineResultBase : IObject - { - /// Result ID - public virtual string ID => default; - /// Result type (see bot API docs) - public virtual string Type => default; - /// Result title - public virtual string Title => default; - /// Result description - public virtual string Description => default; - /// Message to send - public virtual BotInlineMessage SendMessage => default; - } - /// Generic result See + ///See + public abstract partial class BotInlineResultBase : ITLObject { } + ///See [TLDef(0x11965F3A)] - public sealed partial class BotInlineResult : BotInlineResultBase + public partial class BotInlineResult : BotInlineResultBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_title = 0x2, has_description = 0x4, has_url = 0x8, has_thumb = 0x10, has_content = 0x20 } public Flags flags; - /// Result ID public string id; - /// Result type (see bot API docs) public string type; - /// Result title [IfFlag(1)] public string title; - /// Result description [IfFlag(2)] public string description; - /// URL of article or webpage [IfFlag(3)] public string url; - /// Thumbnail for the result [IfFlag(4)] public WebDocumentBase thumb; - /// Content of the result [IfFlag(5)] public WebDocumentBase content; - /// Message to send public BotInlineMessage send_message; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_title = 0x2, - /// Field has a value - has_description = 0x4, - /// Field has a value - has_url = 0x8, - /// Field has a value - has_thumb = 0x10, - /// Field has a value - has_content = 0x20, - } - - /// Result ID - public override string ID => id; - /// Result type (see bot API docs) - public override string Type => type; - /// Result title - public override string Title => title; - /// Result description - public override string Description => description; - /// Message to send - public override BotInlineMessage SendMessage => send_message; } - /// Media result See + ///See [TLDef(0x17DB940B)] - public sealed partial class BotInlineMediaResult : BotInlineResultBase + public partial class BotInlineMediaResult : BotInlineResultBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_photo = 0x1, has_document = 0x2, has_title = 0x4, has_description = 0x8 } public Flags flags; - /// Result ID public string id; - /// Result type (see bot API docs) public string type; - /// If type is photo, the photo to send [IfFlag(0)] public PhotoBase photo; - /// If type is document, the document to send [IfFlag(1)] public DocumentBase document; - /// Result title [IfFlag(2)] public string title; - /// Description [IfFlag(3)] public string description; - /// Depending on the type and on the , contains the caption of the media or the content of the message to be sent instead of the media public BotInlineMessage send_message; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_photo = 0x1, - /// Field has a value - has_document = 0x2, - /// Field has a value - has_title = 0x4, - /// Field has a value - has_description = 0x8, - } - - /// Result ID - public override string ID => id; - /// Result type (see bot API docs) - public override string Type => type; - /// Result title - public override string Title => title; - /// Description - public override string Description => description; - /// Depending on the type and on the , contains the caption of the media or the content of the message to be sent instead of the media - public override BotInlineMessage SendMessage => send_message; } - /// Result of a query to an inline bot See - [TLDef(0xE021F2F6)] - public sealed partial class Messages_BotResults : IObject + ///See + [TLDef(0x947CA848)] + public partial class Messages_BotResults : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { gallery = 0x1, has_next_offset = 0x2, has_switch_pm = 0x4 } public Flags flags; - /// Query ID public long query_id; - /// The next offset to use when navigating through results [IfFlag(1)] public string next_offset; - /// Shown as a button on top of the remaining inline result list; if clicked, redirects the user to a private chat with the bot with the specified start parameter. [IfFlag(2)] public InlineBotSwitchPM switch_pm; - /// Shown as a button on top of the remaining inline result list; if clicked, opens the specified inline mode mini app. - [IfFlag(3)] public InlineBotWebView switch_webview; - /// The results public BotInlineResultBase[] results; - /// Caching validity of the results - public int cache_time; - /// Users mentioned in the results - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Whether the result is a picture gallery - gallery = 0x1, - /// Field has a value - has_next_offset = 0x2, - /// Field has a value - has_switch_pm = 0x4, - /// Field has a value - has_switch_webview = 0x8, - } + public DateTime cache_time; + public UserBase[] users; } - /// Link to a message in a supergroup/channel See + ///See [TLDef(0x5DAB1AF4)] - public sealed partial class ExportedMessageLink : IObject + public partial class ExportedMessageLink : ITLObject { - /// URL public string link; - /// Embed code public string html; } - /// Info about a forwarded message See - [TLDef(0x4E4DF4BB)] - public sealed partial class MessageFwdHeader : IObject + ///See + [TLDef(0x5F777DCE)] + public partial class MessageFwdHeader : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_from_id = 0x1, has_channel_post = 0x4, has_post_author = 0x8, has_saved_from_peer = 0x10, + has_from_name = 0x20, has_psa_type = 0x40, imported = 0x80 } public Flags flags; - /// The ID of the user that originally sent the message [IfFlag(0)] public Peer from_id; - /// The name of the user that originally sent the message [IfFlag(5)] public string from_name; - /// When was the message originally sent public DateTime date; - /// ID of the channel message that was forwarded [IfFlag(2)] public int channel_post; - /// For channels and if signatures are enabled, author of the channel message [IfFlag(3)] public string post_author; - /// Only for messages forwarded to saved messages », contains the dialog where the message was originally sent. [IfFlag(4)] public Peer saved_from_peer; - /// Only for messages forwarded to saved messages », contains the original ID of the message in saved_from_peer. [IfFlag(4)] public int saved_from_msg_id; - /// Only for forwarded messages reforwarded to saved messages », contains the sender of the original message (i.e. if user A sends a message, then user B forwards it somewhere, then user C saves it to saved messages, this field will contain the ID of user B and from_id will contain the ID of user A). - [IfFlag(8)] public Peer saved_from_id; - /// Only for forwarded messages from users with forward privacy enabled, sent by users with forward privacy enabled, reforwarded to saved messages », contains the sender of the original message (i.e. if user A (fwd privacy enabled) sends a message, then user B (fwd privacy enabled) forwards it somewhere, then user C saves it to saved messages, this field will contain the name of user B and from_name will contain the name of user A). - [IfFlag(9)] public string saved_from_name; - /// Only for forwarded messages reforwarded to saved messages », indicates when was the original message sent (i.e. if user A sends a message @ unixtime 1, then user B forwards it somewhere @ unixtime 2, then user C saves it to saved messages @ unixtime 3, this field will contain 2, date will contain 1 and the date of the containing will contain 3). - [IfFlag(10)] public DateTime saved_date; - /// PSA type [IfFlag(6)] public string psa_type; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_from_id = 0x1, - /// Field has a value - has_channel_post = 0x4, - /// Field has a value - has_post_author = 0x8, - /// Fields and have a value - has_saved_from_peer = 0x10, - /// Field has a value - has_from_name = 0x20, - /// Field has a value - has_psa_type = 0x40, - /// Whether this message was imported from a foreign chat service, click here for more info » - imported = 0x80, - /// Field has a value - has_saved_from_id = 0x100, - /// Field has a value - has_saved_from_name = 0x200, - /// Field has a value - has_saved_date = 0x400, - /// Only for messages forwarded to saved messages », set if the original message was outgoing (though the message may have been originally outgoing even if this flag is not set, if from_id points to the current user). - saved_out = 0x800, - } } - /// Type of verification code that will be sent next if you call the resendCode method See + ///See public enum Auth_CodeType : uint { - ///The next time, the authentication code will be delivered via an immediately canceled incoming call. + ///See Sms = 0x72A3158C, - ///The next time, the authentication code is to be delivered via an outgoing phone call. + ///See Call = 0x741CD3E3, - ///The next time, the authentication code will be delivered via an immediately canceled incoming call. + ///See FlashCall = 0x226CCEFB, - ///The next time, the authentication code will be delivered via an immediately canceled incoming call, handled manually by the user. - MissedCall = 0xD61AD6EE, - ///The next time, the authentication code will be delivered via fragment.com - FragmentSms = 0x06ED998C, } - /// Type of the verification code that was sent See Derived classes: , , , , , , , , , , - public abstract partial class Auth_SentCodeType : IObject { } - /// The code was sent through the telegram app See + ///See + public abstract partial class Auth_SentCodeType : ITLObject { } + ///See [TLDef(0x3DBB5986)] - public sealed partial class Auth_SentCodeTypeApp : Auth_SentCodeType - { - /// Length of the code in bytes - public int length; - } - /// The code was sent via SMS See + public partial class Auth_SentCodeTypeApp : Auth_SentCodeType { public int length; } + ///See [TLDef(0xC000BBA2)] - public partial class Auth_SentCodeTypeSms : Auth_SentCodeType - { - /// Length of the code in bytes - public int length; - } - /// The code will be sent via a phone call: a synthesized voice will tell the user which verification code to input. See + public partial class Auth_SentCodeTypeSms : Auth_SentCodeType { public int length; } + ///See [TLDef(0x5353E5A7)] - public partial class Auth_SentCodeTypeCall : Auth_SentCodeType - { - /// Length of the verification code - public int length; - } - /// The code will be sent via a flash phone call, that will be closed immediately. The phone code will then be the phone number itself, just make sure that the phone number matches the specified pattern. See + public partial class Auth_SentCodeTypeCall : Auth_SentCodeType { public int length; } + ///See [TLDef(0xAB03C6D9)] - public sealed partial class Auth_SentCodeTypeFlashCall : Auth_SentCodeType - { - /// pattern to match - public string pattern; - } - /// The code will be sent via a flash phone call, that will be closed immediately. The last digits of the phone number that calls are the code that must be entered manually by the user. See - [TLDef(0x82006484)] - public sealed partial class Auth_SentCodeTypeMissedCall : Auth_SentCodeTypeCall - { - /// Prefix of the phone number from which the call will be made - public string prefix; - } - /// The code was sent via the previously configured login email » See - [TLDef(0xF450F59B)] - public sealed partial class Auth_SentCodeTypeEmailCode : Auth_SentCodeType - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Pattern of the email - public string email_pattern; - /// Length of the sent verification code - public int length; - /// Clients should wait for the specified amount of seconds before allowing the user to invoke Auth_ResetLoginEmail (will be 0 for Premium users). - [IfFlag(3)] public int reset_available_period; - /// An email reset was already requested, and will occur at the specified date. - [IfFlag(4)] public DateTime reset_pending_date; + public partial class Auth_SentCodeTypeFlashCall : Auth_SentCodeType { public string pattern; } - [Flags] public enum Flags : uint - { - /// Whether authorization through Apple ID is allowed - apple_signin_allowed = 0x1, - /// Whether authorization through Google ID is allowed - google_signin_allowed = 0x2, - /// Field has a value - has_reset_available_period = 0x8, - /// Field has a value - has_reset_pending_date = 0x10, - } - } - /// The user should add and verify an email address in order to login as described here ». See - [TLDef(0xA5491DEA)] - public sealed partial class Auth_SentCodeTypeSetUpEmailRequired : Auth_SentCodeType - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - - [Flags] public enum Flags : uint - { - /// Whether authorization through Apple ID is allowed - apple_signin_allowed = 0x1, - /// Whether authorization through Google ID is allowed - google_signin_allowed = 0x2, - } - } - /// The code was delivered via fragment.com. See - [TLDef(0xD9565C39)] - public sealed partial class Auth_SentCodeTypeFragmentSms : Auth_SentCodeTypeSms - { - /// Open the specified URL to log into fragment.com with the wallet that owns the specified phone number and view the code. - public string url; - } - /// An authentication code should be delivered via SMS after Firebase attestation, as described in the auth documentation ». See - [TLDef(0x009FD736)] - public sealed partial class Auth_SentCodeTypeFirebaseSms : Auth_SentCodeTypeSms - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// On Android, the nonce to be used as described in the auth documentation » - [IfFlag(0)] public byte[] nonce; - /// Google Play Integrity project ID - [IfFlag(2)] public long play_integrity_project_id; - /// Play Integrity API nonce - [IfFlag(2)] public byte[] play_integrity_nonce; - /// On iOS, must be compared with the receipt extracted from the received push notification. - [IfFlag(1)] public string receipt; - /// On iOS: if a push notification with the ios_push_secret isn't received within push_timeout seconds, the next_type authentication method must be used, with Auth_ResendCode. - [IfFlag(1)] public int push_timeout; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_nonce = 0x1, - /// Fields and have a value - has_receipt = 0x2, - /// Fields and have a value - has_play_integrity_project_id = 0x4, - } - } - /// The code was sent via SMS as a secret word, starting with the letter specified in beginning See - [TLDef(0xA416AC81)] - public sealed partial class Auth_SentCodeTypeSmsWord : Auth_SentCodeType - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// If set, the secret word in the sent SMS (which may contain multiple words) starts with this letter. - [IfFlag(0)] public string beginning; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_beginning = 0x1, - } - } - /// The code was sent via SMS as a secret phrase starting with the word specified in beginning See - [TLDef(0xB37794AF)] - public sealed partial class Auth_SentCodeTypeSmsPhrase : Auth_SentCodeType - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// If set, the secret phrase (and the SMS) starts with this word. - [IfFlag(0)] public string beginning; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_beginning = 0x1, - } - } - - /// Callback answer sent by the bot in response to a button press See + ///See [TLDef(0x36585EA4)] - public sealed partial class Messages_BotCallbackAnswer : IObject + public partial class Messages_BotCallbackAnswer : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_message = 0x1, alert = 0x2, has_url_field = 0x4, has_url = 0x8, native_ui = 0x10 } public Flags flags; - /// Alert to show [IfFlag(0)] public string message; - /// URL to open [IfFlag(2)] public string url; - /// For how long should this answer be cached - public int cache_time; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_message = 0x1, - /// Whether an alert should be shown to the user instead of a toast notification - alert = 0x2, - /// Field has a value - has_url_field = 0x4, - /// Whether an URL is present - has_url = 0x8, - /// Whether to show games in WebView or in native UI. - native_ui = 0x10, - } + public DateTime cache_time; } - /// Message edit data for media See + ///See [TLDef(0x26B5DDE6)] - public sealed partial class Messages_MessageEditData : IObject + public partial class Messages_MessageEditData : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { caption = 0x1 } public Flags flags; - - [Flags] public enum Flags : uint - { - /// Media caption, if the specified media's caption can be edited - caption = 0x1, - } } - /// Represents a sent inline message from the perspective of a bot See Derived classes: , - public abstract partial class InputBotInlineMessageIDBase : IObject - { - /// DC ID to use when working with this inline message - public abstract int DcId { get; set; } - /// Access hash of message - public abstract long AccessHash { get; set; } - } - /// Represents a sent inline message from the perspective of a bot (legacy constructor) See + ///See + public abstract partial class InputBotInlineMessageIDBase : ITLObject { } + ///See [TLDef(0x890C3D89)] - public sealed partial class InputBotInlineMessageID : InputBotInlineMessageIDBase + public partial class InputBotInlineMessageID : InputBotInlineMessageIDBase { - /// DC ID to use when working with this inline message 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
public long access_hash; - - /// DC ID to use when working with this inline message - public override int DcId { get => dc_id; set => dc_id = value; } - /// Access hash of message - public override long AccessHash { get => access_hash; set => access_hash = value; } } - ///
Represents a sent inline message from the perspective of a bot See + ///See [TLDef(0xB6D915D7)] - public sealed partial class InputBotInlineMessageID64 : InputBotInlineMessageIDBase + public partial class InputBotInlineMessageID64 : InputBotInlineMessageIDBase { - /// DC ID to use when working with this inline message public int dc_id; - /// ID of the owner of this message public long owner_id; - /// ID of message public int id; - /// 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 - public override int DcId { get => dc_id; set => dc_id = value; } - /// Access hash of message - public override long AccessHash { get => access_hash; set => access_hash = value; } } - ///
The bot requested the user to message them in private See + ///See [TLDef(0x3C20629F)] - public sealed partial class InlineBotSwitchPM : IObject + public partial class InlineBotSwitchPM : ITLObject { - /// Text for the button that switches the user to a private chat with the bot and sends the bot a start message with the parameter start_parameter (can be empty) public string text; - /// The parameter for the /start parameter public string start_param; } - /// Dialog info of multiple peers See + ///See [TLDef(0x3371C354)] - public sealed partial class Messages_PeerDialogs : IObject, IPeerResolver + public partial class Messages_PeerDialogs : ITLObject { - /// Dialog info public DialogBase[] dialogs; - /// Messages mentioned in dialog info public MessageBase[] messages; - /// Chats - public Dictionary chats; - /// Users - public Dictionary users; - /// Current update state of dialog + public ChatBase[] chats; + public UserBase[] users; public Updates_State state; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); } - /// Top peer See + ///See [TLDef(0xEDCDC05B)] - public sealed partial class TopPeer : IObject + public partial class TopPeer : ITLObject { - /// Peer public Peer peer; - /// Rating as computed in top peer rating » public double rating; } - /// Top peer category See + ///See public enum TopPeerCategory : uint { - ///Most used bots + ///See BotsPM = 0xAB661B5B, - ///Most used inline bots + ///See BotsInline = 0x148677E2, - ///Users we've chatted most frequently with + ///See Correspondents = 0x0637B7ED, - ///Often-opened groups and supergroups + ///See Groups = 0xBD17A14A, - ///Most frequently visited channels + ///See Channels = 0x161D9628, - ///Most frequently called users + ///See PhoneCalls = 0x1E76A78C, - ///Users to which the users often forwards messages to + ///See ForwardUsers = 0xA8406CA9, - ///Chats to which the users often forwards messages to + ///See ForwardChats = 0xFBEEC0F0, - ///Most frequently used Main Mini Bot Apps. - BotsApp = 0xFD9E7BEC, } - /// Top peer category See + ///See [TLDef(0xFB834291)] - public sealed partial class TopPeerCategoryPeers : IObject + public partial class TopPeerCategoryPeers : ITLObject { - /// Top peer category of peers public TopPeerCategory category; - /// Count of peers public int count; - /// Peers public TopPeer[] peers; } - /// Top peers See Derived classes: , - /// a value means contacts.topPeersNotModified - public abstract partial class Contacts_TopPeersBase : IObject { } - /// Top peers See + ///See + ///a null value means contacts.topPeersNotModified + public abstract partial class Contacts_TopPeersBase : ITLObject { } + ///See [TLDef(0x70B772A8)] - public sealed partial class Contacts_TopPeers : Contacts_TopPeersBase, IPeerResolver + public partial class Contacts_TopPeers : Contacts_TopPeersBase { - /// Top peers by top peer category public TopPeerCategoryPeers[] categories; - /// Chats - public Dictionary chats; - /// Users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Top peers disabled See + ///See [TLDef(0xB52C939D)] - public sealed partial class Contacts_TopPeersDisabled : Contacts_TopPeersBase { } + public partial class Contacts_TopPeersDisabled : Contacts_TopPeersBase { } - /// Represents a message draft. See Derived classes: , - public abstract partial class DraftMessageBase : IObject { } - /// Empty draft See + ///See + public abstract partial class DraftMessageBase : ITLObject { } + ///See [TLDef(0x1B0C841A)] - public sealed partial class DraftMessageEmpty : DraftMessageBase + public partial class DraftMessageEmpty : DraftMessageBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_date = 0x1 } public Flags flags; - /// When was the draft last updated [IfFlag(0)] public DateTime date; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_date = 0x1, - } } - /// Represents a message draft. See - [TLDef(0x96EAA5EB)] - public sealed partial class DraftMessage : DraftMessageBase + ///See + [TLDef(0xFD8E711F)] + public partial class DraftMessage : DraftMessageBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_reply_to_msg_id = 0x1, no_webpage = 0x2, has_entities = 0x8 } public Flags flags; - /// If set, indicates that the message should be sent in reply to the specified message or story. - [IfFlag(4)] public InputReplyTo reply_to; - /// The draft + [IfFlag(0)] public int reply_to_msg_id; public string message; - /// Message entities for styled text. [IfFlag(3)] public MessageEntity[] entities; - /// Media. - [IfFlag(5)] public InputMedia media; - /// Date of last update of the draft. public DateTime date; - /// A message effect that should be played as specified here ». - [IfFlag(7)] public long effect; - /// Used to suggest a post to a channel, see here » for more info on the full flow. - [IfFlag(8)] public SuggestedPost suggested_post; - - [Flags] public enum Flags : uint - { - /// Whether no webpage preview will be generated - no_webpage = 0x2, - /// Field has a value - has_entities = 0x8, - /// Field has a value - has_reply_to = 0x10, - /// Field has a value - has_media = 0x20, - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - invert_media = 0x40, - /// Field has a value - has_effect = 0x80, - /// Field has a value - has_suggested_post = 0x100, - } } - /// Featured stickers See Derived classes: , - public abstract partial class Messages_FeaturedStickersBase : IObject { } - /// Featured stickers haven't changed See + ///See + public abstract partial class Messages_FeaturedStickersBase : ITLObject { } + ///See [TLDef(0xC6DC0C66)] - public sealed partial class Messages_FeaturedStickersNotModified : Messages_FeaturedStickersBase + public partial class Messages_FeaturedStickersNotModified : Messages_FeaturedStickersBase { public int count; } + ///See + [TLDef(0x84C02310)] + public partial class Messages_FeaturedStickers : Messages_FeaturedStickersBase { - /// Total number of featured stickers - public int count; - } - /// Featured stickersets See - [TLDef(0xBE382906)] - public sealed partial class Messages_FeaturedStickers : Messages_FeaturedStickersBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Hash used for caching, for more info click here public long hash; - /// Total number of featured stickers public int count; - /// Featured stickersets public StickerSetCoveredBase[] sets; - /// IDs of new featured stickersets public long[] unread; - - [Flags] public enum Flags : uint - { - /// Whether this is a premium stickerset - premium = 0x1, - } } - /// Recently used stickers See - /// a value means messages.recentStickersNotModified + ///See + ///a null value means messages.recentStickersNotModified [TLDef(0x88D37C56)] - public sealed partial class Messages_RecentStickers : IObject + public partial class Messages_RecentStickers : ITLObject { - /// Hash used for caching, for more info click here public long hash; - /// Emojis associated to stickers public StickerPack[] packs; - /// Recent stickers public DocumentBase[] stickers; - /// When was each sticker last used public int[] dates; } - /// Archived stickersets See + ///See [TLDef(0x4FCBA9C8)] - public sealed partial class Messages_ArchivedStickers : IObject + public partial class Messages_ArchivedStickers : ITLObject { - /// Number of archived stickers public int count; - /// Archived stickersets public StickerSetCoveredBase[] sets; } - /// Result of stickerset installation process See Derived classes: , - public abstract partial class Messages_StickerSetInstallResult : IObject { } - /// The stickerset was installed successfully See + ///See + public abstract partial class Messages_StickerSetInstallResult : ITLObject { } + ///See [TLDef(0x38641628)] - public sealed partial class Messages_StickerSetInstallResultSuccess : Messages_StickerSetInstallResult { } - /// The stickerset was installed, but since there are too many stickersets some were archived See + public partial class Messages_StickerSetInstallResultSuccess : Messages_StickerSetInstallResult { } + ///See [TLDef(0x35E410A8)] - public sealed partial class Messages_StickerSetInstallResultArchive : Messages_StickerSetInstallResult - { - /// Archived stickersets - public StickerSetCoveredBase[] sets; - } + public partial class Messages_StickerSetInstallResultArchive : Messages_StickerSetInstallResult { public StickerSetCoveredBase[] sets; } - /// Stickerset preview See Derived classes: , , , - public abstract partial class StickerSetCoveredBase : IObject - { - /// Stickerset - public virtual StickerSet Set => default; - } - /// Stickerset with a single sticker as preview See + ///See + public abstract partial class StickerSetCoveredBase : ITLObject { } + ///See [TLDef(0x6410A5D2)] - public sealed partial class StickerSetCovered : StickerSetCoveredBase + public partial class StickerSetCovered : StickerSetCoveredBase { - /// Stickerset public StickerSet set; - /// Preview public DocumentBase cover; - - /// Stickerset - public override StickerSet Set => set; } - /// Stickerset, with multiple stickers as preview See + ///See [TLDef(0x3407E51B)] - public sealed partial class StickerSetMultiCovered : StickerSetCoveredBase + public partial class StickerSetMultiCovered : StickerSetCoveredBase { - /// Stickerset public StickerSet set; - /// Preview stickers public DocumentBase[] covers; - - /// 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
- [TLDef(0x40D13C0E)] - public sealed partial class StickerSetFullCovered : StickerSetCoveredBase - { - /// Stickerset - public StickerSet set; - /// Emoji information about every sticker in the stickerset - public StickerPack[] packs; - /// Keywords for some or every sticker in the stickerset. - public StickerKeyword[] keywords; - /// Stickers - public DocumentBase[] documents; - - /// Stickerset - public override StickerSet Set => set; - } - /// Just the stickerset information, with no previews. See - [TLDef(0x77B15D1C)] - public sealed partial class StickerSetNoCovered : StickerSetCoveredBase - { - /// Stickerset information. - public StickerSet set; - - /// Stickerset information. - public override StickerSet Set => set; } - /// Position on a photo where a mask should be placed when attaching stickers to media » See + ///See [TLDef(0xAED6DBB2)] - public sealed partial class MaskCoords : IObject + public partial class MaskCoords : ITLObject { - /// Part of the face, relative to which the mask should be placed public int n; - /// Shift by X-axis measured in widths of the mask scaled to the face size, from left to right. (For example, -1.0 will place the mask just to the left of the default mask position) public double x; - /// Shift by Y-axis measured in widths of the mask scaled to the face size, from left to right. (For example, -1.0 will place the mask just below the default mask position) public double y; - /// Mask scaling coefficient. (For example, 2.0 means a doubled size) public double zoom; } - /// Represents a media with attached stickers See Derived classes: , - public abstract partial class InputStickeredMedia : IObject { } - /// A photo with stickers attached See + ///See + public abstract partial class InputStickeredMedia : ITLObject { } + ///See [TLDef(0x4A992157)] - public sealed partial class InputStickeredMediaPhoto : InputStickeredMedia - { - /// The photo - public InputPhoto id; - } - /// A document with stickers attached See + public partial class InputStickeredMediaPhoto : InputStickeredMedia { public InputPhoto id; } + ///See [TLDef(0x0438865B)] - public sealed partial class InputStickeredMediaDocument : InputStickeredMedia - { - /// The document - public InputDocument id; - } + public partial class InputStickeredMediaDocument : InputStickeredMedia { public InputDocument id; } - /// Indicates an already sent game See + ///See [TLDef(0xBDF9653B)] - public sealed partial class Game : IObject + public partial class Game : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_document = 0x1 } public Flags flags; - /// ID of the game public long id; - /// Access hash of the game public long access_hash; - /// Short name for the game public string short_name; - /// Title of the game public string title; - /// Game description public string description; - /// Game preview public PhotoBase photo; - /// Optional attached document [IfFlag(0)] public DocumentBase document; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_document = 0x1, - } } - /// A game to send See Derived classes: , - public abstract partial class InputGame : IObject { } - /// Indicates an already sent game See + ///See + public abstract partial class InputGame : ITLObject { } + ///See [TLDef(0x032C3E77)] - public sealed partial class InputGameID : InputGame + public partial class InputGameID : InputGame { - /// game ID from constructor public long id; - /// REQUIRED FIELD. See how to obtain it
access hash from constructor
public long access_hash; } - ///
Game by short name See + ///See [TLDef(0xC331E80A)] - public sealed partial class InputGameShortName : InputGame + public partial class InputGameShortName : InputGame { - /// The bot that provides the game public InputUserBase bot_id; - /// The game's short name, usually obtained from a game link » public string short_name; } - /// Game highscore See + ///See [TLDef(0x73A379EB)] - public sealed partial class HighScore : IObject + public partial class HighScore : ITLObject { - /// Position in highscore list public int pos; - /// User ID public long user_id; - /// Score public int score; } - /// Highscores in a game See + ///See [TLDef(0x9A3BFD99)] - public sealed partial class Messages_HighScores : IObject + public partial class Messages_HighScores : ITLObject { - /// Highscores public HighScore[] scores; - /// Users, associated to the highscores - public Dictionary users; + public UserBase[] users; } - /// Rich text See Derived classes: , , , , , , , , , , , , , , - /// a value means textEmpty - public abstract partial class RichText : IObject { } - /// Plain text See + ///See + ///a null value means textEmpty + public abstract partial class RichText : ITLObject { } + ///See [TLDef(0x744694E0)] - public sealed partial class TextPlain : RichText - { - /// Text - public string text; - } - /// Bold text See + public partial class TextPlain : RichText { public string text; } + ///See [TLDef(0x6724ABC4)] - public sealed partial class TextBold : RichText - { - /// Text - public RichText text; - } - /// Italic text See + public partial class TextBold : RichText { public RichText text; } + ///See [TLDef(0xD912A59C)] - public sealed partial class TextItalic : RichText - { - /// Text - public RichText text; - } - /// Underlined text See + public partial class TextItalic : RichText { public RichText text; } + ///See [TLDef(0xC12622C4)] - public sealed partial class TextUnderline : RichText - { - /// Text - public RichText text; - } - /// Strikethrough text See + public partial class TextUnderline : RichText { public RichText text; } + ///See [TLDef(0x9BF8BB95)] - public sealed partial class TextStrike : RichText - { - /// Text - public RichText text; - } - /// fixed-width rich text See + public partial class TextStrike : RichText { public RichText text; } + ///See [TLDef(0x6C3F19B9)] - public sealed partial class TextFixed : RichText - { - /// Text - public RichText text; - } - /// Link See + public partial class TextFixed : RichText { public RichText text; } + ///See [TLDef(0x3C2884C1)] - public sealed partial class TextUrl : RichText + public partial class TextUrl : RichText { - /// Text of link public RichText text; - /// Webpage HTTP URL public string url; - /// If a preview was already generated for the page, the page ID public long webpage_id; } - /// Rich text email link See + ///See [TLDef(0xDE5A0DD6)] - public sealed partial class TextEmail : RichText + public partial class TextEmail : RichText { - /// Link text public RichText text; - /// Email address public string email; } - /// Concatenation of rich texts See + ///See [TLDef(0x7E6260D7)] - public sealed partial class TextConcat : RichText - { - /// Concatenated rich texts - public RichText[] texts; - } - /// Subscript text See + public partial class TextConcat : RichText { public RichText[] texts; } + ///See [TLDef(0xED6A8504)] - public sealed partial class TextSubscript : RichText - { - /// Text - public RichText text; - } - /// Superscript text See + public partial class TextSubscript : RichText { public RichText text; } + ///See [TLDef(0xC7FB5E01)] - public sealed partial class TextSuperscript : RichText - { - /// Text - public RichText text; - } - /// Highlighted text See + public partial class TextSuperscript : RichText { public RichText text; } + ///See [TLDef(0x034B8621)] - public sealed partial class TextMarked : RichText - { - /// Text - public RichText text; - } - /// Rich text linked to a phone number See + public partial class TextMarked : RichText { public RichText text; } + ///See [TLDef(0x1CCB966A)] - public sealed partial class TextPhone : RichText + public partial class TextPhone : RichText { - /// Text public RichText text; - /// Phone number public string phone; } - /// Inline image See + ///See [TLDef(0x081CCF4F)] - public sealed partial class TextImage : RichText + public partial class TextImage : RichText { - /// Document ID public long document_id; - /// Width public int w; - /// Height public int h; } - /// Text linking to another section of the page See + ///See [TLDef(0x35553762)] - public sealed partial class TextAnchor : RichText + public partial class TextAnchor : RichText { - /// Text public RichText text; - /// Section name public string name; } - /// Represents an instant view page element See Derived classes: , , , , , , , , , , , , , , , , , , , , , , , , , , , , - public abstract partial class PageBlock : IObject { } - /// Unsupported IV element See + ///See + public abstract partial class PageBlock : ITLObject { } + ///See [TLDef(0x13567E8A)] - public sealed partial class PageBlockUnsupported : PageBlock { } - /// Title See + public partial class PageBlockUnsupported : PageBlock { } + ///See [TLDef(0x70ABC3FD)] - public sealed partial class PageBlockTitle : PageBlock - { - /// Title - public RichText text; - } - /// Subtitle See + public partial class PageBlockTitle : PageBlock { public RichText text; } + ///See [TLDef(0x8FFA9A1F)] - public sealed partial class PageBlockSubtitle : PageBlock - { - /// Text - public RichText text; - } - /// Author and date of creation of article See + public partial class PageBlockSubtitle : PageBlock { public RichText text; } + ///See [TLDef(0xBAAFE5E0)] - public sealed partial class PageBlockAuthorDate : PageBlock + public partial class PageBlockAuthorDate : PageBlock { - /// Author name public RichText author; - /// Date of publication public DateTime published_date; } - /// Page header See + ///See [TLDef(0xBFD064EC)] - public sealed partial class PageBlockHeader : PageBlock - { - /// Contents - public RichText text; - } - /// Subheader See + public partial class PageBlockHeader : PageBlock { public RichText text; } + ///See [TLDef(0xF12BB6E1)] - public sealed partial class PageBlockSubheader : PageBlock - { - /// Subheader - public RichText text; - } - /// A paragraph See + public partial class PageBlockSubheader : PageBlock { public RichText text; } + ///See [TLDef(0x467A0766)] - public sealed partial class PageBlockParagraph : PageBlock - { - /// Text - public RichText text; - } - /// Preformatted (<pre> text) See + public partial class PageBlockParagraph : PageBlock { public RichText text; } + ///See [TLDef(0xC070D93E)] - public sealed partial class PageBlockPreformatted : PageBlock + public partial class PageBlockPreformatted : PageBlock { - /// Text public RichText text; - /// Programming language of preformatted text public string language; } - /// Page footer See + ///See [TLDef(0x48870999)] - public sealed partial class PageBlockFooter : PageBlock - { - /// Contents - public RichText text; - } - /// An empty block separating a page See + public partial class PageBlockFooter : PageBlock { public RichText text; } + ///See [TLDef(0xDB20B188)] - public sealed partial class PageBlockDivider : PageBlock { } - /// Link to section within the page itself (like <a href="#target">anchor</a>) See + public partial class PageBlockDivider : PageBlock { } + ///See [TLDef(0xCE0D37B0)] - public sealed partial class PageBlockAnchor : PageBlock - { - /// Name of target section - public string name; - } - /// Unordered list of IV blocks See + public partial class PageBlockAnchor : PageBlock { public string name; } + ///See [TLDef(0xE4E88011)] - public sealed partial class PageBlockList : PageBlock - { - /// List of blocks in an IV page - public PageListItem[] items; - } - /// Quote (equivalent to the HTML <blockquote>) See + public partial class PageBlockList : PageBlock { public PageListItem[] items; } + ///See [TLDef(0x263D7C26)] - public sealed partial class PageBlockBlockquote : PageBlock + public partial class PageBlockBlockquote : PageBlock { - /// Quote contents public RichText text; - /// Caption public RichText caption; } - /// Pullquote See + ///See [TLDef(0x4F4456D3)] - public sealed partial class PageBlockPullquote : PageBlock + public partial class PageBlockPullquote : PageBlock { - /// Text public RichText text; - /// Caption public RichText caption; } - /// A photo See + ///See [TLDef(0x1759C560)] - public sealed partial class PageBlockPhoto : PageBlock + public partial class PageBlockPhoto : PageBlock { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_url = 0x1 } public Flags flags; - /// Photo ID public long photo_id; - /// Caption public PageCaption caption; - /// HTTP URL of page the photo leads to when clicked [IfFlag(0)] public string url; - /// ID of preview of the page the photo leads to when clicked [IfFlag(0)] public long webpage_id; - - [Flags] public enum Flags : uint - { - /// Fields and have a value - has_url = 0x1, - } } - /// Video See + ///See [TLDef(0x7C8FE7B6)] - public sealed partial class PageBlockVideo : PageBlock + public partial class PageBlockVideo : PageBlock { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { autoplay = 0x1, loop = 0x2 } public Flags flags; - /// Video ID public long video_id; - /// Caption public PageCaption caption; - - [Flags] public enum Flags : uint - { - /// Whether the video is set to autoplay - autoplay = 0x1, - /// Whether the video is set to loop - loop = 0x2, - } } - /// A page cover See + ///See [TLDef(0x39F23300)] - public sealed partial class PageBlockCover : PageBlock - { - /// Cover - public PageBlock cover; - } - /// An embedded webpage See + public partial class PageBlockCover : PageBlock { public PageBlock cover; } + ///See [TLDef(0xA8718DC5)] - public sealed partial class PageBlockEmbed : PageBlock + public partial class PageBlockEmbed : PageBlock { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { full_width = 0x1, has_url = 0x2, has_html = 0x4, allow_scrolling = 0x8, has_poster_photo_id = 0x10, + has_w = 0x20 } public Flags flags; - /// Web page URL, if available [IfFlag(1)] public string url; - /// HTML-markup of the embedded page [IfFlag(2)] public string html; - /// Poster photo, if available [IfFlag(4)] public long poster_photo_id; - /// Block width, if known [IfFlag(5)] public int w; - /// Block height, if known [IfFlag(5)] public int h; - /// Caption public PageCaption caption; - - [Flags] public enum Flags : uint - { - /// Whether the block should be full width - full_width = 0x1, - /// Field has a value - has_url = 0x2, - /// Field has a value - has_html = 0x4, - /// Whether scrolling should be allowed - allow_scrolling = 0x8, - /// Field has a value - has_poster_photo_id = 0x10, - /// Fields and have a value - has_w = 0x20, - } } - /// An embedded post See + ///See [TLDef(0xF259A80B)] - public sealed partial class PageBlockEmbedPost : PageBlock + public partial class PageBlockEmbedPost : PageBlock { - /// Web page URL public string url; - /// ID of generated webpage preview public long webpage_id; - /// ID of the author's photo public long author_photo_id; - /// Author name public string author; - /// Creation date public DateTime date; - /// Post contents public PageBlock[] blocks; - /// Caption public PageCaption caption; } - /// Collage of media See + ///See [TLDef(0x65A0FA4D)] - public sealed partial class PageBlockCollage : PageBlock + public partial class PageBlockCollage : PageBlock { - /// Media elements public PageBlock[] items; - /// Caption public PageCaption caption; } - /// Slideshow See + ///See [TLDef(0x031F9590)] - public sealed partial class PageBlockSlideshow : PageBlock + public partial class PageBlockSlideshow : PageBlock { - /// Slideshow items public PageBlock[] items; - /// Caption public PageCaption caption; } - /// Reference to a telegram channel See + ///See [TLDef(0xEF1751B5)] - public sealed partial class PageBlockChannel : PageBlock - { - /// The channel/supergroup/chat - public ChatBase channel; - } - /// Audio See + public partial class PageBlockChannel : PageBlock { public ChatBase channel; } + ///See [TLDef(0x804361EA)] - public sealed partial class PageBlockAudio : PageBlock + public partial class PageBlockAudio : PageBlock { - /// Audio ID (to be fetched from the container public long audio_id; - /// Audio caption public PageCaption caption; } - /// Kicker See + ///See [TLDef(0x1E148390)] - public sealed partial class PageBlockKicker : PageBlock - { - /// Contents - public RichText text; - } - /// Table See + public partial class PageBlockKicker : PageBlock { public RichText text; } + ///See [TLDef(0xBF4DEA82)] - public sealed partial class PageBlockTable : PageBlock + public partial class PageBlockTable : PageBlock { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { bordered = 0x1, striped = 0x2 } public Flags flags; - /// Title public RichText title; - /// Table rows public PageTableRow[] rows; - - [Flags] public enum Flags : uint - { - /// Does the table have a visible border? - bordered = 0x1, - /// Is the table striped? - striped = 0x2, - } } - /// Ordered list of IV blocks See + ///See [TLDef(0x9A8AE1E1)] - public sealed partial class PageBlockOrderedList : PageBlock - { - /// List items - public PageListOrderedItem[] items; - } - /// A collapsible details block See + public partial class PageBlockOrderedList : PageBlock { public PageListOrderedItem[] items; } + ///See [TLDef(0x76768BED)] - public sealed partial class PageBlockDetails : PageBlock + public partial class PageBlockDetails : PageBlock { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { open = 0x1 } public Flags flags; - /// Block contents public PageBlock[] blocks; - /// Always visible heading for the block public RichText title; - - [Flags] public enum Flags : uint - { - /// Whether the block is open by default - open = 0x1, - } } - /// Related articles See + ///See [TLDef(0x16115A96)] - public sealed partial class PageBlockRelatedArticles : PageBlock + public partial class PageBlockRelatedArticles : PageBlock { - /// Title public RichText title; - /// Related articles public PageRelatedArticle[] articles; } - /// A map See + ///See [TLDef(0xA44F3EF6)] - public sealed partial class PageBlockMap : PageBlock + public partial class PageBlockMap : PageBlock { - /// Location of the map center public GeoPoint geo; - /// Map zoom level; 13-20 public int zoom; - /// Map width in pixels before applying scale; 16-102 public int w; - /// Map height in pixels before applying scale; 16-1024 public int h; - /// Caption public PageCaption caption; } - /// Why was the phone call discarded? See Derived classes: , , , , - public abstract partial class PhoneCallDiscardReason : IObject { } - /// The phone call was missed See - [TLDef(0x85E42301)] - public sealed partial class PhoneCallDiscardReasonMissed : PhoneCallDiscardReason { } - /// The phone call was disconnected See - [TLDef(0xE095C1A0)] - public sealed partial class PhoneCallDiscardReasonDisconnect : PhoneCallDiscardReason { } - /// The phone call was ended normally See - [TLDef(0x57ADC690)] - public sealed partial class PhoneCallDiscardReasonHangup : PhoneCallDiscardReason { } - /// The phone call was discarded because the user is busy in another call See - [TLDef(0xFAF7E8C9)] - public sealed partial class PhoneCallDiscardReasonBusy : PhoneCallDiscardReason { } - /// This phone call was migrated to a conference call. See - [TLDef(0x9FBBF1F7)] - public sealed partial class PhoneCallDiscardReasonMigrateConferenceCall : PhoneCallDiscardReason + ///See + public enum PhoneCallDiscardReason : uint { - /// Conference link » slug. - public string slug; + ///See + Missed = 0x85E42301, + ///See + Disconnect = 0xE095C1A0, + ///See + Hangup = 0x57ADC690, + ///See + Busy = 0xFAF7E8C9, } - /// Represents a json-encoded object See + ///See [TLDef(0x7D748D04)] - public sealed partial class DataJSON : IObject - { - /// JSON-encoded object - public string data; - } + public partial class DataJSON : ITLObject { public string data; } - /// This object represents a portion of the price for goods or services. See + ///See [TLDef(0xCB296BF8)] - public sealed partial class LabeledPrice : IObject + public partial class LabeledPrice : ITLObject { - /// Portion label public string label; - /// Price of the product 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). public long amount; } - /// Invoice See - [TLDef(0x049EE584)] - public sealed partial class Invoice : IObject + ///See + [TLDef(0x0CD886E0)] + public partial class Invoice : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { test = 0x1, name_requested = 0x2, phone_requested = 0x4, email_requested = 0x8, + shipping_address_requested = 0x10, flexible = 0x20, phone_to_provider = 0x40, email_to_provider = 0x80, + has_max_tip_amount = 0x100 } public Flags flags; - /// Three-letter ISO 4217 currency code, or XTR for Telegram Stars. public string currency; - /// Price breakdown, a list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.) public LabeledPrice[] prices; - /// The maximum accepted amount for tips 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). [IfFlag(8)] public long max_tip_amount; - /// A vector of suggested amounts of tips in the smallest units of the currency (integer, not float/double). At most 4 suggested tip amounts can be specified. The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount. [IfFlag(8)] public long[] suggested_tip_amounts; - /// Terms of service URL - [IfFlag(10)] public string terms_url; - /// The number of seconds between consecutive Telegram Star debiting for bot subscription invoices - [IfFlag(11)] public int subscription_period; - - [Flags] public enum Flags : uint - { - /// Test invoice - test = 0x1, - /// Set this flag if you require the user's full name to complete the order - name_requested = 0x2, - /// Set this flag if you require the user's phone number to complete the order - phone_requested = 0x4, - /// Set this flag if you require the user's email address to complete the order - email_requested = 0x8, - /// Set this flag if you require the user's shipping address to complete the order - shipping_address_requested = 0x10, - /// Set this flag if the final price depends on the shipping method - flexible = 0x20, - /// Set this flag if user's phone number should be sent to provider - phone_to_provider = 0x40, - /// Set this flag if user's email address should be sent to provider - email_to_provider = 0x80, - /// Fields and have a value - has_max_tip_amount = 0x100, - /// Whether this is a recurring payment - recurring = 0x200, - /// Field has a value - has_terms_url = 0x400, - /// Field has a value - has_subscription_period = 0x800, - } } - /// Payment identifier See + ///See [TLDef(0xEA02C27E)] - public sealed partial class PaymentCharge : IObject + public partial class PaymentCharge : ITLObject { - /// Telegram payment identifier public string id; - /// Provider payment identifier public string provider_charge_id; } - /// Shipping address See + ///See [TLDef(0x1E8CAAEB)] - public sealed partial class PostAddress : IObject + public partial class PostAddress : ITLObject { - /// First line for the address public string street_line1; - /// Second line for the address public string street_line2; - /// City public string city; - /// State, if applicable (empty otherwise) public string state; - /// ISO 3166-1 alpha-2 country code public string country_iso2; - /// Address post code public string post_code; } - /// Order info provided by the user See + ///See [TLDef(0x909C3F94)] - public sealed partial class PaymentRequestedInfo : IObject + public partial class PaymentRequestedInfo : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_name = 0x1, has_phone = 0x2, has_email = 0x4, has_shipping_address = 0x8 } public Flags flags; - /// User's full name [IfFlag(0)] public string name; - /// User's phone number [IfFlag(1)] public string phone; - /// User's email address [IfFlag(2)] public string email; - /// User's shipping address [IfFlag(3)] public PostAddress shipping_address; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_name = 0x1, - /// Field has a value - has_phone = 0x2, - /// Field has a value - has_email = 0x4, - /// Field has a value - has_shipping_address = 0x8, - } } - /// Saved payment credentials See Derived classes: - public abstract partial class PaymentSavedCredentials : IObject { } - /// Saved credit card See + ///See + public abstract partial class PaymentSavedCredentials : ITLObject { } + ///See [TLDef(0xCDC27A1F)] - public sealed partial class PaymentSavedCredentialsCard : PaymentSavedCredentials + public partial class PaymentSavedCredentialsCard : PaymentSavedCredentials { - /// Card ID public string id; - /// Title public string title; } - /// Remote document See Derived classes: , - public abstract partial class WebDocumentBase : IObject - { - /// Document URL - public virtual string Url => default; - /// File size - public virtual int Size => default; - /// MIME type - public virtual string MimeType => default; - /// Attributes for media types - public virtual DocumentAttribute[] Attributes => default; - } - /// Remote document See + ///See + public abstract partial class WebDocumentBase : ITLObject { } + ///See [TLDef(0x1C570ED1)] - public sealed partial class WebDocument : WebDocumentBase + public partial class WebDocument : WebDocumentBase { - /// Document URL public string url; - /// Access hash public long access_hash; - /// File size public int size; - /// MIME type public string mime_type; - /// Attributes for media types public DocumentAttribute[] attributes; - - /// Document URL - public override string Url => url; - /// File size - public override int Size => size; - /// MIME type - public override string MimeType => mime_type; - /// Attributes for media types - public override DocumentAttribute[] Attributes => attributes; } - /// Remote document that can be downloaded without proxying through telegram See + ///See [TLDef(0xF9C8BCC6)] - public sealed partial class WebDocumentNoProxy : WebDocumentBase + public partial class WebDocumentNoProxy : WebDocumentBase { - /// Document URL public string url; - /// File size public int size; - /// MIME type public string mime_type; - /// Attributes for media types public DocumentAttribute[] attributes; - - /// Document URL - public override string Url => url; - /// File size - public override int Size => size; - /// MIME type - public override string MimeType => mime_type; - /// Attributes for media types - public override DocumentAttribute[] Attributes => attributes; } - /// The document See + ///See [TLDef(0x9BED434D)] - public sealed partial class InputWebDocument : IObject + public partial class InputWebDocument : ITLObject { - /// Remote document URL to be downloaded using the appropriate method public string url; - /// Remote file size public int size; - /// Mime type public string mime_type; - /// Attributes for media types public DocumentAttribute[] attributes; } - /// Location of remote file See Derived classes: , , - public abstract partial class InputWebFileLocationBase : IObject { } - /// Location of a remote HTTP(s) file See + ///See + public abstract partial class InputWebFileLocationBase : ITLObject { } + ///See [TLDef(0xC239D686)] - public sealed partial class InputWebFileLocation : InputWebFileLocationBase + public partial class InputWebFileLocation : InputWebFileLocationBase { - /// HTTP URL of file public string url; - /// 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 + ///See [TLDef(0x9F2221C9)] - public sealed partial class InputWebFileGeoPointLocation : InputWebFileLocationBase + public partial class InputWebFileGeoPointLocation : InputWebFileLocationBase { - /// 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
public long access_hash; - /// Map width in pixels before applying scale; 16-1024 public int w; - /// Map height in pixels before applying scale; 16-1024 public int h; - /// Map zoom level; 13-20 public int zoom; - /// 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 - [TLDef(0xF46FE924)] - public sealed partial class InputWebFileAudioAlbumThumbLocation : InputWebFileLocationBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The audio file in question: must NOT be provided in secret chats, provide the title and performer fields instead. - [IfFlag(0)] public InputDocument document; - /// Song title: should only be used in secret chats, in normal chats provide document instead, as it has more lax rate limits. - [IfFlag(1)] public string title; - /// Song performer: should only be used in secret chats, in normal chats provide document instead, as it has more lax rate limits. - [IfFlag(1)] public string performer; - [Flags] public enum Flags : uint - { - /// Field has a value - has_document = 0x1, - /// Fields and have a value - has_title = 0x2, - /// Used to return a thumbnail with 100x100 resolution (instead of the default 600x600) - small = 0x4, - } - } - - /// Represents a chunk of an HTTP webfile downloaded through telegram's secure MTProto servers See + ///See [TLDef(0x21E753BC)] - public sealed partial class Upload_WebFile : IObject + public partial class Upload_WebFile : ITLObject { - /// File size public int size; - /// Mime type public string mime_type; - /// File type public Storage_FileType file_type; - /// Modified time public int mtime; - /// Data public byte[] bytes; } - /// Payment form See Derived classes: , , - public abstract partial class Payments_PaymentFormBase : IObject + ///See + [TLDef(0x1694761B)] + public partial class Payments_PaymentForm : ITLObject { - /// Form ID - public virtual long FormId => default; - /// Invoice - public virtual Invoice Invoice => default; - } - /// Payment form See - [TLDef(0xA0058751)] - public sealed partial class Payments_PaymentForm : Payments_PaymentFormBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_saved_info = 0x1, has_saved_credentials = 0x2, can_save_credentials = 0x4, + password_missing = 0x8, has_native_provider = 0x10 } public Flags flags; - /// Form ID public long form_id; - /// Bot ID public long bot_id; - /// Form title - public string title; - /// Description - public string description; - /// Product photo - [IfFlag(5)] public WebDocumentBase photo; - /// Invoice public Invoice invoice; - /// Payment provider ID. public long provider_id; - /// Payment form URL public string url; - /// Payment provider name.
One of the following:
- stripe
[IfFlag(4)] public string native_provider; - /// Contains information about the payment provider, if available, to support it natively without the need for opening the URL.
A JSON object that can contain the following fields:

- apple_pay_merchant_id: Apple Pay merchant ID
- google_pay_public_key: Google Pay public key
- need_country: True, if the user country must be provided,
- need_zip: True, if the user ZIP/postal code must be provided,
- need_cardholder_name: True, if the cardholder name must be provided
[IfFlag(4)] public DataJSON native_params; - /// Additional payment methods - [IfFlag(6)] public PaymentFormMethod[] additional_methods; - /// Saved server-side order information [IfFlag(0)] public PaymentRequestedInfo saved_info; - /// Contains information about saved card credentials - [IfFlag(1)] public PaymentSavedCredentials[] saved_credentials; - /// Users - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_saved_info = 0x1, - /// Field has a value - has_saved_credentials = 0x2, - /// Whether the user can choose to save credentials. - can_save_credentials = 0x4, - ///
Indicates that the user can save payment credentials, but only after setting up a 2FA password (currently the account doesn't have a 2FA password) - password_missing = 0x8, - /// Fields and have a value - has_native_provider = 0x10, - /// Field has a value - has_photo = 0x20, - /// Field has a value - has_additional_methods = 0x40, - } - - /// Form ID - public override long FormId => form_id; - /// Invoice - public override Invoice Invoice => invoice; - } - /// Represents a payment form, for payments to be using Telegram Stars, see here » for more info. See - [TLDef(0x7BF6B15C)] - public sealed partial class Payments_PaymentFormStars : Payments_PaymentFormBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Form ID. - public long form_id; - /// Bot ID. - public long bot_id; - /// Form title - public string title; - /// Description - public string description; - /// Product photo - [IfFlag(5)] public WebDocumentBase photo; - /// Invoice - public Invoice invoice; - /// Info about users mentioned in the other fields. - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_photo = 0x20, - } - - /// Form ID. - public override long FormId => form_id; - /// Invoice - public override Invoice Invoice => invoice; - } - /// Represents a payment form for a gift, see here » for more info. See - [TLDef(0xB425CFE1)] - public sealed partial class Payments_PaymentFormStarGift : Payments_PaymentFormBase - { - /// Form ID. - public long form_id; - /// Invoice - public Invoice invoice; - - /// Form ID. - public override long FormId => form_id; - /// Invoice - public override Invoice Invoice => invoice; + [IfFlag(1)] public PaymentSavedCredentials saved_credentials; + public UserBase[] users; } - /// Validated user-provided info See + ///See [TLDef(0xD1451883)] - public sealed partial class Payments_ValidatedRequestedInfo : IObject + public partial class Payments_ValidatedRequestedInfo : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_id = 0x1, has_shipping_options = 0x2 } public Flags flags; - /// ID [IfFlag(0)] public string id; - /// Shipping options [IfFlag(1)] public ShippingOption[] shipping_options; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_id = 0x1, - /// Field has a value - has_shipping_options = 0x2, - } } - /// Payment result See Derived classes: , - public abstract partial class Payments_PaymentResultBase : IObject { } - /// Payment result See + ///See + public abstract partial class Payments_PaymentResultBase : ITLObject { } + ///See [TLDef(0x4E5F810D)] - public sealed partial class Payments_PaymentResult : Payments_PaymentResultBase - { - /// Info about the payment - public UpdatesBase updates; - } - /// Payment was not successful, additional verification is needed See + public partial class Payments_PaymentResult : Payments_PaymentResultBase { public UpdatesBase updates; } + ///See [TLDef(0xD8411139)] - public sealed partial class Payments_PaymentVerificationNeeded : Payments_PaymentResultBase - { - /// URL for additional payment credentials verification - public string url; - } + public partial class Payments_PaymentVerificationNeeded : Payments_PaymentResultBase { public string url; } - /// Payment receipt See Derived classes: , - public abstract partial class Payments_PaymentReceiptBase : IObject - { - /// Date of generation - public virtual DateTime Date => default; - /// Bot ID - public virtual long BotId => default; - /// Title - public virtual string Title => default; - /// Description - public virtual string Description => default; - /// Photo - public virtual WebDocumentBase Photo => default; - /// Invoice - public virtual Invoice Invoice => default; - /// Three-letter ISO 4217 currency code - public virtual string Currency => default; - /// Total amount 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). - public virtual long TotalAmount => default; - /// Users - public virtual Dictionary Users => default; - } - /// Receipt See + ///See [TLDef(0x70C4FE03)] - public sealed partial class Payments_PaymentReceipt : Payments_PaymentReceiptBase + public partial class Payments_PaymentReceipt : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_info = 0x1, has_shipping = 0x2, has_photo = 0x4, has_tip_amount = 0x8 } public Flags flags; - /// Date of generation public DateTime date; - /// Bot ID public long bot_id; - /// Provider ID public long provider_id; - /// Title public string title; - /// Description public string description; - /// Photo [IfFlag(2)] public WebDocumentBase photo; - /// Invoice public Invoice invoice; - /// Info [IfFlag(0)] public PaymentRequestedInfo info; - /// Selected shipping option [IfFlag(1)] public ShippingOption shipping; - /// Tipped amount [IfFlag(3)] public long tip_amount; - /// Three-letter ISO 4217 currency code public string currency; - /// Total amount 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). public long total_amount; - /// Payment credential name public string credentials_title; - /// Users - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_info = 0x1, - /// Field has a value - has_shipping = 0x2, - /// Field has a value - has_photo = 0x4, - /// Field has a value - has_tip_amount = 0x8, - } - - /// Date of generation - public override DateTime Date => date; - /// Bot ID - public override long BotId => bot_id; - /// Title - public override string Title => title; - /// Description - public override string Description => description; - /// Photo - public override WebDocumentBase Photo => photo; - /// Invoice - public override Invoice Invoice => invoice; - /// Three-letter ISO 4217 currency code - public override string Currency => currency; - /// Total amount 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). - public override long TotalAmount => total_amount; - /// Users - public override Dictionary Users => users; - } - /// Receipt for payment made using Telegram Stars. See - [TLDef(0xDABBF83A)] - public sealed partial class Payments_PaymentReceiptStars : Payments_PaymentReceiptBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Date of generation - public DateTime date; - /// Bot ID - public long bot_id; - /// Title - public string title; - /// Description - public string description; - /// Product photo - [IfFlag(2)] public WebDocumentBase photo; - /// Invoice - public Invoice invoice; - /// Currency, always XTR. - public string currency; - /// Amount of Telegram Stars. - public long total_amount; - /// Transaction ID - public string transaction_id; - /// Info about users mentioned in the other fields. - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_photo = 0x4, - } - - /// Date of generation - public override DateTime Date => date; - /// Bot ID - public override long BotId => bot_id; - /// Title - public override string Title => title; - /// Description - public override string Description => description; - /// Product photo - public override WebDocumentBase Photo => photo; - /// Invoice - public override Invoice Invoice => invoice; - /// Currency, always XTR. - public override string Currency => currency; - /// Amount of Telegram Stars. - public override long TotalAmount => total_amount; - /// Info about users mentioned in the other fields. - public override Dictionary Users => users; + public UserBase[] users; } - /// Saved server-side order information See + ///See [TLDef(0xFB8FE43C)] - public sealed partial class Payments_SavedInfo : IObject + public partial class Payments_SavedInfo : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_saved_info = 0x1, has_saved_credentials = 0x2 } public Flags flags; - /// Saved server-side order information [IfFlag(0)] public PaymentRequestedInfo saved_info; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_saved_info = 0x1, - /// Whether the user has some saved payment credentials - has_saved_credentials = 0x2, - } } - /// Payment credentials See Derived classes: , , , - public abstract partial class InputPaymentCredentialsBase : IObject { } - /// Saved payment credentials See + ///See + public abstract partial class InputPaymentCredentialsBase : ITLObject { } + ///See [TLDef(0xC10EB2CF)] - public sealed partial class InputPaymentCredentialsSaved : InputPaymentCredentialsBase + public partial class InputPaymentCredentialsSaved : InputPaymentCredentialsBase { - /// Credential ID public string id; - /// Temporary password public byte[] tmp_password; } - /// Payment credentials See + ///See [TLDef(0x3417D728)] - public sealed partial class InputPaymentCredentials : InputPaymentCredentialsBase + public partial class InputPaymentCredentials : InputPaymentCredentialsBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { save = 0x1 } public Flags flags; - /// Payment credentials public DataJSON data; - - [Flags] public enum Flags : uint - { - /// Save payment credential for future use - save = 0x1, - } } - /// Apple pay payment credentials See + ///See [TLDef(0x0AA1C39F)] - public sealed partial class InputPaymentCredentialsApplePay : InputPaymentCredentialsBase - { - /// Payment data - public DataJSON payment_data; - } - /// Google Pay payment credentials See + public partial class InputPaymentCredentialsApplePay : InputPaymentCredentialsBase { public DataJSON payment_data; } + ///See [TLDef(0x8AC32801)] - public sealed partial class InputPaymentCredentialsGooglePay : InputPaymentCredentialsBase - { - /// Payment token - public DataJSON payment_token; - } + public partial class InputPaymentCredentialsGooglePay : InputPaymentCredentialsBase { public DataJSON payment_token; } - /// Temporary payment password See + ///See [TLDef(0xDB64FD34)] - public sealed partial class Account_TmpPassword : IObject + public partial class Account_TmpPassword : ITLObject { - /// Temporary password public byte[] tmp_password; - /// Validity period public DateTime valid_until; } - /// Shipping option See + ///See [TLDef(0xB6213CDF)] - public sealed partial class ShippingOption : IObject + public partial class ShippingOption : ITLObject { - /// Option ID public string id; - /// Title public string title; - /// List of price portions public LabeledPrice[] prices; } - /// Sticker in a stickerset See - [TLDef(0x32DA9E9C)] - public sealed partial class InputStickerSetItem : IObject + ///See + [TLDef(0xFFA0A496)] + public partial class InputStickerSetItem : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_mask_coords = 0x1 } public Flags flags; - /// The sticker public InputDocument document; - /// Associated emoji public string emoji; - /// Coordinates for mask sticker [IfFlag(0)] public MaskCoords mask_coords; - /// Set of keywords, separated by commas (can't be provided for mask stickers) - [IfFlag(1)] public string keywords; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_mask_coords = 0x1, - /// Field has a value - has_keywords = 0x2, - } } - /// Phone call See + ///See [TLDef(0x1E36FDED)] - public sealed partial class InputPhoneCall : IObject + public partial class InputPhoneCall : ITLObject { - /// Call ID public long id; - /// REQUIRED FIELD. See how to obtain it
Access hash
public long access_hash; } - ///
Phone call See Derived classes: , , , , , - public abstract partial class PhoneCallBase : IObject - { - /// Call ID - public virtual long ID => default; - /// Access hash - public virtual long AccessHash => default; - /// Date - public virtual DateTime Date => default; - /// Admin ID - public virtual long AdminId => default; - /// Participant ID - public virtual long ParticipantId => default; - /// Phone call protocol info - public virtual PhoneCallProtocol Protocol => default; - } - /// Empty constructor See + ///See + public abstract partial class PhoneCallBase : ITLObject { } + ///See [TLDef(0x5366C915)] - public sealed partial class PhoneCallEmpty : PhoneCallBase - { - /// Call ID - public long id; - - /// Call ID - public override long ID => id; - } - /// Incoming phone call See + public partial class PhoneCallEmpty : PhoneCallBase { public long id; } + ///See [TLDef(0xC5226F17)] - public sealed partial class PhoneCallWaiting : PhoneCallBase + public partial class PhoneCallWaiting : PhoneCallBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_receive_date = 0x1, video = 0x40 } public Flags flags; - /// Call ID public long id; - /// Access hash public long access_hash; - /// Date public DateTime date; - /// Admin ID public long admin_id; - /// Participant ID public long participant_id; - /// Phone call protocol info public PhoneCallProtocol protocol; - /// When was the phone call received [IfFlag(0)] public DateTime receive_date; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_receive_date = 0x1, - /// Is this a video call - video = 0x40, - } - - /// 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 + ///See [TLDef(0x14B0ED0C)] - public sealed partial class PhoneCallRequested : PhoneCallBase + public partial class PhoneCallRequested : PhoneCallBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { video = 0x40 } public Flags flags; - /// Phone call ID public long id; - /// Access hash public long access_hash; - /// When was the phone call created public DateTime date; - /// ID of the creator of the phone call public long admin_id; - /// ID of the other participant of the phone call public long participant_id; - /// Parameter for key exchange public byte[] g_a_hash; - /// Call protocol info to be passed to libtgvoip public PhoneCallProtocol protocol; - - [Flags] public enum Flags : uint - { - /// Whether this is a video call - video = 0x40, - } - - /// 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 + ///See [TLDef(0x3660C311)] - public sealed partial class PhoneCallAccepted : PhoneCallBase + public partial class PhoneCallAccepted : PhoneCallBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { video = 0x40 } public Flags flags; - /// ID of accepted phone call public long id; - /// Access hash of phone call public long access_hash; - /// When was the call accepted public DateTime date; - /// ID of the call creator public long admin_id; - /// ID of the other user in the call public long participant_id; - /// B parameter for secure E2E phone call key exchange public byte[] g_b; - /// Protocol to use for phone call public PhoneCallProtocol protocol; - - [Flags] public enum Flags : uint - { - /// Whether this is a video call - video = 0x40, - } - - /// 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(0x30535AF5)] - public sealed partial class PhoneCall : PhoneCallBase + ///See + [TLDef(0x967F7C67)] + public partial class PhoneCall : PhoneCallBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { p2p_allowed = 0x20, video = 0x40 } public Flags flags; - /// Call ID public long id; - /// Access hash public long access_hash; - /// Date of creation of the call public DateTime date; - /// User ID of the creator of the call public long admin_id; - /// User ID of the other participant in the call public long participant_id; - /// Parameter for key exchange public byte[] g_a_or_b; - /// Key fingerprint public long key_fingerprint; - /// Call protocol info to be passed to libtgvoip public PhoneCallProtocol protocol; - /// List of endpoints the user can connect to exchange call data public PhoneConnectionBase[] connections; - /// When was the call actually started public DateTime start_date; - /// Custom JSON-encoded call parameters to be passed to tgcalls. - [IfFlag(7)] public DataJSON custom_parameters; - - [Flags] public enum Flags : uint - { - /// Whether P2P connection to the other peer is allowed - p2p_allowed = 0x20, - /// Whether this is a video call - video = 0x40, - /// Field has a value - has_custom_parameters = 0x80, - /// If set, the other party supports upgrading of the call to a conference call. - conference_supported = 0x100, - } - - /// 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 + ///See [TLDef(0x50CA4DE1)] - public sealed partial class PhoneCallDiscarded : PhoneCallBase + public partial class PhoneCallDiscarded : PhoneCallBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_reason = 0x1, has_duration = 0x2, need_rating = 0x4, need_debug = 0x8, video = 0x40 } public Flags flags; - /// Call ID public long id; - /// Why was the phone call discarded [IfFlag(0)] public PhoneCallDiscardReason reason; - /// Duration of the phone call in seconds [IfFlag(1)] public int duration; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_reason = 0x1, - /// Field has a value - has_duration = 0x2, - /// Whether the server required the user to Phone_SetCallRating the call - need_rating = 0x4, - /// 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, - } - - /// Call ID - public override long ID => id; } - /// Phone call connection See Derived classes: , - public abstract partial class PhoneConnectionBase : IObject + ///See + public abstract partial class PhoneConnectionBase : ITLObject { } + ///See + [TLDef(0x9D4C17C0)] + public partial class PhoneConnection : PhoneConnectionBase { - /// Endpoint ID - public virtual long ID => default; - /// IP address of endpoint - public virtual string Ip => default; - /// IPv6 address of endpoint - public virtual string Ipv6 => default; - /// Port ID - public virtual int Port => default; - } - /// Identifies an endpoint that can be used to connect to the other user in a phone call See - [TLDef(0x9CC123C7)] - public sealed partial class PhoneConnection : PhoneConnectionBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Endpoint ID public long id; - /// IP address of endpoint public string ip; - /// IPv6 address of endpoint public string ipv6; - /// Port ID public int port; - /// Our peer tag public byte[] peer_tag; - - [Flags] public enum Flags : uint - { - /// Whether TCP should be used - tcp = 0x1, - } - - /// Endpoint ID - public override long ID => id; - /// IP address of endpoint - public override string Ip => ip; - /// IPv6 address of endpoint - public override string Ipv6 => ipv6; - /// Port ID - public override int Port => port; } - /// WebRTC connection parameters See + ///See [TLDef(0x635FE375)] - public sealed partial class PhoneConnectionWebrtc : PhoneConnectionBase + public partial class PhoneConnectionWebrtc : PhoneConnectionBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { turn = 0x1, stun = 0x2 } public Flags flags; - /// Endpoint ID public long id; - /// IP address public string ip; - /// IPv6 address public string ipv6; - /// Port public int port; - /// Username public string username; - /// Password public string password; - - [Flags] public enum Flags : uint - { - /// Whether this is a TURN endpoint - turn = 0x1, - /// Whether this is a STUN endpoint - stun = 0x2, - } - - /// Endpoint ID - public override long ID => id; - /// IP address - public override string Ip => ip; - /// IPv6 address - public override string Ipv6 => ipv6; - /// Port - public override int Port => port; } - /// Protocol info for libtgvoip See + ///See [TLDef(0xFC878FC8)] - public sealed partial class PhoneCallProtocol : IObject + public partial class PhoneCallProtocol : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { udp_p2p = 0x1, udp_reflector = 0x2 } public Flags flags; - /// Minimum layer for remote libtgvoip 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.
public string[] library_versions; - - [Flags] public enum Flags : uint - { - /// Whether to allow P2P connection to the other participant - udp_p2p = 0x1, - /// Whether to allow connection to the other participants through the reflector servers - udp_reflector = 0x2, - } } - ///
A VoIP phone call See + ///See [TLDef(0xEC82E140)] - public sealed partial class Phone_PhoneCall : IObject + public partial class Phone_PhoneCall : ITLObject { - /// The VoIP phone call public PhoneCallBase phone_call; - /// VoIP phone call participants - public Dictionary users; + public UserBase[] users; } - /// Represents the download status of a CDN file See Derived classes: , - public abstract partial class Upload_CdnFileBase : IObject { } - /// The file was cleared from the temporary RAM cache of the CDN and has to be re-uploaded. See + ///See + public abstract partial class Upload_CdnFileBase : ITLObject { } + ///See [TLDef(0xEEA8E46E)] - public sealed partial class Upload_CdnFileReuploadNeeded : Upload_CdnFileBase - { - /// Request token (see CDN) - public byte[] request_token; - } - /// Represent a chunk of a CDN file. See + public partial class Upload_CdnFileReuploadNeeded : Upload_CdnFileBase { public byte[] request_token; } + ///See [TLDef(0xA99FCA4F)] - public sealed partial class Upload_CdnFile : Upload_CdnFileBase - { - /// The data - public byte[] bytes; - } + public partial class Upload_CdnFile : Upload_CdnFileBase { public byte[] bytes; } - /// Public key to use only during handshakes to CDN DCs. See + ///See [TLDef(0xC982EABA)] - public sealed partial class CdnPublicKey : IObject + public partial class CdnPublicKey : ITLObject { - /// CDN DC ID public int dc_id; - /// RSA public key public string public_key; } - /// Configuration for CDN file downloads. See + ///See [TLDef(0x5725E40A)] - public sealed partial class CdnConfig : IObject - { - /// Vector of public keys to use only during handshakes to CDN DCs. - public CdnPublicKey[] public_keys; - } + public partial class CdnConfig : ITLObject { public CdnPublicKey[] public_keys; } - /// Language pack string See Derived classes: , , - public abstract partial class LangPackStringBase : IObject - { - /// Language key - public virtual string Key => default; - } - /// Translated localization string See + ///See + public abstract partial class LangPackStringBase : ITLObject { } + ///See [TLDef(0xCAD181F6)] - public sealed partial class LangPackString : LangPackStringBase + public partial class LangPackString : LangPackStringBase { - /// Language key public string key; - /// Value public string value; - - /// Language key - public override string Key => key; } - /// A language pack string which has different forms based on the number of some object it mentions. See https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html for more info See + ///See [TLDef(0x6C47AC9F)] - public sealed partial class LangPackStringPluralized : LangPackStringBase + public partial class LangPackStringPluralized : LangPackStringBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_zero_value = 0x1, has_one_value = 0x2, has_two_value = 0x4, has_few_value = 0x8, + has_many_value = 0x10 } public Flags flags; - /// Localization key public string key; - /// Value for zero objects [IfFlag(0)] public string zero_value; - /// Value for one object [IfFlag(1)] public string one_value; - /// Value for two objects [IfFlag(2)] public string two_value; - /// Value for a few objects [IfFlag(3)] public string few_value; - /// Value for many objects [IfFlag(4)] public string many_value; - /// Default value public string other_value; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_zero_value = 0x1, - /// Field has a value - has_one_value = 0x2, - /// Field has a value - has_two_value = 0x4, - /// Field has a value - has_few_value = 0x8, - /// Field has a value - has_many_value = 0x10, - } - - /// Localization key - public override string Key => key; } - /// Deleted localization string See + ///See [TLDef(0x2979EEB2)] - public sealed partial class LangPackStringDeleted : LangPackStringBase - { - /// Localization key - public string key; + public partial class LangPackStringDeleted : LangPackStringBase { public string key; } - /// Localization key - public override string Key => key; - } - - /// Changes to the app's localization pack See + ///See [TLDef(0xF385C1F6)] - public sealed partial class LangPackDifference : IObject + public partial class LangPackDifference : ITLObject { - /// Language code public string lang_code; - /// Previous version number public int from_version; - /// New version number public int version; - /// Localized strings public LangPackStringBase[] strings; } - /// Identifies a localization pack See + ///See [TLDef(0xEECA5CE3)] - public sealed partial class LangPackLanguage : IObject + public partial class LangPackLanguage : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { official = 0x1, has_base_lang_code = 0x2, rtl = 0x4, beta = 0x8 } public Flags flags; - /// Language name public string name; - /// Language name in the language itself public string native_name; - /// Language code (pack identifier) public string lang_code; - /// Identifier of a base language pack; may be empty. If a string is missed in the language pack, then it should be fetched from base language pack. Unsupported in custom language packs [IfFlag(1)] public string base_lang_code; - /// A language code to be used to apply plural forms. See https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html for more info public string plural_code; - /// Total number of non-deleted strings from the language pack public int strings_count; - /// Total number of translated strings from the language pack public int translated_count; - /// Link to language translation interface; empty for custom local language packs public string translations_url; - - [Flags] public enum Flags : uint - { - /// Whether the language pack is official - official = 0x1, - /// Field has a value - has_base_lang_code = 0x2, - /// Is this a localization pack for an RTL language - rtl = 0x4, - /// Is this a beta localization pack? - beta = 0x8, - } } - /// Channel admin log event See Derived classes: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , - public abstract partial class ChannelAdminLogEventAction : IObject { } - /// Channel/supergroup title was changed See + ///See + public abstract partial class ChannelAdminLogEventAction : ITLObject { } + ///See [TLDef(0xE6DFB825)] - public sealed partial class ChannelAdminLogEventActionChangeTitle : ChannelAdminLogEventAction + public partial class ChannelAdminLogEventActionChangeTitle : ChannelAdminLogEventAction { - /// Previous title public string prev_value; - /// New title public string new_value; } - /// The description was changed See + ///See [TLDef(0x55188A2E)] - public sealed partial class ChannelAdminLogEventActionChangeAbout : ChannelAdminLogEventAction + public partial class ChannelAdminLogEventActionChangeAbout : ChannelAdminLogEventAction { - /// Previous description public string prev_value; - /// New description public string new_value; } - /// Channel/supergroup username was changed See + ///See [TLDef(0x6A4AFC38)] - public sealed partial class ChannelAdminLogEventActionChangeUsername : ChannelAdminLogEventAction + public partial class ChannelAdminLogEventActionChangeUsername : ChannelAdminLogEventAction { - /// Old username public string prev_value; - /// New username public string new_value; } - /// The channel/supergroup's picture was changed See + ///See [TLDef(0x434BD2AF)] - public sealed partial class ChannelAdminLogEventActionChangePhoto : ChannelAdminLogEventAction + public partial class ChannelAdminLogEventActionChangePhoto : ChannelAdminLogEventAction { - /// Previous picture public PhotoBase prev_photo; - /// New picture public PhotoBase new_photo; } - /// Invites were enabled/disabled See + ///See [TLDef(0x1B7907AE)] - public sealed partial class ChannelAdminLogEventActionToggleInvites : ChannelAdminLogEventAction - { - /// New value - public bool new_value; - } - /// Channel signatures were enabled/disabled See + public partial class ChannelAdminLogEventActionToggleInvites : ChannelAdminLogEventAction { public bool new_value; } + ///See [TLDef(0x26AE0971)] - public partial class ChannelAdminLogEventActionToggleSignatures : ChannelAdminLogEventAction - { - /// New value - public bool new_value; - } - /// A message was pinned See + public partial class ChannelAdminLogEventActionToggleSignatures : ChannelAdminLogEventAction { public bool new_value; } + ///See [TLDef(0xE9E82C18)] - public sealed partial class ChannelAdminLogEventActionUpdatePinned : ChannelAdminLogEventAction - { - /// The message that was pinned - public MessageBase message; - } - /// A message was edited See + public partial class ChannelAdminLogEventActionUpdatePinned : ChannelAdminLogEventAction { public MessageBase message; } + ///See [TLDef(0x709B2405)] - public sealed partial class ChannelAdminLogEventActionEditMessage : ChannelAdminLogEventAction + public partial class ChannelAdminLogEventActionEditMessage : ChannelAdminLogEventAction { - /// Old message public MessageBase prev_message; - /// New message public MessageBase new_message; } - /// A message was deleted See + ///See [TLDef(0x42E047BB)] - public sealed partial class ChannelAdminLogEventActionDeleteMessage : ChannelAdminLogEventAction - { - /// The message that was deleted - public MessageBase message; - } - /// A user has joined the group (in the case of big groups, info of the user that has joined isn't shown) See + public partial class ChannelAdminLogEventActionDeleteMessage : ChannelAdminLogEventAction { public MessageBase message; } + ///See [TLDef(0x183040D3)] - public sealed partial class ChannelAdminLogEventActionParticipantJoin : ChannelAdminLogEventAction { } - /// A user left the channel/supergroup (in the case of big groups, info of the user that has joined isn't shown) See + public partial class ChannelAdminLogEventActionParticipantJoin : ChannelAdminLogEventAction { } + ///See [TLDef(0xF89777F2)] - public sealed partial class ChannelAdminLogEventActionParticipantLeave : ChannelAdminLogEventAction { } - /// A user was invited to the group See + public partial class ChannelAdminLogEventActionParticipantLeave : ChannelAdminLogEventAction { } + ///See [TLDef(0xE31C34D8)] - public sealed partial class ChannelAdminLogEventActionParticipantInvite : ChannelAdminLogEventAction - { - /// The user that was invited - public ChannelParticipantBase participant; - } - /// The banned rights of a user were changed See + public partial class ChannelAdminLogEventActionParticipantInvite : ChannelAdminLogEventAction { public ChannelParticipantBase participant; } + ///See [TLDef(0xE6D83D7E)] - public sealed partial class ChannelAdminLogEventActionParticipantToggleBan : ChannelAdminLogEventAction + public partial class ChannelAdminLogEventActionParticipantToggleBan : ChannelAdminLogEventAction { - /// Old banned rights of user public ChannelParticipantBase prev_participant; - /// New banned rights of user public ChannelParticipantBase new_participant; } - /// The admin rights of a user were changed See + ///See [TLDef(0xD5676710)] - public sealed partial class ChannelAdminLogEventActionParticipantToggleAdmin : ChannelAdminLogEventAction + public partial class ChannelAdminLogEventActionParticipantToggleAdmin : ChannelAdminLogEventAction { - /// Previous admin rights public ChannelParticipantBase prev_participant; - /// New admin rights public ChannelParticipantBase new_participant; } - /// The supergroup's stickerset was changed See + ///See [TLDef(0xB1C3CAA7)] public partial class ChannelAdminLogEventActionChangeStickerSet : ChannelAdminLogEventAction { - /// Previous stickerset public InputStickerSet prev_stickerset; - /// New stickerset public InputStickerSet new_stickerset; } - /// The hidden prehistory setting was Channels_TogglePreHistoryHidden See + ///See [TLDef(0x5F5C95F1)] - public sealed partial class ChannelAdminLogEventActionTogglePreHistoryHidden : ChannelAdminLogEventAction - { - /// New value - public bool new_value; - } - /// The default banned rights were modified See + public partial class ChannelAdminLogEventActionTogglePreHistoryHidden : ChannelAdminLogEventAction { public bool new_value; } + ///See [TLDef(0x2DF5FC0A)] - public sealed partial class ChannelAdminLogEventActionDefaultBannedRights : ChannelAdminLogEventAction + public partial class ChannelAdminLogEventActionDefaultBannedRights : ChannelAdminLogEventAction { - /// Previous global banned rights public ChatBannedRights prev_banned_rights; - /// New global banned rights. public ChatBannedRights new_banned_rights; } - /// A poll was stopped See + ///See [TLDef(0x8F079643)] - public sealed partial class ChannelAdminLogEventActionStopPoll : ChannelAdminLogEventAction - { - /// The poll that was stopped - public MessageBase message; - } - /// The linked chat was changed See + public partial class ChannelAdminLogEventActionStopPoll : ChannelAdminLogEventAction { public MessageBase message; } + ///See [TLDef(0x050C7AC8)] - public sealed partial class ChannelAdminLogEventActionChangeLinkedChat : ChannelAdminLogEventAction + public partial class ChannelAdminLogEventActionChangeLinkedChat : ChannelAdminLogEventAction { - /// Previous linked chat public long prev_value; - /// New linked chat public long new_value; } - /// The geogroup location was changed See + ///See [TLDef(0x0E6B76AE)] - public sealed partial class ChannelAdminLogEventActionChangeLocation : ChannelAdminLogEventAction + public partial class ChannelAdminLogEventActionChangeLocation : ChannelAdminLogEventAction { - /// Previous location public ChannelLocation prev_value; - /// New location public ChannelLocation new_value; } - /// Channels_ToggleSlowMode See + ///See [TLDef(0x53909779)] - public sealed partial class ChannelAdminLogEventActionToggleSlowMode : ChannelAdminLogEventAction + public partial class ChannelAdminLogEventActionToggleSlowMode : ChannelAdminLogEventAction { - /// Previous slow mode value public int prev_value; - /// New slow mode value public int new_value; } - /// A group call was started See + ///See [TLDef(0x23209745)] - public sealed partial class ChannelAdminLogEventActionStartGroupCall : ChannelAdminLogEventAction - { - /// Group call - public InputGroupCallBase call; - } - /// A group call was terminated See + public partial class ChannelAdminLogEventActionStartGroupCall : ChannelAdminLogEventAction { public InputGroupCall call; } + ///See [TLDef(0xDB9F9140)] - public sealed partial class ChannelAdminLogEventActionDiscardGroupCall : ChannelAdminLogEventAction - { - /// The group call that was terminated - public InputGroupCallBase call; - } - /// A group call participant was muted See + public partial class ChannelAdminLogEventActionDiscardGroupCall : ChannelAdminLogEventAction { public InputGroupCall call; } + ///See [TLDef(0xF92424D2)] - public sealed partial class ChannelAdminLogEventActionParticipantMute : ChannelAdminLogEventAction - { - /// The participant that was muted - public GroupCallParticipant participant; - } - /// A group call participant was unmuted See + public partial class ChannelAdminLogEventActionParticipantMute : ChannelAdminLogEventAction { public GroupCallParticipant participant; } + ///See [TLDef(0xE64429C0)] - public sealed partial class ChannelAdminLogEventActionParticipantUnmute : ChannelAdminLogEventAction - { - /// The participant that was unmuted - public GroupCallParticipant participant; - } - /// Group call settings were changed See + public partial class ChannelAdminLogEventActionParticipantUnmute : ChannelAdminLogEventAction { public GroupCallParticipant participant; } + ///See [TLDef(0x56D6A247)] - public sealed partial class ChannelAdminLogEventActionToggleGroupCallSetting : ChannelAdminLogEventAction - { - /// Whether all users are muted by default upon joining - public bool join_muted; - } - /// A user joined the supergroup/channel using a specific invite link See - [TLDef(0xFE9FC158)] - public sealed partial class ChannelAdminLogEventActionParticipantJoinByInvite : ChannelAdminLogEventAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The invite link used to join the supergroup/channel - public ExportedChatInvite invite; - - [Flags] public enum Flags : uint - { - /// The participant joined by importing a chat folder deep link ». - via_chatlist = 0x1, - } - } - /// A chat invite was deleted See + public partial class ChannelAdminLogEventActionToggleGroupCallSetting : ChannelAdminLogEventAction { public bool join_muted; } + ///See + [TLDef(0x5CDADA77)] + public partial class ChannelAdminLogEventActionParticipantJoinByInvite : ChannelAdminLogEventAction { public ExportedChatInvite invite; } + ///See [TLDef(0x5A50FCA4)] - public sealed partial class ChannelAdminLogEventActionExportedInviteDelete : ChannelAdminLogEventAction - { - /// The deleted chat invite - public ExportedChatInvite invite; - } - /// A specific invite link was revoked See + public partial class ChannelAdminLogEventActionExportedInviteDelete : ChannelAdminLogEventAction { public ExportedChatInvite invite; } + ///See [TLDef(0x410A134E)] - public sealed partial class ChannelAdminLogEventActionExportedInviteRevoke : ChannelAdminLogEventAction - { - /// The invite link that was revoked - public ExportedChatInvite invite; - } - /// A chat invite was edited See + public partial class ChannelAdminLogEventActionExportedInviteRevoke : ChannelAdminLogEventAction { public ExportedChatInvite invite; } + ///See [TLDef(0xE90EBB59)] - public sealed partial class ChannelAdminLogEventActionExportedInviteEdit : ChannelAdminLogEventAction + public partial class ChannelAdminLogEventActionExportedInviteEdit : ChannelAdminLogEventAction { - /// Previous chat invite information public ExportedChatInvite prev_invite; - /// New chat invite information public ExportedChatInvite new_invite; } - /// channelAdminLogEvent.user_id has set the volume of participant.peer to participant.volume See + ///See [TLDef(0x3E7F6847)] - public sealed partial class ChannelAdminLogEventActionParticipantVolume : ChannelAdminLogEventAction - { - /// The participant whose volume was changed - public GroupCallParticipant participant; - } - /// The Time-To-Live of messages in this chat was changed See + public partial class ChannelAdminLogEventActionParticipantVolume : ChannelAdminLogEventAction { public GroupCallParticipant participant; } + ///See [TLDef(0x6E941A38)] - public sealed partial class ChannelAdminLogEventActionChangeHistoryTTL : ChannelAdminLogEventAction + public partial class ChannelAdminLogEventActionChangeHistoryTTL : ChannelAdminLogEventAction { - /// Previous value public int prev_value; - /// New value public int new_value; } - /// A new member was accepted to the chat by an admin See - [TLDef(0xAFB6144A)] - public sealed partial class ChannelAdminLogEventActionParticipantJoinByRequest : ChannelAdminLogEventAction + ///See + [TLDef(0xFE69018D)] + public partial class ChannelAdminLogEventActionChangeTheme : ChannelAdminLogEventAction { - /// The invite link that was used to join the chat - public ExportedChatInvite invite; - /// ID of the admin that approved the invite - public long approved_by; - } - /// Forwards were enabled or disabled See - [TLDef(0xCB2AC766)] - public sealed partial class ChannelAdminLogEventActionToggleNoForwards : ChannelAdminLogEventAction - { - /// Old value - public bool new_value; - } - /// A message was posted in a channel See - [TLDef(0x278F2868)] - public sealed partial class ChannelAdminLogEventActionSendMessage : ChannelAdminLogEventAction - { - /// The message that was sent - public MessageBase message; - } - /// The set of allowed message reactions » for this channel has changed See - [TLDef(0xBE4E0EF8)] - public sealed partial class ChannelAdminLogEventActionChangeAvailableReactions : ChannelAdminLogEventAction - { - /// Previously allowed reaction emojis - public ChatReactions prev_value; - /// New allowed reaction emojis - public ChatReactions new_value; - } - /// The list of usernames associated with the channel was changed See - [TLDef(0xF04FB3A9)] - public sealed partial class ChannelAdminLogEventActionChangeUsernames : ChannelAdminLogEventAction - { - /// Previous set of usernames - public string[] prev_value; - /// New set of usernames - public string[] new_value; - } - /// Forum functionality was enabled or disabled. See - [TLDef(0x02CC6383)] - public sealed partial class ChannelAdminLogEventActionToggleForum : ChannelAdminLogEventAction - { - /// Whether forum functionality was enabled or disabled. - public bool new_value; - } - /// A forum topic was created See - [TLDef(0x58707D28)] - public sealed partial class ChannelAdminLogEventActionCreateTopic : ChannelAdminLogEventAction - { - /// The forum topic that was created - public ForumTopicBase topic; - } - /// A forum topic was edited See - [TLDef(0xF06FE208)] - public sealed partial class ChannelAdminLogEventActionEditTopic : ChannelAdminLogEventAction - { - /// Previous topic information - public ForumTopicBase prev_topic; - /// New topic information - public ForumTopicBase new_topic; - } - /// A forum topic was deleted See - [TLDef(0xAE168909)] - public sealed partial class ChannelAdminLogEventActionDeleteTopic : ChannelAdminLogEventAction - { - /// The forum topic that was deleted - public ForumTopicBase topic; - } - /// A forum topic was pinned or unpinned See - [TLDef(0x5D8D353B)] - public sealed partial class ChannelAdminLogEventActionPinTopic : ChannelAdminLogEventAction - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Previous topic information - [IfFlag(0)] public ForumTopicBase prev_topic; - /// New topic information - [IfFlag(1)] public ForumTopicBase new_topic; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_prev_topic = 0x1, - /// Field has a value - has_new_topic = 0x2, - } - } - /// Native antispam functionality was enabled or disabled. See - [TLDef(0x64F36DFC)] - public sealed partial class ChannelAdminLogEventActionToggleAntiSpam : ChannelAdminLogEventAction - { - /// Whether antispam functionality was enabled or disabled. - public bool new_value; - } - /// The message accent color was changed See - [TLDef(0x5796E780)] - public partial class ChannelAdminLogEventActionChangePeerColor : ChannelAdminLogEventAction - { - /// Previous accent palette - public PeerColorBase prev_value; - /// New accent palette - public PeerColorBase new_value; - } - /// The profile accent color was changed See - [TLDef(0x5E477B25)] - public sealed partial class ChannelAdminLogEventActionChangeProfilePeerColor : ChannelAdminLogEventActionChangePeerColor { } - /// The wallpaper was changed See - [TLDef(0x31BB5D52)] - public sealed partial class ChannelAdminLogEventActionChangeWallpaper : ChannelAdminLogEventAction - { - /// Previous wallpaper - public WallPaperBase prev_value; - /// New wallpaper - public WallPaperBase new_value; - } - /// The emoji status was changed See - [TLDef(0x3EA9FEB1)] - public sealed partial class ChannelAdminLogEventActionChangeEmojiStatus : ChannelAdminLogEventAction - { - /// Previous emoji status - public EmojiStatusBase prev_value; - /// New emoji status - public EmojiStatusBase new_value; - } - /// The supergroup's custom emoji stickerset was changed. See - [TLDef(0x46D840AB)] - public sealed partial class ChannelAdminLogEventActionChangeEmojiStickerSet : ChannelAdminLogEventActionChangeStickerSet { } - /// Channel signature profiles were enabled/disabled. See - [TLDef(0x60A79C79)] - public sealed partial class ChannelAdminLogEventActionToggleSignatureProfiles : ChannelAdminLogEventActionToggleSignatures { } - /// A paid subscriber has extended their Telegram Star subscription ». See - [TLDef(0x64642DB3)] - public sealed partial class ChannelAdminLogEventActionParticipantSubExtend : ChannelAdminLogEventAction - { - /// Same as new_participant. - public ChannelParticipantBase prev_participant; - /// The subscriber that extended the subscription. - public ChannelParticipantBase new_participant; - } - /// Channel autotranslation was toggled ». See - [TLDef(0xC517F77E)] - public sealed partial class ChannelAdminLogEventActionToggleAutotranslation : ChannelAdminLogEventAction - { - /// New value of the toggle - public bool new_value; - } - /// See - [TLDef(0x5806B4EC)] - public sealed partial class ChannelAdminLogEventActionParticipantEditRank : ChannelAdminLogEventAction - { - public long user_id; - public string prev_rank; - public string new_rank; + public string prev_value; + public string new_value; } - /// Admin log event See + ///See [TLDef(0x1FAD68CD)] - public sealed partial class ChannelAdminLogEvent : IObject + public partial class ChannelAdminLogEvent : ITLObject { - /// Event ID public long id; - /// Date public DateTime date; - /// User ID public long user_id; - /// Action public ChannelAdminLogEventAction action; } - /// Admin log events See + ///See [TLDef(0xED8AF74D)] - public sealed partial class Channels_AdminLogResults : IObject, IPeerResolver + public partial class Channels_AdminLogResults : ITLObject { - /// Admin log events public ChannelAdminLogEvent[] events; - /// Chats mentioned in events - public Dictionary chats; - /// Users mentioned in events - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Filter only certain admin log events See + ///See [TLDef(0xEA107AE4)] - public sealed partial class ChannelAdminLogEventsFilter : IObject + public partial class ChannelAdminLogEventsFilter : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { join = 0x1, leave = 0x2, invite = 0x4, ban = 0x8, unban = 0x10, kick = 0x20, unkick = 0x40, + promote = 0x80, demote = 0x100, info = 0x200, settings = 0x400, pinned = 0x800, edit = 0x1000, delete = 0x2000, + group_call = 0x4000, invites = 0x8000 } public Flags flags; - - [Flags] public enum Flags : uint - { - /// Join events, including joins using invite links and join requests. - 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 about, linked chat, location, photo, stickerset, title or username, slowmode, history TTL settings of a channel gets modified) - info = 0x200, - /// Settings change events (invites, hidden prehistory, signatures, default banned rights, forum toggle events) - settings = 0x400, - /// Message pin events - pinned = 0x800, - /// Message edit events - edit = 0x1000, - /// Message deletion events - delete = 0x2000, - /// Group call events - group_call = 0x4000, - /// Invite events - invites = 0x8000, - /// A message was posted in a channel - send = 0x10000, - /// Forum-related events - forums = 0x20000, - /// Telegram Star subscription extension events » - sub_extend = 0x40000, - edit_rank = 0x80000, - } } - /// Popular contact See + ///See [TLDef(0x5CE14175)] - public sealed partial class PopularContact : IObject + public partial class PopularContact : ITLObject { - /// Contact identifier public long client_id; - /// How many people imported this contact public int importers; } - /// Favorited stickers See - /// a value means messages.favedStickersNotModified + ///See + ///a null value means messages.favedStickersNotModified [TLDef(0x2CB51097)] - public sealed partial class Messages_FavedStickers : IObject + public partial class Messages_FavedStickers : ITLObject { - /// Hash used for caching, for more info click here public long hash; - /// Emojis associated to stickers public StickerPack[] packs; - /// Favorited stickers public DocumentBase[] stickers; } - /// Recent t.me urls See Derived classes: , , , , - public abstract partial class RecentMeUrl : IObject - { - /// URL - public string url; - } - /// Unknown t.me url See + ///See + public abstract partial class RecentMeUrl : ITLObject { public string url; } + ///See [TLDef(0x46E1D13D)] - public sealed partial class RecentMeUrlUnknown : RecentMeUrl { } - /// Recent t.me link to a user See - [TLDef(0xB92C09E2, inheritAt = 0)] - public sealed partial class RecentMeUrlUser : RecentMeUrl - { - /// User ID - public long user_id; - } - /// Recent t.me link to a chat See - [TLDef(0xB2DA71D2, inheritAt = 0)] - public sealed partial class RecentMeUrlChat : RecentMeUrl - { - /// Chat ID - public long chat_id; - } - /// Recent t.me invite link to a chat See - [TLDef(0xEB49081D, inheritAt = 0)] - public sealed partial class RecentMeUrlChatInvite : RecentMeUrl - { - /// Chat invitation - public ChatInviteBase chat_invite; - } - /// Recent t.me stickerset installation URL See - [TLDef(0xBC0A57DC, inheritAt = 0)] - public sealed partial class RecentMeUrlStickerSet : RecentMeUrl - { - /// Stickerset - public StickerSetCoveredBase set; - } + public partial class RecentMeUrlUnknown : RecentMeUrl { } + ///See + [TLDef(0xB92C09E2)] + public partial class RecentMeUrlUser : RecentMeUrl { public long user_id; } + ///See + [TLDef(0xB2DA71D2)] + public partial class RecentMeUrlChat : RecentMeUrl { public long chat_id; } + ///See + [TLDef(0xEB49081D)] + public partial class RecentMeUrlChatInvite : RecentMeUrl { public ChatInviteBase chat_invite; } + ///See + [TLDef(0xBC0A57DC)] + public partial class RecentMeUrlStickerSet : RecentMeUrl { public StickerSetCoveredBase set; } - /// Recent t.me URLs See + ///See [TLDef(0x0E0310D7)] - public sealed partial class Help_RecentMeUrls : IObject, IPeerResolver + public partial class Help_RecentMeUrls : ITLObject { - /// URLs public RecentMeUrl[] urls; - /// Chats - public Dictionary chats; - /// Users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// A single media in an album or grouped media sent with Messages_SendMultiMedia. See + ///See [TLDef(0x1CC6E91F)] - public sealed partial class InputSingleMedia : IObject + public partial class InputSingleMedia : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_entities = 0x1 } public Flags flags; - /// The media public InputMedia media; - /// Unique client media ID required to prevent message resending public long random_id; - /// A caption for the media public string message; - /// Message entities for styled text [IfFlag(0)] public MessageEntity[] entities; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_entities = 0x1, - } } - /// Represents a bot logged in using the Telegram login widget See + ///See [TLDef(0xA6F8F452)] - public sealed partial class WebAuthorization : IObject + public partial class WebAuthorization : ITLObject { - /// Authorization hash public long hash; - /// Bot ID public long bot_id; - /// The domain name of the website on which the user has logged in. public string domain; - /// Browser user-agent public string browser; - /// Platform public string platform; - /// When was the web session created - public DateTime date_created; - /// When was the web session last active - public DateTime date_active; - /// IP address + public int date_created; + public int date_active; public string ip; - /// Region, determined from IP address public string region; } - /// Web authorizations See + ///See [TLDef(0xED56C9FC)] - public sealed partial class Account_WebAuthorizations : IObject + public partial class Account_WebAuthorizations : ITLObject { - /// Web authorization list public WebAuthorization[] authorizations; - /// Users - public Dictionary users; + public UserBase[] users; } - /// A message See Derived classes: , , , - public abstract partial class InputMessage : IObject { } - /// Message by ID See + ///See + public abstract partial class InputMessage : ITLObject { } + ///See [TLDef(0xA676A322)] - public sealed partial class InputMessageID : InputMessage - { - /// Message ID - public int id; - } - /// Message to which the specified message replies to See + public partial class InputMessageID : InputMessage { public int id; } + ///See [TLDef(0xBAD88395)] - public sealed partial class InputMessageReplyTo : InputMessage - { - /// ID of the message that replies to the message we need - public int id; - } - /// Pinned message See + public partial class InputMessageReplyTo : InputMessage { public int id; } + ///See [TLDef(0x86872538)] - public sealed partial class InputMessagePinned : InputMessage { } - /// Used by bots for fetching information about the message that originated a callback query See + public partial class InputMessagePinned : InputMessage { } + ///See [TLDef(0xACFA1A7E)] - public sealed partial class InputMessageCallbackQuery : InputMessage + public partial class InputMessageCallbackQuery : InputMessage { - /// Message ID public int id; - /// Callback query ID public long query_id; } - /// Peer, or all peers in a certain folder See Derived classes: , - public abstract partial class InputDialogPeerBase : IObject { } - /// A peer See + ///See + public abstract partial class InputDialogPeerBase : ITLObject { } + ///See [TLDef(0xFCAAFEB7)] - public sealed partial class InputDialogPeer : InputDialogPeerBase - { - /// Peer - public InputPeer peer; - } - /// All peers in a peer folder See + public partial class InputDialogPeer : InputDialogPeerBase { public InputPeer peer; } + ///See [TLDef(0x64600527)] - public sealed partial class InputDialogPeerFolder : InputDialogPeerBase - { - /// Peer folder ID, for more info click here - public int folder_id; - } + public partial class InputDialogPeerFolder : InputDialogPeerBase { public int folder_id; } - /// Peer, or all peers in a folder See Derived classes: , - public abstract partial class DialogPeerBase : IObject { } - /// Peer See + ///See + public abstract partial class DialogPeerBase : ITLObject { } + ///See [TLDef(0xE56DBF05)] - public sealed partial class DialogPeer : DialogPeerBase - { - /// Peer - public Peer peer; - } - /// Peer folder See + public partial class DialogPeer : DialogPeerBase { public Peer peer; } + ///See [TLDef(0x514519E2)] - public sealed partial class DialogPeerFolder : DialogPeerBase - { - /// Peer folder ID, for more info click here - public int folder_id; - } + public partial class DialogPeerFolder : DialogPeerBase { public int folder_id; } - /// Found stickersets See - /// a value means messages.foundStickerSetsNotModified + ///See + ///a null value means messages.foundStickerSetsNotModified [TLDef(0x8AF09DD2)] - public sealed partial class Messages_FoundStickerSets : IObject + public partial class Messages_FoundStickerSets : ITLObject { - /// Hash used for caching, for more info click here public long hash; - /// Found stickersets public StickerSetCoveredBase[] sets; } - /// SHA256 Hash of an uploaded file, to be checked for validity after download See - [TLDef(0xF39B035C)] - public sealed partial class FileHash : IObject + ///See + [TLDef(0x6242C773)] + public partial class FileHash : ITLObject { - /// Offset from where to start computing SHA-256 hash - public long offset; - /// Length + public int offset; public int limit; - /// SHA-256 Hash of file chunk, to be checked for validity after download public byte[] hash; } - /// Info about an MTProxy used to connect. See + ///See [TLDef(0x75588B3F)] - public sealed partial class InputClientProxy : IObject + public partial class InputClientProxy : ITLObject { - /// Proxy address public string address; - /// Proxy port public int port; } - /// Update of Telegram's terms of service See Derived classes: , - public abstract partial class Help_TermsOfServiceUpdateBase : IObject { } - /// No changes were made to telegram's terms of service See + ///See + public abstract partial class Help_TermsOfServiceUpdateBase : ITLObject { } + ///See [TLDef(0xE3309F7F)] - public sealed partial class Help_TermsOfServiceUpdateEmpty : Help_TermsOfServiceUpdateBase - { - /// 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 + public partial class Help_TermsOfServiceUpdateEmpty : Help_TermsOfServiceUpdateBase { public DateTime expires; } + ///See [TLDef(0x28ECF961)] - public sealed partial class Help_TermsOfServiceUpdate : Help_TermsOfServiceUpdateBase + public partial class Help_TermsOfServiceUpdate : Help_TermsOfServiceUpdateBase { - /// 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; } - /// Secure passport file, for more info see the passport docs » See Derived classes: , - public abstract partial class InputSecureFileBase : IObject - { - /// Secure file ID - public abstract long ID { get; set; } - } - /// Uploaded secure file, for more info see the passport docs » See + ///See + public abstract partial class InputSecureFileBase : ITLObject { } + ///See [TLDef(0x3334B0F0)] - public sealed partial class InputSecureFileUploaded : InputSecureFileBase + public partial class InputSecureFileUploaded : InputSecureFileBase { - /// Secure file ID public long id; - /// Secure file part count public int parts; - /// MD5 hash of encrypted uploaded file, to be checked server-side - public string md5_checksum; - /// File hash + public byte[] md5_checksum; public byte[] file_hash; - /// Secret public byte[] secret; - - /// Secure file ID - public override long ID { get => id; set => id = value; } } - /// Pre-uploaded passport file, for more info see the passport docs » See + ///See [TLDef(0x5367E5BE)] - public sealed partial class InputSecureFile : InputSecureFileBase + public partial class InputSecureFile : InputSecureFileBase { - /// Secure file ID public long id; - /// REQUIRED FIELD. See how to obtain it
Secure file access hash
public long access_hash; - - /// Secure file ID - public override long ID { get => id; set => id = value; } } - ///
Secure passport file, for more info see the passport docs » See - /// a value means secureFileEmpty - [TLDef(0x7D09C27E)] - public sealed partial class SecureFile : IObject + ///See + ///a null value means secureFileEmpty + [TLDef(0xE0277A62)] + public partial class SecureFile : ITLObject { - /// ID public long id; - /// Access hash public long access_hash; - /// File size - public long size; - /// DC ID + public int size; public int dc_id; - /// Date of upload public DateTime date; - /// File hash public byte[] file_hash; - /// Secret public byte[] secret; } - /// Secure passport data, for more info see the passport docs » See + ///See [TLDef(0x8AEABEC3)] - public sealed partial class SecureData : IObject + public partial class SecureData : ITLObject { - /// Data public byte[] data; - /// Data hash public byte[] data_hash; - /// Secret public byte[] secret; } - /// Plaintext verified passport data. See Derived classes: , - public abstract partial class SecurePlainData : IObject { } - /// Phone number to use in telegram passport: it must be verified, first ». See + ///See + public abstract partial class SecurePlainData : ITLObject { } + ///See [TLDef(0x7D6099DD)] - public sealed partial class SecurePlainPhone : SecurePlainData - { - /// Phone number - public string phone; - } - /// Email address to use in telegram passport: it must be verified, first ». See + public partial class SecurePlainPhone : SecurePlainData { public string phone; } + ///See [TLDef(0x21EC5A5F)] - public sealed partial class SecurePlainEmail : SecurePlainData - { - /// Email address - public string email; - } + public partial class SecurePlainEmail : SecurePlainData { public string email; } - /// Secure value type See + ///See public enum SecureValueType : uint { - ///Personal details + ///See PersonalDetails = 0x9D2A81E3, - ///Passport + ///See Passport = 0x3DAC6A00, - ///Driver's license + ///See DriverLicense = 0x06E425C4, - ///Identity card + ///See IdentityCard = 0xA0D0744B, - ///Internal passport + ///See InternalPassport = 0x99A48F23, - ///Address + ///See Address = 0xCBE31E26, - ///Utility bill + ///See UtilityBill = 0xFC36954E, - ///Bank statement + ///See BankStatement = 0x89137C0D, - ///Rental agreement + ///See RentalAgreement = 0x8B883488, - ///Internal registration passport + ///See PassportRegistration = 0x99E3806A, - ///Temporary registration + ///See TemporaryRegistration = 0xEA02EC33, - ///Phone + ///See Phone = 0xB320AADB, - ///Email + ///See Email = 0x8E3CA7EE, } - /// Secure value See + ///See [TLDef(0x187FA0CA)] - public sealed partial class SecureValue : IObject + public partial class SecureValue : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_data = 0x1, has_front_side = 0x2, has_reverse_side = 0x4, has_selfie = 0x8, has_files = 0x10, + has_plain_data = 0x20, has_translation = 0x40 } public Flags flags; - /// Secure passport value type public SecureValueType type; - /// Encrypted Telegram Passport element data [IfFlag(0)] public SecureData data; - /// Encrypted passport file with the front side of the document [IfFlag(1)] public SecureFile front_side; - /// Encrypted passport file with the reverse side of the document [IfFlag(2)] public SecureFile reverse_side; - /// Encrypted passport file with a selfie of the user holding the document [IfFlag(3)] public SecureFile selfie; - /// Array of encrypted passport files with translated versions of the provided documents [IfFlag(6)] public SecureFile[] translation; - /// Array of encrypted passport files with photos the of the documents [IfFlag(4)] public SecureFile[] files; - /// Plaintext verified passport data [IfFlag(5)] public SecurePlainData plain_data; - /// Data hash public byte[] hash; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_data = 0x1, - /// Field has a value - has_front_side = 0x2, - /// Field has a value - has_reverse_side = 0x4, - /// Field has a value - has_selfie = 0x8, - /// Field has a value - has_files = 0x10, - /// Field has a value - has_plain_data = 0x20, - /// Field has a value - has_translation = 0x40, - } } - /// Secure value, for more info see the passport docs » See + ///See [TLDef(0xDB21D0A7)] - public sealed partial class InputSecureValue : IObject + public partial class InputSecureValue : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_data = 0x1, has_front_side = 0x2, has_reverse_side = 0x4, has_selfie = 0x8, has_files = 0x10, + has_plain_data = 0x20, has_translation = 0x40 } public Flags flags; - /// Secure passport value type public SecureValueType type; - /// Encrypted Telegram Passport element data [IfFlag(0)] public SecureData data; - /// Encrypted passport file with the front side of the document [IfFlag(1)] public InputSecureFileBase front_side; - /// Encrypted passport file with the reverse side of the document [IfFlag(2)] public InputSecureFileBase reverse_side; - /// Encrypted passport file with a selfie of the user holding the document [IfFlag(3)] public InputSecureFileBase selfie; - /// Array of encrypted passport files with translated versions of the provided documents [IfFlag(6)] public InputSecureFileBase[] translation; - /// Array of encrypted passport files with photos the of the documents [IfFlag(4)] public InputSecureFileBase[] files; - /// Plaintext verified passport data [IfFlag(5)] public SecurePlainData plain_data; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_data = 0x1, - /// Field has a value - has_front_side = 0x2, - /// Field has a value - has_reverse_side = 0x4, - /// Field has a value - has_selfie = 0x8, - /// Field has a value - has_files = 0x10, - /// Field has a value - has_plain_data = 0x20, - /// Field has a value - has_translation = 0x40, - } } - /// Secure value hash See + ///See [TLDef(0xED1ECDB0)] - public sealed partial class SecureValueHash : IObject + public partial class SecureValueHash : ITLObject { - /// Secure value type public SecureValueType type; - /// Hash public byte[] hash; } - /// Secure value error See Derived classes: , , , , , , , , - public abstract partial class SecureValueErrorBase : IObject - { - /// The section of the user's Telegram Passport which has the error, one of , , , , , - public virtual SecureValueType Type => default; - /// Error message - public virtual string Text => default; - } - /// Represents an issue in one of the data fields that was provided by the user. The error is considered resolved when the field's value changes. See + ///See + public abstract partial class SecureValueErrorBase : ITLObject { } + ///See [TLDef(0xE8A40BD9)] - public sealed partial class SecureValueErrorData : SecureValueErrorBase + public partial class SecureValueErrorData : SecureValueErrorBase { - /// The section of the user's Telegram Passport which has the error, one of , , , , , public SecureValueType type; - /// Data hash public byte[] data_hash; - /// Name of the data field which has the error public string field; - /// Error message public string text; - - /// The section of the user's Telegram Passport which has the error, one of , , , , , - public override SecureValueType Type => type; - /// Error message - public override string Text => text; } - /// Represents an issue with the front side of a document. The error is considered resolved when the file with the front side of the document changes. See + ///See [TLDef(0x00BE3DFA)] - public sealed partial class SecureValueErrorFrontSide : SecureValueErrorBase + public partial class SecureValueErrorFrontSide : SecureValueErrorBase { - /// One of , , , public SecureValueType type; - /// File hash public byte[] file_hash; - /// Error message public string text; - - /// One of , , , - public override SecureValueType Type => type; - /// Error message - public override string Text => text; } - /// Represents an issue with the reverse side of a document. The error is considered resolved when the file with reverse side of the document changes. See + ///See [TLDef(0x868A2AA5)] - public sealed partial class SecureValueErrorReverseSide : SecureValueErrorBase + public partial class SecureValueErrorReverseSide : SecureValueErrorBase { - /// One of , public SecureValueType type; - /// File hash public byte[] file_hash; - /// Error message public string text; - - /// One of , - public override SecureValueType Type => type; - /// Error message - public override string Text => text; } - /// Represents an issue with the selfie with a document. The error is considered resolved when the file with the selfie changes. See + ///See [TLDef(0xE537CED6)] - public sealed partial class SecureValueErrorSelfie : SecureValueErrorBase + public partial class SecureValueErrorSelfie : SecureValueErrorBase { - /// One of , , , public SecureValueType type; - /// File hash public byte[] file_hash; - /// Error message public string text; - - /// One of , , , - public override SecureValueType Type => type; - /// Error message - public override string Text => text; } - /// Represents an issue with a document scan. The error is considered resolved when the file with the document scan changes. See + ///See [TLDef(0x7A700873)] public partial class SecureValueErrorFile : SecureValueErrorBase { - /// One of , , , , public SecureValueType type; - /// File hash public byte[] file_hash; - /// Error message public string text; - - /// One of , , , , - public override SecureValueType Type => type; - /// Error message - public override string Text => text; } - /// Represents an issue with a list of scans. The error is considered resolved when the list of files containing the scans changes. See + ///See [TLDef(0x666220E9)] public partial class SecureValueErrorFiles : SecureValueErrorBase { - /// One of , , , , public SecureValueType type; - /// File hash public byte[][] file_hash; - /// Error message public string text; - - /// One of , , , , - public override SecureValueType Type => type; - /// Error message - public override string Text => text; } - /// Secure value error See + ///See [TLDef(0x869D758F)] - public sealed partial class SecureValueError : SecureValueErrorBase + public partial class SecureValueError : SecureValueErrorBase { - /// Type of element which has the issue public SecureValueType type; - /// Hash public byte[] hash; - /// Error message public string text; - - /// Type of element which has the issue - public override SecureValueType Type => type; - /// Error message - public override string Text => text; } - /// Represents an issue with one of the files that constitute the translation of a document. The error is considered resolved when the file changes. See + ///See [TLDef(0xA1144770)] - public sealed partial class SecureValueErrorTranslationFile : SecureValueErrorFile - { - } - /// Represents an issue with the translated version of a document. The error is considered resolved when a file with the document translation changes. See + public partial class SecureValueErrorTranslationFile : SecureValueErrorFile { } + ///See [TLDef(0x34636DD8)] - public sealed partial class SecureValueErrorTranslationFiles : SecureValueErrorFiles - { - } + public partial class SecureValueErrorTranslationFiles : SecureValueErrorFiles { } - /// Encrypted credentials required to decrypt telegram passport data. See + ///See [TLDef(0x33F0EA47)] - public sealed partial class SecureCredentialsEncrypted : IObject + public partial class SecureCredentialsEncrypted : ITLObject { - /// Encrypted JSON-serialized data with unique user's payload, data hashes and secrets required for EncryptedPassportElement decryption and authentication, as described in decrypting data » public byte[] data; - /// Data hash for data authentication as described in decrypting data » public byte[] hash; - /// Secret, encrypted with the bot's public RSA key, required for data decryption as described in decrypting data » public byte[] secret; } - /// Telegram Passport authorization form See + ///See [TLDef(0xAD2E1CD8)] - public sealed partial class Account_AuthorizationForm : IObject + public partial class Account_AuthorizationForm : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_privacy_policy_url = 0x1 } public Flags flags; - /// Required Telegram Passport documents public SecureRequiredTypeBase[] required_types; - /// Already submitted Telegram Passport documents public SecureValue[] values; - /// Telegram Passport errors public SecureValueErrorBase[] errors; - /// Info about the bot to which the form will be submitted - public Dictionary users; - /// URL of the service's privacy policy + public UserBase[] users; [IfFlag(0)] public string privacy_policy_url; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_privacy_policy_url = 0x1, - } } - /// The sent email code See + ///See [TLDef(0x811F854F)] - public sealed partial class Account_SentEmailCode : IObject + public partial class Account_SentEmailCode : ITLObject { - /// The email (to which the code was sent) must match this pattern public string email_pattern; - /// The length of the verification code public int length; } - /// Deep link info, see the here for more details See - /// a value means help.deepLinkInfoEmpty + ///See + ///a null value means help.deepLinkInfoEmpty [TLDef(0x6A4EE832)] - public sealed partial class Help_DeepLinkInfo : IObject + public partial class Help_DeepLinkInfo : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { update_app = 0x1, has_entities = 0x2 } public Flags flags; - /// Message to show to the user public string message; - /// Message entities for styled text [IfFlag(1)] public MessageEntity[] entities; - - [Flags] public enum Flags : uint - { - /// An update of the app is required to parse this link - update_app = 0x1, - /// Field has a value - has_entities = 0x2, - } } - /// Saved contact See Derived classes: - public abstract partial class SavedContact : IObject { } - /// Saved contact See + ///See + public abstract partial class SavedContact : ITLObject { } + ///See [TLDef(0x1142BD56)] - public sealed partial class SavedPhoneContact : SavedContact + public partial class SavedPhoneContact : SavedContact { - /// Phone number public string phone; - /// First name public string first_name; - /// Last name public string last_name; - /// Date added public DateTime date; } - /// Takeout info See + ///See [TLDef(0x4DBA4501)] - public sealed partial class Account_Takeout : IObject - { - /// Takeout ID - public long id; - } + public partial class Account_Takeout : ITLObject { public long id; } - /// Key derivation function to use when generating the password hash for SRP two-factor authorization See Derived classes: - /// a value means passwordKdfAlgoUnknown - public abstract partial class PasswordKdfAlgo : IObject { } - /// This key derivation algorithm defines that SRP 2FA login must be used See + ///See + ///a null value means passwordKdfAlgoUnknown + public abstract partial class PasswordKdfAlgo : ITLObject { } + ///See [TLDef(0x3A912D4A)] - public sealed partial class PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow : PasswordKdfAlgo + public partial class PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow : PasswordKdfAlgo { - /// One of two salts used by the derivation function (see SRP 2FA login) public byte[] salt1; - /// One of two salts used by the derivation function (see SRP 2FA login) public byte[] salt2; - /// Base (see SRP 2FA login) public int g; - /// 2048-bit modulus (see SRP 2FA login) public byte[] p; } - /// KDF algorithm to use for computing telegram passport hash See Derived classes: , - /// a value means securePasswordKdfAlgoUnknown - public abstract partial class SecurePasswordKdfAlgo : IObject - { - /// Salt - public byte[] salt; - } - /// PBKDF2 with SHA512 and 100000 iterations KDF algo See + ///See + ///a null value means securePasswordKdfAlgoUnknown + public abstract partial class SecurePasswordKdfAlgo : ITLObject { public byte[] salt; } + ///See [TLDef(0xBBF2DDA0)] - public sealed partial class SecurePasswordKdfAlgoPBKDF2HMACSHA512iter100000 : SecurePasswordKdfAlgo { } - /// SHA512 KDF algo See + public partial class SecurePasswordKdfAlgoPBKDF2HMACSHA512iter100000 : SecurePasswordKdfAlgo { } + ///See [TLDef(0x86471D92)] - public sealed partial class SecurePasswordKdfAlgoSHA512 : SecurePasswordKdfAlgo { } + public partial class SecurePasswordKdfAlgoSHA512 : SecurePasswordKdfAlgo { } - /// Secure settings See + ///See [TLDef(0x1527BCAC)] - public sealed partial class SecureSecretSettings : IObject + public partial class SecureSecretSettings : ITLObject { - /// Secure KDF algo public SecurePasswordKdfAlgo secure_algo; - /// Secure secret public byte[] secure_secret; - /// Secret ID public long secure_secret_id; } - /// Constructor for checking the validity of a 2FA SRP password (see SRP) See - /// a value means inputCheckPasswordEmpty + ///See + ///a null value means inputCheckPasswordEmpty [TLDef(0xD27FF082)] - public sealed partial class InputCheckPasswordSRP : IObject + public partial class InputCheckPasswordSRP : ITLObject { - /// SRP ID public long srp_id; - /// A parameter (see SRP) public byte[] A; - /// M1 parameter (see SRP) public byte[] M1; } - /// Required secure file type See Derived classes: , - public abstract partial class SecureRequiredTypeBase : IObject { } - /// Required type See + ///See + public abstract partial class SecureRequiredTypeBase : ITLObject { } + ///See [TLDef(0x829D99DA)] - public sealed partial class SecureRequiredType : SecureRequiredTypeBase + public partial class SecureRequiredType : SecureRequiredTypeBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { native_names = 0x1, selfie_required = 0x2, translation_required = 0x4 } public Flags flags; - /// Secure value type public SecureValueType type; - - [Flags] public enum Flags : uint - { - /// Native names - native_names = 0x1, - /// Is a selfie required - selfie_required = 0x2, - /// Is a translation required - translation_required = 0x4, - } } - /// One of See + ///See [TLDef(0x027477B4)] - public sealed partial class SecureRequiredTypeOneOf : SecureRequiredTypeBase - { - /// Secure required value types - public SecureRequiredTypeBase[] types; - } + public partial class SecureRequiredTypeOneOf : SecureRequiredTypeBase { public SecureRequiredTypeBase[] types; } - /// Telegram passport configuration See - /// a value means help.passportConfigNotModified + ///See + ///a null value means help.passportConfigNotModified [TLDef(0xA098D6AF)] - public sealed partial class Help_PassportConfig : IObject + public partial class Help_PassportConfig : ITLObject { - /// Hash used for caching, for more info click here public int hash; - /// Localization public DataJSON countries_langs; } - /// Event that occurred in the application. See + ///See [TLDef(0x1D1B1245)] - public sealed partial class InputAppEvent : IObject + public partial class InputAppEvent : ITLObject { - /// Client's exact timestamp for the event public double time; - /// Type of event public string type; - /// Arbitrary numeric value for more convenient selection of certain event types, or events referring to a certain object public long peer; - /// Details of the event public JSONValue data; } - /// JSON key: value pair See + ///See + public abstract partial class JSONObjectValue : ITLObject { } + ///See [TLDef(0xC0DE1BD9)] - public sealed partial class JsonObjectValue : IObject + public partial class JsonObjectValue : JSONObjectValue { - /// Key public string key; - /// Value public JSONValue value; } - /// JSON value See Derived classes: , , , , , - public abstract partial class JSONValue : IObject { } - /// null JSON value See + ///See + public abstract partial class JSONValue : ITLObject { } + ///See [TLDef(0x3F6D7B68)] - public sealed partial class JsonNull : JSONValue { } - /// JSON boolean value See + public partial class JsonNull : JSONValue { } + ///See [TLDef(0xC7345E6A)] - public sealed partial class JsonBool : JSONValue - { - /// Value - public bool value; - } - /// JSON numeric value See + public partial class JsonBool : JSONValue { public bool value; } + ///See [TLDef(0x2BE0DFA4)] - public sealed partial class JsonNumber : JSONValue - { - /// Value - public double value; - } - /// JSON string See + public partial class JsonNumber : JSONValue { public double value; } + ///See [TLDef(0xB71E767A)] - public sealed partial class JsonString : JSONValue - { - /// Value - public string value; - } - /// JSON array See + public partial class JsonString : JSONValue { public string value; } + ///See [TLDef(0xF7444763)] - public sealed partial class JsonArray : JSONValue - { - /// JSON values - public JSONValue[] value; - } - /// JSON object value See + public partial class JsonArray : JSONValue { public JSONValue[] value; } + ///See [TLDef(0x99C1D49D)] - public sealed partial class JsonObject : JSONValue - { - /// Values - public JsonObjectValue[] value; - } + public partial class JsonObject : JSONValue { public JSONObjectValue[] value; } - /// Table cell See + ///See [TLDef(0x34566B6A)] - public sealed partial class PageTableCell : IObject + public partial class PageTableCell : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { header = 0x1, has_colspan = 0x2, has_rowspan = 0x4, align_center = 0x8, align_right = 0x10, + valign_middle = 0x20, valign_bottom = 0x40, has_text = 0x80 } public Flags flags; - /// Content [IfFlag(7)] public RichText text; - /// For how many columns should this cell extend [IfFlag(1)] public int colspan; - /// For how many rows should this cell extend [IfFlag(2)] public int rowspan; - - [Flags] public enum Flags : uint - { - /// Is this element part of the column header - header = 0x1, - /// Field has a value - has_colspan = 0x2, - /// Field has a value - has_rowspan = 0x4, - /// Horizontally centered block - align_center = 0x8, - /// Right-aligned block - align_right = 0x10, - /// Vertically centered block - valign_middle = 0x20, - /// Block vertically-aligned to the bottom - valign_bottom = 0x40, - /// Field has a value - has_text = 0x80, - } } - /// Table row See + ///See [TLDef(0xE0C0C5E5)] - public sealed partial class PageTableRow : IObject - { - /// Table cells - public PageTableCell[] cells; - } + public partial class PageTableRow : ITLObject { public PageTableCell[] cells; } - /// Page caption See + ///See [TLDef(0x6F747657)] - public sealed partial class PageCaption : IObject + public partial class PageCaption : ITLObject { - /// Caption public RichText text; - /// Credits public RichText credit; } - /// Item in block list See Derived classes: , - public abstract partial class PageListItem : IObject { } - /// List item See + ///See + public abstract partial class PageListItem : ITLObject { } + ///See [TLDef(0xB92FB6CD)] - public sealed partial class PageListItemText : PageListItem - { - /// Text - public RichText text; - } - /// List item See + public partial class PageListItemText : PageListItem { public RichText text; } + ///See [TLDef(0x25E073FC)] - public sealed partial class PageListItemBlocks : PageListItem - { - /// Blocks - public PageBlock[] blocks; - } + public partial class PageListItemBlocks : PageListItem { public PageBlock[] blocks; } - /// Represents an instant view ordered list See Derived classes: , - public abstract partial class PageListOrderedItem : IObject - { - /// Number of element within ordered list - public string num; - } - /// Ordered list of text items See - [TLDef(0x5E068047, inheritAt = 0)] - public sealed partial class PageListOrderedItemText : PageListOrderedItem - { - /// Text - public RichText text; - } - /// Ordered list of IV blocks See - [TLDef(0x98DD8936, inheritAt = 0)] - public sealed partial class PageListOrderedItemBlocks : PageListOrderedItem - { - /// Item contents - public PageBlock[] blocks; - } + ///See + public abstract partial class PageListOrderedItem : ITLObject { public string num; } + ///See + [TLDef(0x5E068047)] + public partial class PageListOrderedItemText : PageListOrderedItem { public RichText text; } + ///See + [TLDef(0x98DD8936)] + public partial class PageListOrderedItemBlocks : PageListOrderedItem { public PageBlock[] blocks; } - /// Related article See + ///See [TLDef(0xB390DC08)] - public sealed partial class PageRelatedArticle : IObject + public partial class PageRelatedArticle : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_title = 0x1, has_description = 0x2, has_photo_id = 0x4, has_author = 0x8, + has_published_date = 0x10 } public Flags flags; - /// URL of article public string url; - /// Webpage ID of generated IV preview public long webpage_id; - /// Title [IfFlag(0)] public string title; - /// Description [IfFlag(1)] public string description; - /// ID of preview photo [IfFlag(2)] public long photo_id; - /// Author name [IfFlag(3)] public string author; - /// Date of publication [IfFlag(4)] public DateTime published_date; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_title = 0x1, - /// Field has a value - has_description = 0x2, - /// Field has a value - has_photo_id = 0x4, - /// Field has a value - has_author = 0x8, - /// Field has a value - has_published_date = 0x10, - } } - /// Instant view page See + ///See [TLDef(0x98657F0D)] - public sealed partial class Page : IObject + public partial class Page : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { part = 0x1, rtl = 0x2, v2 = 0x4, has_views = 0x8 } public Flags flags; - /// Original page HTTP URL public string url; - /// Page elements (like with HTML elements, only as TL constructors) public PageBlock[] blocks; - /// Photos in page public PhotoBase[] photos; - /// Media in page public DocumentBase[] documents; - /// View count [IfFlag(3)] public int views; - - [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. - part = 0x1, - /// Whether the page contains RTL text - rtl = 0x2, - /// Whether this is an IV v2 page - v2 = 0x4, - /// Field has a value - has_views = 0x8, - } } - /// Localized name for telegram support See + ///See [TLDef(0x8C05F1C9)] - public sealed partial class Help_SupportName : IObject - { - /// Localized name - public string name; - } + public partial class Help_SupportName : ITLObject { public string name; } - /// Internal use See - /// a value means help.userInfoEmpty + ///See + ///a null value means help.userInfoEmpty [TLDef(0x01EB3758)] - public sealed partial class Help_UserInfo : IObject + public partial class Help_UserInfo : ITLObject { - /// Info public string message; - /// Message entities for styled text public MessageEntity[] entities; - /// Author public string author; - /// Date public DateTime date; } - /// A possible answer of a poll See - [TLDef(0xFF16E2CA)] - public sealed partial class PollAnswer : IObject + ///See + [TLDef(0x6CA9C2E9)] + public partial class PollAnswer : ITLObject { - /// Textual representation of the answer (only Premium users can use custom emoji entities here). - public TextWithEntities text; - /// The param that has to be passed to Messages_SendVote. + public string text; public byte[] option; } - /// Poll See - [TLDef(0x58747131)] - public sealed partial class Poll : IObject + ///See + [TLDef(0x86E18161)] + public partial class Poll : ITLObject { - /// ID of the poll + [Flags] public enum Flags { closed = 0x1, public_voters = 0x2, multiple_choice = 0x4, quiz = 0x8, has_close_period = 0x10, + has_close_date = 0x20 } public long id; - /// Extra bits of information, use flags.HasFlag(...) to test for those public Flags flags; - /// The question of the poll (only Premium users can use custom emoji entities here). - public TextWithEntities question; - /// The possible answers (2-poll_answers_max), vote using Messages_SendVote. + public string question; 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; - /// Point in time (Unix timestamp) when the poll will be automatically closed. Must be at least 5 and no more than 600 seconds in the future; can't be used together with close_period. [IfFlag(5)] public DateTime close_date; - - [Flags] public enum Flags : uint - { - /// Whether the poll is closed and doesn't accept any more answers - closed = 0x1, - /// Whether cast votes are publicly visible to all users (non-anonymous poll) - public_voters = 0x2, - /// Whether multiple options can be chosen as answer - multiple_choice = 0x4, - /// Whether this is a quiz (with wrong and correct answers, results shown in the return type) - quiz = 0x8, - /// Field has a value - has_close_period = 0x10, - /// Field has a value - has_close_date = 0x20, - } } - /// A poll answer, and how users voted on it See + ///See [TLDef(0x3B6DDAD2)] - public sealed partial class PollAnswerVoters : IObject + public partial class PollAnswerVoters : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { chosen = 0x1, correct = 0x2 } public Flags flags; - /// The param that has to be passed to Messages_SendVote. public byte[] option; - /// How many users voted for this option public int voters; - - [Flags] public enum Flags : uint - { - /// Whether we have chosen this answer - chosen = 0x1, - /// For quizzes, whether the option we have chosen is correct - correct = 0x2, - } } - /// Results of poll See - [TLDef(0x7ADF2420)] - public sealed partial class PollResults : IObject + ///See + [TLDef(0xDCB82EA3)] + public partial class PollResults : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { min = 0x1, has_results = 0x2, has_total_voters = 0x4, has_recent_voters = 0x8, has_solution = 0x10 } public Flags flags; - /// Poll results [IfFlag(1)] public PollAnswerVoters[] results; - /// Total number of people that voted in the poll [IfFlag(2)] public int total_voters; - /// IDs of the last users that recently voted in the poll - [IfFlag(3)] public Peer[] recent_voters; - /// Explanation of quiz solution + [IfFlag(3)] public long[] recent_voters; [IfFlag(4)] public string solution; - /// Message entities for styled text in quiz solution [IfFlag(4)] public MessageEntity[] solution_entities; - - [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). - min = 0x1, - /// Field has a value - has_results = 0x2, - /// Field has a value - has_total_voters = 0x4, - /// Field has a value - has_recent_voters = 0x8, - /// Fields and have a value - has_solution = 0x10, - } } - /// Number of online users in a chat See + ///See [TLDef(0xF041E250)] - public sealed partial class ChatOnlines : IObject - { - /// Number of online users - public int onlines; - } + public partial class ChatOnlines : ITLObject { public int onlines; } - /// URL with chat statistics See + ///See [TLDef(0x47A971E0)] - public sealed partial class StatsURL : IObject - { - /// Chat statistics - public string url; - } + public partial class StatsURL : ITLObject { public string url; } - /// Represents the rights of an admin in a channel/supergroup. See + ///See [TLDef(0x5FB224D5)] - public sealed partial class ChatAdminRights : IObject + public partial class ChatAdminRights : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { change_info = 0x1, post_messages = 0x2, edit_messages = 0x4, delete_messages = 0x8, + ban_users = 0x10, invite_users = 0x20, pin_messages = 0x80, add_admins = 0x200, anonymous = 0x400, manage_call = 0x800, + other = 0x1000 } public Flags flags; - - [Flags] public enum Flags : uint - { - /// If set, allows the admin to modify the description of the channel/supergroup - change_info = 0x1, - /// If set, allows the admin to post messages in the channel - post_messages = 0x2, - /// If set, allows the admin to also edit messages from other admins in the channel - edit_messages = 0x4, - /// If set, allows the admin to also delete messages from other admins in the channel - delete_messages = 0x8, - /// If set, allows the admin to ban users from the channel/supergroup - ban_users = 0x10, - /// If set, allows the admin to invite users in the channel/supergroup - invite_users = 0x20, - /// If set, allows the admin to pin messages in the channel/supergroup - pin_messages = 0x80, - /// If set, allows the admin to add other admins with the same (or more limited) permissions in the channel/supergroup - add_admins = 0x200, - /// Whether this admin is anonymous - anonymous = 0x400, - /// If set, allows the admin to change group call/livestream settings - 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, - /// If set, allows the admin to create, delete or modify forum topics ». - manage_topics = 0x2000, - /// If set, allows the admin to post stories as the channel. - post_stories = 0x4000, - /// If set, allows the admin to edit stories posted by the other admins of the channel. - edit_stories = 0x8000, - /// If set, allows the admin to delete stories posted by the other admins of the channel. - delete_stories = 0x10000, - /// If set, allows the admin to manage the direct messages monoforum » and decline suggested posts ». - manage_direct_messages = 0x20000, - manage_ranks = 0x40000, - } } - /// Represents the rights of a normal user in a supergroup/channel/chat. In this case, the flags are inverted: if set, a flag does not allow a user to do X. See + ///See [TLDef(0x9F120418)] - public sealed partial class ChatBannedRights : IObject + public partial class ChatBannedRights : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { view_messages = 0x1, send_messages = 0x2, send_media = 0x4, send_stickers = 0x8, send_gifs = 0x10, + send_games = 0x20, send_inline = 0x40, embed_links = 0x80, send_polls = 0x100, change_info = 0x400, invite_users = 0x8000, + pin_messages = 0x20000 } public Flags flags; - /// Validity of said permissions (it is considered forever any value less then 30 seconds or more then 366 days). public DateTime until_date; - - [Flags] public enum Flags : uint - { - /// If set, does not allow a user to view messages in a supergroup/channel/chat - view_messages = 0x1, - /// If set, does not allow a user to send messages in a supergroup/chat - send_messages = 0x2, - /// If set, does not allow a user to send any media in a supergroup/chat - send_media = 0x4, - /// If set, does not allow a user to send stickers in a supergroup/chat - send_stickers = 0x8, - /// If set, does not allow a user to send gifs in a supergroup/chat - send_gifs = 0x10, - /// If set, does not allow a user to send games in a supergroup/chat - send_games = 0x20, - /// If set, does not allow a user to use inline bots in a supergroup/chat. - send_inline = 0x40, - /// If set, does not allow a user to embed links in the messages of a supergroup/chat - embed_links = 0x80, - /// If set, does not allow a user to send polls in a supergroup/chat - send_polls = 0x100, - /// If set, does not allow any user to change the description of a supergroup/chat - change_info = 0x400, - /// If set, does not allow any user to invite users in a supergroup/chat - invite_users = 0x8000, - /// If set, does not allow any user to pin messages in a supergroup/chat - pin_messages = 0x20000, - /// If set, does not allow any user to create, delete or modify forum topics ». - manage_topics = 0x40000, - /// If set, does not allow a user to send photos in a supergroup/chat. - send_photos = 0x80000, - /// If set, does not allow a user to send videos in a supergroup/chat. - send_videos = 0x100000, - /// If set, does not allow a user to send round videos in a supergroup/chat. - send_roundvideos = 0x200000, - /// If set, does not allow a user to send audio files in a supergroup/chat. - send_audios = 0x400000, - /// If set, does not allow a user to send voice messages in a supergroup/chat. - send_voices = 0x800000, - /// If set, does not allow a user to send documents in a supergroup/chat. - send_docs = 0x1000000, - /// If set, does not allow a user to send text messages in a supergroup/chat. - send_plain = 0x2000000, - edit_rank = 0x4000000, - } } - /// Wallpaper See Derived classes: , , - public abstract partial class InputWallPaperBase : IObject { } - /// Wallpaper See + ///See + public abstract partial class InputWallPaperBase : ITLObject { } + ///See [TLDef(0xE630B979)] - public sealed partial class InputWallPaper : InputWallPaperBase + public partial class InputWallPaper : InputWallPaperBase { - /// Wallpaper ID public long id; - /// 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 + ///See [TLDef(0x72091C80)] - public sealed partial class InputWallPaperSlug : InputWallPaperBase - { - /// 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 + public partial class InputWallPaperSlug : InputWallPaperBase { public string slug; } + ///See [TLDef(0x967A462E)] - public sealed partial class InputWallPaperNoFile : InputWallPaperBase - { - /// Wallpaper ID - public long id; - } + public partial class InputWallPaperNoFile : InputWallPaperBase { public long id; } - /// Installed wallpapers See - /// a value means account.wallPapersNotModified + ///See + ///a null value means account.wallPapersNotModified [TLDef(0xCDC3858C)] - public sealed partial class Account_WallPapers : IObject + public partial class Account_WallPapers : ITLObject { - /// Hash used for caching, for more info click here public long hash; - /// Wallpapers public WallPaperBase[] wallpapers; } - /// Settings used by telegram servers for sending the confirm code. See - [TLDef(0xAD253D78)] - public sealed partial class CodeSettings : IObject + ///See + [TLDef(0xDEBEBE83)] + public partial class CodeSettings : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { allow_flashcall = 0x1, current_number = 0x2, allow_app_hash = 0x10 } public Flags flags; - /// Previously stored future auth tokens, see the documentation for more info » - [IfFlag(6)] public byte[][] logout_tokens; - /// Used only by official iOS apps for Firebase auth: device token for apple push. - [IfFlag(8)] public string token; - /// Used only by official iOS apps for firebase auth: whether a sandbox-certificate will be used during transmission of the push notification. - [IfFlag(8)] public bool app_sandbox; - - [Flags] public enum Flags : uint - { - /// Whether to allow phone verification via phone calls. - allow_flashcall = 0x1, - /// Pass true if the phone number is used on the current device. Ignored if allow_flashcall is not set. - current_number = 0x2, - /// If a token that will be included in eventually sent SMSs is required: required in newer versions of android, to use the android SMS receiver APIs - allow_app_hash = 0x10, - /// Whether this device supports receiving the code using the method - allow_missed_call = 0x20, - /// Field has a value - has_logout_tokens = 0x40, - /// Whether Firebase auth is supported - allow_firebase = 0x80, - /// Fields and have a value - has_token = 0x100, - /// Set this flag if there is a SIM card in the current device, but it is not possible to check whether the specified phone number matches the SIM's phone number. - unknown_number = 0x200, - } } - /// Wallpaper rendering information. See - [TLDef(0x372EFCD0)] - public sealed partial class WallPaperSettings : IObject + ///See + [TLDef(0x1DC1BCA4)] + public partial class WallPaperSettings : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_background_color = 0x1, blur = 0x2, motion = 0x4, has_intensity = 0x8, + has_second_background_color = 0x10, has_third_background_color = 0x20, has_fourth_background_color = 0x40 } public Flags flags; - /// Used for solid », gradient » and freeform gradient » fills. [IfFlag(0)] public int background_color; - /// Used for gradient » and freeform gradient » fills. [IfFlag(4)] public int second_background_color; - /// Used for freeform gradient » fills. [IfFlag(5)] public int third_background_color; - /// Used for freeform gradient » fills. [IfFlag(6)] public int fourth_background_color; - /// Used for pattern wallpapers ». [IfFlag(3)] public int intensity; - /// Clockwise rotation angle of the gradient, in degrees; 0-359. Should be always divisible by 45. [IfFlag(4)] public int rotation; - /// If set, this wallpaper can be used as a channel wallpaper and is represented by the specified UTF-8 emoji. - [IfFlag(7)] public string emoticon; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_background_color = 0x1, - /// For image wallpapers »: if set, the JPEG must be downscaled to fit in 450x450 square and then box-blurred with radius 12. - blur = 0x2, - /// If set, the background needs to be slightly moved when the device is rotated. - motion = 0x4, - /// Field has a value - has_intensity = 0x8, - /// Fields and have a value - has_second_background_color = 0x10, - /// Field has a value - has_third_background_color = 0x20, - /// Field has a value - has_fourth_background_color = 0x40, - /// Field has a value - has_emoticon = 0x80, - } } - /// Autodownload settings See - [TLDef(0xBAA57628)] - public sealed partial class AutoDownloadSettings : IObject + ///See + [TLDef(0xE04232F3)] + public partial class AutoDownloadSettings : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { disabled = 0x1, video_preload_large = 0x2, audio_preload_next = 0x4, phonecalls_less_data = 0x8 } public Flags flags; - /// Maximum size of photos to preload public int photo_size_max; - /// Maximum size of videos to preload - public long video_size_max; - /// Maximum size of other files to preload - public long file_size_max; - /// Maximum suggested bitrate for uploading videos + public int video_size_max; + public int file_size_max; public int video_upload_maxbitrate; - /// A limit, specifying the maximum number of files that should be downloaded in parallel from the same DC, for files smaller than 20MB. - public int small_queue_active_operations_max; - /// A limit, specifying the maximum number of files that should be downloaded in parallel from the same DC, for files bigger than 20MB. - public int large_queue_active_operations_max; - - [Flags] public enum Flags : uint - { - /// Disable automatic media downloads? - disabled = 0x1, - /// Whether to preload the first seconds of videos larger than the specified limit - video_preload_large = 0x2, - /// Whether to preload the next audio track when you're listening to music - audio_preload_next = 0x4, - /// Whether to enable data saving mode in phone calls - phonecalls_less_data = 0x8, - /// Whether to preload stories; in particular, the first .preload_prefix_size bytes of story videos should be preloaded. - stories_preload = 0x10, - } } - /// Media autodownload settings See + ///See [TLDef(0x63CACF26)] - public sealed partial class Account_AutoDownloadSettings : IObject + public partial class Account_AutoDownloadSettings : ITLObject { - /// Low data usage preset public AutoDownloadSettings low; - /// Medium data usage preset public AutoDownloadSettings medium; - /// High data usage preset public AutoDownloadSettings high; } - /// Emoji keyword See + ///See [TLDef(0xD5B3B9F9)] - public partial class EmojiKeyword : IObject + public partial class EmojiKeyword : ITLObject { - /// Keyword public string keyword; - /// Emojis associated to keyword public string[] emoticons; } - /// Deleted emoji keyword See + ///See [TLDef(0x236DF622)] - public sealed partial class EmojiKeywordDeleted : EmojiKeyword { } + public partial class EmojiKeywordDeleted : EmojiKeyword { } - /// Changes to emoji keywords See + ///See [TLDef(0x5CC761BD)] - public sealed partial class EmojiKeywordsDifference : IObject + public partial class EmojiKeywordsDifference : ITLObject { - /// Language code for keywords public string lang_code; - /// Previous emoji keyword list version public int from_version; - /// Current version of emoji keyword list public int version; - /// Emojis associated to keywords public EmojiKeyword[] keywords; } - /// An HTTP URL which can be used to automatically log in into translation platform and suggest new emoji replacements. The URL will be valid for 30 seconds after generation See + ///See [TLDef(0xA575739D)] - public sealed partial class EmojiURL : IObject - { - /// An HTTP URL which can be used to automatically log in into translation platform and suggest new emoji replacements. The URL will be valid for 30 seconds after generation - public string url; - } + public partial class EmojiURL : ITLObject { public string url; } - /// Emoji language See + ///See [TLDef(0xB3FB5361)] - public sealed partial class EmojiLanguage : IObject - { - /// Language code - public string lang_code; - } + public partial class EmojiLanguage : ITLObject { public string lang_code; } - /// Folder See + ///See [TLDef(0xFF544E65)] - public sealed partial class Folder : IObject + public partial class Folder : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { autofill_new_broadcasts = 0x1, autofill_public_groups = 0x2, autofill_new_correspondents = 0x4, + has_photo = 0x8 } public Flags flags; - /// Folder ID public int id; - /// Folder title public string title; - /// Folder picture [IfFlag(3)] public ChatPhoto photo; - - [Flags] public enum Flags : uint - { - /// Automatically add new channels to this folder - autofill_new_broadcasts = 0x1, - /// Automatically add joined new public supergroups to this folder - autofill_public_groups = 0x2, - /// Automatically add new private chats to this folder - autofill_new_correspondents = 0x4, - /// Field has a value - has_photo = 0x8, - } } - /// Peer in a folder See + ///See [TLDef(0xFBD2C296)] - public sealed partial class InputFolderPeer : IObject + public partial class InputFolderPeer : ITLObject { - /// Peer public InputPeer peer; - /// Peer folder ID, for more info click here public int folder_id; } - /// Peer in a folder See + ///See [TLDef(0xE9BAA668)] - public sealed partial class FolderPeer : IObject + public partial class FolderPeer : ITLObject { - /// Folder peer info public Peer peer; - /// Peer folder ID, for more info click here public int folder_id; } - /// Indicates how many results would be found by a Messages_Search call with the same parameters See + ///See [TLDef(0xE844EBFF)] - public sealed partial class Messages_SearchCounter : IObject + public partial class Messages_SearchCounter : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { inexact = 0x2 } public Flags flags; - /// Provided message filter public MessagesFilter filter; - /// Number of results that were found server-side public int count; - - [Flags] public enum Flags : uint - { - /// If set, the results may be inexact - inexact = 0x2, - } } - /// URL authorization result See Derived classes: , - /// a value means urlAuthResultDefault - public abstract partial class UrlAuthResult : IObject { } - /// Details about the authorization request, for more info click here » See - [TLDef(0xF8F8EB1E)] - public sealed partial class UrlAuthResultRequest : UrlAuthResult + ///See + public abstract partial class UrlAuthResult : ITLObject { } + ///See + [TLDef(0x92D33A0E)] + public partial class UrlAuthResultRequest : UrlAuthResult { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { request_write_access = 0x1 } 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. public UserBase bot; - /// The domain name of the website on which the user will log in. public string domain; - [IfFlag(2)] public string browser; - [IfFlag(2)] public string platform; - [IfFlag(2)] public string ip; - [IfFlag(2)] public string region; - [IfFlag(3)] public string[] match_codes; - [IfFlag(4)] public long user_id_hint; - - [Flags] public enum Flags : uint - { - /// Whether the bot would like to send messages to the user - request_write_access = 0x1, - request_phone_number = 0x2, - /// Fields , , and have a value - has_browser = 0x4, - /// Field has a value - has_match_codes = 0x8, - /// Field has a value - has_user_id_hint = 0x10, - match_codes_first = 0x20, - } } - /// Details about an accepted authorization request, for more info click here » See - [TLDef(0x623A8FA0)] - public sealed partial class UrlAuthResultAccepted : UrlAuthResult - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The URL name of the website on which the user has logged in. - [IfFlag(0)] public string url; + ///See + [TLDef(0x8F8C0E4E)] + public partial class UrlAuthResultAccepted : UrlAuthResult { public string url; } + ///See + [TLDef(0xA9D6DB1F)] + public partial class UrlAuthResultDefault : UrlAuthResult { } - [Flags] public enum Flags : uint - { - /// Field has a value - has_url = 0x1, - } - } - - /// Geographical location of supergroup (geogroups) See - /// a value means channelLocationEmpty + ///See + ///a null value means channelLocationEmpty [TLDef(0x209B82DB)] - public sealed partial class ChannelLocation : IObject + public partial class ChannelLocation : ITLObject { - /// Geographical location of supergroup public GeoPoint geo_point; - /// Textual description of the address public string address; } - /// Geolocated peer See Derived classes: , - public abstract partial class PeerLocatedBase : IObject - { - /// Validity period of current data - public virtual DateTime Expires => default; - } - /// Peer geolocated nearby See + ///See + public abstract partial class PeerLocatedBase : ITLObject { } + ///See [TLDef(0xCA461B5D)] - public sealed partial class PeerLocated : PeerLocatedBase + public partial class PeerLocated : PeerLocatedBase { - /// Peer public Peer peer; - /// Validity period of current data public DateTime expires; - /// Distance from the peer in meters public int distance; - - /// Validity period of current data - public override DateTime Expires => expires; } - /// Current peer See + ///See [TLDef(0xF8EC284B)] - public sealed partial class PeerSelfLocated : PeerLocatedBase - { - /// Expiry of geolocation info for current peer - public DateTime expires; + public partial class PeerSelfLocated : PeerLocatedBase { public DateTime expires; } - /// Expiry of geolocation info for current peer - public override DateTime Expires => expires; - } - - /// Restriction reason. See + ///See [TLDef(0xD072ACB4)] - public sealed partial class RestrictionReason : IObject + public partial class RestrictionReason : ITLObject { - /// Platform identifier (ios, android, wp, all, etc.), can be concatenated with a dash as separator (android-ios, ios-wp, etc) public string platform; - /// Restriction reason (porno, terms, etc.). Ignore this restriction reason if it is contained in the ignore_restriction_reasons » client configuration parameter. public string reason; - /// Error message to be shown to the user public string text; } - /// Cloud theme See Derived classes: , - public abstract partial class InputThemeBase : IObject { } - /// Theme See + ///See + public abstract partial class InputThemeBase : ITLObject { } + ///See [TLDef(0x3C5693E9)] - public sealed partial class InputTheme : InputThemeBase + public partial class InputTheme : InputThemeBase { - /// ID public long id; - /// REQUIRED FIELD. See how to obtain it
Access hash
public long access_hash; } - ///
Theme by theme ID See + ///See [TLDef(0xF5890DF1)] - public sealed partial class InputThemeSlug : InputThemeBase - { - /// Unique theme ID obtained from a theme deep link » - public string slug; - } + public partial class InputThemeSlug : InputThemeBase { public string slug; } - /// Theme See - [TLDef(0xA00E67D6)] - public sealed partial class Theme : IObject + ///See + [TLDef(0xE802B8DC)] + public partial class Theme : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { creator = 0x1, default_ = 0x2, has_document = 0x4, has_settings = 0x8, has_installs_count = 0x10, + for_chat = 0x20 } public Flags flags; - /// Theme ID public long id; - /// Theme access hash public long access_hash; - /// Unique theme ID public string slug; - /// Theme name public string title; - /// Theme [IfFlag(2)] public DocumentBase document; - /// Theme settings - [IfFlag(3)] public ThemeSettings[] settings; - /// Theme emoji - [IfFlag(6)] public string emoticon; - /// Installation count + [IfFlag(3)] public ThemeSettings settings; [IfFlag(4)] public int installs_count; - - [Flags] public enum Flags : uint - { - /// Whether the current user is the creator of this theme - creator = 0x1, - /// Whether this is the default theme - default_ = 0x2, - /// Field has a value - has_document = 0x4, - /// Field has a value - has_settings = 0x8, - /// Field has a value - has_installs_count = 0x10, - /// Whether this theme is meant to be used as a chat theme - for_chat = 0x20, - /// Field has a value - has_emoticon = 0x40, - } } - /// Installed themes See - /// a value means account.themesNotModified + ///See + ///a null value means account.themesNotModified [TLDef(0x9A3D8C6D)] - public sealed partial class Account_Themes : IObject + public partial class Account_Themes : ITLObject { - /// Hash used for caching, for more info click here public long hash; - /// Themes public Theme[] themes; } - /// Login token (for QR code login) See Derived classes: , , - public abstract partial class Auth_LoginTokenBase : IObject { } - /// Login token (for QR code login) See + ///See + public abstract partial class Auth_LoginTokenBase : ITLObject { } + ///See [TLDef(0x629F1980)] - public sealed partial class Auth_LoginToken : Auth_LoginTokenBase + public partial class Auth_LoginToken : Auth_LoginTokenBase { - /// Expiration date of QR code public DateTime expires; - /// Token to render in QR code public byte[] token; } - /// Repeat the query to the specified DC See + ///See [TLDef(0x068E9916)] - public sealed partial class Auth_LoginTokenMigrateTo : Auth_LoginTokenBase + public partial class Auth_LoginTokenMigrateTo : Auth_LoginTokenBase { - /// DC ID public int dc_id; - /// Token to use for login public byte[] token; } - /// Login via token (QR code) succeeded! See + ///See [TLDef(0x390D5C5E)] - public sealed partial class Auth_LoginTokenSuccess : Auth_LoginTokenBase - { - /// Authorization info - public Auth_AuthorizationBase authorization; - } + public partial class Auth_LoginTokenSuccess : Auth_LoginTokenBase { public Auth_AuthorizationBase authorization; } - /// Sensitive content settings See + ///See [TLDef(0x57E28221)] - public sealed partial class Account_ContentSettings : IObject + public partial class Account_ContentSettings : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { sensitive_enabled = 0x1, sensitive_can_change = 0x2 } public Flags flags; - - [Flags] public enum Flags : uint - { - /// Whether viewing of sensitive (NSFW) content is enabled - sensitive_enabled = 0x1, - /// Whether the current client can change the sensitive content settings to view NSFW content - sensitive_can_change = 0x2, - } } - /// Inactive chat list See + ///See [TLDef(0xA927FEC5)] - public sealed partial class Messages_InactiveChats : IObject, IPeerResolver + public partial class Messages_InactiveChats : ITLObject { - /// When was the chat last active public int[] dates; - /// Chat list - public Dictionary chats; - /// Users mentioned in the chat list - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Basic theme settings See + ///See public enum BaseTheme : uint { - ///Classic theme + ///See Classic = 0xC3A12462, - ///Day theme + ///See Day = 0xFBD81688, - ///Night theme + ///See Night = 0xB7B31EA8, - ///Tinted theme + ///See Tinted = 0x6D5F77EE, - ///Arctic theme + ///See Arctic = 0x5B11125A, } - /// Theme settings See + ///See [TLDef(0x8FDE504F)] - public sealed partial class InputThemeSettings : IObject + public partial class InputThemeSettings : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_message_colors = 0x1, has_wallpaper = 0x2, message_colors_animated = 0x4, + has_outbox_accent_color = 0x8 } public Flags flags; - /// Default theme on which this theme is based public BaseTheme base_theme; - /// Accent color, ARGB format public int accent_color; - /// Accent color of outgoing messages in ARGB format [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 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; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_message_colors = 0x1, - /// Fields and have a value - has_wallpaper = 0x2, - /// If set, the freeform gradient fill needs to be animated on every sent message - message_colors_animated = 0x4, - /// Field has a value - has_outbox_accent_color = 0x8, - } } - /// Theme settings See + ///See [TLDef(0xFA58B6D4)] - public sealed partial class ThemeSettings : IObject + public partial class ThemeSettings : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_message_colors = 0x1, has_wallpaper = 0x2, message_colors_animated = 0x4, + has_outbox_accent_color = 0x8 } public Flags flags; - /// Base theme public BaseTheme base_theme; - /// Accent color, ARGB format public int accent_color; - /// Accent color of outgoing messages in ARGB format [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; - ///
Wallpaper [IfFlag(1)] public WallPaperBase wallpaper; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_message_colors = 0x1, - /// Field has a value - has_wallpaper = 0x2, - /// If set, the freeform gradient fill needs to be animated on every sent message. - message_colors_animated = 0x4, - /// Field has a value - has_outbox_accent_color = 0x8, - } } - /// Webpage attributes See Derived classes: , , , , , - public abstract partial class WebPageAttribute : IObject { } - /// Page theme See + ///See + public abstract partial class WebPageAttribute : ITLObject { } + ///See [TLDef(0x54B56617)] - public sealed partial class WebPageAttributeTheme : WebPageAttribute + public partial class WebPageAttributeTheme : WebPageAttribute { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_documents = 0x1, has_settings = 0x2 } public Flags flags; - /// Theme files [IfFlag(0)] public DocumentBase[] documents; - /// Theme settings [IfFlag(1)] public ThemeSettings settings; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_documents = 0x1, - /// Field has a value - has_settings = 0x2, - } } - /// Webpage preview of a Telegram story See - [TLDef(0x2E94C3E7)] - public sealed partial class WebPageAttributeStory : WebPageAttribute + + ///See + public abstract partial class MessageUserVoteBase : ITLObject { } + ///See + [TLDef(0x34D247B4)] + public partial class MessageUserVote : MessageUserVoteBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + public long user_id; + public byte[] option; + public DateTime date; + } + ///See + [TLDef(0x3CA5B0EC)] + public partial class MessageUserVoteInputOption : MessageUserVoteBase + { + public long user_id; + public DateTime date; + } + ///See + [TLDef(0x8A65E557)] + public partial class MessageUserVoteMultiple : MessageUserVoteBase + { + public long user_id; + public byte[][] options; + public DateTime date; + } + + ///See + [TLDef(0x0823F649)] + public partial class Messages_VotesList : ITLObject + { + [Flags] public enum Flags { has_next_offset = 0x1 } public Flags flags; - /// Peer that posted the story - public Peer peer; - /// Story ID - public int id; - /// May contain the story, if not the story should be fetched when and if needed using Stories_GetStoriesByID with the above id and peer. - [IfFlag(0)] public StoryItemBase story; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_story = 0x1, - } - } - /// Contains info about a stickerset », for a preview of a stickerset deep link » (the will have a type of telegram_stickerset). See - [TLDef(0x50CC03D3)] - public sealed partial class WebPageAttributeStickerSet : WebPageAttribute - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// A subset of the stickerset in the stickerset. - public DocumentBase[] stickers; - - [Flags] public enum Flags : uint - { - /// Whether this i s a custom emoji stickerset. - emojis = 0x1, - /// Whether the color of this TGS custom emoji stickerset should be changed to the text color when used in messages, the accent color if used as emoji status, white on chat photos, or another appropriate color based on context. - text_color = 0x2, - } - } - /// Contains info about collectible gift » for a preview of a collectible gift » (the will have a type of telegram_nft). See - [TLDef(0xCF6F6DB8)] - public sealed partial class WebPageAttributeUniqueStarGift : WebPageAttribute - { - /// The . - public StarGiftBase gift; - } - /// Contains info about a gift collection » for a preview of a gift collection » (the will have a type of telegram_collection). See - [TLDef(0x31CAD303)] - public sealed partial class WebPageAttributeStarGiftCollection : WebPageAttribute - { - /// Gifts in the collection. - public DocumentBase[] icons; - } - /// See - [TLDef(0x01C641C2)] - public sealed partial class WebPageAttributeStarGiftAuction : WebPageAttribute - { - public StarGiftBase gift; - public DateTime end_date; - } - - /// How users voted in a poll See - [TLDef(0x4899484E)] - public sealed partial class Messages_VotesList : IObject, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// 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 MessagePeerVoteBase[] votes; - /// Mentioned chats - public Dictionary chats; - /// 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. + public MessageUserVoteBase[] votes; + public UserBase[] users; [IfFlag(0)] public string next_offset; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); } - /// Credit card info URL provided by the bank See + ///See [TLDef(0xF568028A)] - public sealed partial class BankCardOpenUrl : IObject + public partial class BankCardOpenUrl : ITLObject { - /// Info URL public string url; - /// Bank name public string name; } - /// Credit card info, provided by the card's bank(s) See + ///See [TLDef(0x3E24E573)] - public sealed partial class Payments_BankCardData : IObject + public partial class Payments_BankCardData : ITLObject { - /// Credit card title public string title; - /// Info URL(s) provided by the card's bank(s) public BankCardOpenUrl[] open_urls; } - /// Dialog filter (folder ») See Derived classes: , - /// a value means dialogFilterDefault - public abstract partial class DialogFilterBase : IObject + ///See + [TLDef(0x7438F7E8)] + public partial class DialogFilter : ITLObject { - /// Folder ID - public virtual int ID => default; - /// Folder name (max 12 UTF-8 chars) - public virtual TextWithEntities Title => default; - /// Emoji to use as icon for the folder. - public virtual string Emoticon => default; - /// A color ID for the folder tag associated to this folder, see here » for more info. - public virtual int Color => default; - /// Pinned chats, folders can have unlimited pinned chats - public virtual InputPeer[] PinnedPeers => default; - /// Include the following chats in this folder - public virtual InputPeer[] IncludePeers => default; - } - /// Dialog filter AKA folder See - [TLDef(0xAA472651)] - public sealed partial class DialogFilter : DialogFilterBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { contacts = 0x1, non_contacts = 0x2, groups = 0x4, broadcasts = 0x8, bots = 0x10, + exclude_muted = 0x800, exclude_read = 0x1000, exclude_archived = 0x2000, has_emoticon = 0x2000000 } public Flags flags; - /// Folder ID public int id; - /// Folder name (max 12 UTF-8 chars) - public TextWithEntities title; - /// Emoji to use as icon for the folder. + public string title; [IfFlag(25)] public string emoticon; - /// A color ID for the folder tag associated to this folder, see here » for more info. - [IfFlag(27)] public int color; - /// Pinned chats, folders can have unlimited pinned chats public InputPeer[] pinned_peers; - /// Include the following chats in this folder public InputPeer[] include_peers; - /// Exclude the following chats from this folder public InputPeer[] exclude_peers; - - [Flags] public enum Flags : uint - { - /// Whether to include all contacts in this folder - contacts = 0x1, - /// Whether to include all non-contacts in this folder - non_contacts = 0x2, - /// Whether to include all groups in this folder - groups = 0x4, - /// Whether to include all channels in this folder - broadcasts = 0x8, - /// Whether to include all bots in this folder - bots = 0x10, - /// Whether to exclude muted chats from this folder - exclude_muted = 0x800, - /// Whether to exclude read chats from this folder - exclude_read = 0x1000, - /// Whether to exclude archived chats from this folder - exclude_archived = 0x2000, - /// Field has a value - has_emoticon = 0x2000000, - /// Field has a value - has_color = 0x8000000, - /// If set, any animated emojis present in title should not be animated and should be instead frozen on the first frame. - title_noanimate = 0x10000000, - } - - /// Folder ID - public override int ID => id; - /// Folder name (max 12 UTF-8 chars) - public override TextWithEntities Title => title; - /// Emoji to use as icon for the folder. - public override string Emoticon => emoticon; - /// A color ID for the folder tag associated to this folder, see here » for more info. - public override int Color => color; - /// Pinned chats, folders can have unlimited pinned chats - public override InputPeer[] PinnedPeers => pinned_peers; - /// Include the following chats in this folder - public override InputPeer[] IncludePeers => include_peers; - } - /// A folder imported using a chat folder deep link ». See - [TLDef(0x96537BD7)] - public sealed partial class DialogFilterChatlist : DialogFilterBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of the folder - public int id; - /// Name of the folder (max 12 UTF-8 chars) - public TextWithEntities title; - /// Emoji to use as icon for the folder. - [IfFlag(25)] public string emoticon; - /// A color ID for the folder tag associated to this folder, see here » for more info. - [IfFlag(27)] public int color; - /// Pinned chats, folders can have unlimited pinned chats - public InputPeer[] pinned_peers; - /// Chats to include in the folder - public InputPeer[] include_peers; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_emoticon = 0x2000000, - /// Whether the current user has created some chat folder deep links » to share the folder as well. - has_my_invites = 0x4000000, - /// Field has a value - has_color = 0x8000000, - /// If set, any animated emojis present in title should not be animated and should be instead frozen on the first frame. - title_noanimate = 0x10000000, - } - - /// ID of the folder - public override int ID => id; - /// Name of the folder (max 12 UTF-8 chars) - public override TextWithEntities Title => title; - /// Emoji to use as icon for the folder. - public override string Emoticon => emoticon; - /// A color ID for the folder tag associated to this folder, see here » for more info. - public override int Color => color; - /// Pinned chats, folders can have unlimited pinned chats - public override InputPeer[] PinnedPeers => pinned_peers; - /// Chats to include in the folder - public override InputPeer[] IncludePeers => include_peers; } - /// Suggested folders See + ///See [TLDef(0x77744D4A)] - public sealed partial class DialogFilterSuggested : IObject + public partial class DialogFilterSuggested : ITLObject { - /// Folder info - public DialogFilterBase filter; - /// Folder description + public DialogFilter filter; public string description; } - /// Channel statistics date range See + ///See [TLDef(0xB637EDAF)] - public sealed partial class StatsDateRangeDays : IObject + public partial class StatsDateRangeDays : ITLObject { - /// Initial date public DateTime min_date; - /// Final date public DateTime max_date; } - /// Statistics value couple; initial and final value for period of time currently in consideration See + ///See [TLDef(0xCB43ACDE)] - public sealed partial class StatsAbsValueAndPrev : IObject + public partial class StatsAbsValueAndPrev : ITLObject { - /// Current value public double current; - /// Previous value public double previous; } - /// Channel statistics percentage.
Compute the percentage simply by doing part * total / 100 See
+ ///See [TLDef(0xCBCE2FE0)] - public sealed partial class StatsPercentValue : IObject + public partial class StatsPercentValue : ITLObject { - /// Partial value public double part; - /// Total value public double total; } - /// Channel statistics graph See Derived classes: , , - public abstract partial class StatsGraphBase : IObject { } - /// This channel statistics graph must be generated asynchronously using Stats_LoadAsyncGraph to reduce server load See + ///See + public abstract partial class StatsGraphBase : ITLObject { } + ///See [TLDef(0x4A27EB2D)] - public sealed partial class StatsGraphAsync : StatsGraphBase - { - /// Token to use for fetching the async graph - public string token; - } - /// An error occurred while generating the statistics graph See + public partial class StatsGraphAsync : StatsGraphBase { public string token; } + ///See [TLDef(0xBEDC9822)] - public sealed partial class StatsGraphError : StatsGraphBase - { - /// The error - public string error; - } - /// Channel statistics graph See + public partial class StatsGraphError : StatsGraphBase { public string error; } + ///See [TLDef(0x8EA464B6)] - public sealed partial class StatsGraph : StatsGraphBase + public partial class StatsGraph : StatsGraphBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_zoom_token = 0x1 } public Flags flags; - /// Statistics data public DataJSON json; - /// Zoom token [IfFlag(0)] public string zoom_token; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_zoom_token = 0x1, - } } - /// Channel statistics. See - [TLDef(0x396CA5FC)] - public sealed partial class Stats_BroadcastStats : IObject + ///See + [TLDef(0xAD4FC9BD)] + public partial class MessageInteractionCounters : ITLObject + { + public int msg_id; + public int views; + public int forwards; + } + + ///See + [TLDef(0xBDF78394)] + public partial class Stats_BroadcastStats : ITLObject { - /// Period in consideration public StatsDateRangeDays period; - /// Follower count change for period in consideration public StatsAbsValueAndPrev followers; - /// total_viewcount/postcount, for posts posted during the period in consideration.
Note that in this case, current refers to the period in consideration (min_date till max_date), and prev refers to the previous period ((min_date - (max_date - min_date)) till min_date).
public StatsAbsValueAndPrev views_per_post; - /// total_sharecount/postcount, for posts posted during the period in consideration.
Note that in this case, current refers to the period in consideration (min_date till max_date), and prev refers to the previous period ((min_date - (max_date - min_date)) till min_date)
public StatsAbsValueAndPrev shares_per_post; - /// total_reactions/postcount, for posts posted during the period in consideration.
Note that in this case, current refers to the period in consideration (min_date till max_date), and prev refers to the previous period ((min_date - (max_date - min_date)) till min_date)
- public StatsAbsValueAndPrev reactions_per_post; - /// total_views/storycount, for posts posted during the period in consideration.
Note that in this case, current refers to the period in consideration (min_date till max_date), and prev refers to the previous period ((min_date - (max_date - min_date)) till min_date)
- public StatsAbsValueAndPrev views_per_story; - /// total_shares/storycount, for posts posted during the period in consideration.
Note that in this case, current refers to the period in consideration (min_date till max_date), and prev refers to the previous period ((min_date - (max_date - min_date)) till min_date)
- public StatsAbsValueAndPrev shares_per_story; - /// total_reactions/storycount, for posts posted during the period in consideration.
Note that in this case, current refers to the period in consideration (min_date till max_date), and prev refers to the previous period ((min_date - (max_date - min_date)) till min_date)
- public StatsAbsValueAndPrev reactions_per_story; - /// Percentage of subscribers with enabled notifications public StatsPercentValue enabled_notifications; - /// Channel growth graph (absolute subscriber count) public StatsGraphBase growth_graph; - /// Followers growth graph (relative subscriber count) public StatsGraphBase followers_graph; - /// Muted users graph (relative) public StatsGraphBase mute_graph; - /// Views per hour graph (absolute) public StatsGraphBase top_hours_graph; - /// Interactions graph (absolute) public StatsGraphBase interactions_graph; - /// IV interactions graph (absolute) public StatsGraphBase iv_interactions_graph; - /// Views by source graph (absolute) public StatsGraphBase views_by_source_graph; - /// New followers by source graph (absolute) public StatsGraphBase new_followers_by_source_graph; - /// Subscriber language graph (pie chart) public StatsGraphBase languages_graph; - /// A graph containing the number of reactions on posts categorized by emotion - public StatsGraphBase reactions_by_emotion_graph; - /// A graph containing the number of story views and shares - public StatsGraphBase story_interactions_graph; - /// A graph containing the number of reactions on stories categorized by emotion - public StatsGraphBase story_reactions_by_emotion_graph; - /// Detailed statistics about number of views and shares of recently sent messages and stories - public PostInteractionCounters[] recent_posts_interactions; + public MessageInteractionCounters[] recent_message_interactions; } - ///
Info about pinned MTProxy or Public Service Announcement peers. See Derived classes: , - public abstract partial class Help_PromoDataBase : IObject { } - /// No PSA/MTProxy info is available See + ///See + public abstract partial class Help_PromoDataBase : ITLObject { } + ///See [TLDef(0x98F6AC75)] - public sealed partial class Help_PromoDataEmpty : Help_PromoDataBase + public partial class Help_PromoDataEmpty : Help_PromoDataBase { public DateTime expires; } + ///See + [TLDef(0x8C39793F)] + public partial class Help_PromoData : Help_PromoDataBase { - /// Re-fetch PSA/MTProxy info after the specified number of seconds - public DateTime expires; - } - /// A set of useful suggestions and a PSA/MTProxy sponsored peer, see here » for more info. See - [TLDef(0x08A4D87A)] - public sealed partial class Help_PromoData : Help_PromoDataBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { proxy = 0x1, has_psa_type = 0x2, has_psa_message = 0x4 } public Flags flags; - /// Unixtime when to re-invoke Help_GetPromoData. public DateTime expires; - /// MTProxy/PSA peer - [IfFlag(3)] public Peer peer; - /// For Public Service Announcement peers, indicates the type of the PSA. + public Peer peer; + public ChatBase[] chats; + public UserBase[] users; [IfFlag(1)] public string psa_type; - /// For Public Service Announcement peers, contains the PSA itself. [IfFlag(2)] public string psa_message; - /// Contains a list of pending suggestions ». - public string[] pending_suggestions; - /// Contains a list of inverted suggestions ». - public string[] dismissed_suggestions; - /// Contains a list of custom pending suggestions ». - [IfFlag(4)] public PendingSuggestion custom_pending_suggestion; - /// Chat info - public Dictionary chats; - /// User info - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Set when connecting using an MTProxy that has configured an associated peer (that will be passed in peer, i.e. the channel that sponsored the MTProxy) that should be pinned on top of the chat list. - proxy = 0x1, - /// Field has a value - has_psa_type = 0x2, - /// Field has a value - has_psa_message = 0x4, - /// Field has a value - has_peer = 0x8, - /// Field has a value - has_custom_pending_suggestion = 0x10, - } - /// returns a or for the result - public IPeerInfo UserOrChat => peer?.UserOrChat(users, chats); } - /// Represents an animated video thumbnail See Derived classes: , , - public abstract partial class VideoSizeBase : IObject { } - /// An animated profile picture in MPEG4 format See + ///See [TLDef(0xDE33B094)] - public sealed partial class VideoSize : VideoSizeBase + public partial class VideoSize : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_video_start_ts = 0x1 } public Flags flags; - /// u for animated profile pictures, and v for trimmed and downscaled video previews public string type; - /// Video width public int w; - /// Video height public int h; - /// File size public int size; - /// Timestamp that should be shown as static preview to the user (seconds) [IfFlag(0)] public double video_start_ts; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_video_start_ts = 0x1, - } - } - /// An animated profile picture based on a custom emoji sticker. See - [TLDef(0xF85C413C)] - public sealed partial class VideoSizeEmojiMarkup : VideoSizeBase - { - /// Custom emoji ID: the custom emoji sticker is shown at the center of the profile picture and occupies at most 67% of it. - public long emoji_id; - /// 1, 2, 3 or 4 RBG-24 colors used to generate a solid (1), gradient (2) or freeform gradient (3, 4) background, similar to how fill wallpapers are generated. The rotation angle for gradient backgrounds is 0. - public int[] background_colors; - } - /// An animated profile picture based on a sticker. See - [TLDef(0x0DA082FE)] - public sealed partial class VideoSizeStickerMarkup : VideoSizeBase - { - /// Stickerset - public InputStickerSet stickerset; - /// Sticker ID - public long sticker_id; - /// 1, 2, 3 or 4 RBG-24 colors used to generate a solid (1), gradient (2) or freeform gradient (3, 4) background, similar to how fill wallpapers are generated. The rotation angle for gradient backgrounds is 0. - public int[] background_colors; } - /// Information about an active user in a supergroup See + ///See [TLDef(0x9D04AF9B)] - public sealed partial class StatsGroupTopPoster : IObject + public partial class StatsGroupTopPoster : ITLObject { - /// User ID public long user_id; - /// Number of messages for statistics period in consideration public int messages; - /// Average number of characters per message public int avg_chars; } - /// Information about an active admin in a supergroup See + ///See [TLDef(0xD7584C87)] - public sealed partial class StatsGroupTopAdmin : IObject + public partial class StatsGroupTopAdmin : ITLObject { - /// User ID public long user_id; - /// Number of deleted messages for statistics period in consideration public int deleted; - /// Number of kicked users for statistics period in consideration public int kicked; - /// Number of banned users for statistics period in consideration public int banned; } - /// Information about an active supergroup inviter See + ///See [TLDef(0x535F779D)] - public sealed partial class StatsGroupTopInviter : IObject + public partial class StatsGroupTopInviter : ITLObject { - /// User ID public long user_id; - /// Number of invitations for statistics period in consideration public int invitations; } - /// Supergroup statistics See + ///See [TLDef(0xEF7FF916)] - public sealed partial class Stats_MegagroupStats : IObject + public partial class Stats_MegagroupStats : ITLObject { - /// Period in consideration public StatsDateRangeDays period; - /// Member count change for period in consideration public StatsAbsValueAndPrev members; - /// Message number change for period in consideration public StatsAbsValueAndPrev messages; - /// Number of users that viewed messages, for range in consideration public StatsAbsValueAndPrev viewers; - /// Number of users that posted messages, for range in consideration public StatsAbsValueAndPrev posters; - /// Supergroup growth graph (absolute subscriber count) public StatsGraphBase growth_graph; - /// Members growth (relative subscriber count) public StatsGraphBase members_graph; - /// New members by source graph public StatsGraphBase new_members_by_source_graph; - /// Subscriber language graph (pie chart) public StatsGraphBase languages_graph; - /// Message activity graph (stacked bar graph, message type) public StatsGraphBase messages_graph; - /// Group activity graph (deleted, modified messages, blocked users) public StatsGraphBase actions_graph; - /// Activity per hour graph (absolute) public StatsGraphBase top_hours_graph; - /// Activity per day of week graph (absolute) public StatsGraphBase weekdays_graph; - /// Info about most active group members public StatsGroupTopPoster[] top_posters; - /// Info about most active group admins public StatsGroupTopAdmin[] top_admins; - /// Info about most active group inviters public StatsGroupTopInviter[] top_inviters; - /// Info about users mentioned in statistics - public Dictionary users; + public UserBase[] users; } - /// Global privacy settings See - [TLDef(0xFE41B34F)] - public sealed partial class GlobalPrivacySettings : IObject + ///See + [TLDef(0xBEA2F424)] + public partial class GlobalPrivacySettings : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_archive_and_mute_new_noncontact_peers = 0x1 } public Flags flags; - /// If configured, specifies the number of stars users must pay us to send us a message, see here » for more info on paid messages. - [IfFlag(5)] public long noncontact_peers_paid_stars; - /// Disallows the reception of specific gift types. - [IfFlag(6)] public DisallowedGiftsSettings disallowed_gifts; - - [Flags] public enum Flags : uint - { - /// Whether to archive and mute new chats from non-contacts - archive_and_mute_new_noncontact_peers = 0x1, - /// Whether unmuted chats will be kept in the Archive chat list when they get a new message. - keep_archived_unmuted = 0x2, - /// Whether unmuted chats that are always included or pinned in a folder, will be kept in the Archive chat list when they get a new message. Ignored if keep_archived_unmuted is set. - keep_archived_folders = 0x4, - /// If this flag is set, the key will also apply to the ability to use Messages_GetOutboxReadDate on messages sent to us.
Meaning, users that cannot see our exact last online date due to the current value of the key will receive a 403 USER_PRIVACY_RESTRICTED error when invoking Messages_GetOutboxReadDate to fetch the exact read date of a message they sent to us.
The .read_dates_private flag will be set for users that have this flag enabled.
- hide_read_marks = 0x8, - /// See here for more info on this flag ». - new_noncontact_peers_require_premium = 0x10, - /// Field has a value - has_noncontact_peers_paid_stars = 0x20, - /// Field has a value - has_disallowed_gifts = 0x40, - /// Enables or disables our .display_gifts_button flag: if the .display_gifts_button flag of both us and another user is set, a gift button should always be displayed in the text field in private chats with the other user: once clicked, the gift UI should be displayed, offering the user options to gift Telegram Premium » subscriptions or Telegram Gifts ». - display_gifts_button = 0x80, - } + [IfFlag(0)] public bool archive_and_mute_new_noncontact_peers; } - /// Country code and phone number pattern of a specific country See + ///See [TLDef(0x4203C5EF)] - public sealed partial class Help_CountryCode : IObject + public partial class Help_CountryCode : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_prefixes = 0x1, has_patterns = 0x2 } public Flags flags; - /// ISO country code public string country_code; - /// Possible phone prefixes [IfFlag(0)] public string[] prefixes; - /// Phone patterns: for example, XXX XXX XXX [IfFlag(1)] public string[] patterns; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_prefixes = 0x1, - /// Field has a value - has_patterns = 0x2, - } } - /// Name, ISO code, localized name and phone codes/patterns of a specific country See + ///See [TLDef(0xC3878E23)] - public sealed partial class Help_Country : IObject + public partial class Help_Country : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { hidden = 0x1, has_name = 0x2 } public Flags flags; - /// ISO code of country public string iso2; - /// Name of the country in the country's language public string default_name; - /// Name of the country in the user's language, if different from the original name [IfFlag(1)] public string name; - /// Phone codes/patterns public Help_CountryCode[] country_codes; - - [Flags] public enum Flags : uint - { - /// Whether this country should not be shown in the list - hidden = 0x1, - /// Field has a value - has_name = 0x2, - } } - /// Name, ISO code, localized name and phone codes/patterns of all available countries See - /// a value means help.countriesListNotModified + ///See + ///a null value means help.countriesListNotModified [TLDef(0x87D0759E)] - public sealed partial class Help_CountriesList : IObject + public partial class Help_CountriesList : ITLObject { - /// Name, ISO code, localized name and phone codes/patterns of all available countries public Help_Country[] countries; - /// Hash used for caching, for more info click here public int hash; } - /// View, forward counter + info about replies of a specific message See + ///See [TLDef(0x455B853D)] - public sealed partial class MessageViews : IObject + public partial class MessageViews : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_views = 0x1, has_forwards = 0x2, has_replies = 0x4 } public Flags flags; - /// View count of message [IfFlag(0)] public int views; - /// Forward count of message [IfFlag(1)] public int forwards; - /// Reply and thread information of message [IfFlag(2)] public MessageReplies replies; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_views = 0x1, - /// Field has a value - has_forwards = 0x2, - /// Field has a value - has_replies = 0x4, - } } - /// View, forward counter + info about replies See + ///See [TLDef(0xB6C4F543)] - public sealed partial class Messages_MessageViews : IObject, IPeerResolver + public partial class Messages_MessageViews : ITLObject { - /// View, forward counter + info about replies public MessageViews[] views; - /// Chats mentioned in constructor - public Dictionary chats; - /// Users mentioned in constructor - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Information about a message thread See + ///See [TLDef(0xA6341782)] - public sealed partial class Messages_DiscussionMessage : IObject, IPeerResolver + public partial class Messages_DiscussionMessage : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_max_id = 0x1, has_read_inbox_max_id = 0x2, has_read_outbox_max_id = 0x4 } public Flags flags; - /// The messages from which the thread starts. The messages are returned in reverse chronological order (i.e., in order of decreasing message ID). public MessageBase[] messages; - /// Message ID of latest reply in this thread [IfFlag(0)] public int max_id; - /// Message ID of latest read incoming message in this thread [IfFlag(1)] public int read_inbox_max_id; - /// Message ID of latest read outgoing message in this thread [IfFlag(2)] public int read_outbox_max_id; - /// Number of unread messages public int unread_count; - /// Chats mentioned in constructor - public Dictionary chats; - /// Users mentioned in constructor - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_max_id = 0x1, - /// Field has a value - has_read_inbox_max_id = 0x2, - /// Field has a value - has_read_outbox_max_id = 0x4, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Reply information See Derived classes: , - public abstract partial class MessageReplyHeaderBase : IObject { } - /// Message replies and thread information See - [TLDef(0x6917560B)] - public sealed partial class MessageReplyHeader : MessageReplyHeaderBase + ///See + [TLDef(0xA6D57763)] + public partial class MessageReplyHeader : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { has_reply_to_peer_id = 0x1, has_reply_to_top_id = 0x2 } public Flags flags; - /// ID of message to which this message is replying - [IfFlag(4)] public int reply_to_msg_id; - /// For replies sent in channel discussion threads of which the current user is not a member, the discussion group ID + public int reply_to_msg_id; [IfFlag(0)] public Peer reply_to_peer_id; - /// When replying to a message sent by a certain peer to another chat, contains info about the peer that originally sent the message to that other chat. - [IfFlag(5)] public MessageFwdHeader reply_from; - /// When replying to a media sent by a certain peer to another chat, contains the media of the replied-to message. - [IfFlag(8)] public MessageMedia reply_media; - /// ID of the message that started this message thread [IfFlag(1)] public int reply_to_top_id; - /// Used to quote-reply to only a certain section (specified here) of the original message. - [IfFlag(6)] public string quote_text; - /// Message entities for styled text from the quote_text field. - [IfFlag(7)] public MessageEntity[] quote_entities; - /// Offset of the message quote_text within the original message (in UTF-16 code units). - [IfFlag(10)] public int quote_offset; - /// Can be set to reply to the specified item of a todo list ». - [IfFlag(11)] public int todo_item_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_reply_to_peer_id = 0x1, - /// Field has a value - has_reply_to_top_id = 0x2, - /// This is a reply to a scheduled message. - reply_to_scheduled = 0x4, - /// Whether this message was sent in a forum topic (except for the General topic). - forum_topic = 0x8, - /// Field has a value - has_reply_to_msg_id = 0x10, - /// Field has a value - has_reply_from = 0x20, - /// Field has a value - has_quote_text = 0x40, - /// Field has a value - has_quote_entities = 0x80, - /// Field has a value - has_reply_media = 0x100, - /// Whether this message is quoting a part of another message. - quote = 0x200, - /// Field has a value - has_quote_offset = 0x400, - /// Field has a value - has_todo_item_id = 0x800, - } - } - /// Represents a reply to a story See - [TLDef(0x0E5AF939)] - public sealed partial class MessageReplyStoryHeader : MessageReplyHeaderBase - { - /// Sender of the story. - public Peer peer; - /// Story ID - public int story_id; } - /// Info about the comment section of a channel post, a simple message thread, a forum topic, or a direct messages topic (all features ultimately based on message threads). See + ///See [TLDef(0x83D60FC2)] - public sealed partial class MessageReplies : IObject + public partial class MessageReplies : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { comments = 0x1, has_recent_repliers = 0x2, has_max_id = 0x4, has_read_max_id = 0x8 } public Flags flags; - /// Contains the total number of replies in this thread or comment section. public int replies; - /// PTS of the message that started this thread. public int replies_pts; - /// For channel post comments, contains information about the last few comment posters for a specific thread, to show a small list of commenter profile pictures in client previews. [IfFlag(1)] public Peer[] recent_repliers; - /// For channel post comments, contains the ID of the associated discussion supergroup [IfFlag(0)] public long channel_id; - /// ID of the latest message in this thread or comment section. [IfFlag(2)] public int max_id; - /// Contains the ID of the latest read message in this thread or comment section. [IfFlag(3)] public int read_max_id; - - [Flags] public enum Flags : uint - { - /// Whether this constructor contains information about the comment section of a channel post, or a simple message thread - comments = 0x1, - /// Field has a value - has_recent_repliers = 0x2, - /// Field has a value - has_max_id = 0x4, - /// Field has a value - has_read_max_id = 0x8, - } } - /// Information about a blocked peer See + ///See [TLDef(0xE8FD8014)] - public sealed partial class PeerBlocked : IObject + public partial class PeerBlocked : ITLObject { - /// Peer ID public Peer peer_id; - /// When was the peer blocked public DateTime date; } - /// Message statistics See - [TLDef(0x7FE91C14)] - public sealed partial class Stats_MessageStats : IObject - { - /// Message view graph - public StatsGraphBase views_graph; - /// A graph containing the number of reactions on stories categorized by emotion - public StatsGraphBase reactions_by_emotion_graph; - } + ///See + [TLDef(0x8999F295)] + public partial class Stats_MessageStats : ITLObject { public StatsGraphBase views_graph; } - /// A group call See Derived classes: , - public abstract partial class GroupCallBase : IObject - { - /// Group call ID - public virtual long ID => default; - /// Group call access hash - public virtual long AccessHash => default; - } - /// An ended group call See + ///See + public abstract partial class GroupCallBase : ITLObject { } + ///See [TLDef(0x7780BCB4)] - public sealed partial class GroupCallDiscarded : GroupCallBase + public partial class GroupCallDiscarded : GroupCallBase { - /// Group call ID public long id; - /// Group call access hash public long access_hash; - /// Group call duration public int duration; - - /// Group call ID - public override long ID => id; - /// Group call access hash - public override long AccessHash => access_hash; } - /// Info about a group call or livestream See - [TLDef(0xEFB2B617)] - public sealed partial class GroupCall : GroupCallBase + ///See + [TLDef(0xD597650C)] + public partial class GroupCall : GroupCallBase { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { join_muted = 0x2, can_change_join_muted = 0x4, has_title = 0x8, has_stream_dc_id = 0x10, + has_record_start_date = 0x20, join_date_asc = 0x40, has_schedule_date = 0x80, schedule_start_subscribed = 0x100, + can_start_video = 0x200, has_unmuted_video_count = 0x400, record_video_active = 0x800 } public Flags flags; - /// Group call ID public long id; - /// Group call access hash public long access_hash; - /// Participant count public int participants_count; - /// Group call title [IfFlag(3)] public string title; - /// DC ID to be used for livestream chunks [IfFlag(4)] public int stream_dc_id; - /// When was the recording started [IfFlag(5)] public DateTime record_start_date; - /// When is the call scheduled to start [IfFlag(7)] public DateTime schedule_date; - /// Number of people currently streaming video into the call [IfFlag(10)] public int unmuted_video_count; - /// Maximum number of people allowed to stream video into the call public int unmuted_video_limit; - /// Version public int version; - /// Invitation link for the conference. - [IfFlag(16)] public string invite_link; - [IfFlag(20)] public long send_paid_messages_stars; - [IfFlag(21)] public Peer default_send_as; - - [Flags] public enum Flags : uint - { - /// 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 - can_change_join_muted = 0x4, - /// Field has a value - has_title = 0x8, - /// Field has a value - has_stream_dc_id = 0x10, - /// Field has a value - has_record_start_date = 0x20, - /// Specifies the ordering to use when locally sorting by date and displaying in the UI group call participants. - join_date_asc = 0x40, - /// Field has a value - has_schedule_date = 0x80, - /// Whether we subscribed to the scheduled call - schedule_start_subscribed = 0x100, - /// Whether you can start streaming video into the call - can_start_video = 0x200, - /// Field has a value - has_unmuted_video_count = 0x400, - /// Whether the group call is currently being recorded - 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. - listeners_hidden = 0x2000, - /// Whether this is an E2E conference call. - conference = 0x4000, - /// Whether we're created this group call. - creator = 0x8000, - /// Field has a value - has_invite_link = 0x10000, - messages_enabled = 0x20000, - can_change_messages_enabled = 0x40000, - min = 0x80000, - /// Field has a value - has_send_paid_messages_stars = 0x100000, - /// Field has a value - has_default_send_as = 0x200000, - } - - /// Group call ID - public override long ID => id; - /// Group call access hash - public override long AccessHash => access_hash; } - /// Indicates a group call See Derived classes: , , - public abstract partial class InputGroupCallBase : IObject { } - /// Points to a specific group call See + ///See [TLDef(0xD8AA840F)] - public sealed partial class InputGroupCall : InputGroupCallBase + public partial class InputGroupCall : ITLObject { - /// Group call ID public long id; - /// REQUIRED FIELD. See how to obtain it
Group call access hash
public long access_hash; } - ///
Join a conference call through an invitation link ». See - [TLDef(0xFE06823F)] - public sealed partial class InputGroupCallSlug : InputGroupCallBase - { - /// Slug from the conference link ». - public string slug; - } - /// Join a group call through a invitation message. See - [TLDef(0x8C10603F)] - public sealed partial class InputGroupCallInviteMessage : InputGroupCallBase - { - /// ID of the . - public int msg_id; - } - /// Info about a group call participant See - [TLDef(0x2A3DC7AC)] - public sealed partial class GroupCallParticipant : IObject + ///See + [TLDef(0xEBA636FE)] + public partial class GroupCallParticipant : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { muted = 0x1, left = 0x2, can_self_unmute = 0x4, has_active_date = 0x8, just_joined = 0x10, + versioned = 0x20, has_video = 0x40, has_volume = 0x80, min = 0x100, muted_by_you = 0x200, volume_by_admin = 0x400, + has_about = 0x800, self = 0x1000, has_raise_hand_rating = 0x2000, has_presentation = 0x4000, video_joined = 0x8000 } public Flags flags; - /// Peer information public Peer peer; - /// When did this participant join the group call public DateTime date; - /// When was this participant last active in the group call [IfFlag(3)] public DateTime active_date; - /// Source ID public int source; - /// Volume, if not set the volume is set to 100%. [IfFlag(7)] public int volume; - /// Info about this participant [IfFlag(11)] public string about; - /// Specifies the UI visualization order of peers with raised hands: peers with a higher rating should be showed first in the list. [IfFlag(13)] public long raise_hand_rating; - /// Info about the video stream the participant is currently broadcasting [IfFlag(6)] public GroupCallParticipantVideo video; - /// Info about the screen sharing stream the participant is currently broadcasting [IfFlag(14)] public GroupCallParticipantVideo presentation; - [IfFlag(16)] public long paid_stars_total; - - [Flags] public enum Flags : uint - { - /// Whether the participant is muted - muted = 0x1, - /// Whether the participant has left - left = 0x2, - /// Whether the participant can unmute themselves - can_self_unmute = 0x4, - /// Field has a value - 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. - versioned = 0x20, - /// Field has a value - has_video = 0x40, - /// Field has a value - has_volume = 0x80, - /// If not set, the volume and muted_by_you fields can be safely used to overwrite locally cached information; otherwise, volume will contain valid information only if volume_by_admin is set both in the cache and in the received constructor. - min = 0x100, - /// Whether this participant was muted by the current user - muted_by_you = 0x200, - /// Whether our volume can only changed by an admin - volume_by_admin = 0x400, - /// Field has a value - has_about = 0x800, - /// Whether this participant is the current user - self = 0x1000, - /// Field has a value - has_raise_hand_rating = 0x2000, - /// Field has a value - has_presentation = 0x4000, - /// Whether this participant is currently broadcasting video - video_joined = 0x8000, - /// Field has a value - has_paid_stars_total = 0x10000, - } } - /// Contains info about a group call, and partial info about its participants. See + ///See [TLDef(0x9E727AAD)] - public sealed partial class Phone_GroupCall : IObject, IPeerResolver + public partial class Phone_GroupCall : ITLObject { - /// Info about the group call public GroupCallBase call; - /// A partial list of participants. public GroupCallParticipant[] participants; - /// 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; - /// Users mentioned in the participants vector - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// Info about the participants of a group call or livestream See + ///See [TLDef(0xF47751B6)] - public sealed partial class Phone_GroupParticipants : IObject, IPeerResolver + public partial class Phone_GroupParticipants : ITLObject { - /// Number of participants 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. public string next_offset; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - /// Version info + public ChatBase[] chats; + public UserBase[] users; public int version; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); } - /// Inline query peer type. See + ///See public enum InlineQueryPeerType : uint { - ///Peer type: private chat with the bot itself + ///See SameBotPM = 0x3081ED9D, - ///Peer type: private chat + ///See PM = 0x833C0FAC, - ///Peer type: chat + ///See Chat = 0xD766C50A, - ///Peer type: supergroup + ///See Megagroup = 0x5EC4BE43, - ///Peer type: channel + ///See Broadcast = 0x6334EE9A, - ///Peer type: private chat with a bot. - BotPM = 0x0E3B2D0C, } - /// ID of a specific chat import session, click here for more info ». See + ///See [TLDef(0x1662AF0B)] - public sealed partial class Messages_HistoryImport : IObject - { - /// History import ID - public long id; - } + public partial class Messages_HistoryImport : ITLObject { public long id; } - /// Contains information about a chat export file generated by a foreign chat app, click here for more info.
If neither the pm or group flags are set, the specified chat export was generated from a chat of unknown type. See
+ ///See [TLDef(0x5E0FB7B9)] - public sealed partial class Messages_HistoryImportParsed : IObject + public partial class Messages_HistoryImportParsed : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { pm = 0x1, group = 0x2, has_title = 0x4 } public Flags flags; - /// Title of the chat. [IfFlag(2)] public string title; - - [Flags] public enum Flags : uint - { - /// The chat export file was generated from a private chat. - pm = 0x1, - /// The chat export file was generated from a group chat. - group = 0x2, - /// Field has a value - has_title = 0x4, - } } - /// Messages found and affected by changes See - [TLDef(0xEF8D3E6C, inheritAt = 0)] - public sealed partial class Messages_AffectedFoundMessages : Messages_AffectedHistory + ///See + [TLDef(0xEF8D3E6C)] + public partial class Messages_AffectedFoundMessages : ITLObject { - /// Affected message IDs + public int pts; + public int pts_count; + public int offset; public int[] messages; } - /// When and which user joined the chat using a chat invite See - [TLDef(0x8C5ADFD9)] - public sealed partial class ChatInviteImporter : IObject + ///See + [TLDef(0x0B5CD5F4)] + public partial class ChatInviteImporter : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The user public long user_id; - /// When did the user join public DateTime date; - /// For users with pending requests, contains bio of the user that requested to join - [IfFlag(2)] public string about; - /// The administrator that approved the join request » of the user - [IfFlag(1)] public long approved_by; - - [Flags] public enum Flags : uint - { - /// Whether this user currently has a pending join request » - requested = 0x1, - /// Field has a value - has_approved_by = 0x2, - /// Field has a value - has_about = 0x4, - /// The participant joined by importing a chat folder deep link ». - via_chatlist = 0x8, - } } - /// Info about chat invites exported by a certain admin. See + ///See [TLDef(0xBDC62DCC)] - public sealed partial class Messages_ExportedChatInvites : IObject + public partial class Messages_ExportedChatInvites : ITLObject { - /// Number of invites exported by the admin public int count; - /// Exported invites public ExportedChatInvite[] invites; - /// Info about the admin - public Dictionary users; + public UserBase[] users; } - /// Contains info about a chat invite, and eventually a pointer to the newest chat invite. See Derived classes: , - public abstract partial class Messages_ExportedChatInviteBase : IObject - { - /// Info about the chat invite - public virtual ExportedChatInvite Invite => default; - /// Mentioned users - public virtual Dictionary Users => default; - } - /// Info about a chat invite See + ///See + public abstract partial class Messages_ExportedChatInviteBase : ITLObject { } + ///See [TLDef(0x1871BE50)] - public sealed partial class Messages_ExportedChatInvite : Messages_ExportedChatInviteBase + public partial class Messages_ExportedChatInvite : Messages_ExportedChatInviteBase { - /// Info about the chat invite public ExportedChatInvite invite; - /// Mentioned users - public Dictionary users; - - /// Info about the chat invite - public override ExportedChatInvite Invite => invite; - /// Mentioned users - public override Dictionary Users => users; + public UserBase[] users; } - /// The specified chat invite was replaced with another one See + ///See [TLDef(0x222600EF)] - public sealed partial class Messages_ExportedChatInviteReplaced : Messages_ExportedChatInviteBase + public partial class Messages_ExportedChatInviteReplaced : Messages_ExportedChatInviteBase { - /// The replaced chat invite public ExportedChatInvite invite; - /// The invite that replaces the previous invite public ExportedChatInvite new_invite; - /// Mentioned users - public Dictionary users; - - /// The replaced chat invite - public override ExportedChatInvite Invite => invite; - /// Mentioned users - public override Dictionary Users => users; + public UserBase[] users; } - /// Info about the users that joined the chat using a specific chat invite See + ///See [TLDef(0x81B6B00A)] - public sealed partial class Messages_ChatInviteImporters : IObject + public partial class Messages_ChatInviteImporters : ITLObject { - /// Number of users that joined public int count; - /// The users that joined public ChatInviteImporter[] importers; - /// The users that joined - public Dictionary users; + public UserBase[] users; } - /// Info about chat invites generated by admins. See + ///See [TLDef(0xF2ECEF23)] - public sealed partial class ChatAdminWithInvites : IObject + public partial class ChatAdminWithInvites : ITLObject { - /// The admin public long admin_id; - /// Number of invites generated by the admin public int invites_count; - /// Number of revoked invites public int revoked_invites_count; } - /// Info about chat invites generated by admins. See + ///See [TLDef(0xB69B72D7)] - public sealed partial class Messages_ChatAdminsWithInvites : IObject + public partial class Messages_ChatAdminsWithInvites : ITLObject { - /// Info about chat invites generated by admins. public ChatAdminWithInvites[] admins; - /// Mentioned users - public Dictionary users; + public UserBase[] users; } - /// Contains a confirmation text to be shown to the user, upon importing chat history, click here for more info ». See + ///See [TLDef(0xA24DE717)] - public sealed partial class Messages_CheckedHistoryImportPeer : IObject - { - /// A confirmation text to be shown to the user, upon importing chat history ». - public string confirm_text; - } + public partial class Messages_CheckedHistoryImportPeer : ITLObject { public string confirm_text; } - /// A list of peers that can be used to join a group call, presenting yourself as a specific user/channel. See + ///See [TLDef(0xAFE5623F)] - public sealed partial class Phone_JoinAsPeers : IObject, IPeerResolver + public partial class Phone_JoinAsPeers : ITLObject { - /// Peers public Peer[] peers; - /// Chats mentioned in the peers vector - public Dictionary chats; - /// Users mentioned in the peers vector - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); + public ChatBase[] chats; + public UserBase[] users; } - /// An invite to a group call or livestream See + ///See [TLDef(0x204BD158)] - public sealed partial class Phone_ExportedGroupCallInvite : IObject - { - /// Invite link - public string link; - } + public partial class Phone_ExportedGroupCallInvite : ITLObject { public string link; } - /// Describes a group of video synchronization source identifiers See + ///See [TLDef(0xDCB118B7)] - public sealed partial class GroupCallParticipantVideoSourceGroup : IObject + public partial class GroupCallParticipantVideoSourceGroup : ITLObject { - /// SDP semantics public string semantics; - /// Source IDs public int[] sources; } - /// Info about a video stream See + ///See [TLDef(0x67753AC8)] - public sealed partial class GroupCallParticipantVideo : IObject + public partial class GroupCallParticipantVideo : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + [Flags] public enum Flags { paused = 0x1, has_audio_source = 0x2 } public Flags flags; - /// Endpoint public string endpoint; - /// Source groups public GroupCallParticipantVideoSourceGroup[] source_groups; - /// Audio source ID [IfFlag(1)] public int audio_source; - - [Flags] public enum Flags : uint - { - /// Whether the stream is currently paused - paused = 0x1, - /// Field has a value - has_audio_source = 0x2, - } } - /// A suggested short name for a stickerpack See + ///See [TLDef(0x85FEA03F)] - public sealed partial class Stickers_SuggestedShortName : IObject - { - /// Suggested short name - public string short_name; - } + public partial class Stickers_SuggestedShortName : ITLObject { public string short_name; } - /// Represents a scope where the bot commands, specified using Bots_SetBotCommands will be valid. See Derived classes: , , , , , - /// a value means botCommandScopeDefault - public abstract partial class BotCommandScope : IObject { } - /// The specified bot commands will only be valid in all private chats with users. See + ///See + public abstract partial class BotCommandScope : ITLObject { } + ///See + [TLDef(0x2F6CB2AB)] + public partial class BotCommandScopeDefault : BotCommandScope { } + ///See [TLDef(0x3C4F04D8)] - public sealed partial class BotCommandScopeUsers : BotCommandScope { } - /// The specified bot commands will be valid in all groups and supergroups. See + public partial class BotCommandScopeUsers : BotCommandScope { } + ///See [TLDef(0x6FE1A881)] - public sealed partial class BotCommandScopeChats : BotCommandScope { } - /// The specified bot commands will be valid only for chat administrators, in all groups and supergroups. See + public partial class BotCommandScopeChats : BotCommandScope { } + ///See [TLDef(0xB9AA606A)] - public sealed partial class BotCommandScopeChatAdmins : BotCommandScope { } - /// The specified bot commands will be valid only in a specific dialog. See + public partial class BotCommandScopeChatAdmins : BotCommandScope { } + ///See [TLDef(0xDB9D897D)] - public partial class BotCommandScopePeer : BotCommandScope - { - /// The dialog - public InputPeer peer; - } - /// The specified bot commands will be valid for all admins of the specified group or supergroup. See + public partial class BotCommandScopePeer : BotCommandScope { public InputPeer peer; } + ///See [TLDef(0x3FD863D1)] - public sealed partial class BotCommandScopePeerAdmins : BotCommandScopePeer { } - /// The specified bot commands will be valid only for a specific user in the specified group or supergroup. See - [TLDef(0x0A1321F3, inheritAt = 0)] - public sealed partial class BotCommandScopePeerUser : BotCommandScopePeer - { - /// The user - public InputUserBase user_id; - } + public partial class BotCommandScopePeerAdmins : BotCommandScopePeer { } + ///See + [TLDef(0x0A1321F3)] + public partial class BotCommandScopePeerUser : BotCommandScopePeer { public InputUserBase user_id; } - /// Result of an Account_ResetPassword request. See Derived classes: , , - public abstract partial class Account_ResetPasswordResult : IObject { } - /// You recently requested a password reset that was canceled, please wait until the specified date before requesting another reset. See + ///See + public abstract partial class Account_ResetPasswordResult : ITLObject { } + ///See [TLDef(0xE3779861)] - public sealed partial class Account_ResetPasswordFailedWait : Account_ResetPasswordResult - { - /// Wait until this date before requesting another reset. - public DateTime retry_date; - } - /// You successfully requested a password reset, please wait until the specified date before finalizing the reset. See + public partial class Account_ResetPasswordFailedWait : Account_ResetPasswordResult { public DateTime retry_date; } + ///See [TLDef(0xE9EFFC7D)] - public sealed partial class Account_ResetPasswordRequestedWait : Account_ResetPasswordResult - { - /// Wait until this date before finalizing the reset. - public DateTime until_date; - } - /// The 2FA password was reset successfully. See + public partial class Account_ResetPasswordRequestedWait : Account_ResetPasswordResult { public DateTime until_date; } + ///See [TLDef(0xE926D63E)] - public sealed partial class Account_ResetPasswordOk : Account_ResetPasswordResult { } + public partial class Account_ResetPasswordOk : Account_ResetPasswordResult { } - /// A chat theme See Derived classes: , - public abstract partial class ChatThemeBase : IObject { } - /// A chat theme See - [TLDef(0xC3DFFC04)] - public sealed partial class ChatTheme : ChatThemeBase + ///See + [TLDef(0xED0B5C33)] + public partial class ChatTheme : ITLObject { - /// The emoji identifying the chat theme. public string emoticon; - } - /// A chat theme based on a collectible gift ». See - [TLDef(0x3458F9C8)] - public sealed partial class ChatThemeUniqueGift : ChatThemeBase - { - /// The owned collectible gift on which this theme is based, as a . - public StarGiftBase gift; - /// Theme settings. - public ThemeSettings[] theme_settings; + public Theme theme; + public Theme dark_theme; } - /// Available chat themes See - /// a value means account.chatThemesNotModified - [TLDef(0xBE098173)] - public sealed partial class Account_ChatThemes : IObject, IPeerResolver + ///See + ///a null value means account.chatThemesNotModified + [TLDef(0xFE4CBEBD)] + public partial class Account_ChatThemes : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those + public int hash; + public ChatTheme[] themes; + } + + ///See + [TLDef(0x2A3C381F)] + public partial class SponsoredMessage : ITLObject + { + [Flags] public enum Flags { has_start_param = 0x1, has_entities = 0x2 } public Flags flags; - /// Hash to pass to the method that returned this constructor, to avoid refetching the result if it hasn't changed. - public long hash; - /// Themes. - public ChatThemeBase[] themes; - /// Chats mentioned in the themes field. - public Dictionary chats; - /// Users mentioned in the themes field. - public Dictionary users; - /// Next offset for pagination. - [IfFlag(0)] public string next_offset; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// A sponsored message. See - [TLDef(0x7DBF8673)] - public sealed partial class SponsoredMessage : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Message ID public byte[] random_id; - /// Contains the URL to open when the user clicks on the sponsored message. - public string url; - /// Contains the title of the sponsored message. - public string title; - /// Sponsored message + public Peer from_id; + [IfFlag(0)] public string start_param; public string message; - /// Message entities for styled text in message. [IfFlag(1)] public MessageEntity[] entities; - /// If set, contains a custom profile photo bubble that should be displayed for the sponsored message, like for messages sent in groups. - [IfFlag(6)] public PhotoBase photo; - /// If set, contains some media. - [IfFlag(14)] public MessageMedia media; - /// If set, the sponsored message should use the message accent color » specified in color. - [IfFlag(13)] public PeerColorBase color; - /// Label of the sponsored message button. - public string button_text; - /// If set, contains additional information about the sponsor to be shown along with the message. - [IfFlag(7)] public string sponsor_info; - /// If set, contains additional information about the sponsored message to be shown along with the message. - [IfFlag(8)] public string additional_info; - /// For sponsored messages to show on channel videos », allow the user to hide the ad only after the specified amount of seconds. - [IfFlag(15)] public int min_display_duration; - /// For sponsored messages to show on channel videos », autohide the ad after after the specified amount of seconds. - [IfFlag(15)] public int max_display_duration; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_entities = 0x2, - /// Whether the message needs to be labeled as "recommended" instead of "sponsored" - recommended = 0x20, - /// Field has a value - has_photo = 0x40, - /// Field has a value - has_sponsor_info = 0x80, - /// Field has a value - has_additional_info = 0x100, - /// Whether this message can be reported as specified here ». - can_report = 0x1000, - /// Field has a value - has_color = 0x2000, - /// Field has a value - has_media = 0x4000, - /// Fields and have a value - has_min_display_duration = 0x8000, - } } - /// A set of sponsored messages associated to a channel See - /// a value means messages.sponsoredMessagesEmpty - [TLDef(0xFFDA656D)] - public sealed partial class Messages_SponsoredMessages : IObject, IPeerResolver + ///See + [TLDef(0x65A4C7D5)] + public partial class Messages_SponsoredMessages : ITLObject { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// If set, specifies the minimum number of messages between shown sponsored messages; otherwise, only one sponsored message must be shown after all ordinary messages. - [IfFlag(0)] public int posts_between; - /// For sponsored messages to show on channel videos », the number of seconds to wait before showing the first ad. - [IfFlag(1)] public int start_delay; - /// For sponsored messages to show on channel videos », the number of seconds to wait after the previous ad is hidden, before showing the next ad. - [IfFlag(2)] public int between_delay; - /// 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, - /// Field has a value - has_start_delay = 0x2, - /// Field has a value - has_between_delay = 0x4, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Information about found messages sent on a specific day, used to split the messages in s by days. See - [TLDef(0xC9B0539F)] - public sealed partial class SearchResultsCalendarPeriod : IObject - { - /// The day this object is referring to. - public DateTime date; - /// First message ID that was sent on this day. - public int min_msg_id; - /// Last message ID that was sent on this day. - public int max_msg_id; - /// All messages that were sent on this day. - public int count; - } - - /// Information about found messages sent on a specific day See - [TLDef(0x147EE23C)] - public sealed partial class Messages_SearchResultsCalendar : IObject, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of results matching query - public int count; - /// Starting timestamp of attached messages - public DateTime min_date; - /// Ending timestamp of attached messages - public int min_msg_id; - /// Indicates the absolute position of messages[0] within the total result set with count count.
This is useful, for example, if 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(1)] public int offset_id_offset; - /// Used to split the messages by days: multiple constructors are returned, each containing information about the first, last and total number of messages matching the filter that were sent on a specific day.
This information can be easily used to split the returned messages by day.
- public SearchResultsCalendarPeriod[] periods; - /// Messages - public MessageBase[] messages; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// If set, indicates that the results may be inexact - inexact = 0x1, - /// Field has a value - has_offset_id_offset = 0x2, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - ///
Information about a message in a specific position See Derived classes: - public abstract partial class SearchResultsPosition : IObject { } - /// Information about a message in a specific position See - [TLDef(0x7F648B67)] - public sealed partial class SearchResultPosition : SearchResultsPosition - { - /// Message ID - public int msg_id; - /// When was the message sent - public DateTime date; - /// 0-based message position in the full list of suitable messages - public int offset; - } - - /// Information about sparse positions of messages See - [TLDef(0x53B22BAF)] - public sealed partial class Messages_SearchResultsPositions : IObject - { - /// Total number of found messages - public int count; - /// List of message positions - public SearchResultsPosition[] positions; - } - - /// A list of peers that can be used to send messages in a specific group See - [TLDef(0xF496B0C6)] - public sealed partial class Channels_SendAsPeers : IObject, IPeerResolver - { - /// Peers that can be used to send messages to the group - public SendAsPeer[] peers; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Full user information See - [TLDef(0x3B6D152E)] - public sealed partial class Users_UserFull : IObject, IPeerResolver - { - /// Full user information - public UserFull full_user; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Peer settings See - [TLDef(0x6880B94D)] - public sealed partial class Messages_PeerSettings : IObject, IPeerResolver - { - /// Peer settings - public PeerSettings settings; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Future auth token » to be used on subsequent authorizations See - [TLDef(0xC3A2835F)] - public sealed partial class Auth_LoggedOut : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Future auth token » to be used on subsequent authorizations - [IfFlag(0)] public byte[] future_auth_token; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_future_auth_token = 0x1, - } - } - - /// Reactions See - [TLDef(0xA3D1CB80)] - public sealed partial class ReactionCount : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// If set, indicates that the current user also sent this reaction.
The integer value indicates when was the reaction added: the bigger the value, the newer the reaction.
- [IfFlag(0)] public int chosen_order; - /// The reaction. - public Reaction reaction; - /// Number of users that reacted with this emoji. - public int count; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_chosen_order = 0x1, - } - } - - ///
Message reactions » See - [TLDef(0x0A339F0B)] - public sealed partial class MessageReactions : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Reactions - public ReactionCount[] results; - /// List of recent peers and their reactions - [IfFlag(1)] public MessagePeerReaction[] recent_reactions; - /// Paid Telegram Star reactions leaderboard » for this message. - [IfFlag(4)] public MessageReactor[] top_reactors; - - [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). - 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 - can_see_list = 0x4, - /// If set or if there are no reactions, all present and future reactions should be treated as message tags, see here » for more info. - reactions_as_tags = 0x8, - /// Field has a value - has_top_reactors = 0x10, - } - } - - /// List of peers that reacted to a specific message See - [TLDef(0x31BD492D)] - public sealed partial class Messages_MessageReactionsList : IObject, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of reactions matching query - public int count; - /// List of peers that reacted to a specific message - public MessagePeerReaction[] reactions; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - /// 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 - { - /// Field has a value - has_next_offset = 0x1, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Animations associated with a message reaction See - [TLDef(0xC077EC01)] - public sealed partial class AvailableReaction : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Reaction emoji - public string reaction; - /// Reaction description - public string title; - /// Static icon for the reaction - 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 hovers over the reaction - public DocumentBase select_animation; - /// The animated sticker to show when the reaction is chosen and activated - public DocumentBase activate_animation; - /// The background effect (still an animated sticker) to play under the activate_animation, when the reaction is chosen and activated - public DocumentBase effect_animation; - /// The animation that plays around the button when you press an existing reaction (played together with center_icon). - [IfFlag(1)] public DocumentBase around_animation; - /// The animation of the emoji inside the button when you press an existing reaction (played together with around_animation). - [IfFlag(1)] public DocumentBase center_icon; - - [Flags] public enum Flags : uint - { - /// If not set, the reaction can be added to new messages and enabled in chats. - inactive = 0x1, - /// Fields and have a value - has_around_animation = 0x2, - /// Whether this reaction can only be used by Telegram Premium users - premium = 0x4, - } - } - - /// Animations and metadata associated with message reactions » See - /// a value means messages.availableReactionsNotModified - [TLDef(0x768E3AAD)] - public sealed partial class Messages_AvailableReactions : IObject - { - /// Hash used for caching, for more info click here - public int hash; - /// Animations and metadata associated with message reactions » - public AvailableReaction[] reactions; - } - - /// How a certain peer reacted to the message See - [TLDef(0x8C79B63C)] - public sealed partial class MessagePeerReaction : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Peer that reacted to the message - public Peer peer_id; - /// When was this reaction added - public DateTime date; - /// Reaction emoji - public Reaction reaction; - - [Flags] public enum Flags : uint - { - /// Whether the specified message reaction » should elicit a bigger and longer reaction - big = 0x1, - /// Whether the reaction wasn't yet marked as read by the current user - unread = 0x2, - /// Starting from layer 159, Messages_SendReaction will send reactions from the peer (user or channel) specified using Messages_SaveDefaultSendAs.
If set, this flag indicates that this reaction was sent by us, even if the peer doesn't point to the current account.
- my = 0x4, - } - } - - /// Info about an RTMP stream in a group call or livestream See - [TLDef(0x80EB48AF)] - public sealed partial class GroupCallStreamChannel : IObject - { - /// Channel ID - public int channel; - /// Specifies the duration of the video segment to fetch in milliseconds, by bitshifting 1000 to the right scale times: duration_ms := 1000 >> scale. - public int scale; - /// Last seen timestamp to easily start fetching livestream chunks using - public long last_timestamp_ms; - } - - /// Info about RTMP streams in a group call or livestream See - [TLDef(0xD0E482B2)] - public sealed partial class Phone_GroupCallStreamChannels : IObject - { - /// RTMP streams - public GroupCallStreamChannel[] channels; - } - - /// RTMP URL and stream key to be used in streaming software See - [TLDef(0x2DBF3432)] - public sealed partial class Phone_GroupCallStreamRtmpUrl : IObject - { - /// RTMP URL - public string url; - /// Stream key - public string key; - } - - /// Represents an attachment menu icon color for bot mini apps » See - [TLDef(0x4576F3F0)] - public sealed partial class AttachMenuBotIconColor : IObject - { - /// One of the following values:
light_icon - Color of the attachment menu icon (light mode)
light_text - Color of the attachment menu label, once selected (light mode)
dark_icon - Color of the attachment menu icon (dark mode)
dark_text - Color of the attachment menu label, once selected (dark mode)
- public string name; - /// Color in RGB24 format - public int color; - } - - ///
Represents an attachment menu icon for bot mini apps » See - [TLDef(0xB2A7386B)] - public sealed partial class AttachMenuBotIcon : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// One of the following values: note that animated icons must be played when the user clicks on the button, activating the bot mini app.

default_static - Default attachment menu icon in SVG format
placeholder_static - Default placeholder for opened Web Apps in SVG format
ios_static - Attachment menu icon in SVG format for the official iOS app
ios_animated - Animated attachment menu icon in TGS format for the official iOS app
android_animated - Animated attachment menu icon in TGS format for the official Android app
macos_animated - Animated attachment menu icon in TGS format for the official native Mac OS app
ios_side_menu_static - Side menu icon in PNG format for the official iOS app
android_side_menu_static - Side menu icon in SVG format for the official android app
macos_side_menu_static - Side menu icon in PNG format for the official native Mac OS app
- public string name; - /// The actual icon file. - public DocumentBase icon; - /// Attachment menu icon colors. - [IfFlag(0)] public AttachMenuBotIconColor[] colors; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_colors = 0x1, - } - } - - ///
Represents a bot mini app that can be launched from the attachment/side menu » See - [TLDef(0xD90D8DFE)] - public sealed partial class AttachMenuBot : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Bot ID - public long bot_id; - /// Attachment menu item name - public string short_name; - /// List of dialog types where this attachment menu entry should be shown - [IfFlag(3)] public AttachMenuPeerType[] peer_types; - /// List of platform-specific static icons and animations to use for the attachment menu button - public AttachMenuBotIcon[] icons; - - [Flags] public enum Flags : uint - { - /// If set, before launching the mini app the client should ask the user to add the mini app to the attachment/side menu, and only if the user accepts, after invoking Messages_ToggleBotInAttachMenu the app should be opened. - inactive = 0x1, - /// Deprecated flag, can be ignored. - has_settings = 0x2, - /// Whether the bot would like to send messages to the user. - request_write_access = 0x4, - /// Whether, when installed, an attachment menu entry should be shown for the Mini App. - show_in_attach_menu = 0x8, - /// Whether, when installed, an entry in the main view side menu should be shown for the Mini App. - show_in_side_menu = 0x10, - /// If inactive if set and the user hasn't previously accepted the third-party mini apps Terms of Service for this bot, when showing the mini app installation prompt, an additional mandatory checkbox to accept the mini apps TOS and a disclaimer indicating that this Mini App is not affiliated to Telegram should be shown. - side_menu_disclaimer_needed = 0x20, - } - } - - /// Represents a list of bot mini apps that can be launched from the attachment menu » See - /// a value means attachMenuBotsNotModified - [TLDef(0x3C4301C0)] - public sealed partial class AttachMenuBots : IObject - { - /// Hash used for caching, for more info click here - public long hash; - /// List of bot mini apps that can be launched from the attachment menu » - public AttachMenuBot[] bots; - /// Info about related users/bots - public Dictionary users; - } - - /// Represents a bot mini app that can be launched from the attachment menu » See - [TLDef(0x93BF667F)] - public sealed partial class AttachMenuBotsBot : IObject - { - /// Represents a bot mini app that can be launched from the attachment menu »
- public AttachMenuBot bot; - /// Info about related users and bots - public Dictionary users; - } - - /// Contains the webview URL with appropriate theme and user info parameters added See Derived classes: - public abstract partial class WebViewResult : IObject { } - /// Contains the webview URL with appropriate theme and user info parameters added See - [TLDef(0x4D22FF98)] - public sealed partial class WebViewResultUrl : WebViewResult - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Webview session ID (only returned by inline button mini apps, menu button mini apps, attachment menu mini apps). - [IfFlag(0)] public long query_id; - /// Webview URL to open - public string url; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_query_id = 0x1, - /// If set, the app must be opened in fullsize mode instead of compact mode. - fullsize = 0x2, - /// If set, the app must be opened in fullscreen - fullscreen = 0x4, - } - } - - /// Info about a sent inline webview message See - [TLDef(0x0C94511C)] - public sealed partial class WebViewMessageSent : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Message ID - [IfFlag(0)] public InputBotInlineMessageIDBase msg_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_msg_id = 0x1, - } - } - - /// Indicates the action to execute when pressing the in-UI menu button for bots See Derived classes: , - /// a value means botMenuButtonDefault - public abstract partial class BotMenuButtonBase : IObject { } - /// Bot menu button that opens the bot command list when clicked. See - [TLDef(0x4258C205)] - public sealed partial class BotMenuButtonCommands : BotMenuButtonBase { } - /// Bot menu button that opens a web app when clicked. See - [TLDef(0xC7B57CE6)] - public sealed partial class BotMenuButton : BotMenuButtonBase - { - /// Title to be displayed on the menu button instead of 'Menu' - public string text; - /// URL of a web app to open when the user clicks on the button - public string url; - } - - /// A list of saved notification sounds See - /// a value means account.savedRingtonesNotModified - [TLDef(0xC1E92CC5)] - public sealed partial class Account_SavedRingtones : IObject - { - /// Hash used for caching, for more info click here - public long hash; - /// Saved notification sounds - public DocumentBase[] ringtones; - } - - /// Represents a notification sound See Derived classes: , , - /// a value means notificationSoundDefault - public abstract partial class NotificationSound : IObject { } - /// No notification sound should be used See - [TLDef(0x6F0C34DF)] - public sealed partial class NotificationSoundNone : NotificationSound { } - /// Indicates a specific local notification sound should be used See - [TLDef(0x830B9AE4)] - public sealed partial class NotificationSoundLocal : NotificationSound - { - /// Notification sound title - public string title; - /// Notification sound identifier (arbitrary data used by the client to identify a specific local notification sound) - public string data; - } - /// A specific previously uploaded notification sound should be used See - [TLDef(0xFF6C8049)] - public sealed partial class NotificationSoundRingtone : NotificationSound - { - /// Document ID of notification sound uploaded using Account_UploadRingtone - public long id; - } - - /// The notification sound was already in MP3 format and was saved without any modification See - [TLDef(0xB7263F6D)] - public partial class Account_SavedRingtone : IObject { } - /// The notification sound was not in MP3 format and was successfully converted and saved, use the returned to refer to the notification sound from now on See - [TLDef(0x1F307EB7)] - public sealed partial class Account_SavedRingtoneConverted : Account_SavedRingtone - { - /// The converted notification sound - public DocumentBase document; - } - - /// Indicates a supported peer type for a bot mini app attachment menu See - public enum AttachMenuPeerType : uint - { - ///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 (excluding the bot that offers the current attachment menu) - BotPM = 0xC32BFA1A, - ///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, - ///The bot attachment menu entry is available in channels - Broadcast = 0x7BFBDEFC, - } - - /// An invoice See Derived classes: , , , , , , , , , , , , , , - public abstract partial class InputInvoice : IObject { } - /// An invoice contained in a message or paid media ». See - [TLDef(0xC5B56859)] - public sealed partial class InputInvoiceMessage : InputInvoice - { - /// Chat where the invoice/paid media was sent - public InputPeer peer; - /// Message ID - public int msg_id; - } - /// An invoice slug taken from an invoice deep link or from the premium_invoice_slug app config parameter » See - [TLDef(0xC326CAEF)] - public sealed partial class InputInvoiceSlug : InputInvoice - { - /// The invoice slug - public string slug; - } - /// Used if the user wishes to start a channel/supergroup giveaway or send some giftcodes to members of a channel/supergroup, in exchange for boosts. See - [TLDef(0x98986C0D)] - public sealed partial class InputInvoicePremiumGiftCode : InputInvoice - { - /// Should be populated with for giveaways and for gifts. - public InputStorePaymentPurpose purpose; - /// Should be populated with one of the giveaway options returned by Payments_GetPremiumGiftCodeOptions, see the giveaways » documentation for more info. - public PremiumGiftCodeOption option; - } - /// Used to top up the Telegram Stars balance of the current account or someone else's account, or to start a Telegram Star giveaway ». See - [TLDef(0x65F00CE3)] - public sealed partial class InputInvoiceStars : InputInvoice - { - /// An , or . - public InputStorePaymentPurpose purpose; - } - /// Used to pay for a Telegram Star subscription ». See - [TLDef(0x34E793F1)] - public sealed partial class InputInvoiceChatInviteSubscription : InputInvoice - { - /// The invitation link of the Telegram Star subscription » - public string hash; - } - /// Used to buy a Telegram Star Gift, see here » for more info. See - [TLDef(0xE8625E92)] - public sealed partial class InputInvoiceStarGift : InputInvoice - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Receiver of the gift. - public InputPeer peer; - /// Identifier of the gift, from .id - public long gift_id; - /// Optional message, attached with the gift.
The maximum length for this field is specified in the
stargifts_message_length_max client configuration value ».
- [IfFlag(1)] public TextWithEntities message; - - [Flags] public enum Flags : uint - { - /// If set, your name will be hidden if the destination user decides to display the gift on their profile (they will still see that you sent the gift) - hide_name = 0x1, - /// Field has a value - has_message = 0x2, - /// Also pay for an eventual upgrade of the gift to a collectible gift ». - include_upgrade = 0x4, - } - } - /// Used to pay to upgrade a Gift to a collectible gift, see the collectible gifts » documentation for more info on the full flow. See - [TLDef(0x4D818D5D)] - public sealed partial class InputInvoiceStarGiftUpgrade : InputInvoice - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The identifier of the received gift to upgrade. - public InputSavedStarGift stargift; - - [Flags] public enum Flags : uint - { - /// Set this flag to keep the original gift text, sender and receiver in the upgraded gift as a attribute. - keep_original_details = 0x1, - } - } - /// Used to pay to transfer a collectible gift to another peer, see the gifts » documentation for more info. See - [TLDef(0x4A5F5BD9)] - public sealed partial class InputInvoiceStarGiftTransfer : InputInvoice - { - /// The identifier of the received gift - public InputSavedStarGift stargift; - /// The destination peer - public InputPeer to_id; - } - /// Used to gift a Telegram Premium subscription to another user, paying with Telegram Stars. See - [TLDef(0xDABAB2EF)] - public sealed partial class InputInvoicePremiumGiftStars : InputInvoice - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Who will receive the gifted subscription. - public InputUserBase user_id; - /// Duration of the subscription in months, must be one of the options with currency == "XTR" returned by Payments_GetPremiumGiftCodeOptions. - public int months; - /// Message attached with the gift. - [IfFlag(0)] public TextWithEntities message; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_message = 0x1, - } - } - /// Transfer stars from the balance of a user account connected to a business bot, to the balance of the business bot, see here » for more info on the full flow. See - [TLDef(0xF4997E42)] - public sealed partial class InputInvoiceBusinessBotTransferStars : InputInvoice - { - /// Always . - public InputUserBase bot; - /// The number of stars to transfer. - public long stars; - } - /// Used to buy a collectible gift currently up on resale, see here for more info on the full flow. See - [TLDef(0xC39F5324)] - public sealed partial class InputInvoiceStarGiftResale : InputInvoice - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Slug of the gift to buy. - public string slug; - /// The receiver of the gift. - public InputPeer to_id; - - [Flags] public enum Flags : uint - { - /// Buy the gift using TON. - ton = 0x1, - } - } - /// Separately prepay for the upgrade of a gift ». See - [TLDef(0x9A0B48B8)] - public sealed partial class InputInvoiceStarGiftPrepaidUpgrade : InputInvoice - { - /// The peer that owns the gift. - public InputPeer peer; - /// The upgrade hash from .prepaid_upgrade_hash or .prepaid_upgrade_hash. - public string hash; - } - /// See - [TLDef(0x3E77F614)] - public sealed partial class InputInvoicePremiumAuthCode : InputInvoice - { - public InputStorePaymentPurpose purpose; - } - /// See - [TLDef(0x0923D8D1)] - public sealed partial class InputInvoiceStarGiftDropOriginalDetails : InputInvoice - { - public InputSavedStarGift stargift; - } - /// See - [TLDef(0x1ECAFA10)] - public sealed partial class InputInvoiceStarGiftAuctionBid : InputInvoice - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - [IfFlag(3)] public InputPeer peer; - public long gift_id; - public long bid_amount; - [IfFlag(1)] public TextWithEntities message; - - [Flags] public enum Flags : uint - { - hide_name = 0x1, - /// Field has a value - has_message = 0x2, - update_bid = 0x4, - /// Field has a value - has_peer = 0x8, - } - } - - /// Exported invoice deep link See - [TLDef(0xAED0CBD9)] - public sealed partial class Payments_ExportedInvoice : IObject - { - /// Exported invoice deep link - public string url; - } - - /// Transcribed text from a voice message » See - [TLDef(0xCFB9D957)] - public sealed partial class Messages_TranscribedAudio : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Transcription ID - public long transcription_id; - /// Transcripted text - public string text; - /// For non-Premium users, this flag will be set, indicating the remaining transcriptions in the free trial period. - [IfFlag(1)] public int trial_remains_num; - /// For non-Premium users, this flag will be set, indicating the date when the trial_remains_num counter will be reset to the maximum value of transcribe_audio_trial_weekly_number. - [IfFlag(1)] public DateTime trial_remains_until_date; - - [Flags] public enum Flags : uint - { - /// Whether the transcription is partial because audio transcription is still in progress, if set the user may receive further updates with the updated transcription. - pending = 0x1, - /// Fields and have a value - has_trial_remains_num = 0x2, - } - } - - /// Telegram Premium promotion information See - [TLDef(0x5334759C)] - public sealed partial class Help_PremiumPromo : IObject - { - /// Description of the current state of the user's Telegram Premium subscription - public string status_text; - /// Message entities for styled text - public MessageEntity[] status_entities; - /// A list of premium feature identifiers », associated to each video - public string[] video_sections; - /// A list of videos - public DocumentBase[] videos; - /// Telegram Premium subscription options - public PremiumSubscriptionOption[] period_options; - /// Related user information - public Dictionary users; - } - - /// Info about a Telegram Premium purchase See Derived classes: , , , , , , , - public abstract partial class InputStorePaymentPurpose : IObject { } - /// Info about a Telegram Premium purchase See - [TLDef(0xA6751E66)] - public sealed partial class InputStorePaymentPremiumSubscription : InputStorePaymentPurpose - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - - [Flags] public enum Flags : uint - { - /// Pass true if this is a restore of a Telegram Premium purchase; only for the App Store - restore = 0x1, - /// Pass true if this is an upgrade from a monthly subscription to a yearly subscription; only for App Store - upgrade = 0x2, - } - } - /// Info about a gifted Telegram Premium purchase See - [TLDef(0x616F7FE8)] - public sealed partial class InputStorePaymentGiftPremium : InputStorePaymentPurpose - { - /// The user to which the Telegram Premium subscription was gifted - public InputUserBase user_id; - /// Three-letter ISO 4217 currency code - public string currency; - /// Price of the product 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). - public long amount; - } - /// Used to gift Telegram Premium subscriptions only to some specific subscribers of a channel/supergroup or to some of our contacts, see here » for more info on giveaways and gifts. See - [TLDef(0xFB790393)] - public sealed partial class InputStorePaymentPremiumGiftCode : InputStorePaymentPurpose - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The users that will receive the Telegram Premium subscriptions. - public InputUserBase[] users; - /// If set, the gifts will be sent on behalf of a channel/supergroup we are an admin of, which will also assign some boosts to it. Otherwise, the gift will be sent directly from the currently logged in user, and we will gain some extra boost slots. See here » for more info on giveaways and gifts. - [IfFlag(0)] public InputPeer boost_peer; - /// Three-letter ISO 4217 currency code - public string currency; - /// Total price 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). - public long amount; - /// Message attached with the gift - [IfFlag(1)] public TextWithEntities message; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_boost_peer = 0x1, - /// Field has a value - has_message = 0x2, - } - } - /// Used to pay for a giveaway, see here » for more info. See - [TLDef(0x160544CA)] - public sealed partial class InputStorePaymentPremiumGiveaway : InputStorePaymentPurpose - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The channel/supergroup starting the giveaway, that the user must join to participate, that will receive the giveaway boosts; see here » for more info on giveaways. - public InputPeer boost_peer; - /// Additional channels that the user must join to participate to the giveaway can be specified here. - [IfFlag(1)] public InputPeer[] additional_peers; - /// The set of users that can participate to the giveaway can be restricted by passing here an explicit whitelist of up to giveaway_countries_max countries, specified as two-letter ISO 3166-1 alpha-2 country codes. - [IfFlag(2)] public string[] countries_iso2; - /// Can contain a textual description of additional giveaway prizes. - [IfFlag(4)] public string prize_description; - /// Random ID to avoid resending the giveaway - public long random_id; - /// The end date of the giveaway, must be at most giveaway_period_max seconds in the future; see here » for more info on giveaways. - public DateTime until_date; - /// Three-letter ISO 4217 currency code - public string currency; - /// Total price 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). - public long amount; - - [Flags] public enum Flags : uint - { - /// If set, only new subscribers starting from the giveaway creation date will be able to participate to the giveaway. - only_new_subscribers = 0x1, - /// Field has a value - has_additional_peers = 0x2, - /// Field has a value - has_countries_iso2 = 0x4, - /// If set, giveaway winners are public and will be listed in a message that will be automatically sent to the channel once the giveaway ends. - winners_are_visible = 0x8, - /// Field has a value - has_prize_description = 0x10, - } - } - /// Used to top up the Telegram Stars balance of the current account. See - [TLDef(0xF9A2A6CB)] - public sealed partial class InputStorePaymentStarsTopup : InputStorePaymentPurpose - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Amount of stars to topup - public long stars; - /// Three-letter ISO 4217 currency code - public string currency; - /// Total price 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). - public long amount; - /// Should be populated with the peer where the topup process was initiated due to low funds (i.e. a bot for bot payments, a channel for paid media/reactions, etc); leave this flag unpopulated if the topup flow was not initated when attempting to spend more Stars than currently available on the account's balance. - [IfFlag(0)] public InputPeer spend_purpose_peer; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_spend_purpose_peer = 0x1, - } - } - /// Used to gift Telegram Stars to a friend. See - [TLDef(0x1D741EF7)] - public sealed partial class InputStorePaymentStarsGift : InputStorePaymentPurpose - { - /// The user to which the stars should be gifted. - public InputUserBase user_id; - /// Amount of stars to gift - public long stars; - /// Three-letter ISO 4217 currency code - public string currency; - /// Total price 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). - public long amount; - } - /// Used to pay for a star giveaway, see here » for more info. See - [TLDef(0x751F08FA)] - public sealed partial class InputStorePaymentStarsGiveaway : InputStorePaymentPurpose - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of Telegram Stars being given away (each user will receive stars/users stars). - public long stars; - /// The channel/supergroup starting the giveaway, that the user must join to participate, that will receive the giveaway boosts; see here » for more info on giveaways. - public InputPeer boost_peer; - /// Additional channels that the user must join to participate to the giveaway can be specified here. - [IfFlag(1)] public InputPeer[] additional_peers; - /// The set of users that can participate to the giveaway can be restricted by passing here an explicit whitelist of up to giveaway_countries_max countries, specified as two-letter ISO 3166-1 alpha-2 country codes. - [IfFlag(2)] public string[] countries_iso2; - /// Can contain a textual description of additional giveaway prizes. - [IfFlag(4)] public string prize_description; - /// Random ID to avoid resending the giveaway - public long random_id; - /// The end date of the giveaway, must be at most giveaway_period_max seconds in the future; see here » for more info on giveaways. - public DateTime until_date; - /// Three-letter ISO 4217 currency code - public string currency; - /// Total price 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). - public long amount; - /// Number of winners. - public int users; - - [Flags] public enum Flags : uint - { - /// If set, only new subscribers starting from the giveaway creation date will be able to participate to the giveaway. - only_new_subscribers = 0x1, - /// Field has a value - has_additional_peers = 0x2, - /// Field has a value - has_countries_iso2 = 0x4, - /// If set, giveaway winners are public and will be listed in a message that will be automatically sent to the channel once the giveaway ends. - winners_are_visible = 0x8, - /// Field has a value - has_prize_description = 0x10, - } - } - /// Indicates payment for a login code. See - [TLDef(0x9BB2636D)] - public sealed partial class InputStorePaymentAuthCode : InputStorePaymentPurpose - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Phone number. - public string phone_number; - /// phone_code_hash returned by Auth_SendCode. - public string phone_code_hash; - /// Three-letter ISO 4217 currency code - public string currency; - /// Price of the product 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). - public long amount; - - [Flags] public enum Flags : uint - { - /// Set this flag to restore a previously made purchase. - restore = 0x1, - } - } - - /// Represents an additional payment method See - [TLDef(0x88F8F21B)] - public sealed partial class PaymentFormMethod : IObject - { - /// URL to open in a webview to process the payment - public string url; - /// Payment method description - public string title; - } - - /// Emoji status See Derived classes: , , - /// a value means emojiStatusEmpty - public abstract partial class EmojiStatusBase : IObject - { - /// If set, the emoji status will be active until the specified unixtime. - public virtual DateTime Until => default; - } - /// An emoji status See - [TLDef(0xE7FF068A)] - public sealed partial class EmojiStatus : EmojiStatusBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Custom emoji document ID - public long document_id; - /// If set, the emoji status will be active until the specified unixtime. - [IfFlag(0)] public DateTime until; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_until = 0x1, - } - - /// If set, the emoji status will be active until the specified unixtime. - public override DateTime Until => until; - } - /// An owned collectible gift » as emoji status. See - [TLDef(0x7184603B)] - public sealed partial class EmojiStatusCollectible : EmojiStatusBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of the collectible (from .id). - public long collectible_id; - /// ID of the custom emoji representing the status. - public long document_id; - /// Name of the collectible. - public string title; - /// Unique identifier of the collectible that may be used to create a collectible gift link » for the current collectible, or to fetch further info about the collectible using Payments_GetUniqueStarGift. - public string slug; - /// The ID of a pattern to apply on the profile's backdrop, correlated to the from the gift in slug. - public long pattern_document_id; - /// Color of the center of the profile backdrop in RGB24 format, from the gift's . - public int center_color; - /// Color of the edges of the profile backdrop in RGB24 format, from the gift's . - public int edge_color; - /// Color of the pattern_document_id applied on the profile backdrop in RGB24 format, from the gift's . - public int pattern_color; - /// Color of text on the profile backdrop in RGB24 format, from the gift's . - public int text_color; - /// If set, the emoji status will be active until the specified unixtime. - [IfFlag(0)] public DateTime until; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_until = 0x1, - } - - /// If set, the emoji status will be active until the specified unixtime. - public override DateTime Until => until; - } - /// An owned collectible gift » as emoji status: can only be used in Account_UpdateEmojiStatus, is never returned by the API. See - [TLDef(0x07141DBF)] - public sealed partial class InputEmojiStatusCollectible : EmojiStatusBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of the collectible (from .id). - public long collectible_id; - /// If set, the emoji status will be active until the specified unixtime. - [IfFlag(0)] public DateTime until; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_until = 0x1, - } - - /// If set, the emoji status will be active until the specified unixtime. - public override DateTime Until => until; - } - - /// A list of emoji statuses See - /// a value means account.emojiStatusesNotModified - [TLDef(0x90C467D1)] - public sealed partial class Account_EmojiStatuses : IObject - { - /// Hash used for caching, for more info click here - public long hash; - /// Emoji statuses - public EmojiStatusBase[] statuses; - } - - /// Message reaction See Derived classes: , , - /// a value means reactionEmpty - public abstract partial class Reaction : IObject { } - /// Normal emoji message reaction See - [TLDef(0x1B2286B8)] - public sealed partial class ReactionEmoji : Reaction - { - /// Emoji - public string emoticon; - } - /// Custom emoji message reaction See - [TLDef(0x8935FC73)] - public sealed partial class ReactionCustomEmoji : Reaction - { - /// Custom emoji document ID - public long document_id; - } - /// Represents a paid Telegram Star reaction ». See - [TLDef(0x523DA4EB)] - public sealed partial class ReactionPaid : Reaction { } - - /// Available chat reactions See Derived classes: , - /// a value means chatReactionsNone - public abstract partial class ChatReactions : IObject { } - /// All reactions or all non-custom reactions are allowed See - [TLDef(0x52928BCA)] - public sealed partial class ChatReactionsAll : ChatReactions - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - - [Flags] public enum Flags : uint - { - /// Whether to allow custom reactions - allow_custom = 0x1, - } - } - /// Some reactions are allowed See - [TLDef(0x661D4037)] - public sealed partial class ChatReactionsSome : ChatReactions - { - /// Allowed set of reactions: the reactions_in_chat_max configuration field indicates the maximum number of reactions that can be specified in this field. - public Reaction[] reactions; - } - - /// List of message reactions See - /// a value means messages.reactionsNotModified - [TLDef(0xEAFDF716)] - public sealed partial class Messages_Reactions : IObject - { - /// Hash used for caching, can also be locally regenerated using the algorithm specified here ». - public long hash; - /// Reactions - public Reaction[] reactions; - } - - /// Email verification purpose See Derived classes: , , - public abstract partial class EmailVerifyPurpose : IObject { } - /// Email verification purpose: setup login email See - [TLDef(0x4345BE73)] - public sealed partial class EmailVerifyPurposeLoginSetup : EmailVerifyPurpose - { - /// Phone number - public string phone_number; - /// Phone code hash as specified by the documentation - public string phone_code_hash; - } - /// Email verification purpose: change login email See - [TLDef(0x527D22EB)] - public sealed partial class EmailVerifyPurposeLoginChange : EmailVerifyPurpose { } - /// Verify an email for use in telegram passport See - [TLDef(0xBBF51685)] - public sealed partial class EmailVerifyPurposePassport : EmailVerifyPurpose { } - - /// Email verification code or token See Derived classes: , , - public abstract partial class EmailVerification : IObject { } - /// Email verification code See - [TLDef(0x922E55A9)] - public sealed partial class EmailVerificationCode : EmailVerification - { - /// Received verification code - public string code; - } - /// Google ID email verification token See - [TLDef(0xDB909EC2)] - public sealed partial class EmailVerificationGoogle : EmailVerification - { - /// Token - public string token; - } - /// Apple ID email verification token See - [TLDef(0x96D074FD)] - public sealed partial class EmailVerificationApple : EmailVerification - { - /// Token - public string token; - } - - /// The email was verified correctly. See - [TLDef(0x2B96CD1B)] - public partial class Account_EmailVerified : IObject - { - /// The verified email address. - public string email; - } - /// The email was verified correctly, and a login code was just sent to it. See - [TLDef(0xE1BB0D61, inheritAt = 0)] - public sealed partial class Account_EmailVerifiedLogin : Account_EmailVerified - { - /// Info about the sent login code - public Auth_SentCodeBase sent_code; - } - - /// Describes a Telegram Premium subscription option See - [TLDef(0x5F2D1DF2)] - public sealed partial class PremiumSubscriptionOption : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Identifier of the last in-store transaction for the currently used subscription on the current account. - [IfFlag(3)] public string transaction; - /// Duration of subscription in months - public int months; - /// Three-letter ISO 4217 currency code - public string currency; - /// Total price 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). - public long amount; - /// Deep link used to initiate payment - public string bot_url; - /// Store product ID, only for official apps - [IfFlag(0)] public string store_product; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_store_product = 0x1, - /// Whether this subscription option is currently in use. - current = 0x2, - /// Whether this subscription option can be used to upgrade the existing Telegram Premium subscription. When upgrading Telegram Premium subscriptions bought through stores, make sure that the store transaction ID is equal to transaction, to avoid upgrading someone else's account, if the client is currently logged into multiple accounts. - can_purchase_upgrade = 0x4, - /// Field has a value - has_transaction = 0x8, - } - } - - /// Indicates a peer that can be used to send messages See - [TLDef(0xB81C7034)] - public sealed partial class SendAsPeer : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Peer - public Peer peer; - - [Flags] public enum Flags : uint - { - /// Whether a Telegram Premium account is required to send messages as this peer - premium_required = 0x1, - } - } - - /// Paid media, see here » for more info. See Derived classes: , - public abstract partial class MessageExtendedMediaBase : IObject { } - /// Paid media preview for not yet purchased paid media, see here » for more info. See - [TLDef(0xAD628CC8)] - public sealed partial class MessageExtendedMediaPreview : MessageExtendedMediaBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Width - [IfFlag(0)] public int w; - /// Height - [IfFlag(0)] public int h; - /// Extremely low resolution thumbnail. - [IfFlag(1)] public PhotoSizeBase thumb; - /// Video duration for videos. - [IfFlag(2)] public int video_duration; - - [Flags] public enum Flags : uint - { - /// Fields and have a value - has_w = 0x1, - /// Field has a value - has_thumb = 0x2, - /// Field has a value - has_video_duration = 0x4, - } - } - /// Already purchased paid media, see here » for more info. See - [TLDef(0xEE479C64)] - public sealed partial class MessageExtendedMedia : MessageExtendedMediaBase - { - /// The media we purchased. - public MessageMedia media; - } - - /// Keywords for a certain sticker See - [TLDef(0xFCFEB29C)] - public sealed partial class StickerKeyword : IObject - { - /// Sticker ID - public long document_id; - /// Keywords - public string[] keyword; - } - - /// Contains information about a username. See - [TLDef(0xB4073647)] - public sealed partial class Username : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The username. - public string username; - - [Flags] public enum Flags : uint - { - /// Whether the username is editable, meaning it wasn't bought on fragment. - editable = 0x1, - /// Whether the username is active. - active = 0x2, - } - } - - /// Contains information about a forum topic See Derived classes: , - public abstract partial class ForumTopicBase : IObject - { - /// The ID of the deleted forum topic. - public virtual int ID => default; - } - /// Represents a deleted forum topic. See - [TLDef(0x023F109B)] - public sealed partial class ForumTopicDeleted : ForumTopicBase - { - /// The ID of the deleted forum topic. - public int id; - - /// The ID of the deleted forum topic. - public override int ID => id; - } - /// Represents a forum topic. See - [TLDef(0xCDFF0ECA)] - public sealed partial class ForumTopic : ForumTopicBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Topic ID - public int id; - /// Topic creation date - public DateTime date; - public Peer peer; - /// Topic title - public string title; - /// If no custom emoji icon is specified, specifies the color of the fallback topic icon (RGB), one of 0x6FB9F0, 0xFFD67E, 0xCB86DB, 0x8EEE98, 0xFF93B2, or 0xFB6F5F. - public int icon_color; - /// ID of the custom emoji used as topic icon. - [IfFlag(0)] public long icon_emoji_id; - /// ID of the last message that was sent to this topic - public int top_message; - /// Position up to which all incoming messages are read. - public int read_inbox_max_id; - /// Position up to which all outgoing messages are read. - public int read_outbox_max_id; - /// Number of unread messages - public int unread_count; - /// Number of unread mentions - public int unread_mentions_count; - /// Number of unread reactions to messages you sent - public int unread_reactions_count; - /// ID of the peer that created the topic - public Peer from_id; - /// Notification settings - public PeerNotifySettings notify_settings; - /// Message draft - [IfFlag(4)] public DraftMessageBase draft; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_icon_emoji_id = 0x1, - /// Whether the topic was created by the current user - my = 0x2, - /// Whether the topic is closed (no messages can be sent to it) - closed = 0x4, - /// Whether the topic is pinned - pinned = 0x8, - /// Field has a value - has_draft = 0x10, - /// Whether this constructor is a reduced version of the full topic information.
If set, only the my, closed, id, date, title, icon_color, icon_emoji_id and from_id parameters will contain valid information.
Reduced info is usually only returned in topic-related admin log events » and in the : if needed, full information can be fetched using Channels_GetForumTopicsByID.
- short_ = 0x20, - /// Whether the topic is hidden (only valid for the "General" topic, id=1) - hidden = 0x40, - title_missing = 0x80, - } - - /// Topic ID - public override int ID => id; - } - - /// Contains information about multiple forum topics See - [TLDef(0x367617D3)] - public sealed partial class Messages_ForumTopics : IObject, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of topics matching query; may be more than the topics contained in topics, in which case pagination is required. - public int count; - /// Forum topics - public ForumTopicBase[] topics; - /// Related messages (contains the messages mentioned by .top_message). - public MessageBase[] messages; - /// Related chats - public Dictionary chats; - /// Related users - public Dictionary users; - /// Event count after generation - public int pts; - - [Flags] public enum Flags : uint - { - /// Whether the returned topics are ordered by creation date; if set, pagination by offset_date should use .date; otherwise topics are ordered by the last message date, so paginate by the date of the referenced by .top_message. - order_by_create_date = 0x1, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Contains info about the default value of the Time-To-Live setting, applied to all new chats. See - [TLDef(0x43B46B20)] - public sealed partial class DefaultHistoryTTL : IObject - { - /// Time-To-Live setting applied to all new chats. - public int period; - } - - /// Describes a temporary profile link. See - [TLDef(0x41BF109B)] - public sealed partial class ExportedContactToken : IObject - { - /// The temporary profile link. - public string url; - /// Its expiration date - public DateTime expires; - } - - /// Filtering criteria to use for the peer selection list shown to the user. See Derived classes: , , - public abstract partial class RequestPeerType : IObject { } - /// Choose a user. See - [TLDef(0x5F3B8A00)] - public sealed partial class RequestPeerTypeUser : RequestPeerType - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Whether to allow choosing only bots. - [IfFlag(0)] public bool bot; - /// Whether to allow choosing only Premium users. - [IfFlag(1)] public bool premium; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_bot = 0x1, - /// Field has a value - has_premium = 0x2, - } - } - /// Choose a chat or supergroup See - [TLDef(0xC9F06E1B)] - public sealed partial class RequestPeerTypeChat : RequestPeerType - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// If specified, allows only choosing channels with or without a username, according to the value of . - [IfFlag(3)] public bool has_username; - /// If specified, allows only choosing chats or supergroups that are or aren't forums, according to the value of . - [IfFlag(4)] public bool forum; - /// If specified, allows only choosing chats or supergroups where the current user is an admin with at least the specified admin rights. - [IfFlag(1)] public ChatAdminRights user_admin_rights; - /// If specified, allows only choosing chats or supergroups where the bot is an admin with at least the specified admin rights. - [IfFlag(2)] public ChatAdminRights bot_admin_rights; - - [Flags] public enum Flags : uint - { - /// Whether to allow only choosing chats or supergroups that were created by the current user. - creator = 0x1, - /// Field has a value - has_user_admin_rights = 0x2, - /// Field has a value - has_bot_admin_rights = 0x4, - /// Field has a value - has_has_username = 0x8, - /// Field has a value - has_forum = 0x10, - /// Whether to allow only choosing chats or supergroups where the bot is a participant. - bot_participant = 0x20, - } - } - /// Choose a channel See - [TLDef(0x339BEF6C)] - public sealed partial class RequestPeerTypeBroadcast : RequestPeerType - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// If specified, allows only choosing channels with or without a username, according to the value of . - [IfFlag(3)] public bool has_username; - /// If specified, allows only choosing channels where the current user is an admin with at least the specified admin rights. - [IfFlag(1)] public ChatAdminRights user_admin_rights; - /// If specified, allows only choosing channels where the bot is an admin with at least the specified admin rights. - [IfFlag(2)] public ChatAdminRights bot_admin_rights; - - [Flags] public enum Flags : uint - { - /// Whether to allow only choosing channels that were created by the current user. - creator = 0x1, - /// Field has a value - has_user_admin_rights = 0x2, - /// Field has a value - has_bot_admin_rights = 0x4, - /// Field has a value - has_has_username = 0x8, - } - } - - /// Represents a list of custom emojis. See - /// a value means emojiListNotModified - [TLDef(0x7A1E11D1)] - public sealed partial class EmojiList : IObject - { - /// Hash used for caching, for more info click here - public long hash; - /// Custom emoji IDs - public long[] document_id; - } - - /// Represents an emoji category. See Derived classes: , , - public abstract partial class EmojiGroupBase : IObject - { - /// Category name, i.e. "Animals", "Flags", "Faces" and so on... - public virtual string Title => default; - /// A single custom emoji used as preview for the category. - public virtual long IconEmojiId => default; - } - /// Represents an emoji category. See - [TLDef(0x7A9ABDA9)] - public partial class EmojiGroup : EmojiGroupBase - { - /// Category name, i.e. "Animals", "Flags", "Faces" and so on... - public string title; - /// A single custom emoji used as preview for the category. - public long icon_emoji_id; - /// A list of UTF-8 emojis, matching the category. - public string[] emoticons; - - /// Category name, i.e. "Animals", "Flags", "Faces" and so on... - public override string Title => title; - /// A single custom emoji used as preview for the category. - public override long IconEmojiId => icon_emoji_id; - } - /// Represents an emoji category, that should be moved to the top of the list when choosing a sticker for a business introduction See - [TLDef(0x80D26CC7)] - public sealed partial class EmojiGroupGreeting : EmojiGroup - { - } - /// An emoji category, used to select all Premium-only stickers (i.e. those with a Premium effect »)/Premium-only custom emojis (i.e. those where the .free flag is not set) See - [TLDef(0x093BCF34)] - public sealed partial class EmojiGroupPremium : EmojiGroupBase - { - /// Category name, i.e. "Animals", "Flags", "Faces" and so on... - public string title; - /// A single custom emoji used as preview for the category. - public long icon_emoji_id; - - /// Category name, i.e. "Animals", "Flags", "Faces" and so on... - public override string Title => title; - /// A single custom emoji used as preview for the category. - public override long IconEmojiId => icon_emoji_id; - } - - /// Represents a list of emoji categories. See - /// a value means messages.emojiGroupsNotModified - [TLDef(0x881FB94B)] - public sealed partial class Messages_EmojiGroups : IObject - { - /// Hash used for caching, for more info click here - public int hash; - /// A list of emoji categories. - public EmojiGroupBase[] groups; - } - - /// Styled text with message entities See - [TLDef(0x751F3146)] - public sealed partial class TextWithEntities : IObject - { - /// Text - public string text; - /// Message entities for styled text - public MessageEntity[] entities; - } - - /// Translated text with entities. See Derived classes: - public abstract partial class Messages_TranslatedText : IObject { } - /// Translated text with entities See - [TLDef(0x33DB32F8)] - public sealed partial class Messages_TranslateResult : Messages_TranslatedText - { - /// Text+entities, for each input message. - public TextWithEntities[] result; - } - - /// Media autosave settings See - [TLDef(0xC84834CE)] - public sealed partial class AutoSaveSettings : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// If set, specifies a size limit for autosavable videos - [IfFlag(2)] public long video_max_size; - - [Flags] public enum Flags : uint - { - /// Whether photos should be autosaved to the gallery. - photos = 0x1, - /// Whether videos should be autosaved to the gallery. - videos = 0x2, - /// Field has a value - has_video_max_size = 0x4, - } - } - - /// Peer-specific media autosave settings See - [TLDef(0x81602D47)] - public sealed partial class AutoSaveException : IObject - { - /// The peer - public Peer peer; - /// Media autosave settings - public AutoSaveSettings settings; - } - - /// Contains media autosave settings See - [TLDef(0x4C3E069D)] - public sealed partial class Account_AutoSaveSettings : IObject, IPeerResolver - { - /// Default media autosave settings for private chats - public AutoSaveSettings users_settings; - /// Default media autosave settings for groups and supergroups - public AutoSaveSettings chats_settings; - /// Default media autosave settings for channels - public AutoSaveSettings broadcasts_settings; - /// Peer-specific granular autosave settings - public AutoSaveException[] exceptions; - /// Chats mentioned in the peer-specific granular autosave settings - public Dictionary chats; - /// Users mentioned in the peer-specific granular autosave settings - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Contains various client configuration parameters See - /// a value means help.appConfigNotModified - [TLDef(0xDD18782E)] - public sealed partial class Help_AppConfig : IObject - { - /// Hash used for caching, for more info click here - public int hash; - /// Client configuration parameters - public JsonObject config; - } - - /// Used to fetch information about a direct link Mini App See Derived classes: , - public abstract partial class InputBotApp : IObject { } - /// Used to fetch information about a direct link Mini App by its ID See - [TLDef(0xA920BD7A)] - public sealed partial class InputBotAppID : InputBotApp - { - /// direct link Mini App ID. - public long id; - /// REQUIRED FIELD. See how to obtain it
Access hash, obtained from the .
- public long access_hash; - } - /// Used to fetch information about a direct link Mini App by its short name See - [TLDef(0x908C0407)] - public sealed partial class InputBotAppShortName : InputBotApp - { - /// ID of the bot that owns the bot mini app - public InputUserBase bot_id; - /// Short name, obtained from a Direct Mini App deep link - public string short_name; - } - - /// Contains information about a direct link Mini App. See - /// a value means botAppNotModified - [TLDef(0x95FCD1D6)] - public sealed partial class BotApp : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// bot mini app ID - public long id; - /// bot mini app access hash - public long access_hash; - /// bot mini app short name, used to generate Direct Mini App deep links. - public string short_name; - /// bot mini app title. - public string title; - /// bot mini app description. - public string description; - /// bot mini app photo. - public PhotoBase photo; - /// bot mini app animation. - [IfFlag(0)] public DocumentBase document; - /// Hash to pass to Messages_GetBotApp, to avoid refetching bot app info if it hasn't changed. - public long hash; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_document = 0x1, - } - } - - /// Contains information about a direct link Mini App See - [TLDef(0xEB50ADF5)] - public sealed partial class Messages_BotApp : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Bot app information - public BotApp app; - - [Flags] public enum Flags : uint - { - /// Whether the web app was never used by the user, and confirmation must be asked from the user before opening it. - inactive = 0x1, - /// The bot is asking permission to send messages to the user: if the user agrees, set the write_allowed flag when invoking Messages_RequestAppWebView. - request_write_access = 0x2, - /// Deprecated flag, can be ignored. - has_settings = 0x4, - } - } - - /// Specifies an inline mode mini app button, shown on top of the inline query results list. See - [TLDef(0xB57295D5)] - public sealed partial class InlineBotWebView : IObject - { - /// Text of the button - public string text; - /// Webapp URL - public string url; - } - - /// Contains info about when a certain participant has read a message See - [TLDef(0x4A4FF172)] - public sealed partial class ReadParticipantDate : IObject - { - /// User ID - public long user_id; - /// When the user read the message - public DateTime date; - } - - /// Represents a folder See Derived classes: - public abstract partial class InputChatlist : IObject { } - /// Folder ID See - [TLDef(0xF3E0DA33)] - public sealed partial class InputChatlistDialogFilter : InputChatlist - { - /// Folder ID - public int filter_id; - } - - /// Exported chat folder deep link ». See - [TLDef(0x0C5181AC)] - public sealed partial class ExportedChatlistInvite : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Name of the link - public string title; - /// The chat folder deep link ». - public string url; - /// Peers to import - public Peer[] peers; - - [Flags] public enum Flags : uint - { - } - } - - /// Info about an exported chat folder deep link ». See - [TLDef(0x10E6E3A6)] - public sealed partial class Chatlists_ExportedChatlistInvite : IObject - { - /// Folder ID - public DialogFilterBase filter; - /// The exported chat folder deep link ». - public ExportedChatlistInvite invite; - } - - /// Info about multiple chat folder deep links ». See - [TLDef(0x10AB6DC7)] - public sealed partial class Chatlists_ExportedInvites : IObject, IPeerResolver - { - /// The chat folder deep links ». - public ExportedChatlistInvite[] invites; - /// Related chat information - public Dictionary chats; - /// Related user information - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Info about a chat folder deep link ». See Derived classes: , - public abstract partial class Chatlists_ChatlistInviteBase : IObject - { - /// Related chat information - public virtual Dictionary Chats => default; - /// Related user information - public virtual Dictionary Users => default; - } - /// Updated info about a chat folder deep link » we already imported. See - [TLDef(0xFA87F659)] - public sealed partial class Chatlists_ChatlistInviteAlready : Chatlists_ChatlistInviteBase, IPeerResolver - { - /// ID of the imported folder - public int filter_id; - /// New peers to be imported - public Peer[] missing_peers; - /// Peers that were already imported - public Peer[] already_peers; - /// Related chat information - public Dictionary chats; - /// Related user information - public Dictionary users; - - /// Related chat information - public override Dictionary Chats => chats; - /// Related user information - public override Dictionary Users => users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - /// Info about a chat folder deep link ». See - [TLDef(0xF10ECE2F)] - public sealed partial class Chatlists_ChatlistInvite : Chatlists_ChatlistInviteBase, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Name of the link - public TextWithEntities title; - /// Emoji to use as icon for the folder. - [IfFlag(0)] public string emoticon; - /// Supergroups and channels to join - public Peer[] peers; - /// Related chat information - public Dictionary chats; - /// Related user information - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_emoticon = 0x1, - /// If set, any animated emojis present in title should not be animated and should be instead frozen on the first frame. - title_noanimate = 0x2, - } - - /// Related chat information - public override Dictionary Chats => chats; - /// Related user information - public override Dictionary Users => users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Updated information about a chat folder deep link ». See - [TLDef(0x93BD878D)] - public sealed partial class Chatlists_ChatlistUpdates : IObject, IPeerResolver - { - /// New peers to join - public Peer[] missing_peers; - /// Related chat information - public Dictionary chats; - /// Related user information - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Localized information about a bot. See - [TLDef(0xE8A775B0)] - public sealed partial class Bots_BotInfo : IObject - { - /// Bot name - public string name; - /// Bot about text - public string about; - /// Bot description - public string description; - } - - /// How a user voted in a poll See Derived classes: , , - public abstract partial class MessagePeerVoteBase : IObject - { - /// Peer ID - public virtual Peer Peer => default; - /// When did the peer cast the vote - public virtual DateTime Date => default; - } - /// How a peer voted in a poll See - [TLDef(0xB6CC2D5C)] - public sealed partial class MessagePeerVote : MessagePeerVoteBase - { - /// Peer ID - public Peer peer; - /// The option chosen by the peer - public byte[] option; - /// When did the peer cast the vote - public DateTime date; - - /// Peer ID - public override Peer Peer => peer; - /// When did the peer cast the vote - public override DateTime Date => date; - } - /// How a peer voted in a poll (reduced constructor, returned if an option was provided to Messages_GetPollVotes) See - [TLDef(0x74CDA504)] - public sealed partial class MessagePeerVoteInputOption : MessagePeerVoteBase - { - /// The peer that voted for the queried option - public Peer peer; - /// When did the peer cast the vote - public DateTime date; - - /// The peer that voted for the queried option - public override Peer Peer => peer; - /// When did the peer cast the vote - public override DateTime Date => date; - } - /// How a peer voted in a multiple-choice poll See - [TLDef(0x4628F6E6)] - public sealed partial class MessagePeerVoteMultiple : MessagePeerVoteBase - { - /// Peer ID - public Peer peer; - /// Options chosen by the peer - public byte[][] options; - /// When did the peer cast their votes - public DateTime date; - - /// Peer ID - public override Peer Peer => peer; - /// When did the peer cast their votes - public override DateTime Date => date; - } - - /// Aggregated view and reaction information of a story. See - [TLDef(0x8D595CD6)] - public sealed partial class StoryViews : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// View counter of the story - public int views_count; - /// Forward counter of the story - [IfFlag(2)] public int forwards_count; - /// All reactions sent to this story - [IfFlag(3)] public ReactionCount[] reactions; - /// Number of reactions added to the story - [IfFlag(4)] public int reactions_count; - /// User IDs of some recent viewers of the story - [IfFlag(0)] public long[] recent_viewers; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_recent_viewers = 0x1, - /// If set, indicates that the viewers list is currently viewable, and was not yet deleted because the story has expired while the user didn't have a Premium account. - has_viewers = 0x2, - /// Field has a value - has_forwards_count = 0x4, - /// Field has a value - has_reactions = 0x8, - /// Field has a value - has_reactions_count = 0x10, - } - } - - /// Represents a Telegram Story See Derived classes: , , - public abstract partial class StoryItemBase : IObject - { - /// Story ID - public virtual int ID => default; - } - /// Represents a previously active story, that was deleted See - [TLDef(0x51E6EE4F)] - public sealed partial class StoryItemDeleted : StoryItemBase - { - /// Story ID - public int id; - - /// Story ID - public override int ID => id; - } - /// Represents an active story, whose full information was omitted for space and performance reasons; use Stories_GetStoriesByID to fetch full info about the skipped story when and if needed. See - [TLDef(0xFFADC913)] - public sealed partial class StoryItemSkipped : StoryItemBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Story ID - public int id; - /// When was the story posted. - public DateTime date; - /// When does the story expire. - public DateTime expire_date; - - [Flags] public enum Flags : uint - { - /// Whether this story can only be viewed by our close friends, see here » for more info - close_friends = 0x100, - live = 0x200, - } - - /// Story ID - public override int ID => id; - } - /// Represents a story. See - [TLDef(0xEDF164F1)] - public sealed partial class StoryItem : StoryItemBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of the story. - public int id; - /// When was the story posted. - public DateTime date; - /// Sender of the story. - [IfFlag(18)] public Peer from_id; - /// For reposted stories », contains info about the original story. - [IfFlag(17)] public StoryFwdHeader fwd_from; - /// When does the story expire. - public DateTime expire_date; - /// Story caption. - [IfFlag(0)] public string caption; - /// Message entities for styled text - [IfFlag(1)] public MessageEntity[] entities; - /// Story media. - public MessageMedia media; - /// List of media areas, see here » for more info on media areas. - [IfFlag(14)] public MediaArea[] media_areas; - /// Privacy rules indicating who can and can't view this story - [IfFlag(2)] public PrivacyRule[] privacy; - /// View date and reaction information - [IfFlag(3)] public StoryViews views; - /// The reaction we sent. - [IfFlag(15)] public Reaction sent_reaction; - /// Albums this story is part of. - [IfFlag(19)] public int[] albums; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_caption = 0x1, - /// Field has a value - has_entities = 0x2, - /// Field has a value - has_privacy = 0x4, - /// Field has a value - has_views = 0x8, - /// Whether this story is pinned on the user's profile - pinned = 0x20, - /// Whether this story is public and can be viewed by everyone - public_ = 0x80, - /// Whether this story can only be viewed by our close friends, see here » for more info - close_friends = 0x100, - /// Full information about this story was omitted for space and performance reasons; use Stories_GetStoriesByID to fetch full info about this story when and if needed. - min = 0x200, - /// Whether this story is protected and thus cannot be forwarded; clients should also prevent users from saving attached media (i.e. videos should only be streamed, photos should be kept in RAM, et cetera). - noforwards = 0x400, - /// Indicates whether the story was edited. - edited = 0x800, - /// Whether this story can only be viewed by our contacts - contacts = 0x1000, - /// Whether this story can only be viewed by a select list of our contacts - selected_contacts = 0x2000, - /// Field has a value - has_media_areas = 0x4000, - /// Field has a value - has_sent_reaction = 0x8000, - /// indicates whether we sent this story. - out_ = 0x10000, - /// Field has a value - has_fwd_from = 0x20000, - /// Field has a value - has_from_id = 0x40000, - /// Field has a value - has_albums = 0x80000, - } - - /// ID of the story. - public override int ID => id; - } - - /// Full list of active (or active and hidden) stories. See Derived classes: , - public abstract partial class Stories_AllStoriesBase : IObject { } - /// The list of active (or active and hidden) stories has not changed. See - [TLDef(0x1158FE3E)] - public sealed partial class Stories_AllStoriesNotModified : Stories_AllStoriesBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// State to use to ask for updates - public string state; - /// Current stealth mode information - public StoriesStealthMode stealth_mode; - - [Flags] public enum Flags : uint - { - } - } - /// Full list of active (or active and hidden) stories. See - [TLDef(0x6EFC5E81)] - public sealed partial class Stories_AllStories : Stories_AllStoriesBase, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of active (or active and hidden) stories - public int count; - /// State to use for pagination - public string state; - /// Stories - public PeerStories[] peer_stories; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - /// Current stealth mode information - public StoriesStealthMode stealth_mode; - - [Flags] public enum Flags : uint - { - /// Whether more results can be fetched as described here ». - has_more = 0x1, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// List of stories See - [TLDef(0x63C3DD0A)] - public sealed partial class Stories_Stories : IObject, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of stories that can be fetched - public int count; - /// Stories - public StoryItemBase[] stories; - /// IDs of pinned stories. - [IfFlag(0)] public int[] pinned_to_top; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_pinned_to_top = 0x1, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Story view date and reaction information See Derived classes: , , - public abstract partial class StoryViewBase : IObject { } - /// Story view date and reaction information See - [TLDef(0xB0BDEAC5)] - public sealed partial class StoryView : StoryViewBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The user that viewed the story - public long user_id; - /// When did the user view the story - public DateTime date; - /// If present, contains the reaction that the user left on the story - [IfFlag(2)] public Reaction reaction; - - [Flags] public enum Flags : uint - { - /// Whether we have completely blocked this user, including from viewing more of our stories. - blocked = 0x1, - /// Whether we have blocked this user from viewing more of our stories. - blocked_my_stories_from = 0x2, - /// Field has a value - has_reaction = 0x4, - } - } - /// A certain peer has forwarded the story as a message to a public chat or channel. See - [TLDef(0x9083670B)] - public sealed partial class StoryViewPublicForward : StoryViewBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The message with the forwarded story. - public MessageBase message; - - [Flags] public enum Flags : uint - { - /// Whether we have completely blocked this user, including from viewing more of our stories. - blocked = 0x1, - /// Whether we have blocked this user from viewing more of our stories. - blocked_my_stories_from = 0x2, - } - } - /// A certain peer has reposted the story. See - [TLDef(0xBD74CF49)] - public sealed partial class StoryViewPublicRepost : StoryViewBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The peer that reposted the story. - public Peer peer_id; - /// The reposted story. - public StoryItemBase story; - - [Flags] public enum Flags : uint - { - /// Whether we have completely blocked this user, including from viewing more of our stories. - blocked = 0x1, - /// Whether we have blocked this user from viewing more of our stories. - blocked_my_stories_from = 0x2, - } - } - - /// Reaction and view counters for a story See - [TLDef(0x59D78FC5)] - public sealed partial class Stories_StoryViewsList : IObject, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of results that can be fetched - public int count; - /// Total number of story views - public int views_count; - /// Total number of story forwards/reposts - public int forwards_count; - /// Number of reactions that were added to the story - public int reactions_count; - /// Story view date and reaction information - public StoryViewBase[] views; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - /// Offset for pagination - [IfFlag(0)] public string next_offset; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Reaction and view counters for a list of stories See - [TLDef(0xDE9EED1D)] - public sealed partial class Stories_StoryViews : IObject - { - /// View date and reaction information of multiple stories - public StoryViews[] views; - /// Mentioned users - public Dictionary users; - } - - /// Contains info about a message or story to reply to. See Derived classes: , , - public abstract partial class InputReplyTo : IObject { } - /// Reply to a message. See - [TLDef(0x869FBE10)] - public sealed partial class InputReplyToMessage : InputReplyTo - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The message ID to reply to. - public int reply_to_msg_id; - /// This field must contain the topic ID only when replying to messages in forum topics different from the "General" topic (i.e. reply_to_msg_id is set and reply_to_msg_id != topicID and topicID != 1).
If the replied-to message is deleted before the method finishes execution, the value in this field will be used to send the message to the correct topic, instead of the "General" topic.
- [IfFlag(0)] public int top_msg_id; - /// Used to reply to messages sent to another chat (specified here), can only be used for non-protected chats and messages. - [IfFlag(1)] public InputPeer reply_to_peer_id; - ///
Used to quote-reply to only a certain section (specified here) of the original message. The maximum UTF-8 length for quotes is specified in the quote_length_max config key. - [IfFlag(2)] public string quote_text; - /// Message entities for styled text from the quote_text field. - [IfFlag(3)] public MessageEntity[] quote_entities; - /// Offset of the message quote_text within the original message (in UTF-16 code units). - [IfFlag(4)] public int quote_offset; - /// Must be set to the ID of the topic when replying to a message within a monoforum topic. - [IfFlag(5)] public InputPeer monoforum_peer_id; - /// Can be set to reply to the specified item of a todo list ». - [IfFlag(6)] public int todo_item_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_top_msg_id = 0x1, - /// Field has a value - has_reply_to_peer_id = 0x2, - /// Field has a value - has_quote_text = 0x4, - /// Field has a value - has_quote_entities = 0x8, - /// Field has a value - has_quote_offset = 0x10, - /// Field has a value - has_monoforum_peer_id = 0x20, - /// Field has a value - has_todo_item_id = 0x40, - } - } - /// Reply to a story. See - [TLDef(0x5881323A)] - public sealed partial class InputReplyToStory : InputReplyTo - { - /// Sender of the story - public InputPeer peer; - /// ID of the story to reply to. - public int story_id; - } - /// Used to send messages to a monoforum topic. See - [TLDef(0x69D66C45)] - public sealed partial class InputReplyToMonoForum : InputReplyTo - { - /// The topic ID. - public InputPeer monoforum_peer_id; - } - - /// Represents a story deep link. See - [TLDef(0x3FC9053B)] - public sealed partial class ExportedStoryLink : IObject - { - /// The story deep link. - public string link; - } - - /// Information about the current stealth mode session. See - [TLDef(0x712E27FD)] - public sealed partial class StoriesStealthMode : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The date up to which stealth mode will be active. - [IfFlag(0)] public DateTime active_until_date; - /// The date starting from which the user will be allowed to re-enable stealth mode again. - [IfFlag(1)] public DateTime cooldown_until_date; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_active_until_date = 0x1, - /// Field has a value - has_cooldown_until_date = 0x2, - } - } - - /// Coordinates and size of a clickable rectangular area on top of a story. See - [TLDef(0xCFC9E002)] - public sealed partial class MediaAreaCoordinates : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The abscissa of the rectangle's center, as a percentage of the media width (0-100). - public double x; - /// The ordinate of the rectangle's center, as a percentage of the media height (0-100). - public double y; - /// The width of the rectangle, as a percentage of the media width (0-100). - public double w; - /// The height of the rectangle, as a percentage of the media height (0-100). - public double h; - /// Clockwise rotation angle of the rectangle, in degrees (0-360). - public double rotation; - /// The radius of the rectangle corner rounding, as a percentage of the media width. - [IfFlag(0)] public double radius; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_radius = 0x1, - } - } - - /// Represents a story media area » See Derived classes: , , , , , , , , - public abstract partial class MediaArea : IObject - { - /// The size and location of the media area corresponding to the location sticker on top of the story media. - public MediaAreaCoordinates coordinates; - } - /// Represents a location tag attached to a story, with additional venue information. See - [TLDef(0xBE82DB9C, inheritAt = 0)] - public sealed partial class MediaAreaVenue : MediaArea - { - /// Coordinates of the venue - public GeoPoint geo; - /// Venue name - public string title; - /// Address - public string address; - /// Venue provider: currently only "foursquare" needs to be supported. - public string provider; - /// Venue ID in the provider's database - public string venue_id; - /// Venue type in the provider's database - public string venue_type; - } - /// Represents a location tag attached to a story, with additional venue information. See - [TLDef(0xB282217F, inheritAt = 0)] - public sealed partial class InputMediaAreaVenue : MediaArea - { - /// The query_id from , see here » for more info. - public long query_id; - /// The id of the chosen result, see here » for more info. - public string result_id; - } - /// Represents a geolocation tag attached to a story. See - [TLDef(0xCAD5452D, inheritAt = 1)] - public sealed partial class MediaAreaGeoPoint : MediaArea - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Coordinates of the geolocation tag. - public GeoPoint geo; - /// Optional textual representation of the address. - [IfFlag(0)] public GeoPointAddress address; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_address = 0x1, - } - } - /// Represents a reaction bubble. See - [TLDef(0x14455871, inheritAt = 1)] - public sealed partial class MediaAreaSuggestedReaction : MediaArea - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The reaction that should be sent when this area is clicked. - public Reaction reaction; - - [Flags] public enum Flags : uint - { - /// Whether the reaction bubble has a dark background. - dark = 0x1, - /// Whether the reaction bubble is mirrored (see here » for more info). - flipped = 0x2, - } - } - /// Represents a channel post. See - [TLDef(0x770416AF, inheritAt = 0)] - public sealed partial class MediaAreaChannelPost : MediaArea - { - /// The channel that posted the message - public long channel_id; - /// ID of the channel message - public int msg_id; - } - /// Represents a channel post See - [TLDef(0x2271F2BF, inheritAt = 0)] - public sealed partial class InputMediaAreaChannelPost : MediaArea - { - /// The channel that posted the message - public InputChannelBase channel; - /// ID of the channel message - public int msg_id; - } - /// Represents a URL media area. See - [TLDef(0x37381085, inheritAt = 0)] - public sealed partial class MediaAreaUrl : MediaArea - { - /// URL to open when clicked. - public string url; - } - /// Represents a weather widget ». See - [TLDef(0x49A6549C, inheritAt = 0)] - public sealed partial class MediaAreaWeather : MediaArea - { - /// Weather emoji, should be rendered as an animated emoji. - public string emoji; - /// Temperature in degrees Celsius. - public double temperature_c; - /// ARGB background color. - public int color; - } - /// Represents a collectible gift ». See - [TLDef(0x5787686D, inheritAt = 0)] - public sealed partial class MediaAreaStarGift : MediaArea - { - /// slug from .slug, that can be resolved as specified here ». - public string slug; - } - - /// Stories associated to a peer See - [TLDef(0x9A35E999)] - public sealed partial class PeerStories : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The peer - public Peer peer; - /// If set, contains the ID of the maximum read story - [IfFlag(0)] public int max_read_id; - /// Stories - public StoryItemBase[] stories; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_max_read_id = 0x1, - } - } - - /// Active story list of a specific peer. See - [TLDef(0xCAE68768)] - public sealed partial class Stories_PeerStories : IObject, IPeerResolver - { - /// Stories - public PeerStories stories; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Represents an Instant View webpage. See - [TLDef(0xFD5E12BD)] - public sealed partial class Messages_WebPage : IObject, IPeerResolver - { - /// The instant view webpage. - public WebPageBase webpage; - /// Chats mentioned in the webpage. - public Dictionary chats; - /// Users mentioned in the webpage. - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Contains info about a giveaway/gift option. See - [TLDef(0x257E962B)] - public sealed partial class PremiumGiftCodeOption : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Number of users which will be able to activate the gift codes. - public int users; - /// Duration in months of each gifted Telegram Premium subscription. - public int months; - /// Identifier of the store product associated with the option, official apps only. - [IfFlag(0)] public string store_product; - /// Number of times the store product must be paid - [IfFlag(1)] public int store_quantity; - /// Three-letter ISO 4217 currency code - public string currency; - /// Total price 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). - public long amount; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_store_product = 0x1, - /// Field has a value - has_store_quantity = 0x2, - } - } - - /// Contains info about a Telegram Premium giftcode link. See - [TLDef(0xEB983F8F)] - public sealed partial class Payments_CheckedGiftCode : IObject, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The peer that created the gift code. - [IfFlag(4)] public Peer from_id; - /// Message ID of the giveaway in the channel specified in from_id. - [IfFlag(3)] public int giveaway_msg_id; - /// The destination user of the gift. - [IfFlag(0)] public long to_id; - /// Creation date of the gift code. - public DateTime date; - public int days; - /// When was the giftcode imported, if it was imported. - [IfFlag(1)] public DateTime used_date; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_to_id = 0x1, - /// Field has a value - has_used_date = 0x2, - /// Whether this giftcode was created by a giveaway. - via_giveaway = 0x4, - /// Field has a value - has_giveaway_msg_id = 0x8, - /// Field has a value - has_from_id = 0x10, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Info about a Telegram Premium Giveaway. See Derived classes: , - public abstract partial class Payments_GiveawayInfoBase : IObject - { - /// When was the giveaway started - public virtual DateTime StartDate => default; - } - /// Contains info about an ongoing giveaway. See - [TLDef(0x4367DAA0)] - public sealed partial class Payments_GiveawayInfo : Payments_GiveawayInfoBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// When was the giveaway started - public DateTime start_date; - /// The current user can't participate in the giveaway, because they were already a member of the channel when the giveaway started, and the only_new_subscribers was set when starting the giveaway. - [IfFlag(1)] public DateTime joined_too_early_date; - /// If set, the current user can't participate in the giveaway, because they are an administrator in one of the channels (ID specified in this flag) that created the giveaway. - [IfFlag(2)] public long admin_disallowed_chat_id; - /// If set, the current user can't participate in this giveaway, because their phone number is from the specified disallowed country (specified as a two-letter ISO 3166-1 alpha-2 country code). - [IfFlag(4)] public string disallowed_country; - - [Flags] public enum Flags : uint - { - /// The current user is participating in the giveaway. - participating = 0x1, - /// Field has a value - has_joined_too_early_date = 0x2, - /// Field has a value - has_admin_disallowed_chat_id = 0x4, - /// If set, the giveaway has ended and the results are being prepared. - preparing_results = 0x8, - /// Field has a value - has_disallowed_country = 0x10, - } - - /// When was the giveaway started - public override DateTime StartDate => start_date; - } - /// A giveaway has ended. See - [TLDef(0xE175E66F)] - public sealed partial class Payments_GiveawayInfoResults : Payments_GiveawayInfoBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Start date of the giveaway - public DateTime start_date; - /// If we're one of the winners of this giveaway, contains the Premium gift code, see here » for more info on the full giveaway flow. - [IfFlag(3)] public string gift_code_slug; - /// If we're one of the winners of this Telegram Star giveaway, the number Telegram Stars we won. - [IfFlag(4)] public long stars_prize; - /// End date of the giveaway. May be bigger than the end date specified in parameters of the giveaway. - public DateTime finish_date; - /// Number of winners in the giveaway - public int winners_count; - /// Number of winners, which activated their gift codes. - [IfFlag(2)] public int activated_count; - - [Flags] public enum Flags : uint - { - /// Whether we're one of the winners of this giveaway. - winner = 0x1, - /// Whether the giveaway was canceled and was fully refunded. - refunded = 0x2, - /// Field has a value - has_activated_count = 0x4, - /// Field has a value - has_gift_code_slug = 0x8, - /// Field has a value - has_stars_prize = 0x10, - } - - /// Start date of the giveaway - public override DateTime StartDate => start_date; - } - - /// Contains info about a prepaid giveaway ». See Derived classes: , - public abstract partial class PrepaidGiveawayBase : IObject - { - /// Prepaid giveaway ID. - public virtual long ID => default; - /// Number of given away Telegram Premium subscriptions. - public virtual int Quantity => default; - /// Payment date. - public virtual DateTime Date => default; - } - /// Contains info about a prepaid giveaway ». See - [TLDef(0xB2539D54)] - public sealed partial class PrepaidGiveaway : PrepaidGiveawayBase - { - /// Prepaid giveaway ID. - public long id; - /// Duration in months of each gifted Telegram Premium subscription. - public int months; - /// Number of given away Telegram Premium subscriptions. - public int quantity; - /// Payment date. - public DateTime date; - - /// Prepaid giveaway ID. - public override long ID => id; - /// Number of given away Telegram Premium subscriptions. - public override int Quantity => quantity; - /// Payment date. - public override DateTime Date => date; - } - /// Contains info about a prepaid Telegram Star giveaway ». See - [TLDef(0x9A9D77E0)] - public sealed partial class PrepaidStarsGiveaway : PrepaidGiveawayBase - { - /// Prepaid giveaway ID. - public long id; - /// Number of given away Telegram Stars » - public long stars; - /// Number of giveaway winners - public int quantity; - /// Number of boosts the channel will gain by launching the giveaway. - public int boosts; - /// When was the giveaway paid for - public DateTime date; - - /// Prepaid giveaway ID. - public override long ID => id; - /// Number of giveaway winners - public override int Quantity => quantity; - /// When was the giveaway paid for - public override DateTime Date => date; - } - - /// Info about one or more boosts applied by a specific user. See - [TLDef(0x4B3E14D6)] - public sealed partial class Boost : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Unique ID for this set of boosts. - public string id; - /// ID of the user that applied the boost. - [IfFlag(0)] public long user_id; - /// The message ID of the giveaway - [IfFlag(2)] public int giveaway_msg_id; - /// When was the boost applied - public DateTime date; - /// When does the boost expire - public DateTime expires; - /// The created Telegram Premium gift code, only set if either gift or giveaway are set AND it is either a gift code for the currently logged in user or if it was already claimed. - [IfFlag(4)] public string used_gift_slug; - /// If set, this boost counts as multiplier boosts, otherwise it counts as a single boost. - [IfFlag(5)] public int multiplier; - /// Number of Telegram Stars distributed among the winners of the giveaway. - [IfFlag(6)] public long stars; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_user_id = 0x1, - /// Whether this boost was applied because the channel/supergroup directly gifted a subscription to the user. - gift = 0x2, - /// Whether this boost was applied because the user was chosen in a giveaway started by the channel/supergroup. - giveaway = 0x4, - /// If set, the user hasn't yet invoked Payments_ApplyGiftCode to claim a subscription gifted directly or in a giveaway by the channel. - unclaimed = 0x8, - /// Field has a value - has_used_gift_slug = 0x10, - /// Field has a value - has_multiplier = 0x20, - /// Field has a value - has_stars = 0x40, - } - } - - /// List of boosts that were applied to a peer by multiple users. See - [TLDef(0x86F8613C)] - public sealed partial class Premium_BoostsList : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of results - public int count; - /// Boosts - public Boost[] boosts; - /// Offset that can be used for pagination. - [IfFlag(0)] public string next_offset; - /// Mentioned users - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - } - } - - /// Contains information about a single boost slot ». See - [TLDef(0xC448415C)] - public sealed partial class MyBoost : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Boost slot ID » - public int slot; - /// If set, indicates this slot is currently occupied, i.e. we are boosting this peer.
Note that we can assign multiple boost slots to the same peer.
- [IfFlag(0)] public Peer peer; - /// When (unixtime) we started boosting the peer, 0 otherwise. - public DateTime date; - /// Indicates the (unixtime) expiration date of the boost in peer (0 if peer is not set). - public DateTime expires; - /// If peer is set, indicates the (unixtime) date after which this boost can be reassigned to another channel. - [IfFlag(1)] public DateTime cooldown_until_date; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_peer = 0x1, - /// Field has a value - has_cooldown_until_date = 0x2, - } - } - - /// A list of peers we are currently boosting, and how many boost slots we have left. See - [TLDef(0x9AE228E2)] - public sealed partial class Premium_MyBoosts : IObject, IPeerResolver - { - /// Info about boosted peers and remaining boost slots. - public MyBoost[] my_boosts; - /// Referenced chats - public Dictionary chats; - /// Referenced users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Contains info about the current boost status of a peer. See - [TLDef(0x4959427A)] - public sealed partial class Premium_BoostsStatus : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The current boost level of the channel/supergroup. - public int level; - /// The number of boosts acquired so far in the current level. - public int current_level_boosts; - /// Total number of boosts acquired so far. - public int boosts; - /// The number of boosts acquired from created Telegram Premium gift codes and giveaways; only returned to channel/supergroup admins. - [IfFlag(4)] public int gift_boosts; - /// Total number of boosts needed to reach the next level; if absent, the next level isn't available. - [IfFlag(0)] public int next_level_boosts; - /// Only returned to channel/supergroup admins: contains the approximated number of Premium users subscribed to the channel/supergroup, related to the total number of subscribers. - [IfFlag(1)] public StatsPercentValue premium_audience; - /// Boost deep link » that can be used to boost the chat. - public string boost_url; - /// A list of prepaid giveaways available for the chat; only returned to channel/supergroup admins. - [IfFlag(3)] public PrepaidGiveawayBase[] prepaid_giveaways; - /// Indicates which of our boost slots we've assigned to this peer (populated if my_boost is set). - [IfFlag(2)] public int[] my_boost_slots; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_level_boosts = 0x1, - /// Field has a value - has_premium_audience = 0x2, - /// Whether we're currently boosting this channel/supergroup, my_boost_slots will also be set. - my_boost = 0x4, - /// Field has a value - has_prepaid_giveaways = 0x8, - /// Field has a value - has_gift_boosts = 0x10, - } - } - - /// Contains info about the original poster of a reposted story. See - [TLDef(0xB826E150)] - public sealed partial class StoryFwdHeader : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Peer that originally posted the story; will be empty for stories forwarded from a user with forwards privacy enabled, in which case from_name will be set, instead. - [IfFlag(0)] public Peer from; - /// Will be set for stories forwarded from a user with forwards privacy enabled, in which case from will also be empty. - [IfFlag(1)] public string from_name; - /// , contains the story ID - [IfFlag(2)] public int story_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_from = 0x1, - /// Field has a value - has_from_name = 0x2, - /// Field has a value - has_story_id = 0x4, - /// Whether the story media was modified before reposting it (for example by overlaying a round video with a reaction). - modified = 0x8, - } - } - - /// Interaction counters See Derived classes: , - public abstract partial class PostInteractionCounters : IObject - { - /// Number of views - public int views; - /// Number of forwards to public channels - public int forwards; - /// Number of reactions - public int reactions; - } - /// Interaction counters for a message. See - [TLDef(0xE7058E7F)] - public sealed partial class PostInteractionCountersMessage : PostInteractionCounters - { - /// Message ID - public int msg_id; - } - /// Interaction counters for a story. See - [TLDef(0x8A480E27)] - public sealed partial class PostInteractionCountersStory : PostInteractionCounters - { - /// Story ID - public int story_id; - } - - /// Contains statistics about a story. See - [TLDef(0x50CD067C)] - public sealed partial class Stats_StoryStats : IObject - { - /// A graph containing the number of story views and shares - public StatsGraphBase views_graph; - /// A bar graph containing the number of story reactions categorized by "emotion" (i.e. Positive, Negative, Other, etc...) - public StatsGraphBase reactions_by_emotion_graph; - } - - /// Contains info about the forwards of a story as a message to public chats and reposts by public channels. See Derived classes: , - public abstract partial class PublicForward : IObject { } - /// Contains info about a forward of a story as a message. See - [TLDef(0x01F2BF4A)] - public sealed partial class PublicForwardMessage : PublicForward - { - /// Info about the message with the reposted story. - public MessageBase message; - } - /// Contains info about a forward of a story as a repost by a public channel. See - [TLDef(0xEDF3ADD0)] - public sealed partial class PublicForwardStory : PublicForward - { - /// The channel that reposted the story. - public Peer peer; - /// The reposted story (may be different from the original story). - public StoryItemBase story; - } - - /// Contains info about the forwards of a story as a message to public chats and reposts by public channels. See - [TLDef(0x93037E20)] - public sealed partial class Stats_PublicForwards : IObject, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of results - public int count; - /// Info about the forwards of a story. - public PublicForward[] forwards; - /// Offset used for pagination. - [IfFlag(0)] public string next_offset; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Represents a color palette ». See Derived classes: , , - public abstract partial class PeerColorBase : IObject { } - /// Represents a color palette ». See - [TLDef(0xB54B5ACF)] - public sealed partial class PeerColor : PeerColorBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Color palette ID, see here » for more info; if not set, the default palette should be used. - [IfFlag(0)] public int color; - /// Optional custom emoji ID used to generate the pattern. - [IfFlag(1)] public long background_emoji_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_color = 0x1, - /// Field has a value - has_background_emoji_id = 0x2, - } - } - /// See - [TLDef(0xB9C0639A)] - public sealed partial class PeerColorCollectible : PeerColorBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - public long collectible_id; - public long gift_emoji_id; - public long background_emoji_id; - public int accent_color; - public int[] colors; - [IfFlag(0)] public int dark_accent_color; - [IfFlag(1)] public int[] dark_colors; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_dark_accent_color = 0x1, - /// Field has a value - has_dark_colors = 0x2, - } - } - /// See - [TLDef(0xB8EA86A9)] - public sealed partial class InputPeerColorCollectible : PeerColorBase - { - public long collectible_id; - } - - /// Contains info about a color palette ». See Derived classes: , - public abstract partial class Help_PeerColorSetBase : IObject { } - /// Represents a color palette that can be used in message accents ». See - [TLDef(0x26219A58)] - public sealed partial class Help_PeerColorSet : Help_PeerColorSetBase - { - /// A list of 1-3 colors in RGB format, describing the accent color. - public int[] colors; - } - /// Represents a color palette that can be used in profile pages ». See - [TLDef(0x767D61EB)] - public sealed partial class Help_PeerColorProfileSet : Help_PeerColorSetBase - { - /// A list of 1-2 colors in RGB format, shown in the color palette settings to describe the current palette. - public int[] palette_colors; - /// A list of 1-2 colors in RGB format describing the colors used to generate the actual background used in the profile page. - public int[] bg_colors; - /// A list of 2 colors in RGB format describing the colors of the gradient used for the unread active story indicator around the profile photo. - public int[] story_colors; - } - - /// Contains info about a color palette ». See - [TLDef(0xADEC6EBE)] - public sealed partial class Help_PeerColorOption : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Palette ID. - public int color_id; - /// Light mode palette.
Will be empty for IDs 0 to 6 inclusive, in which case a palette containing a single color from the following colors should be used: red, orange, violet, green, cyan, blue, pink for indexes 0 to 6 (i.e. the same colors used for randomized fallback
message accent colors).
- [IfFlag(1)] public Help_PeerColorSetBase colors; - /// Dark mode palette. Optional, defaults to the palette in colors (or the autogenerated palette for IDs 0 to 6) if absent. - [IfFlag(2)] public Help_PeerColorSetBase dark_colors; - /// Channels can use this palette only after reaching at least the boost level specified in this field. - [IfFlag(3)] public int channel_min_level; - /// Supergroups can use this palette only after reaching at least the boost level specified in this field. - [IfFlag(4)] public int group_min_level; - - [Flags] public enum Flags : uint - { - /// Whether this palette should not be displayed as an option to the user when choosing a palette to apply to profile pages or message accents. - hidden = 0x1, - /// Field has a value - has_colors = 0x2, - /// Field has a value - has_dark_colors = 0x4, - /// Field has a value - has_channel_min_level = 0x8, - /// Field has a value - has_group_min_level = 0x10, - } - } - - /// Contains info about multiple color palettes ». See - /// a value means help.peerColorsNotModified - [TLDef(0x00F8ED08)] - public sealed partial class Help_PeerColors : IObject - { - /// Hash used for caching, for more info click here - public int hash; - /// Usable color palettes. - public Help_PeerColorOption[] colors; - } - - /// How a certain peer reacted to or interacted with a story See Derived classes: , , - public abstract partial class StoryReactionBase : IObject { } - /// How a certain peer reacted to a story See - [TLDef(0x6090D6D5)] - public sealed partial class StoryReaction : StoryReactionBase - { - /// The peer - public Peer peer_id; - /// Reaction date - public DateTime date; - /// The reaction - public Reaction reaction; - } - /// A certain peer has forwarded the story as a message to a public chat or channel. See - [TLDef(0xBBAB2643)] - public sealed partial class StoryReactionPublicForward : StoryReactionBase - { - /// The message with the forwarded story. - public MessageBase message; - } - /// A certain peer has reposted the story. See - [TLDef(0xCFCD0F13)] - public sealed partial class StoryReactionPublicRepost : StoryReactionBase - { - /// The peer that reposted the story. - public Peer peer_id; - /// The reposted story. - public StoryItemBase story; - } - - /// List of peers that reacted to or intercated with a specific story See - [TLDef(0xAA5F789C)] - public sealed partial class Stories_StoryReactionsList : IObject, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of reactions matching query - public int count; - /// List of peers that reacted to or interacted with a specific story - public StoryReactionBase[] reactions; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - /// If set, indicates the next offset to use to load more results by invoking Stories_GetStoryReactionsList. - [IfFlag(0)] public string next_offset; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Represents a saved message dialog ». See Derived classes: , - public abstract partial class SavedDialogBase : IObject - { - /// The dialog - public virtual Peer Peer => default; - /// The latest message ID - public virtual int TopMessage => default; - } - /// Represents a saved dialog ». See - [TLDef(0xBD87CB6C)] - public sealed partial class SavedDialog : SavedDialogBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The dialog - public Peer peer; - /// The latest message ID - public int top_message; - - [Flags] public enum Flags : uint - { - /// Is the dialog pinned - pinned = 0x4, - } - - /// The dialog - public override Peer Peer => peer; - /// The latest message ID - public override int TopMessage => top_message; - } - /// Represents a monoforum topic ». See - [TLDef(0x64407EA7)] - public sealed partial class MonoForumDialog : SavedDialogBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The peer associated to the topic, AKA the topic ID. - public Peer peer; - /// The latest message ID - public int top_message; - /// Position up to which all incoming messages are read. - public int read_inbox_max_id; - /// Position up to which all outgoing messages are read. - public int read_outbox_max_id; - /// Number of unread messages. - public int unread_count; - /// Number of unread reactions. - public int unread_reactions_count; - /// A pending message draft. - [IfFlag(1)] public DraftMessageBase draft; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_draft = 0x2, - /// Whether this topic has a manually set (with Messages_MarkDialogUnread) unread mark. - unread_mark = 0x8, - /// If set, an admin has exempted this peer from payment to send messages using Account_ToggleNoPaidMessagesException. - nopaid_messages_exception = 0x10, - } - - /// The peer associated to the topic, AKA the topic ID. - public override Peer Peer => peer; - /// The latest message ID - public override int TopMessage => top_message; - } - - /// Represents some saved message dialogs ». See Derived classes: , , - public abstract partial class Messages_SavedDialogsBase : IObject - { - /// Saved message dialogs ». - public virtual SavedDialogBase[] Dialogs => default; - /// List of last messages from each saved dialog - public virtual MessageBase[] Messages => default; - /// Mentioned chats - public virtual Dictionary Chats => default; - /// Mentioned users - public virtual Dictionary Users => default; - } - /// Represents some saved message dialogs ». See - [TLDef(0xF83AE221)] - public partial class Messages_SavedDialogs : Messages_SavedDialogsBase, IPeerResolver - { - /// Saved message dialogs ». - public SavedDialogBase[] dialogs; - /// List of last messages from each saved dialog - public MessageBase[] messages; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - - /// Saved message dialogs ». - public override SavedDialogBase[] Dialogs => dialogs; - /// List of last messages from each saved dialog - public override MessageBase[] Messages => messages; - /// Mentioned chats - public override Dictionary Chats => chats; - /// Mentioned users - public override Dictionary Users => users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - /// Incomplete list of saved message dialogs » with messages and auxiliary data. See - [TLDef(0x44BA9DD9)] - public sealed partial class Messages_SavedDialogsSlice : Messages_SavedDialogs - { - /// Total number of saved message dialogs - public int count; - } - /// The saved dialogs haven't changed See - [TLDef(0xC01F6FE8)] - public sealed partial class Messages_SavedDialogsNotModified : Messages_SavedDialogsBase - { - /// Number of saved dialogs found server-side by the query - public int count; - } - - /// Info about a saved message reaction tag ». See - [TLDef(0xCB6FF828)] - public sealed partial class SavedReactionTag : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Reaction associated to the tag. - public Reaction reaction; - /// Custom tag name assigned by the user (max 12 UTF-8 chars). - [IfFlag(0)] public string title; - /// Number of messages tagged with this tag. - public int count; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_title = 0x1, - } - } - - /// List of reaction tag » names assigned by the user. See - /// a value means messages.savedReactionTagsNotModified - [TLDef(0x3259950A)] - public sealed partial class Messages_SavedReactionTags : IObject - { - /// Saved reaction tags. - public SavedReactionTag[] tags; - /// Hash used for caching, for more info click here. Can also be manually regenerated, if needed, using the custom algorithm specified here ». - public long hash; - } - - /// Exact read date of a private message we sent to another user. See - [TLDef(0x3BB842AC)] - public sealed partial class OutboxReadDate : IObject - { - /// UNIX timestamp with the read date. - public DateTime date; - } - - /// SMS jobs eligibility See Derived classes: - public abstract partial class Smsjobs_EligibilityToJoin : IObject { } - /// SMS jobs eligibility See - [TLDef(0xDC8B44CF)] - public sealed partial class Smsjobs_EligibleToJoin : Smsjobs_EligibilityToJoin - { - /// Terms of service URL - public string terms_url; - /// Monthly sent SMSes - public int monthly_sent_sms; - } - - /// Status See - [TLDef(0x2AEE9191)] - public sealed partial class Smsjobs_Status : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Recently sent - public int recent_sent; - /// Since - public int recent_since; - /// Remaining - public int recent_remains; - /// Total sent - public int total_sent; - /// Total since - public int total_since; - /// Last gift deep link - [IfFlag(1)] public string last_gift_slug; - /// Terms of service URL - public string terms_url; - - [Flags] public enum Flags : uint - { - /// Allow international numbers - allow_international = 0x1, - /// Field has a value - has_last_gift_slug = 0x2, - } - } - - /// Info about an SMS job. See - [TLDef(0xE6A1EEB8)] - public sealed partial class SmsJob : IObject - { - /// Job ID - public string job_id; - /// Destination phone number - public string phone_number; - /// Text - public string text; - } - - /// A time interval, indicating the opening hours of a business. See - [TLDef(0x120B1AB9)] - public sealed partial class BusinessWeeklyOpen : IObject - { - /// Start minute in minutes of the week, 0 to 7*24*60 inclusively. - public int start_minute; - /// End minute in minutes of the week, 1 to 8*24*60 inclusively (8 and not 7 because this allows to specify intervals that, for example, start on Sunday 21:00 and end on Monday 04:00 (6*24*60+21*60 to 7*24*60+4*60) without passing an invalid end_minute < start_minute). See here » for more info. - public int end_minute; - } - - /// Specifies a set of Telegram Business opening hours. See - [TLDef(0x8C92B098)] - public sealed partial class BusinessWorkHours : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// An ID of one of the timezones returned by Help_GetTimezonesList.
The timezone ID is contained .id, a human-readable, localized name of the timezone is available in .name and the .utc_offset field contains the UTC offset in seconds, which may be displayed in hh:mm format by the client together with the human-readable name (i.e. $name UTC -01:00).
- public string timezone_id; - /// A list of time intervals (max 28) represented by businessWeeklyOpen », indicating the opening hours of their business. - public BusinessWeeklyOpen[] weekly_open; - - [Flags] public enum Flags : uint - { - /// Ignored if set while invoking Account_UpdateBusinessWorkHours, only returned by the server in .business_work_hours, indicating whether the business is currently open according to the current time and the values in weekly_open and timezone. - open_now = 0x1, - } - } - - ///
Represents the location of a Telegram Business ». See - [TLDef(0xAC5C1AF7)] - public sealed partial class BusinessLocation : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Geographical coordinates (optional). - [IfFlag(0)] public GeoPoint geo_point; - /// Textual description of the address (mandatory). - public string address; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_geo_point = 0x1, - } - } - - /// Specifies the chats that can receive Telegram Business away » and greeting » messages. See - [TLDef(0x6F8B32AA)] - public sealed partial class InputBusinessRecipients : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Only private chats with the specified users. - [IfFlag(4)] public InputUserBase[] users; - - [Flags] public enum Flags : uint - { - /// All existing private chats. - existing_chats = 0x1, - /// All new private chats. - new_chats = 0x2, - /// All private chats with contacts. - contacts = 0x4, - /// All private chats with non-contacts. - non_contacts = 0x8, - /// Field has a value - has_users = 0x10, - /// If set, inverts the selection. - exclude_selected = 0x20, - } - } - - /// Specifies the chats that can receive Telegram Business away » and greeting » messages. See - [TLDef(0x21108FF7)] - public sealed partial class BusinessRecipients : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Only private chats with the specified users. - [IfFlag(4)] public long[] users; - - [Flags] public enum Flags : uint - { - /// All existing private chats. - existing_chats = 0x1, - /// All new private chats. - new_chats = 0x2, - /// All private chats with contacts. - contacts = 0x4, - /// All private chats with non-contacts. - non_contacts = 0x8, - /// Field has a value - has_users = 0x10, - /// If set, inverts the selection. - exclude_selected = 0x20, - } - } - - /// Specifies when should the Telegram Business away messages be sent. See Derived classes: , , - public abstract partial class BusinessAwayMessageSchedule : IObject { } - /// Always send Telegram Business away messages to users writing to us in private. See - [TLDef(0xC9B9E2B9)] - public sealed partial class BusinessAwayMessageScheduleAlways : BusinessAwayMessageSchedule { } - /// Send Telegram Business away messages to users writing to us in private outside of the configured Telegram Business working hours. See - [TLDef(0xC3F2F501)] - public sealed partial class BusinessAwayMessageScheduleOutsideWorkHours : BusinessAwayMessageSchedule { } - /// Send Telegram Business away messages to users writing to us in private in the specified time span. See - [TLDef(0xCC4D9ECC)] - public sealed partial class BusinessAwayMessageScheduleCustom : BusinessAwayMessageSchedule - { - /// Start date (UNIX timestamp). - public DateTime start_date; - /// End date (UNIX timestamp). - public DateTime end_date; - } - - /// Describes a Telegram Business greeting, automatically sent to new users writing to us in private for the first time, or after a certain inactivity period. See - [TLDef(0x0194CB3B)] - public sealed partial class InputBusinessGreetingMessage : IObject - { - /// ID of a quick reply shorcut, containing the greeting messages to send, see here » for more info. - public int shortcut_id; - /// Allowed recipients for the greeting messages. - public InputBusinessRecipients recipients; - /// The number of days after which a private chat will be considered as inactive; currently, must be one of 7, 14, 21, or 28. - public int no_activity_days; - } - - /// Describes a Telegram Business greeting, automatically sent to new users writing to us in private for the first time, or after a certain inactivity period. See - [TLDef(0xE519ABAB)] - public sealed partial class BusinessGreetingMessage : IObject - { - /// ID of a quick reply shorcut, containing the greeting messages to send, see here » for more info. - public int shortcut_id; - /// Allowed recipients for the greeting messages. - public BusinessRecipients recipients; - /// The number of days after which a private chat will be considered as inactive; currently, must be one of 7, 14, 21, or 28. - public int no_activity_days; - } - - /// Describes a Telegram Business away message, automatically sent to users writing to us when we're offline, during closing hours, while we're on vacation, or in some other custom time period when we cannot immediately answer to the user. See - [TLDef(0x832175E0)] - public sealed partial class InputBusinessAwayMessage : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of a quick reply shorcut, containing the away messages to send, see here » for more info. - public int shortcut_id; - /// Specifies when should the away messages be sent. - public BusinessAwayMessageSchedule schedule; - /// Allowed recipients for the away messages. - public InputBusinessRecipients recipients; - - [Flags] public enum Flags : uint - { - /// If set, the messages will not be sent if the account was online in the last 10 minutes. - offline_only = 0x1, - } - } - - /// Describes a Telegram Business away message, automatically sent to users writing to us when we're offline, during closing hours, while we're on vacation, or in some other custom time period when we cannot immediately answer to the user. See - [TLDef(0xEF156A5C)] - public sealed partial class BusinessAwayMessage : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of a quick reply shorcut, containing the away messages to send, see here » for more info. - public int shortcut_id; - /// Specifies when should the away messages be sent. - public BusinessAwayMessageSchedule schedule; - /// Allowed recipients for the away messages. - public BusinessRecipients recipients; - - [Flags] public enum Flags : uint - { - /// If set, the messages will not be sent if the account was online in the last 10 minutes. - offline_only = 0x1, - } - } - - /// Timezone information. See - [TLDef(0xFF9289F5)] - public sealed partial class Timezone : IObject - { - /// Unique timezone ID. - public string id; - /// Human-readable and localized timezone name. - public string name; - /// UTC offset in seconds, which may be displayed in hh:mm format by the client together with the human-readable name (i.e. $name UTC -01:00). - public int utc_offset; - } - - /// Timezone information that may be used elsewhere in the API, such as to set Telegram Business opening hours ». See - /// a value means help.timezonesListNotModified - [TLDef(0x7B74ED71)] - public sealed partial class Help_TimezonesList : IObject - { - /// Timezones - public Timezone[] timezones; - /// Hash used for caching, for more info click here - public int hash; - } - - /// A quick reply shortcut. See - [TLDef(0x0697102B)] - public sealed partial class QuickReply : IObject - { - /// Unique shortcut ID. - public int shortcut_id; - /// Shortcut name. - public string shortcut; - /// ID of the last message in the shortcut. - public int top_message; - /// Total number of messages in the shortcut. - public int count; - } - - /// Represents a quick reply shortcut ». See Derived classes: , - public abstract partial class InputQuickReplyShortcutBase : IObject { } - /// Selects a quick reply shortcut by name. See - [TLDef(0x24596D41)] - public sealed partial class InputQuickReplyShortcut : InputQuickReplyShortcutBase - { - /// Shortcut name. - public string shortcut; - } - /// Selects a quick reply shortcut by its numeric ID. See - [TLDef(0x01190CF1)] - public sealed partial class InputQuickReplyShortcutId : InputQuickReplyShortcutBase - { - /// Shortcut ID. - public int shortcut_id; - } - - /// Info about quick reply shortcuts ». See - /// a value means messages.quickRepliesNotModified - [TLDef(0xC68D6695)] - public sealed partial class Messages_QuickReplies : IObject, IPeerResolver - { - /// Quick reply shortcuts. - public QuickReply[] quick_replies; - /// Messages mentioned in quick_replies. - public MessageBase[] messages; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Contains info about a connected business bot ». See - [TLDef(0xCD64636C)] - public sealed partial class ConnectedBot : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of the connected bot - public long bot_id; - /// Specifies the private chats that a connected business bot » may receive messages and interact with.
- public BusinessBotRecipients recipients; - /// Business bot rights. - public BusinessBotRights rights; - - [Flags] public enum Flags : uint - { - } - } - - /// Info about currently connected business bots. See - [TLDef(0x17D7F87B)] - public sealed partial class Account_ConnectedBots : IObject - { - /// Info about the connected bots - public ConnectedBot[] connected_bots; - /// Bot information - public Dictionary users; - } - - /// Folder and folder tags information See - [TLDef(0x2AD93719)] - public sealed partial class Messages_DialogFilters : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Folders. - public DialogFilterBase[] filters; - - [Flags] public enum Flags : uint - { - /// Whether folder tags are enabled. - tags_enabled = 0x1, - } - } - - /// Birthday information for a user. See - [TLDef(0x6C8E1E06)] - public sealed partial class Birthday : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Birth day - public int day; - /// Birth month - public int month; - /// (Optional) birth year. - [IfFlag(0)] public int year; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_year = 0x1, - } - } - - /// Contains info about a bot business connection. See - [TLDef(0x8F34B2F5)] - public sealed partial class BotBusinessConnection : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Business connection ID, used to identify messages coming from the connection and to reply to them as specified here ». - public string connection_id; - /// ID of the user that the bot is connected to via this connection. - public long user_id; - /// ID of the datacenter where to send queries wrapped in a InvokeWithBusinessConnection as specified here ». - public int dc_id; - /// When was the connection created. - public DateTime date; - /// Business bot rights. - [IfFlag(2)] public BusinessBotRights rights; - - [Flags] public enum Flags : uint - { - /// Whether this business connection is currently disabled - disabled = 0x2, - /// Field has a value - has_rights = 0x4, - } - } - - /// Telegram Business introduction ». See - [TLDef(0x09C469CD)] - public sealed partial class InputBusinessIntro : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Title of the introduction message - public string title; - /// Profile introduction - public string description; - /// Optional introduction sticker. - [IfFlag(0)] public InputDocument sticker; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_sticker = 0x1, - } - } - - /// Telegram Business introduction ». See - [TLDef(0x5A0A066D)] - public sealed partial class BusinessIntro : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Title of the introduction message (max intro_title_length_limit » UTF-8 characters). - public string title; - /// Profile introduction (max intro_description_length_limit » UTF-8 characters). - public string description; - /// Optional introduction sticker. - [IfFlag(0)] public DocumentBase sticker; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_sticker = 0x1, - } - } - - /// The list of stickersets owned by the current account ». See - [TLDef(0xFAFF629D)] - public sealed partial class Messages_MyStickers : IObject - { - /// Total number of owned stickersets. - public int count; - /// Stickersets - public StickerSetCoveredBase[] sets; - } - - /// Represents a Fragment collectible ». See Derived classes: , - public abstract partial class InputCollectible : IObject { } - /// Represents a username fragment collectible See - [TLDef(0xE39460A9)] - public sealed partial class InputCollectibleUsername : InputCollectible - { - /// Username - public string username; - } - /// Represents a phone number fragment collectible See - [TLDef(0xA2E214A4)] - public sealed partial class InputCollectiblePhone : InputCollectible - { - /// Phone number - public string phone; - } - - /// Info about a fragment collectible. See - [TLDef(0x6EBDFF91)] - public sealed partial class Fragment_CollectibleInfo : IObject - { - /// Purchase date (unixtime) - public DateTime purchase_date; - /// Three-letter ISO 4217 currency code for amount - public string currency; - /// Total price 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). - public long amount; - /// Cryptocurrency name. - public string crypto_currency; - /// Price, in the smallest units of the cryptocurrency. - public long crypto_amount; - /// Fragment URL with more info about the collectible - public string url; - } - - /// Specifies the private chats that a connected business bot » may interact with. See - [TLDef(0xC4E5921E)] - public sealed partial class InputBusinessBotRecipients : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Explicitly selected private chats. - [IfFlag(4)] public InputUserBase[] users; - /// Identifiers of private chats that are always excluded. - [IfFlag(6)] public InputUserBase[] exclude_users; - - [Flags] public enum Flags : uint - { - /// Selects all existing private chats. - existing_chats = 0x1, - /// Selects all new private chats. - new_chats = 0x2, - /// Selects all private chats with contacts. - contacts = 0x4, - /// Selects all private chats with non-contacts. - non_contacts = 0x8, - /// Field has a value - has_users = 0x10, - /// If set, then all private chats except the ones selected by existing_chats, new_chats, contacts, non_contacts and users are chosen.
Note that if this flag is set, any values passed in exclude_users will be merged and moved into users by the server.
- exclude_selected = 0x20, - /// Field has a value - has_exclude_users = 0x40, - } - } - - ///
Specifies the private chats that a connected business bot » may receive messages and interact with. See - [TLDef(0xB88CF373)] - public sealed partial class BusinessBotRecipients : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Explicitly selected private chats. - [IfFlag(4)] public long[] users; - /// Identifiers of private chats that are always excluded. - [IfFlag(6)] public long[] exclude_users; - - [Flags] public enum Flags : uint - { - /// Selects all existing private chats. - existing_chats = 0x1, - /// Selects all new private chats. - new_chats = 0x2, - /// Selects all private chats with contacts. - contacts = 0x4, - /// Selects all private chats with non-contacts. - non_contacts = 0x8, - /// Field has a value - has_users = 0x10, - /// If set, then all private chats except the ones selected by existing_chats, new_chats, contacts, non_contacts and users are chosen.
Note that if this flag is set, any values passed in exclude_users will be merged and moved into users by the server, thus exclude_users will always be empty.
- exclude_selected = 0x20, - /// Field has a value - has_exclude_users = 0x40, - } - } - - ///
Birthday information of a contact. See - [TLDef(0x1D998733)] - public sealed partial class ContactBirthday : IObject - { - /// User ID. - public long contact_id; - /// Birthday information. - public Birthday birthday; - } - - /// Birthday information of our contacts. See - [TLDef(0x114FF30D)] - public sealed partial class Contacts_ContactBirthdays : IObject - { - /// Birthday info - public ContactBirthday[] contacts; - /// User information - public Dictionary users; - } - - /// Info about why a specific user could not be invited ». See - [TLDef(0x628C9224)] - public sealed partial class MissingInvitee : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of the user. If neither of the flags below are set, we could not add the user because of their privacy settings, and we can create and directly share an invite link with them using a normal message, instead. - public long user_id; - - [Flags] public enum Flags : uint - { - /// If set, we could not add the user only because the current account needs to purchase a Telegram Premium subscription to complete the operation. - premium_would_allow_invite = 0x1, - /// If set, we could not add the user because of their privacy settings, and additionally, the current account needs to purchase a Telegram Premium subscription to directly share an invite link with the user via a private message. - premium_required_for_pm = 0x2, - } - } - - /// Contains info about successfully or unsuccessfully invited » users. See - [TLDef(0x7F5DEFA6)] - public sealed partial class Messages_InvitedUsers : IObject - { - /// List of updates about successfully invited users (and eventually info about the created group) - public UpdatesBase updates; - /// A list of users that could not be invited, along with the reason why they couldn't be invited. - public MissingInvitee[] missing_invitees; - } - - /// Contains info about a business chat deep link » to be created by the current account. See - [TLDef(0x11679FA7)] - public sealed partial class InputBusinessChatLink : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Message to pre-fill in the message input field. - public string message; - /// Message entities for styled text - [IfFlag(0)] public MessageEntity[] entities; - /// Human-readable name of the link, to simplify management in the UI (only visible to the creator of the link). - [IfFlag(1)] public string title; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_entities = 0x1, - /// Field has a value - has_title = 0x2, - } - } - - /// Contains info about a business chat deep link » created by the current account. See - [TLDef(0xB4AE666F)] - public sealed partial class BusinessChatLink : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Business chat deep link. - public string link; - /// Message to pre-fill in the message input field. - public string message; - /// Message entities for styled text - [IfFlag(0)] public MessageEntity[] entities; - /// Human-readable name of the link, to simplify management in the UI (only visible to the creator of the link). - [IfFlag(1)] public string title; - /// Number of times the link was resolved (clicked/scanned/etc...). - public int views; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_entities = 0x1, - /// Field has a value - has_title = 0x2, - } - } - - /// Contains info about business chat deep links » created by the current account. See - [TLDef(0xEC43A2D1)] - public sealed partial class Account_BusinessChatLinks : IObject, IPeerResolver - { - /// Links - public BusinessChatLink[] links; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Contains info about a single resolved business chat deep link ». See - [TLDef(0x9A23AF21)] - public sealed partial class Account_ResolvedBusinessChatLinks : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Destination peer - public Peer peer; - /// Message to pre-fill in the message input field. - public string message; - /// Message entities for styled text - [IfFlag(0)] public MessageEntity[] entities; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_entities = 0x1, - } - /// returns a or for the result - public IPeerInfo UserOrChat => peer?.UserOrChat(users, chats); - } - - /// Info about a peer, shared by a user with the currently logged in bot using Messages_SendBotRequestedPeer. See Derived classes: , , - public abstract partial class RequestedPeer : IObject { } - /// Info about a user, shared by a user with the currently logged in bot using Messages_SendBotRequestedPeer. See - [TLDef(0xD62FF46A)] - public sealed partial class RequestedPeerUser : RequestedPeer - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// User ID. - public long user_id; - /// First name. - [IfFlag(0)] public string first_name; - /// Last name. - [IfFlag(0)] public string last_name; - /// Username. - [IfFlag(1)] public string username; - /// Profile photo. - [IfFlag(2)] public PhotoBase photo; - - [Flags] public enum Flags : uint - { - /// Fields and have a value - has_first_name = 0x1, - /// Field has a value - has_username = 0x2, - /// Field has a value - has_photo = 0x4, - } - } - /// Info about a chat, shared by a user with the currently logged in bot using Messages_SendBotRequestedPeer. See - [TLDef(0x7307544F)] - public sealed partial class RequestedPeerChat : RequestedPeer - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Chat ID. - public long chat_id; - /// Chat title. - [IfFlag(0)] public string title; - /// Chat photo. - [IfFlag(2)] public PhotoBase photo; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_title = 0x1, - /// Field has a value - has_photo = 0x4, - } - } - /// Info about a channel/supergroup, shared by a user with the currently logged in bot using Messages_SendBotRequestedPeer. See - [TLDef(0x8BA403E4)] - public sealed partial class RequestedPeerChannel : RequestedPeer - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Channel/supergroup ID. - public long channel_id; - /// Channel/supergroup title. - [IfFlag(0)] public string title; - /// Channel/supergroup username. - [IfFlag(1)] public string username; - /// Channel/supergroup photo. - [IfFlag(2)] public PhotoBase photo; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_title = 0x1, - /// Field has a value - has_username = 0x2, - /// Field has a value - has_photo = 0x4, - } - } - - /// A report option for a sponsored message ». See - [TLDef(0x430D3150)] - public sealed partial class SponsoredMessageReportOption : IObject - { - /// Localized description of the option. - public string text; - /// Option identifier to pass to Messages_ReportSponsoredMessage. - public byte[] option; - } - - /// Status of the method call used to report a sponsored message ». See Derived classes: , , - public abstract partial class Channels_SponsoredMessageReportResult : IObject { } - /// The user must choose a report option from the localized options available in options, and after selection, Messages_ReportSponsoredMessage must be invoked again, passing the option's option field to the option param of the method. See - [TLDef(0x846F9E42)] - public sealed partial class Channels_SponsoredMessageReportResultChooseOption : Channels_SponsoredMessageReportResult - { - /// Title of the option selection popup. - public string title; - /// Localized list of options. - public SponsoredMessageReportOption[] options; - } - /// Sponsored messages were hidden for the user in all chats. See - [TLDef(0x3E3BCF2F)] - public sealed partial class Channels_SponsoredMessageReportResultAdsHidden : Channels_SponsoredMessageReportResult { } - /// The sponsored message was reported successfully. See - [TLDef(0xAD798849)] - public sealed partial class Channels_SponsoredMessageReportResultReported : Channels_SponsoredMessageReportResult { } - - /// Reaction notification settings See - public enum ReactionNotificationsFrom : uint - { - ///Receive notifications about reactions made only by our contacts. - Contacts = 0xBAC3A61A, - ///Receive notifications about reactions made by any user. - All = 0x4B9E22A0, - } - - /// Reaction notification settings, see here » for more info. See - [TLDef(0x56E34970)] - public sealed partial class ReactionsNotifySettings : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Message reaction notification settings, if not set completely disables notifications/updates about message reactions. - [IfFlag(0)] public ReactionNotificationsFrom messages_notify_from; - /// Story reaction notification settings, if not set completely disables notifications/updates about reactions to stories. - [IfFlag(1)] public ReactionNotificationsFrom stories_notify_from; - /// Notification sound for reactions » - public NotificationSound sound; - /// If false, push notifications » about message/story reactions will only be of type REACT_HIDDEN/REACT_STORY_HIDDEN, without any information about the reacted-to story or the reaction itself. - public bool show_previews; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_messages_notify_from = 0x1, - /// Field has a value - has_stories_notify_from = 0x2, - } - } - - /// Represents a message effect ». See - [TLDef(0x93C3E27E)] - public sealed partial class AvailableEffect : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Unique effect ID. - public long id; - /// Emoji corresponding to the effect, to be used as icon for the effect if static_icon_id is not set. - public string emoticon; - /// ID of the document containing the static icon (WEBP) of the effect. - [IfFlag(0)] public long static_icon_id; - /// Contains the preview animation (TGS format »), used for the effect selection menu. - public long effect_sticker_id; - /// If set, contains the actual animated effect (TGS format »). If not set, the animated effect must be set equal to the premium animated sticker effect associated to the animated sticker specified in effect_sticker_id (always different from the preview animation, fetched thanks to the of type f as specified here »). - [IfFlag(1)] public long effect_animation_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_static_icon_id = 0x1, - /// Field has a value - has_effect_animation_id = 0x2, - /// Whether a Premium subscription is required to use this effect. - premium_required = 0x4, - } - } - - /// The full list of usable animated message effects ». See - /// a value means messages.availableEffectsNotModified - [TLDef(0xBDDB616E)] - public sealed partial class Messages_AvailableEffects : IObject - { - /// Hash used for caching, for more info click here - public int hash; - /// Message effects - public AvailableEffect[] effects; - /// Documents specified in the effects constructors. - public DocumentBase[] documents; - } - - /// Represents a fact-check » created by an independent fact-checker. See - [TLDef(0xB89BFCCF)] - public sealed partial class FactCheck : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// A two-letter ISO 3166-1 alpha-2 country code of the country for which the fact-check should be shown. - [IfFlag(1)] public string country; - /// The fact-check. - [IfFlag(1)] public TextWithEntities text; - /// Hash used for caching, for more info click here - public long hash; - - [Flags] public enum Flags : uint - { - /// If set, the country/text fields will not be set, and the fact check must be fetched manually by the client (if it isn't already cached with the key specified in hash) using bundled Messages_GetFactCheck requests, when the message with the factcheck scrolls into view. - need_check = 0x1, - /// Fields and have a value - has_country = 0x2, - } - } - - /// Source of an incoming Telegram Star transaction, or its recipient for outgoing Telegram Star transactions. See Derived classes: , , , , , , , - public abstract partial class StarsTransactionPeerBase : IObject { } - /// Describes a Telegram Star transaction that cannot be described using the current layer. See - [TLDef(0x95F2BFE4)] - public sealed partial class StarsTransactionPeerUnsupported : StarsTransactionPeerBase { } - /// Describes a Telegram Star transaction with the App Store, used when purchasing Telegram Stars through the App Store. See - [TLDef(0xB457B375)] - public sealed partial class StarsTransactionPeerAppStore : StarsTransactionPeerBase { } - /// Describes a Telegram Star transaction with the Play Store, used when purchasing Telegram Stars through the Play Store. See - [TLDef(0x7B560A0B)] - public sealed partial class StarsTransactionPeerPlayMarket : StarsTransactionPeerBase { } - /// Describes a Telegram Star transaction made using @PremiumBot (i.e. using the flow described here »). See - [TLDef(0x250DBAF8)] - public sealed partial class StarsTransactionPeerPremiumBot : StarsTransactionPeerBase { } - /// Describes a Telegram Star transaction with Fragment, used when purchasing Telegram Stars through Fragment. See - [TLDef(0xE92FD902)] - public sealed partial class StarsTransactionPeerFragment : StarsTransactionPeerBase { } - /// Describes a Telegram Star transaction with another peer. See - [TLDef(0xD80DA15D)] - public sealed partial class StarsTransactionPeer : StarsTransactionPeerBase - { - /// The peer. - public Peer peer; - } - /// Describes a Telegram Star transaction used to pay for Telegram ads as specified here ». See - [TLDef(0x60682812)] - public sealed partial class StarsTransactionPeerAds : StarsTransactionPeerBase { } - /// Describes a Telegram Star transaction used to pay for paid API usage, such as paid bot broadcasts. See - [TLDef(0xF9677AAD)] - public sealed partial class StarsTransactionPeerAPI : StarsTransactionPeerBase { } - - /// Telegram Stars topup option. See - [TLDef(0x0BD915C0)] - public sealed partial class StarsTopupOption : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Amount of Telegram stars. - public long stars; - /// Identifier of the store product associated with the option, official apps only. - [IfFlag(0)] public string store_product; - /// Three-letter ISO 4217 currency code - public string currency; - /// Price of the product 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). - public long amount; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_store_product = 0x1, - /// If set, the option must only be shown in the full list of topup options. - extended = 0x2, - } - } - - /// Represents a Telegram Stars or TON transaction ». See - [TLDef(0x13659EB0)] - public sealed partial class StarsTransaction : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Transaction ID. - public string id; - /// Amount of Telegram Stars or TON. - public StarsAmountBase amount; - /// Date of the transaction (unixtime). - public DateTime date; - /// Source of the incoming transaction, or its recipient for outgoing transactions. - public StarsTransactionPeerBase peer; - /// For transactions with bots, title of the bought product. - [IfFlag(0)] public string title; - /// For transactions with bots, description of the bought product. - [IfFlag(1)] public string description; - /// For transactions with bots, photo of the bought product. - [IfFlag(2)] public WebDocumentBase photo; - /// If neither pending nor failed are set, the transaction was completed successfully, and this field will contain the point in time (Unix timestamp) when the withdrawal was completed successfully. - [IfFlag(5)] public DateTime transaction_date; - /// If neither pending nor failed are set, the transaction was completed successfully, and this field will contain a URL where the withdrawal transaction can be viewed. - [IfFlag(5)] public string transaction_url; - /// Bot specified invoice payload (i.e. the payload passed to when creating the invoice). - [IfFlag(7)] public byte[] bot_payload; - /// For paid media transactions », message ID of the paid media posted to peer.peer (can point to a deleted message; either way, extended_media will always contain the bought media). - [IfFlag(8)] public int msg_id; - /// The purchased paid media ». - [IfFlag(9)] public MessageMedia[] extended_media; - /// The number of seconds between consecutive Telegram Star debiting for Telegram Star subscriptions ». - [IfFlag(12)] public int subscription_period; - /// ID of the message containing the , for incoming star giveaway prizes. - [IfFlag(13)] public int giveaway_post_id; - /// This transaction indicates a purchase or a sale (conversion back to Stars) of a gift ». - [IfFlag(14)] public StarGiftBase stargift; - /// This transaction is payment for paid bot broadcasts.
Paid broadcasts are only allowed if the allow_paid_floodskip parameter of Messages_SendMessage and other message sending methods is set while trying to broadcast more than 30 messages per second to bot users.
The integer value returned by this flag indicates the number of billed API calls.
- [IfFlag(15)] public int floodskip_number; - /// This transaction is the receival (or refund) of an affiliate commission (i.e. this is the transaction received by the peer that created the referral link, flag 17 is for transactions made by users that imported the referral link). - [IfFlag(16)] public int starref_commission_permille; - /// For transactions made by referred users, the peer that received the affiliate commission. - [IfFlag(17)] public Peer starref_peer; - /// For transactions made by referred users, the amount of Telegram Stars received by the affiliate, can be negative for refunds. - [IfFlag(17)] public StarsAmountBase starref_amount; - /// This transaction is related to the reception or transmission of a paid message ». - [IfFlag(19)] public int paid_messages; - /// This transaction indicates the payment for a gifted Telegram Premium subscription ». - [IfFlag(20)] public int premium_gift_months; - /// Indicates that this is payment for ad revenue from the specified unixtime (always set together with ads_proceeds_to_date). - [IfFlag(23)] public DateTime ads_proceeds_from_date; - /// Indicates that this is payment for ad revenue to the specified unixtime. - [IfFlag(23)] public DateTime ads_proceeds_to_date; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_title = 0x1, - /// Field has a value - has_description = 0x2, - /// Field has a value - has_photo = 0x4, - /// Whether this transaction is a refund. - refund = 0x8, - /// The transaction is currently pending. - pending = 0x10, - /// Fields and have a value - has_transaction_date = 0x20, - /// This transaction has failed. - failed = 0x40, - /// Field has a value - has_bot_payload = 0x80, - /// Field has a value - has_msg_id = 0x100, - /// Field has a value - has_extended_media = 0x200, - /// This transaction was a gift from the user in peer.peer. - gift = 0x400, - /// This transaction is a paid reaction ». - reaction = 0x800, - /// Field has a value - has_subscription_period = 0x1000, - /// Field has a value - has_giveaway_post_id = 0x2000, - /// Field has a value - has_stargift = 0x4000, - /// Field has a value - has_floodskip_number = 0x8000, - /// Field has a value - has_starref_commission_permille = 0x10000, - /// Fields and have a value - has_starref_peer = 0x20000, - /// This transaction pays for the upgrade of a gift to a collectible gift ». - stargift_upgrade = 0x40000, - /// Field has a value - has_paid_messages = 0x80000, - /// Field has a value - has_premium_gift_months = 0x100000, - /// This transaction transfers stars from the balance of a user account connected to a business bot, to the balance of the business bot, see here » for more info. - business_transfer = 0x200000, - /// This transaction is related to the resale of a collectible gift ». - stargift_resale = 0x400000, - /// Fields and have a value - has_ads_proceeds_from_date = 0x800000, - /// Represents payment for a paid global post search ». - posts_search = 0x1000000, - /// Represents payment for a separate prepaid upgrade of a gift. - stargift_prepaid_upgrade = 0x2000000, - stargift_drop_original_details = 0x4000000, - phonegroup_message = 0x8000000, - stargift_auction_bid = 0x10000000, - offer = 0x20000000, - } - } - - /// Info about the current Telegram Star subscriptions, balance and transaction history ». See - [TLDef(0x6C9CE8ED)] - public sealed partial class Payments_StarsStatus : IObject, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Current Telegram Star balance. - public StarsAmountBase balance; - /// Info about current Telegram Star subscriptions, only returned when invoking Payments_GetStarsTransactions and Payments_GetStarsSubscriptions. - [IfFlag(1)] public StarsSubscription[] subscriptions; - /// Offset for pagination of subscriptions: only usable and returned when invoking Payments_GetStarsSubscriptions. - [IfFlag(2)] public string subscriptions_next_offset; - /// The number of Telegram Stars the user should buy to be able to extend expired subscriptions soon (i.e. the current balance is not enough to extend all expired subscriptions). - [IfFlag(4)] public long subscriptions_missing_balance; - /// List of Telegram Star transactions (partial if next_offset is set). - [IfFlag(3)] public StarsTransaction[] history; - /// Offset to use to fetch more transactions from the transaction history using Payments_GetStarsTransactions. - [IfFlag(0)] public string next_offset; - /// Chats mentioned in history. - public Dictionary chats; - /// Users mentioned in history. - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - /// Field has a value - has_subscriptions = 0x2, - /// Field has a value - has_subscriptions_next_offset = 0x4, - /// Field has a value - has_history = 0x8, - /// Field has a value - has_subscriptions_missing_balance = 0x10, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// A story found using global story search ». See - [TLDef(0xE87ACBC0)] - public sealed partial class FoundStory : IObject - { - /// The peer that posted the story. - public Peer peer; - /// The story. - public StoryItemBase story; - } - - /// Stories found using global story search ». See - [TLDef(0xE2DE7737)] - public sealed partial class Stories_FoundStories : IObject, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of results found for the query. - public int count; - /// Matching stories. - public FoundStory[] stories; - /// Offset used to fetch the next page, if not set this is the final page. - [IfFlag(0)] public string next_offset; - /// Mentioned chats - public Dictionary chats; - /// Mentioned users - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Address optionally associated to a . See - [TLDef(0xDE4C5D93)] - public sealed partial class GeoPointAddress : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Two-letter ISO 3166-1 alpha-2 country code - public string country_iso2; - /// State - [IfFlag(0)] public string state; - /// City - [IfFlag(1)] public string city; - /// Street - [IfFlag(2)] public string street; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_state = 0x1, - /// Field has a value - has_city = 0x2, - /// Field has a value - has_street = 0x4, - } - } - - /// Describes Telegram Star revenue balances ». See - [TLDef(0xFEBE5491)] - public sealed partial class StarsRevenueStatus : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Amount of not-yet-withdrawn Telegram Stars. - public StarsAmountBase current_balance; - /// Amount of withdrawable Telegram Stars. - public StarsAmountBase available_balance; - /// Total amount of earned Telegram Stars. - public StarsAmountBase overall_revenue; - /// Unixtime indicating when will withdrawal be available to the user. If not set, withdrawal can be started now. - [IfFlag(1)] public DateTime next_withdrawal_at; - - [Flags] public enum Flags : uint - { - /// If set, the user may withdraw up to available_balance stars. - withdrawal_enabled = 0x1, - /// Field has a value - has_next_withdrawal_at = 0x2, - } - } - - /// Star revenue statistics, see here » for more info. See - [TLDef(0x6C207376)] - public sealed partial class Payments_StarsRevenueStats : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// For ad revenue statistics, ad impressions graph - [IfFlag(0)] public StatsGraphBase top_hours_graph; - /// Star revenue graph (number of earned stars) - public StatsGraphBase revenue_graph; - /// Current balance, current withdrawable balance and overall earned Telegram Stars - public StarsRevenueStatus status; - /// Current conversion rate of Telegram Stars to USD - public double usd_rate; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_top_hours_graph = 0x1, - } - } - - /// Contains the URL to use to withdraw Telegram Star revenue. See - [TLDef(0x1DAB80B7)] - public sealed partial class Payments_StarsRevenueWithdrawalUrl : IObject - { - /// Contains the URL to use to withdraw Telegram Star revenue. - public string url; - } - - /// Contains a URL leading to a page where the user will be able to place ads for the channel/bot, paying using Telegram Stars. See - [TLDef(0x394E7F21)] - public sealed partial class Payments_StarsRevenueAdsAccountUrl : IObject - { - /// URL to open. - public string url; - } - - /// Used to fetch info about a Telegram Star transaction ». See - [TLDef(0x206AE6D1)] - public sealed partial class InputStarsTransaction : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Transaction ID. - public string id; - - [Flags] public enum Flags : uint - { - /// If set, fetches info about the refund transaction for this transaction. - refund = 0x1, - } - } - - /// Telegram Stars gift option. See - [TLDef(0x5E0589F1)] - public sealed partial class StarsGiftOption : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Amount of Telegram stars. - public long stars; - /// Identifier of the store product associated with the option, official apps only. - [IfFlag(0)] public string store_product; - /// Three-letter ISO 4217 currency code - public string currency; - /// Price of the product 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). - public long amount; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_store_product = 0x1, - /// If set, the option must only be shown in the full list of topup options. - extended = 0x2, - } - } - - /// Popular Main Mini Apps, to be used in the apps tab of global search ». See - [TLDef(0x1991B13B)] - public sealed partial class Bots_PopularAppBots : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Offset for pagination. - [IfFlag(0)] public string next_offset; - /// The bots associated to each Main Mini App, see here » for more info. - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - } - } - - /// Represents a Main Mini App preview media, see here » for more info. See - [TLDef(0x23E91BA3)] - public sealed partial class BotPreviewMedia : IObject - { - /// When was this media last updated. - public DateTime date; - /// The actual photo/video. - public MessageMedia media; - } - - /// Contains info about Main Mini App previews, see here » for more info. See - [TLDef(0x0CA71D64)] - public sealed partial class Bots_PreviewInfo : IObject - { - /// All preview medias for the language code passed to Bots_GetPreviewInfo. - public BotPreviewMedia[] media; - /// All available language codes for which preview medias were uploaded (regardless of the language code passed to Bots_GetPreviewInfo). - public string[] lang_codes; - } - - /// Pricing of a Telegram Star subscription ». See - [TLDef(0x05416D58)] - public sealed partial class StarsSubscriptionPricing : IObject - { - /// The user should pay amount stars every period seconds to gain and maintain access to the channel.
Currently the only allowed subscription period is 30*24*60*60, i.e. the user will be debited amount stars every month.
- public int period; - /// Price of the subscription in Telegram Stars. - public long amount; - } - - ///
Represents a Telegram Star subscription ». See - [TLDef(0x2E6EAB1A)] - public sealed partial class StarsSubscription : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Subscription ID. - public string id; - /// Identifier of the associated private chat. - public Peer peer; - /// Expiration date of the current subscription period. - public DateTime until_date; - /// Pricing of the subscription in Telegram Stars. - public StarsSubscriptionPricing pricing; - /// Invitation link, used to renew the subscription after cancellation or expiration. - [IfFlag(3)] public string chat_invite_hash; - /// For bot subscriptions, the title of the subscription invoice - [IfFlag(4)] public string title; - /// For bot subscriptions, the photo from the subscription invoice - [IfFlag(5)] public WebDocumentBase photo; - /// For bot subscriptions, the identifier of the subscription invoice - [IfFlag(6)] public string invoice_slug; - - [Flags] public enum Flags : uint - { - /// Whether this subscription was cancelled. - canceled = 0x1, - /// Whether we left the associated private channel, but we can still rejoin it using Payments_FulfillStarsSubscription because the current subscription period hasn't expired yet. - can_refulfill = 0x2, - /// Whether this subscription has expired because there are not enough stars on the user's balance to extend it. - missing_balance = 0x4, - /// Field has a value - has_chat_invite_hash = 0x8, - /// Field has a value - has_title = 0x10, - /// Field has a value - has_photo = 0x20, - /// Field has a value - has_invoice_slug = 0x40, - /// Set if this bot subscription was cancelled by the bot - bot_canceled = 0x80, - } - } - - /// Info about a user in the paid Star reactions leaderboard for a message. See - [TLDef(0x4BA3A95A)] - public sealed partial class MessageReactor : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Identifier of the peer that reacted: may be unset for anonymous reactors different from the current user (i.e. if the current user sent an anonymous reaction anonymous will be set but this field will also be set). - [IfFlag(3)] public Peer peer_id; - /// The number of sent Telegram Stars. - public int count; - - [Flags] public enum Flags : uint - { - /// If set, the reactor is one of the most active reactors; may be unset if the reactor is the current user. - top = 0x1, - /// If set, this reactor is the current user. - my = 0x2, - /// If set, the reactor is anonymous. - anonymous = 0x4, - /// Field has a value - has_peer_id = 0x8, - } - } - - /// Contains info about a Telegram Star giveaway option. See - [TLDef(0x94CE852A)] - public sealed partial class StarsGiveawayOption : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The number of Telegram Stars that will be distributed among winners - public long stars; - /// Number of times the chat will be boosted for one year if the .boost_peer flag is populated - public int yearly_boosts; - /// Identifier of the store product associated with the option, official apps only. - [IfFlag(2)] public string store_product; - /// Three-letter ISO 4217 currency code - public string currency; - /// Total price 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). - public long amount; - /// Allowed options for the number of giveaway winners. - public StarsGiveawayWinnersOption[] winners; - - [Flags] public enum Flags : uint - { - /// If set, this option must only be shown in the full list of giveaway options (i.e. they must be added to the list only when the user clicks on the expand button). - extended = 0x1, - /// If set, this option must be pre-selected by default in the option list. - default_ = 0x2, - /// Field has a value - has_store_product = 0x4, - } - } - - /// Allowed options for the number of giveaway winners. See - [TLDef(0x54236209)] - public sealed partial class StarsGiveawayWinnersOption : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The number of users that will be randomly chosen as winners. - public int users; - /// The number of Telegram Stars each winner will receive. - public long per_user_stars; - - [Flags] public enum Flags : uint - { - /// If set, this option must be pre-selected by default in the option list. - default_ = 0x1, - } - } - - /// Represents a star gift, see here » for more info. See Derived classes: , - public abstract partial class StarGiftBase : IObject - { - /// Identifier of the gift - public virtual long ID => default; - /// For limited-supply gifts: the total number of gifts that was available in the initial supply. - public virtual int AvailabilityTotal => default; - /// Title of the gift - public virtual string Title => default; - /// This gift was released by the specified peer. - public virtual Peer ReleasedBy => default; - } - /// Represents a star gift, see here » for more info. See - [TLDef(0x313A9547)] - public sealed partial class StarGift : StarGiftBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Identifier of the gift - public long id; - /// Sticker that represents the gift. - public DocumentBase sticker; - /// Price of the gift in Telegram Stars. - public long stars; - /// For limited-supply gifts: the remaining number of gifts that may be bought. - [IfFlag(0)] public int availability_remains; - /// For limited-supply gifts: the total number of gifts that was available in the initial supply. - [IfFlag(0)] public int availability_total; - /// The total number of (upgraded to collectibles) gifts of this type currently on resale - [IfFlag(4)] public long availability_resale; - /// The receiver of this gift may convert it to this many Telegram Stars, instead of displaying it on their profile page.
convert_stars will be equal to stars only if the gift was bought using recently bought Telegram Stars, otherwise it will be less than stars.
- public long convert_stars; - /// For sold out gifts only: when was the gift first bought. - [IfFlag(1)] public DateTime first_sale_date; - /// For sold out gifts only: when was the gift last bought. - [IfFlag(1)] public DateTime last_sale_date; - /// The number of Telegram Stars the user can pay to convert the gift into a collectible gift ». - [IfFlag(3)] public long upgrade_stars; - /// The minimum price in Stars for gifts of this type currently on resale. - [IfFlag(4)] public long resell_min_stars; - /// Title of the gift - [IfFlag(5)] public string title; - /// This gift was released by the specified peer. - [IfFlag(6)] public Peer released_by; - /// Maximum number of gifts of this type that can be owned by any user. - [IfFlag(8)] public int per_user_total; - /// Remaining number of gifts of this type that can be owned by the current user. - [IfFlag(8)] public int per_user_remains; - /// If set, the specified gift possibly cannot be sent until the specified date, see here » for the full flow. - [IfFlag(9)] public DateTime locked_until_date; - [IfFlag(11)] public string auction_slug; - [IfFlag(11)] public int gifts_per_round; - [IfFlag(11)] public DateTime auction_start_date; - [IfFlag(12)] public int upgrade_variants; - [IfFlag(13)] public StarGiftBackground background; - - [Flags] public enum Flags : uint - { - /// Whether this is a limited-supply gift. - limited = 0x1, - /// Whether this gift sold out and cannot be bought anymore. - sold_out = 0x2, - /// Whether this is a birthday-themed gift - birthday = 0x4, - /// Field has a value - has_upgrade_stars = 0x8, - /// Fields and have a value - has_availability_resale = 0x10, - /// Field has a value - has_title = 0x20, - /// Field has a value - has_released_by = 0x40, - /// This gift can only be bought by users with a Premium subscription. - require_premium = 0x80, - /// If set, the maximum number of gifts of this type that can be owned by a single user is limited and specified in per_user_total, and the remaining slots for the current user in per_user_remains. - limited_per_user = 0x100, - /// Field has a value - has_locked_until_date = 0x200, - peer_color_available = 0x400, - auction = 0x800, - /// Field has a value - has_upgrade_variants = 0x1000, - /// Field has a value - has_background = 0x2000, - } - - /// Identifier of the gift - public override long ID => id; - /// For limited-supply gifts: the total number of gifts that was available in the initial supply. - public override int AvailabilityTotal => availability_total; - /// Title of the gift - public override string Title => title; - /// This gift was released by the specified peer. - public override Peer ReleasedBy => released_by; - } - /// Represents a collectible star gift, see here » for more info. See - [TLDef(0x85F0A9CD)] - public sealed partial class StarGiftUnique : StarGiftBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Identifier of the collectible gift. - public long id; - /// Unique ID of the gift. - public long gift_id; - /// Collectible title. - public string title; - /// Slug that can be used to create a collectible gift deep link », or elsewhere in the API where a collectible slug is accepted. - public string slug; - /// Unique identifier of this collectible gift among all (already upgraded) collectible gifts of the same type. - public int num; - /// The owner of the gift. - [IfFlag(0)] public Peer owner_id; - /// The name of the owner if neither owner_id nor owner_address are set. - [IfFlag(1)] public string owner_name; - /// For NFTs on the TON blockchain, contains the address of the owner (append it to the ton_blockchain_explorer_url client configuration value » to obtain a link with information about the address). - [IfFlag(2)] public string owner_address; - /// Collectible attributes - public StarGiftAttribute[] attributes; - /// Total number of gifts of the same type that were upgraded to a collectible gift. - public int availability_issued; - /// Total number of gifts of the same type that can be upgraded or were already upgraded to a collectible gift. - public int availability_total; - /// For NFTs on the TON blockchain, contains the address of the NFT (append it to the ton_blockchain_explorer_url client configuration value » to obtain a link with information about the address). - [IfFlag(3)] public string gift_address; - /// Resale price of the gift. - [IfFlag(4)] public StarsAmountBase[] resell_amount; - /// This gift was released by the specified peer. - [IfFlag(5)] public Peer released_by; - /// Price of the gift. - [IfFlag(8)] public long value_amount; - /// Currency for the gift's price. - [IfFlag(8)] public string value_currency; - [IfFlag(8)] public long value_usd_amount; - /// The current chat where the associated chat theme is installed, if any (gift-based themes can only be installed in one chat at a time). - [IfFlag(10)] public Peer theme_peer; - [IfFlag(11)] public PeerColorBase peer_color; - [IfFlag(12)] public Peer host_id; - [IfFlag(13)] public int offer_min_stars; - [IfFlag(16)] public int craft_chance_permille; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_owner_id = 0x1, - /// Field has a value - has_owner_name = 0x2, - /// Field has a value - has_owner_address = 0x4, - /// Field has a value - has_gift_address = 0x8, - /// Field has a value - has_resell_amount = 0x10, - /// Field has a value - has_released_by = 0x20, - /// This gift can only be bought by users with a Premium subscription. - require_premium = 0x40, - /// Whether the gift can be bought only using Toncoins. - resale_ton_only = 0x80, - /// Fields , and have a value - has_value_amount = 0x100, - /// A chat theme associated to this gift is available, see here » for more info on how to use it. - theme_available = 0x200, - /// Field has a value - has_theme_peer = 0x400, - /// Field has a value - has_peer_color = 0x800, - /// Field has a value - has_host_id = 0x1000, - /// Field has a value - has_offer_min_stars = 0x2000, - burned = 0x4000, - crafted = 0x8000, - /// Field has a value - has_craft_chance_permille = 0x10000, - } - - /// Identifier of the collectible gift. - public override long ID => id; - /// Total number of gifts of the same type that can be upgraded or were already upgraded to a collectible gift. - public override int AvailabilityTotal => availability_total; - /// Collectible title. - public override string Title => title; - /// This gift was released by the specified peer. - public override Peer ReleasedBy => released_by; - } - - /// Available gifts ». See - /// a value means payments.starGiftsNotModified - [TLDef(0x2ED82995)] - public sealed partial class Payments_StarGifts : IObject, IPeerResolver - { - /// Hash used for caching, for more info click here - public int hash; - /// List of available gifts. - public StarGiftBase[] gifts; - /// Chats mentioned in the gifts field. - public Dictionary chats; - /// Users mentioned in the gifts field. - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Report menu option See - [TLDef(0x7903E3D9)] - public sealed partial class MessageReportOption : IObject - { - /// Option title - public string text; - /// Option identifier: if the user selects this option, re-invoke Messages_Report, passing this option to option - public byte[] option; - } - - /// Represents a report menu or result See Derived classes: , , - public abstract partial class ReportResult : IObject { } - /// The user must choose one of the following options, and then Messages_Report must be re-invoked, passing the option's option identifier to Messages_Report.option. See - [TLDef(0xF0E4E0B6)] - public sealed partial class ReportResultChooseOption : ReportResult - { - /// Title of the option popup - public string title; - /// Available options, rendered as menu entries. - public MessageReportOption[] options; - } - /// The user should enter an additional comment for the moderators, and then Messages_Report must be re-invoked, passing the comment to Messages_Report.message. See - [TLDef(0x6F09AC31)] - public sealed partial class ReportResultAddComment : ReportResult - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The Messages_Report method must be re-invoked, passing this option to option - public byte[] option; - - [Flags] public enum Flags : uint - { - /// Whether this step can be skipped by the user, passing an empty message to Messages_Report, or if a non-empty message is mandatory. - optional = 0x1, - } - } - /// The report was sent successfully, no further actions are required. See - [TLDef(0x8DB33C4B)] - public sealed partial class ReportResultReported : ReportResult { } - - /// Represents a prepared inline message saved by a bot, to be sent to the user via a web app » See - [TLDef(0x8ECF0511)] - public sealed partial class Messages_BotPreparedInlineMessage : IObject - { - /// The ID of the saved message, to be passed to the id field of the web_app_send_prepared_message event » - public string id; - /// Expiration date of the message - public DateTime expire_date; - } - - /// Represents a prepared inline message received via a bot's mini app, that can be sent to some chats » See - [TLDef(0xFF57708D)] - public sealed partial class Messages_PreparedInlineMessage : IObject - { - /// The query_id to pass to Messages_SendInlineBotResult - public long query_id; - /// The contents of the message, to be shown in a preview - public BotInlineResultBase result; - /// Types of chats where this message can be sent - public InlineQueryPeerType[] peer_types; - /// Caching validity of the results - public int cache_time; - /// Users mentioned in the results - public Dictionary users; - } - - /// Mini app » settings See - [TLDef(0xC99B1950)] - public sealed partial class BotAppSettings : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// SVG placeholder logo, compressed using the same format used for vector thumbnails ». - [IfFlag(0)] public byte[] placeholder_path; - /// Default light mode background color - [IfFlag(1)] public int background_color; - /// Default dark mode background color - [IfFlag(2)] public int background_dark_color; - /// Default light mode header color - [IfFlag(3)] public int header_color; - /// Default dark mode header color - [IfFlag(4)] public int header_dark_color; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_placeholder_path = 0x1, - /// Field has a value - has_background_color = 0x2, - /// Field has a value - has_background_dark_color = 0x4, - /// Field has a value - has_header_color = 0x8, - /// Field has a value - has_header_dark_color = 0x10, - } - } - - /// Indo about an affiliate program offered by a bot See - [TLDef(0xDD0C66F2)] - public sealed partial class StarRefProgram : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of the bot that offers the program - public long bot_id; - /// An affiliate gets a commission of .commission_permilleTelegram Stars for every mini app transaction made by users they refer - public int commission_permille; - /// An affiliate gets a commission for every mini app transaction made by users they refer, for duration_months months after a referral link is imported, starting the bot for the first time - [IfFlag(0)] public int duration_months; - /// Point in time (Unix timestamp) when the affiliate program will be closed (optional, if not set the affiliate program isn't scheduled to be closed) - [IfFlag(1)] public DateTime end_date; - /// The amount of daily revenue per user in Telegram Stars of the bot that created the affiliate program.
To obtain the approximated revenue per referred user, multiply this value by commission_permille and divide by 1000.
- [IfFlag(2)] public StarsAmountBase daily_revenue_per_user; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_duration_months = 0x1, - /// Field has a value - has_end_date = 0x2, - /// Field has a value - has_daily_revenue_per_user = 0x4, - } - } - - /// Info about an active affiliate program we have with a Mini App See - [TLDef(0x19A13F71)] - public sealed partial class ConnectedBotStarRef : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Referral link to be shared - public string url; - /// When did we affiliate with bot_id - public DateTime date; - /// ID of the mini app that created the affiliate program - public long bot_id; - /// The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by bot_id - public int commission_permille; - /// Number of months the program will be active; if not set, there is no expiration date. - [IfFlag(0)] public int duration_months; - /// The number of users that used the affiliate program - public long participants; - /// The number of Telegram Stars that were earned by the affiliate program - public long revenue; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_duration_months = 0x1, - /// If set, this affiliation was revoked by the affiliate using Payments_EditConnectedStarRefBot, or by the affiliation program owner using Bots_UpdateStarRefProgram - revoked = 0x2, - } - } - - /// Active affiliations See - [TLDef(0x98D5EA1D)] - public sealed partial class Payments_ConnectedStarRefBots : IObject - { - /// Total number of active affiliations - public int count; - /// The affiliations - public ConnectedBotStarRef[] connected_bots; - /// Peers mentioned in connected_bots - public Dictionary users; - } - - /// A list of suggested mini apps with available affiliate programs See - [TLDef(0xB4D5D859)] - public sealed partial class Payments_SuggestedStarRefBots : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of results (for pagination) - public int count; - /// Suggested affiliate programs (full or partial list to be fetched using pagination) - public StarRefProgram[] suggested_bots; - /// Peers mentioned in suggested_bots - public Dictionary users; - /// Next offset for pagination - [IfFlag(0)] public string next_offset; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - } - } - - /// Describes a real (i.e. possibly decimal) amount of Telegram Stars. See Derived classes: , - public abstract partial class StarsAmountBase : IObject - { - /// The integer amount of Telegram Stars. - public virtual long Amount => default; - } - /// Describes a real (i.e. possibly decimal) amount of Telegram Stars. See - [TLDef(0xBBB6B4A3)] - public sealed partial class StarsAmount : StarsAmountBase - { - /// The integer amount of Telegram Stars. - public long amount; - /// The decimal amount of Telegram Stars, expressed as nanostars (i.e. 1 nanostar is equal to 1/1'000'000'000th (one billionth) of a Telegram Star).
This field may also be negative (the allowed range is -999999999 to 999999999).
- public int nanos; - - /// The integer amount of Telegram Stars. - public override long Amount => amount; - } - ///
Describes an amount of toncoin in nanotons (i.e. 1/1_000_000_000 of a toncoin). See - [TLDef(0x74AEE3E0)] - public sealed partial class StarsTonAmount : StarsAmountBase - { - /// The amount in nanotons. - public long amount; - - /// The amount in nanotons. - public override long Amount => amount; - } - - /// Found stickers See Derived classes: , - public abstract partial class Messages_FoundStickersBase : IObject { } - /// No new stickers were found for the specified query See - [TLDef(0x6010C534)] - public sealed partial class Messages_FoundStickersNotModified : Messages_FoundStickersBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Offset for pagination - [IfFlag(0)] public int next_offset; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - } - } - /// Found stickers See - [TLDef(0x82C9E290)] - public sealed partial class Messages_FoundStickers : Messages_FoundStickersBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Offset for pagination - [IfFlag(0)] public int next_offset; - /// Hash used for caching, for more info click here - public long hash; - /// Found stickers - public DocumentBase[] stickers; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - } - } - - /// Info about the current verifier bot ». See - [TLDef(0xB0CD6617)] - public sealed partial class BotVerifierSettings : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Verification icon - public long icon; - /// The name of the organization that provides the verification - public string company; - /// An optional default description for the verification - [IfFlag(0)] public string custom_description; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_custom_description = 0x1, - /// Indicates whether the bot is allowed to set a custom description field for individual verified peers, different from the custom_description provided here. - can_modify_custom_description = 0x2, - } - } - - /// Describes a bot verification icon ». See - [TLDef(0xF93CD45C)] - public sealed partial class BotVerification : IObject - { - /// ID of the bot that verified this peer - public long bot_id; - /// Verification icon - public long icon; - /// Verification description - public string description; - } - - /// An attribute of a collectible gift ». See Derived classes: , , , - public abstract partial class StarGiftAttribute : IObject { } - /// The model of a collectible gift ». See - [TLDef(0x565251E2)] - public sealed partial class StarGiftAttributeModel : StarGiftAttribute - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Name of the model - public string name; - /// The sticker representing the upgraded gift - public DocumentBase document; - public StarGiftAttributeRarityBase rarity; - - [Flags] public enum Flags : uint - { - crafted = 0x1, - } - } - /// A sticker applied on the backdrop of a collectible gift » using a repeating pattern. See - [TLDef(0x4E7085EA)] - public sealed partial class StarGiftAttributePattern : StarGiftAttribute - { - /// Name of the symbol - public string name; - /// The symbol - public DocumentBase document; - public StarGiftAttributeRarityBase rarity; - } - /// The backdrop of a collectible gift ». See - [TLDef(0x9F2504E4)] - public sealed partial class StarGiftAttributeBackdrop : StarGiftAttribute - { - /// Name of the backdrop - public string name; - /// Unique ID of the backdrop - public int backdrop_id; - /// Color of the center of the backdrop in RGB24 format. - public int center_color; - /// Color of the edges of the backdrop in RGB24 format. - public int edge_color; - /// Color of the applied on the backdrop in RGB24 format. - public int pattern_color; - /// Color of the text on the backdrop in RGB24 format. - public int text_color; - public StarGiftAttributeRarityBase rarity; - } - /// Info about the sender, receiver and message attached to the original gift », before it was upgraded to a collectible gift ». See - [TLDef(0xE0BFF26C)] - public sealed partial class StarGiftAttributeOriginalDetails : StarGiftAttribute - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Original sender of the gift, absent if the gift was private. - [IfFlag(0)] public Peer sender_id; - /// Original receiver of the gift. - public Peer recipient_id; - /// When was the gift sent. - public DateTime date; - /// Original message attached to the gift, if present. - [IfFlag(1)] public TextWithEntities message; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_sender_id = 0x1, - /// Field has a value - has_message = 0x2, - } - } - - /// A preview of the possible attributes (chosen randomly) a gift » can receive after upgrading it to a collectible gift », see here » for more info. See - [TLDef(0x3DE1DFED)] - public sealed partial class Payments_StarGiftUpgradePreview : IObject - { - /// Possible gift attributes - public StarGiftAttribute[] sample_attributes; - public StarGiftUpgradePrice[] prices; - public StarGiftUpgradePrice[] next_prices; - } - - /// Describes a list of users (or bots). See - [TLDef(0x62D706B8)] - public partial class Users_Users : IObject - { - /// Users - public Dictionary users; - } - /// Describes a partial list of users. See - [TLDef(0x315A4974)] - public sealed partial class Users_UsersSlice : Users_Users - { - /// Total number of users (bigger than the users specified in users) - public int count; - } - - /// Represents a collectible gift ». See - [TLDef(0x416C56E8)] - public sealed partial class Payments_UniqueStarGift : IObject, IPeerResolver - { - /// The . - public StarGiftBase gift; - /// Chats mentioned in the gift field. - public Dictionary chats; - /// Users mentioned in the gift field. - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Represents a webpage preview. See - [TLDef(0x8C9A88AC)] - public sealed partial class Messages_WebPagePreview : IObject, IPeerResolver - { - /// The or a if there is no preview. - public MessageMedia media; - /// Chats mentioned in the gift field. - public Dictionary chats; - /// Users mentioned within the media object. - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Represents a gift owned by a peer. See - [TLDef(0x41DF43FC)] - public sealed partial class SavedStarGift : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Sender of the gift (unset for anonymous gifts). - [IfFlag(1)] public Peer from_id; - /// Reception date of the gift. - public DateTime date; - /// The collectible gift. - public StarGiftBase gift; - /// Message attached to the gift. - [IfFlag(2)] public TextWithEntities message; - /// For gifts received by users, ID to use in s. - [IfFlag(3)] public int msg_id; - /// For gifts received by channels, ID to use in s. - [IfFlag(11)] public long saved_id; - /// For non-collectible gifts, the receiver of this gift may convert it to this many Telegram Stars, instead of displaying it on their profile page. - [IfFlag(4)] public long convert_stars; - /// Only for pre-paid non-collectible gifts, the number of Telegram Stars the sender has already paid to convert the gift into a collectible gift » (this is different from the meaning of the flag in , where it signals the upgrade price for not yet upgraded gifts). - [IfFlag(6)] public long upgrade_stars; - /// If set, indicates that the current gift can't be exported to the TON blockchain » yet: the owner will be able to export it at the specified unixtime. - [IfFlag(7)] public DateTime can_export_at; - /// If set, indicates that the gift can be transferred » to another user by paying the specified amount of stars. - [IfFlag(8)] public long transfer_stars; - /// If set, indicates that the current gift can't be transferred » yet: the owner will be able to transfer it at the specified unixtime. - [IfFlag(13)] public DateTime can_transfer_at; - /// If set, indicates that the current gift can't be resold » yet: the owner will be able to put it up for sale at the specified unixtime. - [IfFlag(14)] public DateTime can_resell_at; - /// IDs of the collections » that this gift is a part of. - [IfFlag(15)] public int[] collection_id; - /// Hash to prepay for a gift upgrade separately ». - [IfFlag(16)] public string prepaid_upgrade_hash; - [IfFlag(18)] public long drop_original_details_stars; - [IfFlag(19)] public int gift_num; - [IfFlag(20)] public DateTime can_craft_at; - - [Flags] public enum Flags : uint - { - /// If set, the gift sender in from_id and the message are set only for the receiver of the gift. - name_hidden = 0x1, - /// Field has a value - has_from_id = 0x2, - /// Field has a value - has_message = 0x4, - /// Field has a value - has_msg_id = 0x8, - /// Field has a value - has_convert_stars = 0x10, - /// If set, the gift is not pinned on the user's profile. - unsaved = 0x20, - /// Field has a value - has_upgrade_stars = 0x40, - /// Field has a value - has_can_export_at = 0x80, - /// Field has a value - has_transfer_stars = 0x100, - /// This gift was upgraded to a collectible gift » and then re-downgraded to a regular gift because a request to refund the payment related to the upgrade was made, and the money was returned. - refunded = 0x200, - /// Only set for non-collectible gifts, if they can be upgraded to a collectible gift ». - can_upgrade = 0x400, - /// Field has a value - has_saved_id = 0x800, - /// Whether this gift is pinned on top of the user's profile page. - pinned_to_top = 0x1000, - /// Field has a value - has_can_transfer_at = 0x2000, - /// Field has a value - has_can_resell_at = 0x4000, - /// Field has a value - has_collection_id = 0x8000, - /// Field has a value - has_prepaid_upgrade_hash = 0x10000, - /// If set, someone already separately pre-paid for the upgrade of this gift. - upgrade_separate = 0x20000, - /// Field has a value - has_drop_original_details_stars = 0x40000, - /// Field has a value - has_gift_num = 0x80000, - /// Field has a value - has_can_craft_at = 0x100000, - } - } - - /// Represents a list of gifts. See - [TLDef(0x95F389B1)] - public sealed partial class Payments_SavedStarGifts : IObject, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of results (can be less than the returned gifts, in which case next_offset will be set). - public int count; - /// Ternary value: can be not set, set&true, set&false.
Can only be set for channels we own: the value indicates whether we
enabled gift notifications for this channel.
- [IfFlag(1)] public bool chat_notifications_enabled; - /// Gifts - public SavedStarGift[] gifts; - /// Offset to pass to Payments_GetSavedStarGifts to fetch the next page of results. - [IfFlag(0)] public string next_offset; - /// Channels mentioned in gifts - public Dictionary chats; - /// Users mentioned in gifts - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - /// Field has a value - has_chat_notifications_enabled = 0x2, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Points to a gift ». See Derived classes: , , - public abstract partial class InputSavedStarGift : IObject { } - /// A gift received in a private chat with another user. See - [TLDef(0x69279795)] - public sealed partial class InputSavedStarGiftUser : InputSavedStarGift - { - /// ID of the with the with the gift. - public int msg_id; - } - /// A gift received by a channel we own. See - [TLDef(0xF101AA7F)] - public sealed partial class InputSavedStarGiftChat : InputSavedStarGift - { - /// The channel. - public InputPeer peer; - /// ID of the gift, must be the saved_id of a /. - public long saved_id; - } - /// Points to a collectible gift obtained from a collectible gift link ». See - [TLDef(0x2085C238)] - public sealed partial class InputSavedStarGiftSlug : InputSavedStarGift - { - /// Slug from the link. - public string slug; - } - - /// A URL that can be used to import the exported NFT on Fragment. See - [TLDef(0x84AA3A9C)] - public sealed partial class Payments_StarGiftWithdrawalUrl : IObject - { - /// The URL to open. - public string url; - } - - /// Paid reaction privacy settings » See Derived classes: , - /// a value means paidReactionPrivacyDefault - public abstract partial class PaidReactionPrivacy : IObject { } - /// Send paid reactions anonymously. See - [TLDef(0x1F0C1AD9)] - public sealed partial class PaidReactionPrivacyAnonymous : PaidReactionPrivacy { } - /// Send paid reactions as the specified peer, fetched using Channels_GetSendAs. See - [TLDef(0xDC6CFCF0)] - public sealed partial class PaidReactionPrivacyPeer : PaidReactionPrivacy - { - /// The peer to send reactions as. - public InputPeer peer; - } - - /// Total number of non-refunded Telegram Stars a user has spent on sending us messages either directly or through a channel, see here » for more info on paid messages. See - [TLDef(0x1E109708)] - public sealed partial class Account_PaidMessagesRevenue : IObject - { - /// Amount in Stars. - public long stars_amount; - } - - /// Specifies a requirement that must be satisfied in order to contact a user. See Derived classes: , - /// a value means requirementToContactEmpty - public abstract partial class RequirementToContact : IObject { } - /// This user requires us to buy a Premium subscription in order to contact them. See - [TLDef(0xE581E4E9)] - public sealed partial class RequirementToContactPremium : RequirementToContact { } - /// This user requires us to pay the specified amount of Telegram Stars to send them a message, see here » for the full flow. See - [TLDef(0xB4F67E93)] - public sealed partial class RequirementToContactPaidMessages : RequirementToContact - { - /// The required amount of Telegram Stars. - public long stars_amount; - } - - /// Business bot rights. See - [TLDef(0xA0624CF7)] - public sealed partial class BusinessBotRights : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - - [Flags] public enum Flags : uint - { - /// Whether the bot can send and edit messages in private chats that had incoming messages in the last 24 hours. - reply = 0x1, - /// Whether the bot can mark incoming private messages as read. - read_messages = 0x2, - /// Whether the bot can delete messages sent by the bot. - delete_sent_messages = 0x4, - /// Whether the bot can delete received private messages in managed chats. - delete_received_messages = 0x8, - /// Whether the bot can edit the first and last name of the business account. - edit_name = 0x10, - /// Whether the bot can edit the bio of the business account. - edit_bio = 0x20, - /// Whether the bot can edit the profile photo of the business account. - edit_profile_photo = 0x40, - /// Whether the bot can edit the username of the business account. - edit_username = 0x80, - /// Whether the bot can view gifts and the amount of Telegram Stars owned by the business account. - view_gifts = 0x100, - /// Whether the bot can convert regular gifts owned by the business account to Telegram Stars. - sell_gifts = 0x200, - /// Whether the bot can change the privacy settings pertaining to gifts for the business account. - change_gift_settings = 0x400, - /// Whether the bot can transfer and upgrade gifts owned by the business account. - transfer_and_upgrade_gifts = 0x800, - /// Whether the bot can transfer Telegram Stars received by the business account to its own account, or use them to upgrade and transfer gifts. - transfer_stars = 0x1000, - /// Whether the bot can post, edit and delete stories on behalf of the business account. - manage_stories = 0x2000, - } - } - - /// Disallow the reception of specific gift types. See - [TLDef(0x71F276C4)] - public sealed partial class DisallowedGiftsSettings : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - - [Flags] public enum Flags : uint - { - /// Disallow the reception of gifts with an unlimited supply (those with the .limited flag not set). - disallow_unlimited_stargifts = 0x1, - /// Disallow the reception of limited-supply gifts (those with the .limited flag set). - disallow_limited_stargifts = 0x2, - /// Disallow the reception of collectible gifts ». - disallow_unique_stargifts = 0x4, - /// Disallow the reception of gifted Telegram Premium subscriptions ». - disallow_premium_gifts = 0x8, - disallow_stargifts_from_channels = 0x10, - } - } - - /// A sponsored peer. See - [TLDef(0xC69708D3)] - public sealed partial class SponsoredPeer : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of the sponsored peer, to be passed to Messages_ViewSponsoredMessage, Messages_ClickSponsoredMessage or Messages_ReportSponsoredMessage (the same methods used for sponsored messages &raquo). - public byte[] random_id; - /// The sponsored peer. - public Peer peer; - /// If set, contains additional information about the sponsor to be shown along with the peer. - [IfFlag(0)] public string sponsor_info; - /// If set, contains additional information about the sponsored message to be shown along with the peer. - [IfFlag(1)] public string additional_info; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_sponsor_info = 0x1, - /// Field has a value - has_additional_info = 0x2, - } - } - - /// Sponsored peers. See - /// a value means contacts.sponsoredPeersEmpty - [TLDef(0xEB032884)] - public sealed partial class Contacts_SponsoredPeers : IObject, IPeerResolver - { - /// Sponsored peers. - public SponsoredPeer[] peers; - /// Info about sponsored chats and channels - public Dictionary chats; - /// Info about sponsored users - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Represents the identifier of a collectible gift attribute. See Derived classes: , , - public abstract partial class StarGiftAttributeId : IObject { } - /// The ID of a model of a collectible gift ». See - [TLDef(0x48AAAE3C)] - public sealed partial class StarGiftAttributeIdModel : StarGiftAttributeId - { - /// The sticker representing the upgraded gift - public long document_id; - } - /// The ID of a pattern of a collectible gift ». See - [TLDef(0x4A162433)] - public sealed partial class StarGiftAttributeIdPattern : StarGiftAttributeId - { - /// The sticker representing the symbol - public long document_id; - } - /// The ID of a backdrop of a collectible gift ». See - [TLDef(0x1F01C757)] - public sealed partial class StarGiftAttributeIdBackdrop : StarGiftAttributeId - { - /// Unique ID of the backdrop. - public int backdrop_id; - } - - /// Indicates the total number of gifts that have the specified attribute. See - [TLDef(0x2EB1B658)] - public sealed partial class StarGiftAttributeCounter : IObject - { - /// The attribute (just the ID, without the attribute itself). - public StarGiftAttributeId attribute; - /// Total number of gifts with this attribute. - public int count; - } - - /// List of gifts currently on resale ». See - [TLDef(0x947A12DF)] - public sealed partial class Payments_ResaleStarGifts : IObject, IPeerResolver - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of results. - public int count; - /// Collectible gifts on resale (may be less than count, in which case next_offset will be set). - public StarGiftBase[] gifts; - /// Offset for pagination, pass this to Payments_GetResaleStarGifts.offset to fetch the next results. - [IfFlag(0)] public string next_offset; - /// Possible gift attributes, only set if Payments_GetResaleStarGifts.attributes_hash is set (on the first call, it must be equal to 0). - [IfFlag(1)] public StarGiftAttribute[] attributes; - /// Hash of the attributes field, pass this to Payments_GetResaleStarGifts.attributes_hash to avoid returning any attributes (flag not set) if they haven't changed. - [IfFlag(1)] public long attributes_hash; - /// Chats mentioned in the attributes. - public Dictionary chats; - /// Indicates the total number of gifts that have a specific attribute, only set if Payments_GetResaleStarGifts.offset is empty (since this field is not related to the current result page but to all of them, it's only returned on the first page). - [IfFlag(2)] public StarGiftAttributeCounter[] counters; - /// Users mentioned in the attributes. - public Dictionary users; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_offset = 0x1, - /// Fields and have a value - has_attributes = 0x2, - /// Field has a value - has_counters = 0x4, - } - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// Contains the number of available active story slots (equal to the value of the story_expiring_limit_* client configuration parameter minus the number of currently active stories). See - [TLDef(0xC387C04E)] - public sealed partial class Stories_CanSendStoryCount : IObject - { - /// Remaining active story slots. - public int count_remains; - } - - /// Represents a custom pending suggestion ». See - [TLDef(0xE7E82E12)] - public sealed partial class PendingSuggestion : IObject - { - /// The suggestion ID, can be passed to Help_DismissSuggestion. - public string suggestion; - /// Title of the suggestion. - public TextWithEntities title; - /// Body of the suggestion. - public TextWithEntities description; - /// URL to open when the user clicks on the suggestion. - public string url; - } - - /// An item of a todo list ». See - [TLDef(0xCBA9A52F)] - public sealed partial class TodoItem : IObject - { - /// ID of the item, a positive (non-zero) integer unique within the current list. - public int id; - /// Text of the item, maximum length equal to todo_item_length_max ». - public TextWithEntities title; - } - - /// Represents a todo list ». See - [TLDef(0x49B92A26)] - public sealed partial class TodoList : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Title of the todo list, maximum length equal to todo_title_length_max ». - public TextWithEntities title; - /// Items of the list. - public TodoItem[] list; - - [Flags] public enum Flags : uint - { - /// If set, users different from the creator of the list can append items to the list. - others_can_append = 0x1, - /// If set, users different from the creator of the list can complete items in the list. - others_can_complete = 0x2, - } - } - - /// A completed todo list » item. See - [TLDef(0x221BB5E4)] - public sealed partial class TodoCompletion : IObject - { - /// The ID of the completed item. - public int id; - /// ID of the user that completed the item. - public Peer completed_by; - /// When was the item completed. - public DateTime date; - } - - /// Contains info about a suggested post ». See - [TLDef(0x0E8E37E5)] - public sealed partial class SuggestedPost : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Price of the suggested post. - [IfFlag(3)] public StarsAmountBase price; - /// Scheduling date. - [IfFlag(0)] public DateTime schedule_date; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_schedule_date = 0x1, - /// Whether the suggested post was accepted. - accepted = 0x2, - /// Whether the suggested post was rejected. - rejected = 0x4, - /// Field has a value - has_price = 0x8, - } - } - - /// Represents the profile's star rating, see here » for more info. See - [TLDef(0x1B0E4F07)] - public sealed partial class StarsRating : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The current level, may be negative. - public int level; - /// The numerical value of the rating required for the current level. - public long current_level_stars; - /// Numerical value of the current rating. - public long stars; - /// The numerical value of the rating required for the next level. - [IfFlag(0)] public long next_level_stars; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_next_level_stars = 0x1, - } - } - - /// Represents a star gift collection ». See - [TLDef(0x9D6B13B0)] - public sealed partial class StarGiftCollection : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// The ID of the collection. - public int collection_id; - /// Title of the collection. - public string title; - /// Optional icon for the collection, taken from the first gift in the collection. - [IfFlag(0)] public DocumentBase icon; - /// Number of gifts in the collection. - public int gifts_count; - /// Field to use instead of collection_id when generating the hash to pass to Payments_GetStarGiftCollections. - public long hash; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_icon = 0x1, - } - } - - /// Represents a list of star gift collections ». See - /// a value means payments.starGiftCollectionsNotModified - [TLDef(0x8A2932F3)] - public sealed partial class Payments_StarGiftCollections : IObject - { - /// Star gift collections. - public StarGiftCollection[] collections; - } - - /// Represents a story album ». See - [TLDef(0x9325705A)] - public sealed partial class StoryAlbum : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// ID of the album. - public int album_id; - /// Name of the album. - public string title; - /// Photo from the first story of the album, if it's a photo. - [IfFlag(0)] public PhotoBase icon_photo; - /// Video from the first story of the album, if it's a video. - [IfFlag(1)] public DocumentBase icon_video; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_icon_photo = 0x1, - /// Field has a value - has_icon_video = 0x2, - } - } - - /// Story albums ». See - /// a value means stories.albumsNotModified - [TLDef(0xC3987A3A)] - public sealed partial class Stories_Albums : IObject - { - /// Hash to pass to Stories_GetAlbums to avoid returning any results if they haven't changed. - public long hash; - /// The albums. - public StoryAlbum[] albums; - } - - /// Indicates if the specified global post search » requires payment. See - [TLDef(0x3E0B5B6A)] - public sealed partial class SearchPostsFlood : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Total number of daily free search slots. - public int total_daily; - /// Remaining number of free search slots. - public int remains; - /// If there are no more search slots, specifies the unixtime when more search slots will be available. - [IfFlag(1)] public int wait_till; - /// The number of Telegram Stars to pay for each non-free search. - public long stars_amount; - - [Flags] public enum Flags : uint - { - /// The specified query is free (and it will not use up free search slots). - query_is_free = 0x1, - /// Field has a value - has_wait_till = 0x2, - } - } - - /// Information about the value of a collectible gift ». See - [TLDef(0x512FE446)] - public sealed partial class Payments_UniqueStarGiftValueInfo : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Three-letter ISO 4217 currency code (a localized fiat currency used to represent prices and price estimations in this constructor). - public string currency; - /// Estimated value of the gift, in the smallest unit of the currency specified in currency. - public long value; - /// Initial purchase date of the gift. - public DateTime initial_sale_date; - /// Initial purchase price in Stars. - public long initial_sale_stars; - /// Initial purchase price in the smallest unit of the currency specified in currency (automatically converted from initial_sale_stars). - public long initial_sale_price; - /// Last resale date of the gift. - [IfFlag(0)] public DateTime last_sale_date; - /// Last resale price, in the smallest unit of the currency specified in currency. - [IfFlag(0)] public long last_sale_price; - /// The current minimum price of collectible gifts of the same type, in the smallest unit of the currency specified in currency. - [IfFlag(2)] public long floor_price; - /// The current average sale price of collectible gifts of the same type, in the smallest unit of the currency specified in currency. - [IfFlag(3)] public long average_price; - /// Number of gifts of the same type currently being resold on Telegram. - [IfFlag(4)] public int listed_count; - /// Number of gifts of the same type currently being resold on fragment. - [IfFlag(5)] public int fragment_listed_count; - /// Fragment link to the listing of gifts of the same type currently being resold on fragment. - [IfFlag(5)] public string fragment_listed_url; - - [Flags] public enum Flags : uint - { - /// Fields and have a value - has_last_sale_date = 0x1, - /// If set, the last sale was completed on Fragment. - last_sale_on_fragment = 0x2, - /// Field has a value - has_floor_price = 0x4, - /// Field has a value - has_average_price = 0x8, - /// Field has a value - has_listed_count = 0x10, - /// Fields and have a value - has_fragment_listed_count = 0x20, - /// If set, the value is calculated from the average value of sold gifts of the same type. Otherwise, it is based on the sale price of the gift. - value_is_average = 0x40, - } - } - - /// Represents a tab of a profile page ». See - public enum ProfileTab : uint - { - ///Represents the stories tab of a profile page. - Posts = 0xB98CD696, - ///Represents the gifts tab of a profile page. - Gifts = 0x4D4BD46A, - ///Represents the media tab of a profile page. - Media = 0x72C64955, - ///Represents the shared files tab of a profile. - Files = 0xAB339C00, - ///Represents the music tab of a profile page. - Music = 0x9F27D26E, - ///Represents the voice messages tab of a profile page. - Voice = 0xE477092E, - ///Represents the shared links tab of a profile page. - Links = 0xD3656499, - ///Represents the gifs tab of a profile page. - Gifs = 0xA2C0F695, - } - - /// List of songs (.ids) currently pinned on a user's profile, see here » for more info. See Derived classes: , - public abstract partial class Users_SavedMusicBase : IObject { } - /// This subset of the songs currently pinned on a user's profile hasn't changed, see here » for more info. See - [TLDef(0xE3878AA4)] - public sealed partial class Users_SavedMusicNotModified : Users_SavedMusicBase - { - /// Total number of songs on the user's profile. - public int count; - } - /// List of songs currently pinned on a user's profile, see here » for more info. See - [TLDef(0x34A2F297)] - public sealed partial class Users_SavedMusic : Users_SavedMusicBase - { - /// Total number of songs (can be bigger than documents depending on the passed limit, and the default maximum limit in which case pagination is required). - public int count; - /// Songs. - public DocumentBase[] documents; - } - - /// List of IDs of songs (.ids) currently pinned on our profile, see here » for more info. See - /// a value means account.savedMusicIdsNotModified - [TLDef(0x998D6636)] - public sealed partial class Account_SavedMusicIds : IObject - { - /// Full list of .ids - public long[] ids; - } - - /// Specifies if a gift can or cannot be sent. See Derived classes: , - public abstract partial class Payments_CheckCanSendGiftResult : IObject { } - /// The specified gift can be sent. See - [TLDef(0x374FA7AD)] - public sealed partial class Payments_CheckCanSendGiftResultOk : Payments_CheckCanSendGiftResult { } - /// The specified gift cannot be sent yet for the specified reason. See - [TLDef(0xD5E58274)] - public sealed partial class Payments_CheckCanSendGiftResultFail : Payments_CheckCanSendGiftResult - { - /// The reason why it can't be sent yet. - public TextWithEntities reason; - } - - /// Specifies a chat theme ». See Derived classes: , - /// a value means inputChatThemeEmpty - public abstract partial class InputChatThemeBase : IObject { } - /// Set an emoji-based chat theme, returned by Account_GetChatThemes. See - [TLDef(0xC93DE95C)] - public sealed partial class InputChatTheme : InputChatThemeBase - { - /// The emoji. - public string emoticon; - } - /// Set a theme based on an owned collectible gift », returned by Account_GetUniqueGiftChatThemes. See - [TLDef(0x87E5DFE4)] - public sealed partial class InputChatThemeUniqueGift : InputChatThemeBase - { - /// The slug from .slug. - public string slug; - } - - /// See - [TLDef(0x99EA331D)] - public sealed partial class StarGiftUpgradePrice : IObject - { - public DateTime date; - public long upgrade_stars; - } - - /// See - [TLDef(0x1A8AFC7E)] - public sealed partial class GroupCallMessage : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - public int id; - public Peer from_id; - public DateTime date; - public TextWithEntities message; - [IfFlag(0)] public long paid_message_stars; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_paid_message_stars = 0x1, - from_admin = 0x2, - } - } - - /// See - [TLDef(0xEE430C85)] - public sealed partial class GroupCallDonor : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - [IfFlag(3)] public Peer peer_id; - public long stars; - - [Flags] public enum Flags : uint - { - top = 0x1, - my = 0x2, - /// Field has a value - has_peer_id = 0x8, - } - } - - /// See - [TLDef(0x9D1DBD26)] - public sealed partial class Phone_GroupCallStars : IObject, IPeerResolver - { - public long total_stars; - public GroupCallDonor[] top_donors; - public Dictionary chats; - public Dictionary users; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// See - [TLDef(0x711D692D)] - public sealed partial class RecentStory : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - [IfFlag(1)] public int max_id; - - [Flags] public enum Flags : uint - { - live = 0x1, - /// Field has a value - has_max_id = 0x2, - } - } - - /// See - [TLDef(0x310240CC)] - public sealed partial class AuctionBidLevel : IObject - { - public int pos; - public long amount; - public DateTime date; - } - - /// See Derived classes: , - /// a value means starGiftAuctionStateNotModified - public abstract partial class StarGiftAuctionStateBase : IObject - { - public virtual DateTime StartDate => default; - public virtual DateTime EndDate => default; - } - /// See - [TLDef(0x771A4E66)] - public sealed partial class StarGiftAuctionState : StarGiftAuctionStateBase - { - public int version; - public DateTime start_date; - public DateTime end_date; - public long min_bid_amount; - public AuctionBidLevel[] bid_levels; - public long[] top_bidders; - public DateTime next_round_at; - public int last_gift_num; - public int gifts_left; - public int current_round; - public int total_rounds; - public StarGiftAuctionRound[] rounds; - - public override DateTime StartDate => start_date; - public override DateTime EndDate => end_date; - } - /// See - [TLDef(0x972DABBF)] - public sealed partial class StarGiftAuctionStateFinished : StarGiftAuctionStateBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - public DateTime start_date; - public DateTime end_date; - public long average_price; - [IfFlag(0)] public int listed_count; - [IfFlag(1)] public int fragment_listed_count; - [IfFlag(1)] public string fragment_listed_url; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_listed_count = 0x1, - /// Fields and have a value - has_fragment_listed_count = 0x2, - } - - public override DateTime StartDate => start_date; - public override DateTime EndDate => end_date; - } - - /// See - [TLDef(0x2EEED1C4)] - public sealed partial class StarGiftAuctionUserState : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - [IfFlag(0)] public long bid_amount; - [IfFlag(0)] public DateTime bid_date; - [IfFlag(0)] public long min_bid_amount; - [IfFlag(0)] public Peer bid_peer; - public int acquired_count; - - [Flags] public enum Flags : uint - { - /// Fields , , and have a value - has_bid_amount = 0x1, - returned = 0x2, - } - } - - /// See - [TLDef(0x6B39F4EC)] - public sealed partial class Payments_StarGiftAuctionState : IObject, IPeerResolver - { - public StarGiftBase gift; - public StarGiftAuctionStateBase state; - public StarGiftAuctionUserState user_state; - public int timeout; - public Dictionary users; - public Dictionary chats; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// See - [TLDef(0x42B00348)] - public sealed partial class StarGiftAuctionAcquiredGift : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - public Peer peer; - public DateTime date; - public long bid_amount; - public int round; - public int pos; - [IfFlag(1)] public TextWithEntities message; - [IfFlag(2)] public int gift_num; - - [Flags] public enum Flags : uint - { - name_hidden = 0x1, - /// Field has a value - has_message = 0x2, - /// Field has a value - has_gift_num = 0x4, - } - } - - /// See - [TLDef(0x7D5BD1F0)] - public sealed partial class Payments_StarGiftAuctionAcquiredGifts : IObject, IPeerResolver - { - public StarGiftAuctionAcquiredGift[] gifts; - public Dictionary users; - public Dictionary chats; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// See - [TLDef(0xD31BC45D)] - public sealed partial class StarGiftActiveAuctionState : IObject - { - public StarGiftBase gift; - public StarGiftAuctionStateBase state; - public StarGiftAuctionUserState user_state; - } - - /// See - /// a value means payments.starGiftActiveAuctionsNotModified - [TLDef(0xAEF6ABBC)] - public sealed partial class Payments_StarGiftActiveAuctions : IObject, IPeerResolver - { - public StarGiftActiveAuctionState[] auctions; - public Dictionary users; - public Dictionary chats; - /// returns a or for the given Peer - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(users, chats); - } - - /// See Derived classes: , - public abstract partial class InputStarGiftAuctionBase : IObject { } - /// See - [TLDef(0x02E16C98)] - public sealed partial class InputStarGiftAuction : InputStarGiftAuctionBase - { - public long gift_id; - } - /// See - [TLDef(0x7AB58308)] - public sealed partial class InputStarGiftAuctionSlug : InputStarGiftAuctionBase - { - public string slug; - } - - /// See - [TLDef(0x98613EBF)] - public sealed partial class Passkey : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - public string id; - public string name; - public DateTime date; - [IfFlag(0)] public long software_emoji_id; - [IfFlag(1)] public DateTime last_usage_date; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_software_emoji_id = 0x1, - /// Field has a value - has_last_usage_date = 0x2, - } - } - - /// See - [TLDef(0xF8E0AA1C)] - public sealed partial class Account_Passkeys : IObject - { - public Passkey[] passkeys; - } - - /// See - [TLDef(0xE16B5CE1)] - public sealed partial class Account_PasskeyRegistrationOptions : IObject - { - public DataJSON options; - } - - /// See - [TLDef(0xE2037789)] - public sealed partial class Auth_PasskeyLoginOptions : IObject - { - public DataJSON options; - } - - /// See Derived classes: , - public abstract partial class InputPasskeyResponse : IObject - { - public DataJSON client_data; - } - /// See - [TLDef(0x3E63935C, inheritAt = 0)] - public sealed partial class InputPasskeyResponseRegister : InputPasskeyResponse - { - public byte[] attestation_data; - } - /// See - [TLDef(0xC31FC14A, inheritAt = 0)] - public sealed partial class InputPasskeyResponseLogin : InputPasskeyResponse - { - public byte[] authenticator_data; - public byte[] signature; - public string user_handle; - } - - /// See Derived classes: , - public abstract partial class InputPasskeyCredential : IObject { } - /// See - [TLDef(0x3C27B78F)] - public sealed partial class InputPasskeyCredentialPublicKey : InputPasskeyCredential - { - public string id; - public string raw_id; - public InputPasskeyResponse response; - } - /// See - [TLDef(0x5B1CCB28)] - public sealed partial class InputPasskeyCredentialFirebasePNV : InputPasskeyCredential - { - public string pnv_token; - } - - /// See - [TLDef(0xAFF56398)] - public sealed partial class StarGiftBackground : IObject - { - public int center_color; - public int edge_color; - public int text_color; - } - - /// See - [TLDef(0x3AAE0528)] - public partial class StarGiftAuctionRound : IObject - { - public int num; - public int duration; - } - /// See - [TLDef(0x0AA021E5, inheritAt = 0)] - public sealed partial class StarGiftAuctionRoundExtendable : StarGiftAuctionRound - { - public int extend_top; - public int extend_window; - } - - /// See - [TLDef(0x46C6E36F)] - public sealed partial class Payments_StarGiftUpgradeAttributes : IObject - { - public StarGiftAttribute[] attributes; - } - - /// See - [TLDef(0xDA2AD647)] - public sealed partial class Messages_EmojiGameOutcome : IObject - { - public byte[] seed; - public long stake_ton_amount; - public long ton_amount; - } - - /// See Derived classes: , - public abstract partial class Messages_EmojiGameInfo : IObject { } - /// See - [TLDef(0x59E65335)] - public sealed partial class Messages_EmojiGameUnavailable : Messages_EmojiGameInfo { } - /// See - [TLDef(0x44E56023)] - public sealed partial class Messages_EmojiGameDiceInfo : Messages_EmojiGameInfo - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - public string game_hash; - public long prev_stake; - public int current_streak; - public int[] params_; - [IfFlag(0)] public int plays_left; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_plays_left = 0x1, - } - } - - /// See Derived classes: , , , , - public abstract partial class StarGiftAttributeRarityBase : IObject { } - /// See - [TLDef(0x36437737)] - public sealed partial class StarGiftAttributeRarity : StarGiftAttributeRarityBase - { - public int permille; - } - /// See - [TLDef(0xDBCE6389)] - public sealed partial class StarGiftAttributeRarityUncommon : StarGiftAttributeRarityBase { } - /// See - [TLDef(0xF08D516B)] - public sealed partial class StarGiftAttributeRarityRare : StarGiftAttributeRarityBase { } - /// See - [TLDef(0x78FBF3A8)] - public sealed partial class StarGiftAttributeRarityEpic : StarGiftAttributeRarityBase { } - /// See - [TLDef(0xCEF7E7A8)] - public sealed partial class StarGiftAttributeRarityLegendary : StarGiftAttributeRarityBase { } - - /// See - [TLDef(0x4FDD3430)] - public sealed partial class KeyboardButtonStyle : IObject - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - [IfFlag(3)] public long icon; - - [Flags] public enum Flags : uint - { - bg_primary = 0x1, - bg_danger = 0x2, - bg_success = 0x4, - /// Field has a value - has_icon = 0x8, - } + public ChatBase[] chats; + public UserBase[] users; + } + + // ---functions--- + + public static class Schema + { + ///See + public static Task InvokeAfterMsg(this Client client, long msg_id, ITLFunction query) + => client.CallAsync(writer => + { + writer.Write(0xCB9F372D); + writer.Write(msg_id); + query(writer); + return "InvokeAfterMsg"; + }); + + ///See + public static Task InvokeAfterMsgs(this Client client, long[] msg_ids, ITLFunction query) + => client.CallAsync(writer => + { + writer.Write(0x3DC4B4F0); + writer.WriteTLVector(msg_ids); + query(writer); + return "InvokeAfterMsgs"; + }); + + ///See + public static ITLFunction InitConnection(int api_id, string device_model, string system_version, string app_version, string system_lang_code, string lang_pack, string lang_code, ITLFunction query, InputClientProxy proxy = null, JSONValue params_ = null) + => writer => + { + writer.Write(0xC1CD5EA9); + writer.Write((proxy != null ? 0x1 : 0) | (params_ != null ? 0x2 : 0)); + writer.Write(api_id); + writer.WriteTLString(device_model); + writer.WriteTLString(system_version); + writer.WriteTLString(app_version); + writer.WriteTLString(system_lang_code); + writer.WriteTLString(lang_pack); + writer.WriteTLString(lang_code); + if (proxy != null) + writer.WriteTLObject(proxy); + if (params_ != null) + writer.WriteTLObject(params_); + query(writer); + return "InitConnection"; + }; + + ///See + public static Task InvokeWithLayer(this Client client, int layer, ITLFunction query) + => client.CallAsync(writer => + { + writer.Write(0xDA9B0D0D); + writer.Write(layer); + query(writer); + return "InvokeWithLayer"; + }); + + ///See + public static Task InvokeWithoutUpdates(this Client client, ITLFunction query) + => client.CallAsync(writer => + { + writer.Write(0xBF9459B7); + query(writer); + return "InvokeWithoutUpdates"; + }); + + ///See + public static Task InvokeWithMessagesRange(this Client client, MessageRange range, ITLFunction query) + => client.CallAsync(writer => + { + writer.Write(0x365275F2); + writer.WriteTLObject(range); + query(writer); + return "InvokeWithMessagesRange"; + }); + + ///See + public static Task InvokeWithTakeout(this Client client, long takeout_id, ITLFunction query) + => client.CallAsync(writer => + { + writer.Write(0xACA9FD2E); + writer.Write(takeout_id); + query(writer); + return "InvokeWithTakeout"; + }); + + ///See + public static Task Auth_SendCode(this Client client, string phone_number, int api_id, string api_hash, CodeSettings settings) + => client.CallAsync(writer => + { + writer.Write(0xA677244F); + writer.WriteTLString(phone_number); + writer.Write(api_id); + writer.WriteTLString(api_hash); + writer.WriteTLObject(settings); + return "Auth_SendCode"; + }); + + ///See + public static Task Auth_SignUp(this Client client, string phone_number, string phone_code_hash, string first_name, string last_name) + => client.CallAsync(writer => + { + writer.Write(0x80EEE427); + writer.WriteTLString(phone_number); + writer.WriteTLString(phone_code_hash); + writer.WriteTLString(first_name); + writer.WriteTLString(last_name); + return "Auth_SignUp"; + }); + + ///See + public static Task Auth_SignIn(this Client client, string phone_number, string phone_code_hash, string phone_code) + => client.CallAsync(writer => + { + writer.Write(0xBCD51581); + writer.WriteTLString(phone_number); + writer.WriteTLString(phone_code_hash); + writer.WriteTLString(phone_code); + return "Auth_SignIn"; + }); + + ///See + public static Task Auth_LogOut(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x5717DA40); + return "Auth_LogOut"; + }); + + ///See + public static Task Auth_ResetAuthorizations(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x9FAB0D1A); + return "Auth_ResetAuthorizations"; + }); + + ///See + public static Task Auth_ExportAuthorization(this Client client, int dc_id) + => client.CallAsync(writer => + { + writer.Write(0xE5BFFFCD); + writer.Write(dc_id); + return "Auth_ExportAuthorization"; + }); + + ///See + public static Task Auth_ImportAuthorization(this Client client, long id, byte[] bytes) + => client.CallAsync(writer => + { + writer.Write(0xA57A7DAD); + writer.Write(id); + writer.WriteTLBytes(bytes); + return "Auth_ImportAuthorization"; + }); + + ///See + public static Task Auth_BindTempAuthKey(this Client client, long perm_auth_key_id, long nonce, DateTime expires_at, byte[] encrypted_message) + => client.CallAsync(writer => + { + writer.Write(0xCDD42A05); + writer.Write(perm_auth_key_id); + writer.Write(nonce); + writer.WriteTLStamp(expires_at); + writer.WriteTLBytes(encrypted_message); + return "Auth_BindTempAuthKey"; + }); + + ///See + public static Task Auth_ImportBotAuthorization(this Client client, int flags, int api_id, string api_hash, string bot_auth_token) + => client.CallAsync(writer => + { + writer.Write(0x67A3FF2C); + writer.Write(flags); + writer.Write(api_id); + writer.WriteTLString(api_hash); + writer.WriteTLString(bot_auth_token); + return "Auth_ImportBotAuthorization"; + }); + + ///See + public static Task Auth_CheckPassword(this Client client, InputCheckPasswordSRP password) + => client.CallAsync(writer => + { + writer.Write(0xD18B4D16); + writer.WriteTLObject(password); + return "Auth_CheckPassword"; + }); + + ///See + public static Task Auth_RequestPasswordRecovery(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xD897BC66); + return "Auth_RequestPasswordRecovery"; + }); + + ///See + public static Task Auth_RecoverPassword(this Client client, string code, Account_PasswordInputSettings new_settings = null) + => client.CallAsync(writer => + { + writer.Write(0x37096C70); + writer.Write(new_settings != null ? 0x1 : 0); + writer.WriteTLString(code); + if (new_settings != null) + writer.WriteTLObject(new_settings); + return "Auth_RecoverPassword"; + }); + + ///See + public static Task Auth_ResendCode(this Client client, string phone_number, string phone_code_hash) + => client.CallAsync(writer => + { + writer.Write(0x3EF1A9BF); + writer.WriteTLString(phone_number); + writer.WriteTLString(phone_code_hash); + return "Auth_ResendCode"; + }); + + ///See + public static Task Auth_CancelCode(this Client client, string phone_number, string phone_code_hash) + => client.CallAsync(writer => + { + writer.Write(0x1F040578); + writer.WriteTLString(phone_number); + writer.WriteTLString(phone_code_hash); + return "Auth_CancelCode"; + }); + + ///See + public static Task Auth_DropTempAuthKeys(this Client client, long[] except_auth_keys) + => client.CallAsync(writer => + { + writer.Write(0x8E48A188); + writer.WriteTLVector(except_auth_keys); + return "Auth_DropTempAuthKeys"; + }); + + ///See + public static Task Auth_ExportLoginToken(this Client client, int api_id, string api_hash, long[] except_ids) + => client.CallAsync(writer => + { + writer.Write(0xB7E085FE); + writer.Write(api_id); + writer.WriteTLString(api_hash); + writer.WriteTLVector(except_ids); + return "Auth_ExportLoginToken"; + }); + + ///See + public static Task Auth_ImportLoginToken(this Client client, byte[] token) + => client.CallAsync(writer => + { + writer.Write(0x95AC5CE4); + writer.WriteTLBytes(token); + return "Auth_ImportLoginToken"; + }); + + ///See + public static Task Auth_AcceptLoginToken(this Client client, byte[] token) + => client.CallAsync(writer => + { + writer.Write(0xE894AD4D); + writer.WriteTLBytes(token); + return "Auth_AcceptLoginToken"; + }); + + ///See + public static Task Auth_CheckRecoveryPassword(this Client client, string code) + => client.CallAsync(writer => + { + writer.Write(0x0D36BF79); + writer.WriteTLString(code); + return "Auth_CheckRecoveryPassword"; + }); + + ///See + 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) + => client.CallAsync(writer => + { + writer.Write(0xEC86017A); + writer.Write(no_muted ? 0x1 : 0); + writer.Write(token_type); + writer.WriteTLString(token); + writer.Write(app_sandbox ? 0x997275B5 : 0xBC799737); + writer.WriteTLBytes(secret); + writer.WriteTLVector(other_uids); + return "Account_RegisterDevice"; + }); + + ///See + public static Task Account_UnregisterDevice(this Client client, int token_type, string token, long[] other_uids) + => client.CallAsync(writer => + { + writer.Write(0x6A0D3206); + writer.Write(token_type); + writer.WriteTLString(token); + writer.WriteTLVector(other_uids); + return "Account_UnregisterDevice"; + }); + + ///See + public static Task Account_UpdateNotifySettings(this Client client, InputNotifyPeerBase peer, InputPeerNotifySettings settings) + => client.CallAsync(writer => + { + writer.Write(0x84BE5B93); + writer.WriteTLObject(peer); + writer.WriteTLObject(settings); + return "Account_UpdateNotifySettings"; + }); + + ///See + public static Task Account_GetNotifySettings(this Client client, InputNotifyPeerBase peer) + => client.CallAsync(writer => + { + writer.Write(0x12B3AD31); + writer.WriteTLObject(peer); + return "Account_GetNotifySettings"; + }); + + ///See + public static Task Account_ResetNotifySettings(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xDB7E1747); + return "Account_ResetNotifySettings"; + }); + + ///See + public static Task Account_UpdateProfile(this Client client, string first_name = null, string last_name = null, string about = null) + => client.CallAsync(writer => + { + writer.Write(0x78515775); + writer.Write((first_name != null ? 0x1 : 0) | (last_name != null ? 0x2 : 0) | (about != null ? 0x4 : 0)); + if (first_name != null) + writer.WriteTLString(first_name); + if (last_name != null) + writer.WriteTLString(last_name); + if (about != null) + writer.WriteTLString(about); + return "Account_UpdateProfile"; + }); + + ///See + public static Task Account_UpdateStatus(this Client client, bool offline) + => client.CallAsync(writer => + { + writer.Write(0x6628562C); + writer.Write(offline ? 0x997275B5 : 0xBC799737); + return "Account_UpdateStatus"; + }); + + ///See + public static Task Account_GetWallPapers(this Client client, long hash) + => client.CallAsync(writer => + { + writer.Write(0x07967D36); + writer.Write(hash); + return "Account_GetWallPapers"; + }); + + ///See + public static Task Account_ReportPeer(this Client client, InputPeer peer, ReportReason reason, string message) + => client.CallAsync(writer => + { + writer.Write(0xC5BA3D86); + writer.WriteTLObject(peer); + writer.Write((uint)reason); + writer.WriteTLString(message); + return "Account_ReportPeer"; + }); + + ///See + public static Task Account_CheckUsername(this Client client, string username) + => client.CallAsync(writer => + { + writer.Write(0x2714D86C); + writer.WriteTLString(username); + return "Account_CheckUsername"; + }); + + ///See + public static Task Account_UpdateUsername(this Client client, string username) + => client.CallAsync(writer => + { + writer.Write(0x3E0BDD7C); + writer.WriteTLString(username); + return "Account_UpdateUsername"; + }); + + ///See + public static Task Account_GetPrivacy(this Client client, InputPrivacyKey key) + => client.CallAsync(writer => + { + writer.Write(0xDADBC950); + writer.Write((uint)key); + return "Account_GetPrivacy"; + }); + + ///See + public static Task Account_SetPrivacy(this Client client, InputPrivacyKey key, InputPrivacyRule[] rules) + => client.CallAsync(writer => + { + writer.Write(0xC9F81CE8); + writer.Write((uint)key); + writer.WriteTLVector(rules); + return "Account_SetPrivacy"; + }); + + ///See + public static Task Account_DeleteAccount(this Client client, string reason) + => client.CallAsync(writer => + { + writer.Write(0x418D4E0B); + writer.WriteTLString(reason); + return "Account_DeleteAccount"; + }); + + ///See + public static Task Account_GetAccountTTL(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x08FC711D); + return "Account_GetAccountTTL"; + }); + + ///See + public static Task Account_SetAccountTTL(this Client client, AccountDaysTTL ttl) + => client.CallAsync(writer => + { + writer.Write(0x2442485E); + writer.WriteTLObject(ttl); + return "Account_SetAccountTTL"; + }); + + ///See + public static Task Account_SendChangePhoneCode(this Client client, string phone_number, CodeSettings settings) + => client.CallAsync(writer => + { + writer.Write(0x82574AE5); + writer.WriteTLString(phone_number); + writer.WriteTLObject(settings); + return "Account_SendChangePhoneCode"; + }); + + ///See + public static Task Account_ChangePhone(this Client client, string phone_number, string phone_code_hash, string phone_code) + => client.CallAsync(writer => + { + writer.Write(0x70C32EDB); + writer.WriteTLString(phone_number); + writer.WriteTLString(phone_code_hash); + writer.WriteTLString(phone_code); + return "Account_ChangePhone"; + }); + + ///See + public static Task Account_UpdateDeviceLocked(this Client client, int period) + => client.CallAsync(writer => + { + writer.Write(0x38DF3532); + writer.Write(period); + return "Account_UpdateDeviceLocked"; + }); + + ///See + public static Task Account_GetAuthorizations(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xE320C158); + return "Account_GetAuthorizations"; + }); + + ///See + public static Task Account_ResetAuthorization(this Client client, long hash) + => client.CallAsync(writer => + { + writer.Write(0xDF77F3BC); + writer.Write(hash); + return "Account_ResetAuthorization"; + }); + + ///See + public static Task Account_GetPassword(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x548A30F5); + return "Account_GetPassword"; + }); + + ///See + public static Task Account_GetPasswordSettings(this Client client, InputCheckPasswordSRP password) + => client.CallAsync(writer => + { + writer.Write(0x9CD4EAF9); + writer.WriteTLObject(password); + return "Account_GetPasswordSettings"; + }); + + ///See + public static Task Account_UpdatePasswordSettings(this Client client, InputCheckPasswordSRP password, Account_PasswordInputSettings new_settings) + => client.CallAsync(writer => + { + writer.Write(0xA59B102F); + writer.WriteTLObject(password); + writer.WriteTLObject(new_settings); + return "Account_UpdatePasswordSettings"; + }); + + ///See + public static Task Account_SendConfirmPhoneCode(this Client client, string hash, CodeSettings settings) + => client.CallAsync(writer => + { + writer.Write(0x1B3FAA88); + writer.WriteTLString(hash); + writer.WriteTLObject(settings); + return "Account_SendConfirmPhoneCode"; + }); + + ///See + public static Task Account_ConfirmPhone(this Client client, string phone_code_hash, string phone_code) + => client.CallAsync(writer => + { + writer.Write(0x5F2178C3); + writer.WriteTLString(phone_code_hash); + writer.WriteTLString(phone_code); + return "Account_ConfirmPhone"; + }); + + ///See + public static Task Account_GetTmpPassword(this Client client, InputCheckPasswordSRP password, int period) + => client.CallAsync(writer => + { + writer.Write(0x449E0B51); + writer.WriteTLObject(password); + writer.Write(period); + return "Account_GetTmpPassword"; + }); + + ///See + public static Task Account_GetWebAuthorizations(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x182E6D6F); + return "Account_GetWebAuthorizations"; + }); + + ///See + public static Task Account_ResetWebAuthorization(this Client client, long hash) + => client.CallAsync(writer => + { + writer.Write(0x2D01B9EF); + writer.Write(hash); + return "Account_ResetWebAuthorization"; + }); + + ///See + public static Task Account_ResetWebAuthorizations(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x682D2594); + return "Account_ResetWebAuthorizations"; + }); + + ///See + public static Task Account_GetAllSecureValues(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xB288BC7D); + return "Account_GetAllSecureValues"; + }); + + ///See + public static Task Account_GetSecureValue(this Client client, SecureValueType[] types) + => client.CallAsync(writer => + { + writer.Write(0x73665BC2); + writer.WriteTLVector(types); + return "Account_GetSecureValue"; + }); + + ///See + public static Task Account_SaveSecureValue(this Client client, InputSecureValue value, long secure_secret_id) + => client.CallAsync(writer => + { + writer.Write(0x899FE31D); + writer.WriteTLObject(value); + writer.Write(secure_secret_id); + return "Account_SaveSecureValue"; + }); + + ///See + public static Task Account_DeleteSecureValue(this Client client, SecureValueType[] types) + => client.CallAsync(writer => + { + writer.Write(0xB880BC4B); + writer.WriteTLVector(types); + return "Account_DeleteSecureValue"; + }); + + ///See + public static Task Account_GetAuthorizationForm(this Client client, long bot_id, string scope, string public_key) + => client.CallAsync(writer => + { + writer.Write(0xA929597A); + writer.Write(bot_id); + writer.WriteTLString(scope); + writer.WriteTLString(public_key); + return "Account_GetAuthorizationForm"; + }); + + ///See + public static Task Account_AcceptAuthorization(this Client client, long bot_id, string scope, string public_key, SecureValueHash[] value_hashes, SecureCredentialsEncrypted credentials) + => client.CallAsync(writer => + { + writer.Write(0xF3ED4C73); + writer.Write(bot_id); + writer.WriteTLString(scope); + writer.WriteTLString(public_key); + writer.WriteTLVector(value_hashes); + writer.WriteTLObject(credentials); + return "Account_AcceptAuthorization"; + }); + + ///See + public static Task Account_SendVerifyPhoneCode(this Client client, string phone_number, CodeSettings settings) + => client.CallAsync(writer => + { + writer.Write(0xA5A356F9); + writer.WriteTLString(phone_number); + writer.WriteTLObject(settings); + return "Account_SendVerifyPhoneCode"; + }); + + ///See + public static Task Account_VerifyPhone(this Client client, string phone_number, string phone_code_hash, string phone_code) + => client.CallAsync(writer => + { + writer.Write(0x4DD3A7F6); + writer.WriteTLString(phone_number); + writer.WriteTLString(phone_code_hash); + writer.WriteTLString(phone_code); + return "Account_VerifyPhone"; + }); + + ///See + public static Task Account_SendVerifyEmailCode(this Client client, string email) + => client.CallAsync(writer => + { + writer.Write(0x7011509F); + writer.WriteTLString(email); + return "Account_SendVerifyEmailCode"; + }); + + ///See + public static Task Account_VerifyEmail(this Client client, string email, string code) + => client.CallAsync(writer => + { + writer.Write(0xECBA39DB); + writer.WriteTLString(email); + writer.WriteTLString(code); + return "Account_VerifyEmail"; + }); + + ///See + 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, int? file_max_size = null) + => client.CallAsync(writer => + { + writer.Write(0xF05B4804); + writer.Write((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)); + if (file_max_size != null) + writer.Write(file_max_size.Value); + return "Account_InitTakeoutSession"; + }); + + ///See + public static Task Account_FinishTakeoutSession(this Client client, bool success = false) + => client.CallAsync(writer => + { + writer.Write(0x1D2652EE); + writer.Write(success ? 0x1 : 0); + return "Account_FinishTakeoutSession"; + }); + + ///See + public static Task Account_ConfirmPasswordEmail(this Client client, string code) + => client.CallAsync(writer => + { + writer.Write(0x8FDF1920); + writer.WriteTLString(code); + return "Account_ConfirmPasswordEmail"; + }); + + ///See + public static Task Account_ResendPasswordEmail(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x7A7F2A15); + return "Account_ResendPasswordEmail"; + }); + + ///See + public static Task Account_CancelPasswordEmail(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xC1CBD5B6); + return "Account_CancelPasswordEmail"; + }); + + ///See + public static Task Account_GetContactSignUpNotification(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x9F07C728); + return "Account_GetContactSignUpNotification"; + }); + + ///See + public static Task Account_SetContactSignUpNotification(this Client client, bool silent) + => client.CallAsync(writer => + { + writer.Write(0xCFF43F61); + writer.Write(silent ? 0x997275B5 : 0xBC799737); + return "Account_SetContactSignUpNotification"; + }); + + ///See + public static Task Account_GetNotifyExceptions(this Client client, bool compare_sound = false, InputNotifyPeerBase peer = null) + => client.CallAsync(writer => + { + writer.Write(0x53577479); + writer.Write((compare_sound ? 0x2 : 0) | (peer != null ? 0x1 : 0)); + if (peer != null) + writer.WriteTLObject(peer); + return "Account_GetNotifyExceptions"; + }); + + ///See + public static Task Account_GetWallPaper(this Client client, InputWallPaperBase wallpaper) + => client.CallAsync(writer => + { + writer.Write(0xFC8DDBEA); + writer.WriteTLObject(wallpaper); + return "Account_GetWallPaper"; + }); + + ///See + public static Task Account_UploadWallPaper(this Client client, InputFileBase file, string mime_type, WallPaperSettings settings) + => client.CallAsync(writer => + { + writer.Write(0xDD853661); + writer.WriteTLObject(file); + writer.WriteTLString(mime_type); + writer.WriteTLObject(settings); + return "Account_UploadWallPaper"; + }); + + ///See + public static Task Account_SaveWallPaper(this Client client, InputWallPaperBase wallpaper, bool unsave, WallPaperSettings settings) + => client.CallAsync(writer => + { + writer.Write(0x6C5A5B37); + writer.WriteTLObject(wallpaper); + writer.Write(unsave ? 0x997275B5 : 0xBC799737); + writer.WriteTLObject(settings); + return "Account_SaveWallPaper"; + }); + + ///See + public static Task Account_InstallWallPaper(this Client client, InputWallPaperBase wallpaper, WallPaperSettings settings) + => client.CallAsync(writer => + { + writer.Write(0xFEED5769); + writer.WriteTLObject(wallpaper); + writer.WriteTLObject(settings); + return "Account_InstallWallPaper"; + }); + + ///See + public static Task Account_ResetWallPapers(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xBB3B9804); + return "Account_ResetWallPapers"; + }); + + ///See + public static Task Account_GetAutoDownloadSettings(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x56DA0B3F); + return "Account_GetAutoDownloadSettings"; + }); + + ///See + public static Task Account_SaveAutoDownloadSettings(this Client client, AutoDownloadSettings settings, bool low = false, bool high = false) + => client.CallAsync(writer => + { + writer.Write(0x76F36233); + writer.Write((low ? 0x1 : 0) | (high ? 0x2 : 0)); + writer.WriteTLObject(settings); + return "Account_SaveAutoDownloadSettings"; + }); + + ///See + public static Task Account_UploadTheme(this Client client, InputFileBase file, string file_name, string mime_type, InputFileBase thumb = null) + => client.CallAsync(writer => + { + writer.Write(0x1C3DB333); + writer.Write(thumb != null ? 0x1 : 0); + writer.WriteTLObject(file); + if (thumb != null) + writer.WriteTLObject(thumb); + writer.WriteTLString(file_name); + writer.WriteTLString(mime_type); + return "Account_UploadTheme"; + }); + + ///See + public static Task Account_CreateTheme(this Client client, string slug, string title, InputDocument document = null, InputThemeSettings settings = null) + => client.CallAsync(writer => + { + writer.Write(0x8432C21F); + writer.Write((document != null ? 0x4 : 0) | (settings != null ? 0x8 : 0)); + writer.WriteTLString(slug); + writer.WriteTLString(title); + if (document != null) + writer.WriteTLObject(document); + if (settings != null) + writer.WriteTLObject(settings); + return "Account_CreateTheme"; + }); + + ///See + public static Task Account_UpdateTheme(this Client client, string format, InputThemeBase theme, string slug = null, string title = null, InputDocument document = null, InputThemeSettings settings = null) + => client.CallAsync(writer => + { + writer.Write(0x5CB367D5); + writer.Write((slug != null ? 0x1 : 0) | (title != null ? 0x2 : 0) | (document != null ? 0x4 : 0) | (settings != null ? 0x8 : 0)); + writer.WriteTLString(format); + writer.WriteTLObject(theme); + if (slug != null) + writer.WriteTLString(slug); + if (title != null) + writer.WriteTLString(title); + if (document != null) + writer.WriteTLObject(document); + if (settings != null) + writer.WriteTLObject(settings); + return "Account_UpdateTheme"; + }); + + ///See + public static Task Account_SaveTheme(this Client client, InputThemeBase theme, bool unsave) + => client.CallAsync(writer => + { + writer.Write(0xF257106C); + writer.WriteTLObject(theme); + writer.Write(unsave ? 0x997275B5 : 0xBC799737); + return "Account_SaveTheme"; + }); + + ///See + public static Task Account_InstallTheme(this Client client, bool dark = false, string format = null, InputThemeBase theme = null) + => client.CallAsync(writer => + { + writer.Write(0x7AE43737); + writer.Write((dark ? 0x1 : 0) | (format != null ? 0x2 : 0) | (theme != null ? 0x2 : 0)); + if (format != null) + writer.WriteTLString(format); + if (theme != null) + writer.WriteTLObject(theme); + return "Account_InstallTheme"; + }); + + ///See + public static Task Account_GetTheme(this Client client, string format, InputThemeBase theme, long document_id) + => client.CallAsync(writer => + { + writer.Write(0x8D9D742B); + writer.WriteTLString(format); + writer.WriteTLObject(theme); + writer.Write(document_id); + return "Account_GetTheme"; + }); + + ///See + public static Task Account_GetThemes(this Client client, string format, long hash) + => client.CallAsync(writer => + { + writer.Write(0x7206E458); + writer.WriteTLString(format); + writer.Write(hash); + return "Account_GetThemes"; + }); + + ///See + public static Task Account_SetContentSettings(this Client client, bool sensitive_enabled = false) + => client.CallAsync(writer => + { + writer.Write(0xB574B16B); + writer.Write(sensitive_enabled ? 0x1 : 0); + return "Account_SetContentSettings"; + }); + + ///See + public static Task Account_GetContentSettings(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x8B9B4DAE); + return "Account_GetContentSettings"; + }); + + ///See + public static Task Account_GetMultiWallPapers(this Client client, InputWallPaperBase[] wallpapers) + => client.CallAsync(writer => + { + writer.Write(0x65AD71DC); + writer.WriteTLVector(wallpapers); + return "Account_GetMultiWallPapers"; + }); + + ///See + public static Task Account_GetGlobalPrivacySettings(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xEB2B4CF6); + return "Account_GetGlobalPrivacySettings"; + }); + + ///See + public static Task Account_SetGlobalPrivacySettings(this Client client, GlobalPrivacySettings settings) + => client.CallAsync(writer => + { + writer.Write(0x1EDAAAC2); + writer.WriteTLObject(settings); + return "Account_SetGlobalPrivacySettings"; + }); + + ///See + public static Task Account_ReportProfilePhoto(this Client client, InputPeer peer, InputPhoto photo_id, ReportReason reason, string message) + => client.CallAsync(writer => + { + writer.Write(0xFA8CC6F5); + writer.WriteTLObject(peer); + writer.WriteTLObject(photo_id); + writer.Write((uint)reason); + writer.WriteTLString(message); + return "Account_ReportProfilePhoto"; + }); + + ///See + public static Task Account_ResetPassword(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x9308CE1B); + return "Account_ResetPassword"; + }); + + ///See + public static Task Account_DeclinePasswordReset(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x4C9409F6); + return "Account_DeclinePasswordReset"; + }); + + ///See + public static Task Account_GetChatThemes(this Client client, int hash) + => client.CallAsync(writer => + { + writer.Write(0xD6D71D7B); + writer.Write(hash); + return "Account_GetChatThemes"; + }); + + ///See + public static Task Users_GetUsers(this Client client, InputUserBase[] id) + => client.CallAsync(writer => + { + writer.Write(0x0D91A548); + writer.WriteTLVector(id); + return "Users_GetUsers"; + }); + + ///See + public static Task Users_GetFullUser(this Client client, InputUserBase id) + => client.CallAsync(writer => + { + writer.Write(0xCA30A5B1); + writer.WriteTLObject(id); + return "Users_GetFullUser"; + }); + + ///See + public static Task Users_SetSecureValueErrors(this Client client, InputUserBase id, SecureValueErrorBase[] errors) + => client.CallAsync(writer => + { + writer.Write(0x90C894B5); + writer.WriteTLObject(id); + writer.WriteTLVector(errors); + return "Users_SetSecureValueErrors"; + }); + + ///See + public static Task Contacts_GetContactIDs(this Client client, long hash) + => client.CallAsync(writer => + { + writer.Write(0x7ADC669D); + writer.Write(hash); + return "Contacts_GetContactIDs"; + }); + + ///See + public static Task Contacts_GetStatuses(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xC4A353EE); + return "Contacts_GetStatuses"; + }); + + ///See + public static Task Contacts_GetContacts(this Client client, long hash) + => client.CallAsync(writer => + { + writer.Write(0x5DD69E12); + writer.Write(hash); + return "Contacts_GetContacts"; + }); + + ///See + public static Task Contacts_ImportContacts(this Client client, InputContact[] contacts) + => client.CallAsync(writer => + { + writer.Write(0x2C800BE5); + writer.WriteTLVector(contacts); + return "Contacts_ImportContacts"; + }); + + ///See + public static Task Contacts_DeleteContacts(this Client client, InputUserBase[] id) + => client.CallAsync(writer => + { + writer.Write(0x096A0E00); + writer.WriteTLVector(id); + return "Contacts_DeleteContacts"; + }); + + ///See + public static Task Contacts_DeleteByPhones(this Client client, string[] phones) + => client.CallAsync(writer => + { + writer.Write(0x1013FD9E); + writer.WriteTLVector(phones); + return "Contacts_DeleteByPhones"; + }); + + ///See + public static Task Contacts_Block(this Client client, InputPeer id) + => client.CallAsync(writer => + { + writer.Write(0x68CC1411); + writer.WriteTLObject(id); + return "Contacts_Block"; + }); + + ///See + public static Task Contacts_Unblock(this Client client, InputPeer id) + => client.CallAsync(writer => + { + writer.Write(0xBEA65D50); + writer.WriteTLObject(id); + return "Contacts_Unblock"; + }); + + ///See + public static Task Contacts_GetBlocked(this Client client, int offset, int limit) + => client.CallAsync(writer => + { + writer.Write(0xF57C350F); + writer.Write(offset); + writer.Write(limit); + return "Contacts_GetBlocked"; + }); + + ///See + public static Task Contacts_Search(this Client client, string q, int limit) + => client.CallAsync(writer => + { + writer.Write(0x11F812D8); + writer.WriteTLString(q); + writer.Write(limit); + return "Contacts_Search"; + }); + + ///See + public static Task Contacts_ResolveUsername(this Client client, string username) + => client.CallAsync(writer => + { + writer.Write(0xF93CCBA3); + writer.WriteTLString(username); + return "Contacts_ResolveUsername"; + }); + + ///See + public static Task Contacts_GetTopPeers(this Client client, int offset, int limit, long hash, bool correspondents = false, bool bots_pm = false, bool bots_inline = false, bool phone_calls = false, bool forward_users = false, bool forward_chats = false, bool groups = false, bool channels = false) + => client.CallAsync(writer => + { + writer.Write(0x973478B6); + writer.Write((correspondents ? 0x1 : 0) | (bots_pm ? 0x2 : 0) | (bots_inline ? 0x4 : 0) | (phone_calls ? 0x8 : 0) | (forward_users ? 0x10 : 0) | (forward_chats ? 0x20 : 0) | (groups ? 0x400 : 0) | (channels ? 0x8000 : 0)); + writer.Write(offset); + writer.Write(limit); + writer.Write(hash); + return "Contacts_GetTopPeers"; + }); + + ///See + public static Task Contacts_ResetTopPeerRating(this Client client, TopPeerCategory category, InputPeer peer) + => client.CallAsync(writer => + { + writer.Write(0x1AE373AC); + writer.Write((uint)category); + writer.WriteTLObject(peer); + return "Contacts_ResetTopPeerRating"; + }); + + ///See + public static Task Contacts_ResetSaved(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x879537F1); + return "Contacts_ResetSaved"; + }); + + ///See + public static Task Contacts_GetSaved(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x82F1E39F); + return "Contacts_GetSaved"; + }); + + ///See + public static Task Contacts_ToggleTopPeers(this Client client, bool enabled) + => client.CallAsync(writer => + { + writer.Write(0x8514BDDA); + writer.Write(enabled ? 0x997275B5 : 0xBC799737); + return "Contacts_ToggleTopPeers"; + }); + + ///See + public static Task Contacts_AddContact(this Client client, InputUserBase id, string first_name, string last_name, string phone, bool add_phone_privacy_exception = false) + => client.CallAsync(writer => + { + writer.Write(0xE8F463D0); + writer.Write(add_phone_privacy_exception ? 0x1 : 0); + writer.WriteTLObject(id); + writer.WriteTLString(first_name); + writer.WriteTLString(last_name); + writer.WriteTLString(phone); + return "Contacts_AddContact"; + }); + + ///See + public static Task Contacts_AcceptContact(this Client client, InputUserBase id) + => client.CallAsync(writer => + { + writer.Write(0xF831A20F); + writer.WriteTLObject(id); + return "Contacts_AcceptContact"; + }); + + ///See + public static Task Contacts_GetLocated(this Client client, InputGeoPoint geo_point, bool background = false, int? self_expires = null) + => client.CallAsync(writer => + { + writer.Write(0xD348BC44); + writer.Write((background ? 0x2 : 0) | (self_expires != null ? 0x1 : 0)); + writer.WriteTLObject(geo_point); + if (self_expires != null) + writer.Write(self_expires.Value); + return "Contacts_GetLocated"; + }); + + ///See + public static Task Contacts_BlockFromReplies(this Client client, int msg_id, bool delete_message = false, bool delete_history = false, bool report_spam = false) + => client.CallAsync(writer => + { + writer.Write(0x29A8962C); + writer.Write((delete_message ? 0x1 : 0) | (delete_history ? 0x2 : 0) | (report_spam ? 0x4 : 0)); + writer.Write(msg_id); + return "Contacts_BlockFromReplies"; + }); + + ///See + public static Task Messages_GetMessages(this Client client, InputMessage[] id) + => client.CallAsync(writer => + { + writer.Write(0x63C66506); + writer.WriteTLVector(id); + return "Messages_GetMessages"; + }); + + ///See + public static Task Messages_GetDialogs(this Client client, DateTime offset_date, int offset_id, InputPeer offset_peer, int limit, long hash, bool exclude_pinned = false, int? folder_id = null) + => client.CallAsync(writer => + { + writer.Write(0xA0F4CB4F); + writer.Write((exclude_pinned ? 0x1 : 0) | (folder_id != null ? 0x2 : 0)); + if (folder_id != null) + writer.Write(folder_id.Value); + writer.WriteTLStamp(offset_date); + writer.Write(offset_id); + writer.WriteTLObject(offset_peer); + writer.Write(limit); + writer.Write(hash); + return "Messages_GetDialogs"; + }); + + ///See + public static Task Messages_GetHistory(this Client client, InputPeer peer, int offset_id, DateTime offset_date, int add_offset, int limit, int max_id, int min_id, long hash) + => client.CallAsync(writer => + { + writer.Write(0x4423E6C5); + writer.WriteTLObject(peer); + writer.Write(offset_id); + writer.WriteTLStamp(offset_date); + writer.Write(add_offset); + writer.Write(limit); + writer.Write(max_id); + writer.Write(min_id); + writer.Write(hash); + return "Messages_GetHistory"; + }); + + ///See + public static Task Messages_Search(this Client client, InputPeer peer, string q, MessagesFilter filter, DateTime min_date, DateTime max_date, int offset_id, int add_offset, int limit, int max_id, int min_id, long hash, InputPeer from_id = null, int? top_msg_id = null) + => client.CallAsync(writer => + { + writer.Write(0xA0FDA762); + writer.Write((from_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x2 : 0)); + writer.WriteTLObject(peer); + writer.WriteTLString(q); + if (from_id != null) + writer.WriteTLObject(from_id); + if (top_msg_id != null) + writer.Write(top_msg_id.Value); + writer.WriteTLObject(filter); + writer.WriteTLStamp(min_date); + writer.WriteTLStamp(max_date); + writer.Write(offset_id); + writer.Write(add_offset); + writer.Write(limit); + writer.Write(max_id); + writer.Write(min_id); + writer.Write(hash); + return "Messages_Search"; + }); + + ///See + public static Task Messages_ReadHistory(this Client client, InputPeer peer, int max_id) + => client.CallAsync(writer => + { + writer.Write(0x0E306D3A); + writer.WriteTLObject(peer); + writer.Write(max_id); + return "Messages_ReadHistory"; + }); + + ///See + public static Task Messages_DeleteHistory(this Client client, InputPeer peer, int max_id, bool just_clear = false, bool revoke = false) + => client.CallAsync(writer => + { + writer.Write(0x1C015B09); + writer.Write((just_clear ? 0x1 : 0) | (revoke ? 0x2 : 0)); + writer.WriteTLObject(peer); + writer.Write(max_id); + return "Messages_DeleteHistory"; + }); + + ///See + public static Task Messages_DeleteMessages(this Client client, int[] id, bool revoke = false) + => client.CallAsync(writer => + { + writer.Write(0xE58E95D2); + writer.Write(revoke ? 0x1 : 0); + writer.WriteTLVector(id); + return "Messages_DeleteMessages"; + }); + + ///See + public static Task Messages_ReceivedMessages(this Client client, int max_id) + => client.CallAsync(writer => + { + writer.Write(0x05A954C0); + writer.Write(max_id); + return "Messages_ReceivedMessages"; + }); + + ///See + public static Task Messages_SetTyping(this Client client, InputPeer peer, SendMessageAction action, int? top_msg_id = null) + => client.CallAsync(writer => + { + writer.Write(0x58943EE2); + writer.Write(top_msg_id != null ? 0x1 : 0); + writer.WriteTLObject(peer); + if (top_msg_id != null) + writer.Write(top_msg_id.Value); + writer.WriteTLObject(action); + return "Messages_SetTyping"; + }); + + ///See + 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, int? reply_to_msg_id = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null) + => client.CallAsync(writer => + { + writer.Write(0x520C3870); + writer.Write((no_webpage ? 0x2 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x400 : 0)); + writer.WriteTLObject(peer); + if (reply_to_msg_id != null) + writer.Write(reply_to_msg_id.Value); + writer.WriteTLString(message); + writer.Write(random_id); + if (reply_markup != null) + writer.WriteTLObject(reply_markup); + if (entities != null) + writer.WriteTLVector(entities); + if (schedule_date != null) + writer.WriteTLStamp(schedule_date.Value); + return "Messages_SendMessage"; + }); + + ///See + 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, int? reply_to_msg_id = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null) + => client.CallAsync(writer => + { + writer.Write(0x3491EBA9); + writer.Write((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x400 : 0)); + writer.WriteTLObject(peer); + if (reply_to_msg_id != null) + writer.Write(reply_to_msg_id.Value); + writer.WriteTLObject(media); + writer.WriteTLString(message); + writer.Write(random_id); + if (reply_markup != null) + writer.WriteTLObject(reply_markup); + if (entities != null) + writer.WriteTLVector(entities); + if (schedule_date != null) + writer.WriteTLStamp(schedule_date.Value); + return "Messages_SendMedia"; + }); + + ///See + 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, DateTime? schedule_date = null) + => client.CallAsync(writer => + { + writer.Write(0xD9FEE60E); + writer.Write((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (with_my_score ? 0x100 : 0) | (drop_author ? 0x800 : 0) | (drop_media_captions ? 0x1000 : 0) | (schedule_date != null ? 0x400 : 0)); + writer.WriteTLObject(from_peer); + writer.WriteTLVector(id); + writer.WriteTLVector(random_id); + writer.WriteTLObject(to_peer); + if (schedule_date != null) + writer.WriteTLStamp(schedule_date.Value); + return "Messages_ForwardMessages"; + }); + + ///See + public static Task Messages_ReportSpam(this Client client, InputPeer peer) + => client.CallAsync(writer => + { + writer.Write(0xCF1592DB); + writer.WriteTLObject(peer); + return "Messages_ReportSpam"; + }); + + ///See + public static Task Messages_GetPeerSettings(this Client client, InputPeer peer) + => client.CallAsync(writer => + { + writer.Write(0x3672E09C); + writer.WriteTLObject(peer); + return "Messages_GetPeerSettings"; + }); + + ///See + public static Task Messages_Report(this Client client, InputPeer peer, int[] id, ReportReason reason, string message) + => client.CallAsync(writer => + { + writer.Write(0x8953AB4E); + writer.WriteTLObject(peer); + writer.WriteTLVector(id); + writer.Write((uint)reason); + writer.WriteTLString(message); + return "Messages_Report"; + }); + + ///See + public static Task Messages_GetChats(this Client client, long[] id) + => client.CallAsync(writer => + { + writer.Write(0x49E9528F); + writer.WriteTLVector(id); + return "Messages_GetChats"; + }); + + ///See + public static Task Messages_GetFullChat(this Client client, long chat_id) + => client.CallAsync(writer => + { + writer.Write(0xAEB00B34); + writer.Write(chat_id); + return "Messages_GetFullChat"; + }); + + ///See + public static Task Messages_EditChatTitle(this Client client, long chat_id, string title) + => client.CallAsync(writer => + { + writer.Write(0x73783FFD); + writer.Write(chat_id); + writer.WriteTLString(title); + return "Messages_EditChatTitle"; + }); + + ///See + public static Task Messages_EditChatPhoto(this Client client, long chat_id, InputChatPhotoBase photo) + => client.CallAsync(writer => + { + writer.Write(0x35DDD674); + writer.Write(chat_id); + writer.WriteTLObject(photo); + return "Messages_EditChatPhoto"; + }); + + ///See + public static Task Messages_AddChatUser(this Client client, long chat_id, InputUserBase user_id, int fwd_limit) + => client.CallAsync(writer => + { + writer.Write(0xF24753E3); + writer.Write(chat_id); + writer.WriteTLObject(user_id); + writer.Write(fwd_limit); + return "Messages_AddChatUser"; + }); + + ///See + public static Task Messages_DeleteChatUser(this Client client, long chat_id, InputUserBase user_id, bool revoke_history = false) + => client.CallAsync(writer => + { + writer.Write(0xA2185CAB); + writer.Write(revoke_history ? 0x1 : 0); + writer.Write(chat_id); + writer.WriteTLObject(user_id); + return "Messages_DeleteChatUser"; + }); + + ///See + public static Task Messages_CreateChat(this Client client, InputUserBase[] users, string title) + => client.CallAsync(writer => + { + writer.Write(0x09CB126E); + writer.WriteTLVector(users); + writer.WriteTLString(title); + return "Messages_CreateChat"; + }); + + ///See + public static Task Messages_GetDhConfig(this Client client, int version, int random_length) + => client.CallAsync(writer => + { + writer.Write(0x26CF8950); + writer.Write(version); + writer.Write(random_length); + return "Messages_GetDhConfig"; + }); + + ///See + public static Task Messages_RequestEncryption(this Client client, InputUserBase user_id, int random_id, byte[] g_a) + => client.CallAsync(writer => + { + writer.Write(0xF64DAF43); + writer.WriteTLObject(user_id); + writer.Write(random_id); + writer.WriteTLBytes(g_a); + return "Messages_RequestEncryption"; + }); + + ///See + public static Task Messages_AcceptEncryption(this Client client, InputEncryptedChat peer, byte[] g_b, long key_fingerprint) + => client.CallAsync(writer => + { + writer.Write(0x3DBC0415); + writer.WriteTLObject(peer); + writer.WriteTLBytes(g_b); + writer.Write(key_fingerprint); + return "Messages_AcceptEncryption"; + }); + + ///See + public static Task Messages_DiscardEncryption(this Client client, int chat_id, bool delete_history = false) + => client.CallAsync(writer => + { + writer.Write(0xF393AEA0); + writer.Write(delete_history ? 0x1 : 0); + writer.Write(chat_id); + return "Messages_DiscardEncryption"; + }); + + ///See + public static Task Messages_SetEncryptedTyping(this Client client, InputEncryptedChat peer, bool typing) + => client.CallAsync(writer => + { + writer.Write(0x791451ED); + writer.WriteTLObject(peer); + writer.Write(typing ? 0x997275B5 : 0xBC799737); + return "Messages_SetEncryptedTyping"; + }); + + ///See + public static Task Messages_ReadEncryptedHistory(this Client client, InputEncryptedChat peer, DateTime max_date) + => client.CallAsync(writer => + { + writer.Write(0x7F4B690A); + writer.WriteTLObject(peer); + writer.WriteTLStamp(max_date); + return "Messages_ReadEncryptedHistory"; + }); + + ///See + public static Task Messages_SendEncrypted(this Client client, InputEncryptedChat peer, long random_id, byte[] data, bool silent = false) + => client.CallAsync(writer => + { + writer.Write(0x44FA7A15); + writer.Write(silent ? 0x1 : 0); + writer.WriteTLObject(peer); + writer.Write(random_id); + writer.WriteTLBytes(data); + return "Messages_SendEncrypted"; + }); + + ///See + public static Task Messages_SendEncryptedFile(this Client client, InputEncryptedChat peer, long random_id, byte[] data, InputEncryptedFileBase file, bool silent = false) + => client.CallAsync(writer => + { + writer.Write(0x5559481D); + writer.Write(silent ? 0x1 : 0); + writer.WriteTLObject(peer); + writer.Write(random_id); + writer.WriteTLBytes(data); + writer.WriteTLObject(file); + return "Messages_SendEncryptedFile"; + }); + + ///See + public static Task Messages_SendEncryptedService(this Client client, InputEncryptedChat peer, long random_id, byte[] data) + => client.CallAsync(writer => + { + writer.Write(0x32D439A4); + writer.WriteTLObject(peer); + writer.Write(random_id); + writer.WriteTLBytes(data); + return "Messages_SendEncryptedService"; + }); + + ///See + public static Task Messages_ReceivedQueue(this Client client, int max_qts) + => client.CallAsync(writer => + { + writer.Write(0x55A5BB66); + writer.Write(max_qts); + return "Messages_ReceivedQueue"; + }); + + ///See + public static Task Messages_ReportEncryptedSpam(this Client client, InputEncryptedChat peer) + => client.CallAsync(writer => + { + writer.Write(0x4B0C8C0F); + writer.WriteTLObject(peer); + return "Messages_ReportEncryptedSpam"; + }); + + ///See + public static Task Messages_ReadMessageContents(this Client client, int[] id) + => client.CallAsync(writer => + { + writer.Write(0x36A73F77); + writer.WriteTLVector(id); + return "Messages_ReadMessageContents"; + }); + + ///See + public static Task Messages_GetStickers(this Client client, string emoticon, long hash) + => client.CallAsync(writer => + { + writer.Write(0xD5A5D3A1); + writer.WriteTLString(emoticon); + writer.Write(hash); + return "Messages_GetStickers"; + }); + + ///See + public static Task Messages_GetAllStickers(this Client client, long hash) + => client.CallAsync(writer => + { + writer.Write(0xB8A0A1A8); + writer.Write(hash); + return "Messages_GetAllStickers"; + }); + + ///See + public static Task Messages_GetWebPagePreview(this Client client, string message, MessageEntity[] entities = null) + => client.CallAsync(writer => + { + writer.Write(0x8B68B0CC); + writer.Write(entities != null ? 0x8 : 0); + writer.WriteTLString(message); + if (entities != null) + writer.WriteTLVector(entities); + return "Messages_GetWebPagePreview"; + }); + + ///See + public static Task Messages_ExportChatInvite(this Client client, InputPeer peer, bool legacy_revoke_permanent = false, DateTime? expire_date = null, int? usage_limit = null) + => client.CallAsync(writer => + { + writer.Write(0x14B9BCD7); + writer.Write((legacy_revoke_permanent ? 0x4 : 0) | (expire_date != null ? 0x1 : 0) | (usage_limit != null ? 0x2 : 0)); + writer.WriteTLObject(peer); + if (expire_date != null) + writer.WriteTLStamp(expire_date.Value); + if (usage_limit != null) + writer.Write(usage_limit.Value); + return "Messages_ExportChatInvite"; + }); + + ///See + public static Task Messages_CheckChatInvite(this Client client, string hash) + => client.CallAsync(writer => + { + writer.Write(0x3EADB1BB); + writer.WriteTLString(hash); + return "Messages_CheckChatInvite"; + }); + + ///See + public static Task Messages_ImportChatInvite(this Client client, string hash) + => client.CallAsync(writer => + { + writer.Write(0x6C50051C); + writer.WriteTLString(hash); + return "Messages_ImportChatInvite"; + }); + + ///See + public static Task Messages_GetStickerSet(this Client client, InputStickerSet stickerset) + => client.CallAsync(writer => + { + writer.Write(0x2619A90E); + writer.WriteTLObject(stickerset); + return "Messages_GetStickerSet"; + }); + + ///See + public static Task Messages_InstallStickerSet(this Client client, InputStickerSet stickerset, bool archived) + => client.CallAsync(writer => + { + writer.Write(0xC78FE460); + writer.WriteTLObject(stickerset); + writer.Write(archived ? 0x997275B5 : 0xBC799737); + return "Messages_InstallStickerSet"; + }); + + ///See + public static Task Messages_UninstallStickerSet(this Client client, InputStickerSet stickerset) + => client.CallAsync(writer => + { + writer.Write(0xF96E55DE); + writer.WriteTLObject(stickerset); + return "Messages_UninstallStickerSet"; + }); + + ///See + public static Task Messages_StartBot(this Client client, InputUserBase bot, InputPeer peer, long random_id, string start_param) + => client.CallAsync(writer => + { + writer.Write(0xE6DF7378); + writer.WriteTLObject(bot); + writer.WriteTLObject(peer); + writer.Write(random_id); + writer.WriteTLString(start_param); + return "Messages_StartBot"; + }); + + ///See + public static Task Messages_GetMessagesViews(this Client client, InputPeer peer, int[] id, bool increment) + => client.CallAsync(writer => + { + writer.Write(0x5784D3E1); + writer.WriteTLObject(peer); + writer.WriteTLVector(id); + writer.Write(increment ? 0x997275B5 : 0xBC799737); + return "Messages_GetMessagesViews"; + }); + + ///See + public static Task Messages_EditChatAdmin(this Client client, long chat_id, InputUserBase user_id, bool is_admin) + => client.CallAsync(writer => + { + writer.Write(0xA85BD1C2); + writer.Write(chat_id); + writer.WriteTLObject(user_id); + writer.Write(is_admin ? 0x997275B5 : 0xBC799737); + return "Messages_EditChatAdmin"; + }); + + ///See + public static Task Messages_MigrateChat(this Client client, long chat_id) + => client.CallAsync(writer => + { + writer.Write(0xA2875319); + writer.Write(chat_id); + return "Messages_MigrateChat"; + }); + + ///See + public static Task Messages_SearchGlobal(this Client client, string q, MessagesFilter filter, DateTime min_date, DateTime max_date, int offset_rate, InputPeer offset_peer, int offset_id, int limit, int? folder_id = null) + => client.CallAsync(writer => + { + writer.Write(0x4BC6589A); + writer.Write(folder_id != null ? 0x1 : 0); + if (folder_id != null) + writer.Write(folder_id.Value); + writer.WriteTLString(q); + writer.WriteTLObject(filter); + writer.WriteTLStamp(min_date); + writer.WriteTLStamp(max_date); + writer.Write(offset_rate); + writer.WriteTLObject(offset_peer); + writer.Write(offset_id); + writer.Write(limit); + return "Messages_SearchGlobal"; + }); + + ///See + public static Task Messages_ReorderStickerSets(this Client client, long[] order, bool masks = false) + => client.CallAsync(writer => + { + writer.Write(0x78337739); + writer.Write(masks ? 0x1 : 0); + writer.WriteTLVector(order); + return "Messages_ReorderStickerSets"; + }); + + ///See + public static Task Messages_GetDocumentByHash(this Client client, byte[] sha256, int size, string mime_type) + => client.CallAsync(writer => + { + writer.Write(0x338E2464); + writer.WriteTLBytes(sha256); + writer.Write(size); + writer.WriteTLString(mime_type); + return "Messages_GetDocumentByHash"; + }); + + ///See + public static Task Messages_GetSavedGifs(this Client client, long hash) + => client.CallAsync(writer => + { + writer.Write(0x5CF09635); + writer.Write(hash); + return "Messages_GetSavedGifs"; + }); + + ///See + public static Task Messages_SaveGif(this Client client, InputDocument id, bool unsave) + => client.CallAsync(writer => + { + writer.Write(0x327A30CB); + writer.WriteTLObject(id); + writer.Write(unsave ? 0x997275B5 : 0xBC799737); + return "Messages_SaveGif"; + }); + + ///See + public static Task Messages_GetInlineBotResults(this Client client, InputUserBase bot, InputPeer peer, string query, string offset, InputGeoPoint geo_point = null) + => client.CallAsync(writer => + { + writer.Write(0x514E999D); + writer.Write(geo_point != null ? 0x1 : 0); + writer.WriteTLObject(bot); + writer.WriteTLObject(peer); + if (geo_point != null) + writer.WriteTLObject(geo_point); + writer.WriteTLString(query); + writer.WriteTLString(offset); + return "Messages_GetInlineBotResults"; + }); + + ///See + 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) + => client.CallAsync(writer => + { + writer.Write(0xEB5EA206); + writer.Write((gallery ? 0x1 : 0) | (private_ ? 0x2 : 0) | (next_offset != null ? 0x4 : 0) | (switch_pm != null ? 0x8 : 0)); + writer.Write(query_id); + writer.WriteTLVector(results); + writer.WriteTLStamp(cache_time); + if (next_offset != null) + writer.WriteTLString(next_offset); + if (switch_pm != null) + writer.WriteTLObject(switch_pm); + return "Messages_SetInlineBotResults"; + }); + + ///See + 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) + => client.CallAsync(writer => + { + writer.Write(0x220815B0); + writer.Write((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)); + writer.WriteTLObject(peer); + if (reply_to_msg_id != null) + writer.Write(reply_to_msg_id.Value); + writer.Write(random_id); + writer.Write(query_id); + writer.WriteTLString(id); + if (schedule_date != null) + writer.WriteTLStamp(schedule_date.Value); + return "Messages_SendInlineBotResult"; + }); + + ///See + public static Task Messages_GetMessageEditData(this Client client, InputPeer peer, int id) + => client.CallAsync(writer => + { + writer.Write(0xFDA68D36); + writer.WriteTLObject(peer); + writer.Write(id); + return "Messages_GetMessageEditData"; + }); + + ///See + 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) + => client.CallAsync(writer => + { + writer.Write(0x48F71778); + writer.Write((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)); + writer.WriteTLObject(peer); + writer.Write(id); + if (message != null) + writer.WriteTLString(message); + if (media != null) + writer.WriteTLObject(media); + if (reply_markup != null) + writer.WriteTLObject(reply_markup); + if (entities != null) + writer.WriteTLVector(entities); + if (schedule_date != null) + writer.WriteTLStamp(schedule_date.Value); + return "Messages_EditMessage"; + }); + + ///See + 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) + => client.CallAsync(writer => + { + writer.Write(0x83557DBA); + writer.Write((no_webpage ? 0x2 : 0) | (message != null ? 0x800 : 0) | (media != null ? 0x4000 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0)); + writer.WriteTLObject(id); + if (message != null) + writer.WriteTLString(message); + if (media != null) + writer.WriteTLObject(media); + if (reply_markup != null) + writer.WriteTLObject(reply_markup); + if (entities != null) + writer.WriteTLVector(entities); + return "Messages_EditInlineBotMessage"; + }); + + ///See + public static Task Messages_GetBotCallbackAnswer(this Client client, InputPeer peer, int msg_id, bool game = false, byte[] data = null, InputCheckPasswordSRP password = null) + => client.CallAsync(writer => + { + writer.Write(0x9342CA07); + writer.Write((game ? 0x2 : 0) | (data != null ? 0x1 : 0) | (password != null ? 0x4 : 0)); + writer.WriteTLObject(peer); + writer.Write(msg_id); + if (data != null) + writer.WriteTLBytes(data); + if (password != null) + writer.WriteTLObject(password); + return "Messages_GetBotCallbackAnswer"; + }); + + ///See + public static Task Messages_SetBotCallbackAnswer(this Client client, long query_id, DateTime cache_time, bool alert = false, string message = null, string url = null) + => client.CallAsync(writer => + { + writer.Write(0xD58F130A); + writer.Write((alert ? 0x2 : 0) | (message != null ? 0x1 : 0) | (url != null ? 0x4 : 0)); + writer.Write(query_id); + if (message != null) + writer.WriteTLString(message); + if (url != null) + writer.WriteTLString(url); + writer.WriteTLStamp(cache_time); + return "Messages_SetBotCallbackAnswer"; + }); + + ///See + public static Task Messages_GetPeerDialogs(this Client client, InputDialogPeerBase[] peers) + => client.CallAsync(writer => + { + writer.Write(0xE470BCFD); + writer.WriteTLVector(peers); + return "Messages_GetPeerDialogs"; + }); + + ///See + 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) + => client.CallAsync(writer => + { + writer.Write(0xBC39E14B); + writer.Write((no_webpage ? 0x2 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (entities != null ? 0x8 : 0)); + if (reply_to_msg_id != null) + writer.Write(reply_to_msg_id.Value); + writer.WriteTLObject(peer); + writer.WriteTLString(message); + if (entities != null) + writer.WriteTLVector(entities); + return "Messages_SaveDraft"; + }); + + ///See + public static Task Messages_GetAllDrafts(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x6A3F8D65); + return "Messages_GetAllDrafts"; + }); + + ///See + public static Task Messages_GetFeaturedStickers(this Client client, long hash) + => client.CallAsync(writer => + { + writer.Write(0x64780B14); + writer.Write(hash); + return "Messages_GetFeaturedStickers"; + }); + + ///See + public static Task Messages_ReadFeaturedStickers(this Client client, long[] id) + => client.CallAsync(writer => + { + writer.Write(0x5B118126); + writer.WriteTLVector(id); + return "Messages_ReadFeaturedStickers"; + }); + + ///See + public static Task Messages_GetRecentStickers(this Client client, long hash, bool attached = false) + => client.CallAsync(writer => + { + writer.Write(0x9DA9403B); + writer.Write(attached ? 0x1 : 0); + writer.Write(hash); + return "Messages_GetRecentStickers"; + }); + + ///See + public static Task Messages_SaveRecentSticker(this Client client, InputDocument id, bool unsave, bool attached = false) + => client.CallAsync(writer => + { + writer.Write(0x392718F8); + writer.Write(attached ? 0x1 : 0); + writer.WriteTLObject(id); + writer.Write(unsave ? 0x997275B5 : 0xBC799737); + return "Messages_SaveRecentSticker"; + }); + + ///See + public static Task Messages_ClearRecentStickers(this Client client, bool attached = false) + => client.CallAsync(writer => + { + writer.Write(0x8999602D); + writer.Write(attached ? 0x1 : 0); + return "Messages_ClearRecentStickers"; + }); + + ///See + public static Task Messages_GetArchivedStickers(this Client client, long offset_id, int limit, bool masks = false) + => client.CallAsync(writer => + { + writer.Write(0x57F17692); + writer.Write(masks ? 0x1 : 0); + writer.Write(offset_id); + writer.Write(limit); + return "Messages_GetArchivedStickers"; + }); + + ///See + public static Task Messages_GetMaskStickers(this Client client, long hash) + => client.CallAsync(writer => + { + writer.Write(0x640F82B8); + writer.Write(hash); + return "Messages_GetMaskStickers"; + }); + + ///See + public static Task Messages_GetAttachedStickers(this Client client, InputStickeredMedia media) + => client.CallAsync(writer => + { + writer.Write(0xCC5B67CC); + writer.WriteTLObject(media); + return "Messages_GetAttachedStickers"; + }); + + ///See + public static Task Messages_SetGameScore(this Client client, InputPeer peer, int id, InputUserBase user_id, int score, bool edit_message = false, bool force = false) + => client.CallAsync(writer => + { + writer.Write(0x8EF8ECC0); + writer.Write((edit_message ? 0x1 : 0) | (force ? 0x2 : 0)); + writer.WriteTLObject(peer); + writer.Write(id); + writer.WriteTLObject(user_id); + writer.Write(score); + return "Messages_SetGameScore"; + }); + + ///See + public static Task Messages_SetInlineGameScore(this Client client, InputBotInlineMessageIDBase id, InputUserBase user_id, int score, bool edit_message = false, bool force = false) + => client.CallAsync(writer => + { + writer.Write(0x15AD9F64); + writer.Write((edit_message ? 0x1 : 0) | (force ? 0x2 : 0)); + writer.WriteTLObject(id); + writer.WriteTLObject(user_id); + writer.Write(score); + return "Messages_SetInlineGameScore"; + }); + + ///See + public static Task Messages_GetGameHighScores(this Client client, InputPeer peer, int id, InputUserBase user_id) + => client.CallAsync(writer => + { + writer.Write(0xE822649D); + writer.WriteTLObject(peer); + writer.Write(id); + writer.WriteTLObject(user_id); + return "Messages_GetGameHighScores"; + }); + + ///See + public static Task Messages_GetInlineGameHighScores(this Client client, InputBotInlineMessageIDBase id, InputUserBase user_id) + => client.CallAsync(writer => + { + writer.Write(0x0F635E1B); + writer.WriteTLObject(id); + writer.WriteTLObject(user_id); + return "Messages_GetInlineGameHighScores"; + }); + + ///See + public static Task Messages_GetCommonChats(this Client client, InputUserBase user_id, long max_id, int limit) + => client.CallAsync(writer => + { + writer.Write(0xE40CA104); + writer.WriteTLObject(user_id); + writer.Write(max_id); + writer.Write(limit); + return "Messages_GetCommonChats"; + }); + + ///See + public static Task Messages_GetAllChats(this Client client, long[] except_ids) + => client.CallAsync(writer => + { + writer.Write(0x875F74BE); + writer.WriteTLVector(except_ids); + return "Messages_GetAllChats"; + }); + + ///See + public static Task Messages_GetWebPage(this Client client, string url, int hash) + => client.CallAsync(writer => + { + writer.Write(0x32CA8F91); + writer.WriteTLString(url); + writer.Write(hash); + return "Messages_GetWebPage"; + }); + + ///See + public static Task Messages_ToggleDialogPin(this Client client, InputDialogPeerBase peer, bool pinned = false) + => client.CallAsync(writer => + { + writer.Write(0xA731E257); + writer.Write(pinned ? 0x1 : 0); + writer.WriteTLObject(peer); + return "Messages_ToggleDialogPin"; + }); + + ///See + public static Task Messages_ReorderPinnedDialogs(this Client client, int folder_id, InputDialogPeerBase[] order, bool force = false) + => client.CallAsync(writer => + { + writer.Write(0x3B1ADF37); + writer.Write(force ? 0x1 : 0); + writer.Write(folder_id); + writer.WriteTLVector(order); + return "Messages_ReorderPinnedDialogs"; + }); + + ///See + public static Task Messages_GetPinnedDialogs(this Client client, int folder_id) + => client.CallAsync(writer => + { + writer.Write(0xD6B94DF2); + writer.Write(folder_id); + return "Messages_GetPinnedDialogs"; + }); + + ///See + public static Task Messages_SetBotShippingResults(this Client client, long query_id, string error = null, ShippingOption[] shipping_options = null) + => client.CallAsync(writer => + { + writer.Write(0xE5F672FA); + writer.Write((error != null ? 0x1 : 0) | (shipping_options != null ? 0x2 : 0)); + writer.Write(query_id); + if (error != null) + writer.WriteTLString(error); + if (shipping_options != null) + writer.WriteTLVector(shipping_options); + return "Messages_SetBotShippingResults"; + }); + + ///See + public static Task Messages_SetBotPrecheckoutResults(this Client client, long query_id, bool success = false, string error = null) + => client.CallAsync(writer => + { + writer.Write(0x09C2DD95); + writer.Write((success ? 0x2 : 0) | (error != null ? 0x1 : 0)); + writer.Write(query_id); + if (error != null) + writer.WriteTLString(error); + return "Messages_SetBotPrecheckoutResults"; + }); + + ///See + public static Task Messages_UploadMedia(this Client client, InputPeer peer, InputMedia media) + => client.CallAsync(writer => + { + writer.Write(0x519BC2B1); + writer.WriteTLObject(peer); + writer.WriteTLObject(media); + return "Messages_UploadMedia"; + }); + + ///See + public static Task Messages_SendScreenshotNotification(this Client client, InputPeer peer, int reply_to_msg_id, long random_id) + => client.CallAsync(writer => + { + writer.Write(0xC97DF020); + writer.WriteTLObject(peer); + writer.Write(reply_to_msg_id); + writer.Write(random_id); + return "Messages_SendScreenshotNotification"; + }); + + ///See + public static Task Messages_GetFavedStickers(this Client client, long hash) + => client.CallAsync(writer => + { + writer.Write(0x04F1AAA9); + writer.Write(hash); + return "Messages_GetFavedStickers"; + }); + + ///See + public static Task Messages_FaveSticker(this Client client, InputDocument id, bool unfave) + => client.CallAsync(writer => + { + writer.Write(0xB9FFC55B); + writer.WriteTLObject(id); + writer.Write(unfave ? 0x997275B5 : 0xBC799737); + return "Messages_FaveSticker"; + }); + + ///See + public static Task Messages_GetUnreadMentions(this Client client, InputPeer peer, int offset_id, int add_offset, int limit, int max_id, int min_id) + => client.CallAsync(writer => + { + writer.Write(0x46578472); + writer.WriteTLObject(peer); + writer.Write(offset_id); + writer.Write(add_offset); + writer.Write(limit); + writer.Write(max_id); + writer.Write(min_id); + return "Messages_GetUnreadMentions"; + }); + + ///See + public static Task Messages_ReadMentions(this Client client, InputPeer peer) + => client.CallAsync(writer => + { + writer.Write(0x0F0189D3); + writer.WriteTLObject(peer); + return "Messages_ReadMentions"; + }); + + ///See + public static Task Messages_GetRecentLocations(this Client client, InputPeer peer, int limit, long hash) + => client.CallAsync(writer => + { + writer.Write(0x702A40E0); + writer.WriteTLObject(peer); + writer.Write(limit); + writer.Write(hash); + return "Messages_GetRecentLocations"; + }); + + ///See + public static Task Messages_SendMultiMedia(this Client client, InputPeer peer, InputSingleMedia[] multi_media, bool silent = false, bool background = false, bool clear_draft = false, int? reply_to_msg_id = null, DateTime? schedule_date = null) + => client.CallAsync(writer => + { + writer.Write(0xCC0110CB); + writer.Write((silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (reply_to_msg_id != null ? 0x1 : 0) | (schedule_date != null ? 0x400 : 0)); + writer.WriteTLObject(peer); + if (reply_to_msg_id != null) + writer.Write(reply_to_msg_id.Value); + writer.WriteTLVector(multi_media); + if (schedule_date != null) + writer.WriteTLStamp(schedule_date.Value); + return "Messages_SendMultiMedia"; + }); + + ///See + public static Task Messages_UploadEncryptedFile(this Client client, InputEncryptedChat peer, InputEncryptedFileBase file) + => client.CallAsync(writer => + { + writer.Write(0x5057C497); + writer.WriteTLObject(peer); + writer.WriteTLObject(file); + return "Messages_UploadEncryptedFile"; + }); + + ///See + public static Task Messages_SearchStickerSets(this Client client, string q, long hash, bool exclude_featured = false) + => client.CallAsync(writer => + { + writer.Write(0x35705B8A); + writer.Write(exclude_featured ? 0x1 : 0); + writer.WriteTLString(q); + writer.Write(hash); + return "Messages_SearchStickerSets"; + }); + + ///See + public static Task Messages_GetSplitRanges(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x1CFF7E08); + return "Messages_GetSplitRanges"; + }); + + ///See + public static Task Messages_MarkDialogUnread(this Client client, InputDialogPeerBase peer, bool unread = false) + => client.CallAsync(writer => + { + writer.Write(0xC286D98F); + writer.Write(unread ? 0x1 : 0); + writer.WriteTLObject(peer); + return "Messages_MarkDialogUnread"; + }); + + ///See + public static Task Messages_GetDialogUnreadMarks(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x22E24E22); + return "Messages_GetDialogUnreadMarks"; + }); + + ///See + public static Task Messages_ClearAllDrafts(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x7E58EE9C); + return "Messages_ClearAllDrafts"; + }); + + ///See + public static Task Messages_UpdatePinnedMessage(this Client client, InputPeer peer, int id, bool silent = false, bool unpin = false, bool pm_oneside = false) + => client.CallAsync(writer => + { + writer.Write(0xD2AAF7EC); + writer.Write((silent ? 0x1 : 0) | (unpin ? 0x2 : 0) | (pm_oneside ? 0x4 : 0)); + writer.WriteTLObject(peer); + writer.Write(id); + return "Messages_UpdatePinnedMessage"; + }); + + ///See + public static Task Messages_SendVote(this Client client, InputPeer peer, int msg_id, byte[][] options) + => client.CallAsync(writer => + { + writer.Write(0x10EA6184); + writer.WriteTLObject(peer); + writer.Write(msg_id); + writer.WriteTLVector(options); + return "Messages_SendVote"; + }); + + ///See + public static Task Messages_GetPollResults(this Client client, InputPeer peer, int msg_id) + => client.CallAsync(writer => + { + writer.Write(0x73BB643B); + writer.WriteTLObject(peer); + writer.Write(msg_id); + return "Messages_GetPollResults"; + }); + + ///See + public static Task Messages_GetOnlines(this Client client, InputPeer peer) + => client.CallAsync(writer => + { + writer.Write(0x6E2BE050); + writer.WriteTLObject(peer); + return "Messages_GetOnlines"; + }); + + ///See + public static Task Messages_GetStatsURL(this Client client, InputPeer peer, string params_, bool dark = false) + => client.CallAsync(writer => + { + writer.Write(0x812C2AE6); + writer.Write(dark ? 0x1 : 0); + writer.WriteTLObject(peer); + writer.WriteTLString(params_); + return "Messages_GetStatsURL"; + }); + + ///See + public static Task Messages_EditChatAbout(this Client client, InputPeer peer, string about) + => client.CallAsync(writer => + { + writer.Write(0xDEF60797); + writer.WriteTLObject(peer); + writer.WriteTLString(about); + return "Messages_EditChatAbout"; + }); + + ///See + public static Task Messages_EditChatDefaultBannedRights(this Client client, InputPeer peer, ChatBannedRights banned_rights) + => client.CallAsync(writer => + { + writer.Write(0xA5866B41); + writer.WriteTLObject(peer); + writer.WriteTLObject(banned_rights); + return "Messages_EditChatDefaultBannedRights"; + }); + + ///See + public static Task Messages_GetEmojiKeywords(this Client client, string lang_code) + => client.CallAsync(writer => + { + writer.Write(0x35A0E062); + writer.WriteTLString(lang_code); + return "Messages_GetEmojiKeywords"; + }); + + ///See + public static Task Messages_GetEmojiKeywordsDifference(this Client client, string lang_code, int from_version) + => client.CallAsync(writer => + { + writer.Write(0x1508B6AF); + writer.WriteTLString(lang_code); + writer.Write(from_version); + return "Messages_GetEmojiKeywordsDifference"; + }); + + ///See + public static Task Messages_GetEmojiKeywordsLanguages(this Client client, string[] lang_codes) + => client.CallAsync(writer => + { + writer.Write(0x4E9963B2); + writer.WriteTLVector(lang_codes); + return "Messages_GetEmojiKeywordsLanguages"; + }); + + ///See + public static Task Messages_GetEmojiURL(this Client client, string lang_code) + => client.CallAsync(writer => + { + writer.Write(0xD5B10C26); + writer.WriteTLString(lang_code); + return "Messages_GetEmojiURL"; + }); + + ///See + public static Task Messages_GetSearchCounters(this Client client, InputPeer peer, MessagesFilter[] filters) + => client.CallAsync(writer => + { + writer.Write(0x732EEF00); + writer.WriteTLObject(peer); + writer.WriteTLVector(filters); + return "Messages_GetSearchCounters"; + }); + + ///See + public static Task Messages_RequestUrlAuth(this Client client, InputPeer peer = null, int? msg_id = null, int? button_id = null, string url = null) + => client.CallAsync(writer => + { + writer.Write(0x198FB446); + writer.Write((peer != null ? 0x2 : 0) | (msg_id != null ? 0x2 : 0) | (button_id != null ? 0x2 : 0) | (url != null ? 0x4 : 0)); + if (peer != null) + writer.WriteTLObject(peer); + if (msg_id != null) + writer.Write(msg_id.Value); + if (button_id != null) + writer.Write(button_id.Value); + if (url != null) + writer.WriteTLString(url); + return "Messages_RequestUrlAuth"; + }); + + ///See + 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.CallAsync(writer => + { + writer.Write(0xB12C7125); + writer.Write((write_allowed ? 0x1 : 0) | (peer != null ? 0x2 : 0) | (msg_id != null ? 0x2 : 0) | (button_id != null ? 0x2 : 0) | (url != null ? 0x4 : 0)); + if (peer != null) + writer.WriteTLObject(peer); + if (msg_id != null) + writer.Write(msg_id.Value); + if (button_id != null) + writer.Write(button_id.Value); + if (url != null) + writer.WriteTLString(url); + return "Messages_AcceptUrlAuth"; + }); + + ///See + public static Task Messages_HidePeerSettingsBar(this Client client, InputPeer peer) + => client.CallAsync(writer => + { + writer.Write(0x4FACB138); + writer.WriteTLObject(peer); + return "Messages_HidePeerSettingsBar"; + }); + + ///See + public static Task Messages_GetScheduledHistory(this Client client, InputPeer peer, long hash) + => client.CallAsync(writer => + { + writer.Write(0xF516760B); + writer.WriteTLObject(peer); + writer.Write(hash); + return "Messages_GetScheduledHistory"; + }); + + ///See + public static Task Messages_GetScheduledMessages(this Client client, InputPeer peer, int[] id) + => client.CallAsync(writer => + { + writer.Write(0xBDBB0464); + writer.WriteTLObject(peer); + writer.WriteTLVector(id); + return "Messages_GetScheduledMessages"; + }); + + ///See + public static Task Messages_SendScheduledMessages(this Client client, InputPeer peer, int[] id) + => client.CallAsync(writer => + { + writer.Write(0xBD38850A); + writer.WriteTLObject(peer); + writer.WriteTLVector(id); + return "Messages_SendScheduledMessages"; + }); + + ///See + public static Task Messages_DeleteScheduledMessages(this Client client, InputPeer peer, int[] id) + => client.CallAsync(writer => + { + writer.Write(0x59AE2B16); + writer.WriteTLObject(peer); + writer.WriteTLVector(id); + return "Messages_DeleteScheduledMessages"; + }); + + ///See + public static Task Messages_GetPollVotes(this Client client, InputPeer peer, int id, int limit, byte[] option = null, string offset = null) + => client.CallAsync(writer => + { + writer.Write(0xB86E380E); + writer.Write((option != null ? 0x1 : 0) | (offset != null ? 0x2 : 0)); + writer.WriteTLObject(peer); + writer.Write(id); + if (option != null) + writer.WriteTLBytes(option); + if (offset != null) + writer.WriteTLString(offset); + writer.Write(limit); + return "Messages_GetPollVotes"; + }); + + ///See + public static Task Messages_ToggleStickerSets(this Client client, InputStickerSet[] stickersets, bool uninstall = false, bool archive = false, bool unarchive = false) + => client.CallAsync(writer => + { + writer.Write(0xB5052FEA); + writer.Write((uninstall ? 0x1 : 0) | (archive ? 0x2 : 0) | (unarchive ? 0x4 : 0)); + writer.WriteTLVector(stickersets); + return "Messages_ToggleStickerSets"; + }); + + ///See + public static Task Messages_GetDialogFilters(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xF19ED96D); + return "Messages_GetDialogFilters"; + }); + + ///See + public static Task Messages_GetSuggestedDialogFilters(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xA29CD42C); + return "Messages_GetSuggestedDialogFilters"; + }); + + ///See + public static Task Messages_UpdateDialogFilter(this Client client, int id, DialogFilter filter = null) + => client.CallAsync(writer => + { + writer.Write(0x1AD4A04A); + writer.Write(filter != null ? 0x1 : 0); + writer.Write(id); + if (filter != null) + writer.WriteTLObject(filter); + return "Messages_UpdateDialogFilter"; + }); + + ///See + public static Task Messages_UpdateDialogFiltersOrder(this Client client, int[] order) + => client.CallAsync(writer => + { + writer.Write(0xC563C1E4); + writer.WriteTLVector(order); + return "Messages_UpdateDialogFiltersOrder"; + }); + + ///See + public static Task Messages_GetOldFeaturedStickers(this Client client, int offset, int limit, long hash) + => client.CallAsync(writer => + { + writer.Write(0x7ED094A1); + writer.Write(offset); + writer.Write(limit); + writer.Write(hash); + return "Messages_GetOldFeaturedStickers"; + }); + + ///See + public static Task Messages_GetReplies(this Client client, InputPeer peer, int msg_id, int offset_id, DateTime offset_date, int add_offset, int limit, int max_id, int min_id, long hash) + => client.CallAsync(writer => + { + writer.Write(0x22DDD30C); + writer.WriteTLObject(peer); + writer.Write(msg_id); + writer.Write(offset_id); + writer.WriteTLStamp(offset_date); + writer.Write(add_offset); + writer.Write(limit); + writer.Write(max_id); + writer.Write(min_id); + writer.Write(hash); + return "Messages_GetReplies"; + }); + + ///See + public static Task Messages_GetDiscussionMessage(this Client client, InputPeer peer, int msg_id) + => client.CallAsync(writer => + { + writer.Write(0x446972FD); + writer.WriteTLObject(peer); + writer.Write(msg_id); + return "Messages_GetDiscussionMessage"; + }); + + ///See + public static Task Messages_ReadDiscussion(this Client client, InputPeer peer, int msg_id, int read_max_id) + => client.CallAsync(writer => + { + writer.Write(0xF731A9F4); + writer.WriteTLObject(peer); + writer.Write(msg_id); + writer.Write(read_max_id); + return "Messages_ReadDiscussion"; + }); + + ///See + public static Task Messages_UnpinAllMessages(this Client client, InputPeer peer) + => client.CallAsync(writer => + { + writer.Write(0xF025BC8B); + writer.WriteTLObject(peer); + return "Messages_UnpinAllMessages"; + }); + + ///See + public static Task Messages_DeleteChat(this Client client, long chat_id) + => client.CallAsync(writer => + { + writer.Write(0x5BD0EE50); + writer.Write(chat_id); + return "Messages_DeleteChat"; + }); + + ///See + public static Task Messages_DeletePhoneCallHistory(this Client client, bool revoke = false) + => client.CallAsync(writer => + { + writer.Write(0xF9CBE409); + writer.Write(revoke ? 0x1 : 0); + return "Messages_DeletePhoneCallHistory"; + }); + + ///See + public static Task Messages_CheckHistoryImport(this Client client, string import_head) + => client.CallAsync(writer => + { + writer.Write(0x43FE19F3); + writer.WriteTLString(import_head); + return "Messages_CheckHistoryImport"; + }); + + ///See + public static Task Messages_InitHistoryImport(this Client client, InputPeer peer, InputFileBase file, int media_count) + => client.CallAsync(writer => + { + writer.Write(0x34090C3B); + writer.WriteTLObject(peer); + writer.WriteTLObject(file); + writer.Write(media_count); + return "Messages_InitHistoryImport"; + }); + + ///See + public static Task Messages_UploadImportedMedia(this Client client, InputPeer peer, long import_id, string file_name, InputMedia media) + => client.CallAsync(writer => + { + writer.Write(0x2A862092); + writer.WriteTLObject(peer); + writer.Write(import_id); + writer.WriteTLString(file_name); + writer.WriteTLObject(media); + return "Messages_UploadImportedMedia"; + }); + + ///See + public static Task Messages_StartHistoryImport(this Client client, InputPeer peer, long import_id) + => client.CallAsync(writer => + { + writer.Write(0xB43DF344); + writer.WriteTLObject(peer); + writer.Write(import_id); + return "Messages_StartHistoryImport"; + }); + + ///See + public static Task Messages_GetExportedChatInvites(this Client client, InputPeer peer, InputUserBase admin_id, int limit, bool revoked = false, DateTime? offset_date = null, string offset_link = null) + => client.CallAsync(writer => + { + writer.Write(0xA2B5A3F6); + writer.Write((revoked ? 0x8 : 0) | (offset_date != null ? 0x4 : 0) | (offset_link != null ? 0x4 : 0)); + writer.WriteTLObject(peer); + writer.WriteTLObject(admin_id); + if (offset_date != null) + writer.WriteTLStamp(offset_date.Value); + if (offset_link != null) + writer.WriteTLString(offset_link); + writer.Write(limit); + return "Messages_GetExportedChatInvites"; + }); + + ///See + public static Task Messages_GetExportedChatInvite(this Client client, InputPeer peer, string link) + => client.CallAsync(writer => + { + writer.Write(0x73746F5C); + writer.WriteTLObject(peer); + writer.WriteTLString(link); + return "Messages_GetExportedChatInvite"; + }); + + ///See + public static Task Messages_EditExportedChatInvite(this Client client, InputPeer peer, string link, bool revoked = false, DateTime? expire_date = null, int? usage_limit = null) + => client.CallAsync(writer => + { + writer.Write(0x02E4FFBE); + writer.Write((revoked ? 0x4 : 0) | (expire_date != null ? 0x1 : 0) | (usage_limit != null ? 0x2 : 0)); + writer.WriteTLObject(peer); + writer.WriteTLString(link); + if (expire_date != null) + writer.WriteTLStamp(expire_date.Value); + if (usage_limit != null) + writer.Write(usage_limit.Value); + return "Messages_EditExportedChatInvite"; + }); + + ///See + public static Task Messages_DeleteRevokedExportedChatInvites(this Client client, InputPeer peer, InputUserBase admin_id) + => client.CallAsync(writer => + { + writer.Write(0x56987BD5); + writer.WriteTLObject(peer); + writer.WriteTLObject(admin_id); + return "Messages_DeleteRevokedExportedChatInvites"; + }); + + ///See + public static Task Messages_DeleteExportedChatInvite(this Client client, InputPeer peer, string link) + => client.CallAsync(writer => + { + writer.Write(0xD464A42B); + writer.WriteTLObject(peer); + writer.WriteTLString(link); + return "Messages_DeleteExportedChatInvite"; + }); + + ///See + public static Task Messages_GetAdminsWithInvites(this Client client, InputPeer peer) + => client.CallAsync(writer => + { + writer.Write(0x3920E6EF); + writer.WriteTLObject(peer); + return "Messages_GetAdminsWithInvites"; + }); + + ///See + public static Task Messages_GetChatInviteImporters(this Client client, InputPeer peer, string link, DateTime offset_date, InputUserBase offset_user, int limit) + => client.CallAsync(writer => + { + writer.Write(0x26FB7289); + writer.WriteTLObject(peer); + writer.WriteTLString(link); + writer.WriteTLStamp(offset_date); + writer.WriteTLObject(offset_user); + writer.Write(limit); + return "Messages_GetChatInviteImporters"; + }); + + ///See + public static Task Messages_SetHistoryTTL(this Client client, InputPeer peer, int period) + => client.CallAsync(writer => + { + writer.Write(0xB80E5FE4); + writer.WriteTLObject(peer); + writer.Write(period); + return "Messages_SetHistoryTTL"; + }); + + ///See + public static Task Messages_CheckHistoryImportPeer(this Client client, InputPeer peer) + => client.CallAsync(writer => + { + writer.Write(0x5DC60F03); + writer.WriteTLObject(peer); + return "Messages_CheckHistoryImportPeer"; + }); + + ///See + public static Task Messages_SetChatTheme(this Client client, InputPeer peer, string emoticon) + => client.CallAsync(writer => + { + writer.Write(0xE63BE13F); + writer.WriteTLObject(peer); + writer.WriteTLString(emoticon); + return "Messages_SetChatTheme"; + }); + + ///See + public static Task Messages_GetMessageReadParticipants(this Client client, InputPeer peer, int msg_id) + => client.CallAsync(writer => + { + writer.Write(0x2C6F97B7); + writer.WriteTLObject(peer); + writer.Write(msg_id); + return "Messages_GetMessageReadParticipants"; + }); + + ///See + public static Task Updates_GetState(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xEDD4882A); + return "Updates_GetState"; + }); + + ///See + public static Task Updates_GetDifference(this Client client, int pts, DateTime date, int qts, int? pts_total_limit = null) + => client.CallAsync(writer => + { + writer.Write(0x25939651); + writer.Write(pts_total_limit != null ? 0x1 : 0); + writer.Write(pts); + if (pts_total_limit != null) + writer.Write(pts_total_limit.Value); + writer.WriteTLStamp(date); + writer.Write(qts); + return "Updates_GetDifference"; + }); + + ///See + public static Task Updates_GetChannelDifference(this Client client, InputChannelBase channel, ChannelMessagesFilter filter, int pts, int limit, bool force = false) + => client.CallAsync(writer => + { + writer.Write(0x03173D78); + writer.Write(force ? 0x1 : 0); + writer.WriteTLObject(channel); + writer.WriteTLObject(filter); + writer.Write(pts); + writer.Write(limit); + return "Updates_GetChannelDifference"; + }); + + ///See + public static Task Photos_UpdateProfilePhoto(this Client client, InputPhoto id) + => client.CallAsync(writer => + { + writer.Write(0x72D4742C); + writer.WriteTLObject(id); + return "Photos_UpdateProfilePhoto"; + }); + + ///See + public static Task Photos_UploadProfilePhoto(this Client client, InputFileBase file = null, InputFileBase video = null, double? video_start_ts = null) + => client.CallAsync(writer => + { + writer.Write(0x89F30F69); + writer.Write((file != null ? 0x1 : 0) | (video != null ? 0x2 : 0) | (video_start_ts != null ? 0x4 : 0)); + if (file != null) + writer.WriteTLObject(file); + if (video != null) + writer.WriteTLObject(video); + if (video_start_ts != null) + writer.Write(video_start_ts.Value); + return "Photos_UploadProfilePhoto"; + }); + + ///See + public static Task Photos_DeletePhotos(this Client client, InputPhoto[] id) + => client.CallAsync(writer => + { + writer.Write(0x87CF7F2F); + writer.WriteTLVector(id); + return "Photos_DeletePhotos"; + }); + + ///See + public static Task Photos_GetUserPhotos(this Client client, InputUserBase user_id, int offset, long max_id, int limit) + => client.CallAsync(writer => + { + writer.Write(0x91CD32A8); + writer.WriteTLObject(user_id); + writer.Write(offset); + writer.Write(max_id); + writer.Write(limit); + return "Photos_GetUserPhotos"; + }); + + ///See + public static Task Upload_SaveFilePart(this Client client, long file_id, int file_part, byte[] bytes) + => client.CallAsync(writer => + { + writer.Write(0xB304A621); + writer.Write(file_id); + writer.Write(file_part); + writer.WriteTLBytes(bytes); + return "Upload_SaveFilePart"; + }); + + ///See + public static Task Upload_GetFile(this Client client, InputFileLocationBase location, int offset, int limit, bool precise = false, bool cdn_supported = false) + => client.CallAsync(writer => + { + writer.Write(0xB15A9AFC); + writer.Write((precise ? 0x1 : 0) | (cdn_supported ? 0x2 : 0)); + writer.WriteTLObject(location); + writer.Write(offset); + writer.Write(limit); + return "Upload_GetFile"; + }); + + ///See + public static Task Upload_SaveBigFilePart(this Client client, long file_id, int file_part, int file_total_parts, byte[] bytes) + => client.CallAsync(writer => + { + writer.Write(0xDE7B673D); + writer.Write(file_id); + writer.Write(file_part); + writer.Write(file_total_parts); + writer.WriteTLBytes(bytes); + return "Upload_SaveBigFilePart"; + }); + + ///See + public static Task Upload_GetWebFile(this Client client, InputWebFileLocationBase location, int offset, int limit) + => client.CallAsync(writer => + { + writer.Write(0x24E6818D); + writer.WriteTLObject(location); + writer.Write(offset); + writer.Write(limit); + return "Upload_GetWebFile"; + }); + + ///See + public static Task Upload_GetCdnFile(this Client client, byte[] file_token, int offset, int limit) + => client.CallAsync(writer => + { + writer.Write(0x2000BCC3); + writer.WriteTLBytes(file_token); + writer.Write(offset); + writer.Write(limit); + return "Upload_GetCdnFile"; + }); + + ///See + public static Task Upload_ReuploadCdnFile(this Client client, byte[] file_token, byte[] request_token) + => client.CallAsync(writer => + { + writer.Write(0x9B2754A8); + writer.WriteTLBytes(file_token); + writer.WriteTLBytes(request_token); + return "Upload_ReuploadCdnFile"; + }); + + ///See + public static Task Upload_GetCdnFileHashes(this Client client, byte[] file_token, int offset) + => client.CallAsync(writer => + { + writer.Write(0x4DA54231); + writer.WriteTLBytes(file_token); + writer.Write(offset); + return "Upload_GetCdnFileHashes"; + }); + + ///See + public static Task Upload_GetFileHashes(this Client client, InputFileLocationBase location, int offset) + => client.CallAsync(writer => + { + writer.Write(0xC7025931); + writer.WriteTLObject(location); + writer.Write(offset); + return "Upload_GetFileHashes"; + }); + + ///See + public static Task Help_GetConfig(this Client client) => client.CallAsync(Help_GetConfig); + public static string Help_GetConfig(BinaryWriter writer) + { + writer.Write(0xC4F9186B); + return "Help_GetConfig"; + } + + ///See + public static Task Help_GetNearestDc(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x1FB33026); + return "Help_GetNearestDc"; + }); + + ///See + public static Task Help_GetAppUpdate(this Client client, string source) + => client.CallAsync(writer => + { + writer.Write(0x522D5A7D); + writer.WriteTLString(source); + return "Help_GetAppUpdate"; + }); + + ///See + public static Task Help_GetInviteText(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x4D392343); + return "Help_GetInviteText"; + }); + + ///See + public static Task Help_GetSupport(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x9CDF08CD); + return "Help_GetSupport"; + }); + + ///See + public static Task Help_GetAppChangelog(this Client client, string prev_app_version) + => client.CallAsync(writer => + { + writer.Write(0x9010EF6F); + writer.WriteTLString(prev_app_version); + return "Help_GetAppChangelog"; + }); + + ///See + public static Task Help_SetBotUpdatesStatus(this Client client, int pending_updates_count, string message) + => client.CallAsync(writer => + { + writer.Write(0xEC22CFCD); + writer.Write(pending_updates_count); + writer.WriteTLString(message); + return "Help_SetBotUpdatesStatus"; + }); + + ///See + public static Task Help_GetCdnConfig(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x52029342); + return "Help_GetCdnConfig"; + }); + + ///See + public static Task Help_GetRecentMeUrls(this Client client, string referer) + => client.CallAsync(writer => + { + writer.Write(0x3DC0F114); + writer.WriteTLString(referer); + return "Help_GetRecentMeUrls"; + }); + + ///See + public static Task Help_GetTermsOfServiceUpdate(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x2CA51FD1); + return "Help_GetTermsOfServiceUpdate"; + }); + + ///See + public static Task Help_AcceptTermsOfService(this Client client, DataJSON id) + => client.CallAsync(writer => + { + writer.Write(0xEE72F79A); + writer.WriteTLObject(id); + return "Help_AcceptTermsOfService"; + }); + + ///See + public static Task Help_GetDeepLinkInfo(this Client client, string path) + => client.CallAsync(writer => + { + writer.Write(0x3FEDC75F); + writer.WriteTLString(path); + return "Help_GetDeepLinkInfo"; + }); + + ///See + public static Task Help_GetAppConfig(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x98914110); + return "Help_GetAppConfig"; + }); + + ///See + public static Task Help_SaveAppLog(this Client client, InputAppEvent[] events) + => client.CallAsync(writer => + { + writer.Write(0x6F02F748); + writer.WriteTLVector(events); + return "Help_SaveAppLog"; + }); + + ///See + public static Task Help_GetPassportConfig(this Client client, int hash) + => client.CallAsync(writer => + { + writer.Write(0xC661AD08); + writer.Write(hash); + return "Help_GetPassportConfig"; + }); + + ///See + public static Task Help_GetSupportName(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xD360E72C); + return "Help_GetSupportName"; + }); + + ///See + public static Task Help_GetUserInfo(this Client client, InputUserBase user_id) + => client.CallAsync(writer => + { + writer.Write(0x038A08D3); + writer.WriteTLObject(user_id); + return "Help_GetUserInfo"; + }); + + ///See + public static Task Help_EditUserInfo(this Client client, InputUserBase user_id, string message, MessageEntity[] entities) + => client.CallAsync(writer => + { + writer.Write(0x66B91B70); + writer.WriteTLObject(user_id); + writer.WriteTLString(message); + writer.WriteTLVector(entities); + return "Help_EditUserInfo"; + }); + + ///See + public static Task Help_GetPromoData(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xC0977421); + return "Help_GetPromoData"; + }); + + ///See + public static Task Help_HidePromoData(this Client client, InputPeer peer) + => client.CallAsync(writer => + { + writer.Write(0x1E251C95); + writer.WriteTLObject(peer); + return "Help_HidePromoData"; + }); + + ///See + public static Task Help_DismissSuggestion(this Client client, InputPeer peer, string suggestion) + => client.CallAsync(writer => + { + writer.Write(0xF50DBAA1); + writer.WriteTLObject(peer); + writer.WriteTLString(suggestion); + return "Help_DismissSuggestion"; + }); + + ///See + public static Task Help_GetCountriesList(this Client client, string lang_code, int hash) + => client.CallAsync(writer => + { + writer.Write(0x735787A8); + writer.WriteTLString(lang_code); + writer.Write(hash); + return "Help_GetCountriesList"; + }); + + ///See + public static Task Channels_ReadHistory(this Client client, InputChannelBase channel, int max_id) + => client.CallAsync(writer => + { + writer.Write(0xCC104937); + writer.WriteTLObject(channel); + writer.Write(max_id); + return "Channels_ReadHistory"; + }); + + ///See + public static Task Channels_DeleteMessages(this Client client, InputChannelBase channel, int[] id) + => client.CallAsync(writer => + { + writer.Write(0x84C1FD4E); + writer.WriteTLObject(channel); + writer.WriteTLVector(id); + return "Channels_DeleteMessages"; + }); + + ///See + public static Task Channels_DeleteUserHistory(this Client client, InputChannelBase channel, InputUserBase user_id) + => client.CallAsync(writer => + { + writer.Write(0xD10DD71B); + writer.WriteTLObject(channel); + writer.WriteTLObject(user_id); + return "Channels_DeleteUserHistory"; + }); + + ///See + public static Task Channels_ReportSpam(this Client client, InputChannelBase channel, InputUserBase user_id, int[] id) + => client.CallAsync(writer => + { + writer.Write(0xFE087810); + writer.WriteTLObject(channel); + writer.WriteTLObject(user_id); + writer.WriteTLVector(id); + return "Channels_ReportSpam"; + }); + + ///See + public static Task Channels_GetMessages(this Client client, InputChannelBase channel, InputMessage[] id) + => client.CallAsync(writer => + { + writer.Write(0xAD8C9A23); + writer.WriteTLObject(channel); + writer.WriteTLVector(id); + return "Channels_GetMessages"; + }); + + ///See + public static Task Channels_GetParticipants(this Client client, InputChannelBase channel, ChannelParticipantsFilter filter, int offset, int limit, long hash) + => client.CallAsync(writer => + { + writer.Write(0x77CED9D0); + writer.WriteTLObject(channel); + writer.WriteTLObject(filter); + writer.Write(offset); + writer.Write(limit); + writer.Write(hash); + return "Channels_GetParticipants"; + }); + + ///See + public static Task Channels_GetParticipant(this Client client, InputChannelBase channel, InputPeer participant) + => client.CallAsync(writer => + { + writer.Write(0xA0AB6CC6); + writer.WriteTLObject(channel); + writer.WriteTLObject(participant); + return "Channels_GetParticipant"; + }); + + ///See + public static Task Channels_GetChannels(this Client client, InputChannelBase[] id) + => client.CallAsync(writer => + { + writer.Write(0x0A7F6BBB); + writer.WriteTLVector(id); + return "Channels_GetChannels"; + }); + + ///See + public static Task Channels_GetFullChannel(this Client client, InputChannelBase channel) + => client.CallAsync(writer => + { + writer.Write(0x08736A09); + writer.WriteTLObject(channel); + return "Channels_GetFullChannel"; + }); + + ///See + 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) + => client.CallAsync(writer => + { + writer.Write(0x3D5FB10F); + writer.Write((broadcast ? 0x1 : 0) | (megagroup ? 0x2 : 0) | (for_import ? 0x8 : 0) | (geo_point != null ? 0x4 : 0) | (address != null ? 0x4 : 0)); + writer.WriteTLString(title); + writer.WriteTLString(about); + if (geo_point != null) + writer.WriteTLObject(geo_point); + if (address != null) + writer.WriteTLString(address); + return "Channels_CreateChannel"; + }); + + ///See + public static Task Channels_EditAdmin(this Client client, InputChannelBase channel, InputUserBase user_id, ChatAdminRights admin_rights, string rank) + => client.CallAsync(writer => + { + writer.Write(0xD33C8902); + writer.WriteTLObject(channel); + writer.WriteTLObject(user_id); + writer.WriteTLObject(admin_rights); + writer.WriteTLString(rank); + return "Channels_EditAdmin"; + }); + + ///See + public static Task Channels_EditTitle(this Client client, InputChannelBase channel, string title) + => client.CallAsync(writer => + { + writer.Write(0x566DECD0); + writer.WriteTLObject(channel); + writer.WriteTLString(title); + return "Channels_EditTitle"; + }); + + ///See + public static Task Channels_EditPhoto(this Client client, InputChannelBase channel, InputChatPhotoBase photo) + => client.CallAsync(writer => + { + writer.Write(0xF12E57C9); + writer.WriteTLObject(channel); + writer.WriteTLObject(photo); + return "Channels_EditPhoto"; + }); + + ///See + public static Task Channels_CheckUsername(this Client client, InputChannelBase channel, string username) + => client.CallAsync(writer => + { + writer.Write(0x10E6BD2C); + writer.WriteTLObject(channel); + writer.WriteTLString(username); + return "Channels_CheckUsername"; + }); + + ///See + public static Task Channels_UpdateUsername(this Client client, InputChannelBase channel, string username) + => client.CallAsync(writer => + { + writer.Write(0x3514B3DE); + writer.WriteTLObject(channel); + writer.WriteTLString(username); + return "Channels_UpdateUsername"; + }); + + ///See + public static Task Channels_JoinChannel(this Client client, InputChannelBase channel) + => client.CallAsync(writer => + { + writer.Write(0x24B524C5); + writer.WriteTLObject(channel); + return "Channels_JoinChannel"; + }); + + ///See + public static Task Channels_LeaveChannel(this Client client, InputChannelBase channel) + => client.CallAsync(writer => + { + writer.Write(0xF836AA95); + writer.WriteTLObject(channel); + return "Channels_LeaveChannel"; + }); + + ///See + public static Task Channels_InviteToChannel(this Client client, InputChannelBase channel, InputUserBase[] users) + => client.CallAsync(writer => + { + writer.Write(0x199F3A6C); + writer.WriteTLObject(channel); + writer.WriteTLVector(users); + return "Channels_InviteToChannel"; + }); + + ///See + public static Task Channels_DeleteChannel(this Client client, InputChannelBase channel) + => client.CallAsync(writer => + { + writer.Write(0xC0111FE3); + writer.WriteTLObject(channel); + return "Channels_DeleteChannel"; + }); + + ///See + public static Task Channels_ExportMessageLink(this Client client, InputChannelBase channel, int id, bool grouped = false, bool thread = false) + => client.CallAsync(writer => + { + writer.Write(0xE63FADEB); + writer.Write((grouped ? 0x1 : 0) | (thread ? 0x2 : 0)); + writer.WriteTLObject(channel); + writer.Write(id); + return "Channels_ExportMessageLink"; + }); + + ///See + public static Task Channels_ToggleSignatures(this Client client, InputChannelBase channel, bool enabled) + => client.CallAsync(writer => + { + writer.Write(0x1F69B606); + writer.WriteTLObject(channel); + writer.Write(enabled ? 0x997275B5 : 0xBC799737); + return "Channels_ToggleSignatures"; + }); + + ///See + public static Task Channels_GetAdminedPublicChannels(this Client client, bool by_location = false, bool check_limit = false) + => client.CallAsync(writer => + { + writer.Write(0xF8B036AF); + writer.Write((by_location ? 0x1 : 0) | (check_limit ? 0x2 : 0)); + return "Channels_GetAdminedPublicChannels"; + }); + + ///See + public static Task Channels_EditBanned(this Client client, InputChannelBase channel, InputPeer participant, ChatBannedRights banned_rights) + => client.CallAsync(writer => + { + writer.Write(0x96E6CD81); + writer.WriteTLObject(channel); + writer.WriteTLObject(participant); + writer.WriteTLObject(banned_rights); + return "Channels_EditBanned"; + }); + + ///See + public static Task Channels_GetAdminLog(this Client client, InputChannelBase channel, string q, long max_id, long min_id, int limit, ChannelAdminLogEventsFilter events_filter = null, InputUserBase[] admins = null) + => client.CallAsync(writer => + { + writer.Write(0x33DDF480); + writer.Write((events_filter != null ? 0x1 : 0) | (admins != null ? 0x2 : 0)); + writer.WriteTLObject(channel); + writer.WriteTLString(q); + if (events_filter != null) + writer.WriteTLObject(events_filter); + if (admins != null) + writer.WriteTLVector(admins); + writer.Write(max_id); + writer.Write(min_id); + writer.Write(limit); + return "Channels_GetAdminLog"; + }); + + ///See + public static Task Channels_SetStickers(this Client client, InputChannelBase channel, InputStickerSet stickerset) + => client.CallAsync(writer => + { + writer.Write(0xEA8CA4F9); + writer.WriteTLObject(channel); + writer.WriteTLObject(stickerset); + return "Channels_SetStickers"; + }); + + ///See + public static Task Channels_ReadMessageContents(this Client client, InputChannelBase channel, int[] id) + => client.CallAsync(writer => + { + writer.Write(0xEAB5DC38); + writer.WriteTLObject(channel); + writer.WriteTLVector(id); + return "Channels_ReadMessageContents"; + }); + + ///See + public static Task Channels_DeleteHistory(this Client client, InputChannelBase channel, int max_id) + => client.CallAsync(writer => + { + writer.Write(0xAF369D42); + writer.WriteTLObject(channel); + writer.Write(max_id); + return "Channels_DeleteHistory"; + }); + + ///See + public static Task Channels_TogglePreHistoryHidden(this Client client, InputChannelBase channel, bool enabled) + => client.CallAsync(writer => + { + writer.Write(0xEABBB94C); + writer.WriteTLObject(channel); + writer.Write(enabled ? 0x997275B5 : 0xBC799737); + return "Channels_TogglePreHistoryHidden"; + }); + + ///See + public static Task Channels_GetLeftChannels(this Client client, int offset) + => client.CallAsync(writer => + { + writer.Write(0x8341ECC0); + writer.Write(offset); + return "Channels_GetLeftChannels"; + }); + + ///See + public static Task Channels_GetGroupsForDiscussion(this Client client) + => client.CallAsync(writer => + { + writer.Write(0xF5DAD378); + return "Channels_GetGroupsForDiscussion"; + }); + + ///See + public static Task Channels_SetDiscussionGroup(this Client client, InputChannelBase broadcast, InputChannelBase group) + => client.CallAsync(writer => + { + writer.Write(0x40582BB2); + writer.WriteTLObject(broadcast); + writer.WriteTLObject(group); + return "Channels_SetDiscussionGroup"; + }); + + ///See + public static Task Channels_EditCreator(this Client client, InputChannelBase channel, InputUserBase user_id, InputCheckPasswordSRP password) + => client.CallAsync(writer => + { + writer.Write(0x8F38CD1F); + writer.WriteTLObject(channel); + writer.WriteTLObject(user_id); + writer.WriteTLObject(password); + return "Channels_EditCreator"; + }); + + ///See + public static Task Channels_EditLocation(this Client client, InputChannelBase channel, InputGeoPoint geo_point, string address) + => client.CallAsync(writer => + { + writer.Write(0x58E63F6D); + writer.WriteTLObject(channel); + writer.WriteTLObject(geo_point); + writer.WriteTLString(address); + return "Channels_EditLocation"; + }); + + ///See + public static Task Channels_ToggleSlowMode(this Client client, InputChannelBase channel, int seconds) + => client.CallAsync(writer => + { + writer.Write(0xEDD49EF0); + writer.WriteTLObject(channel); + writer.Write(seconds); + return "Channels_ToggleSlowMode"; + }); + + ///See + public static Task Channels_GetInactiveChannels(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x11E831EE); + return "Channels_GetInactiveChannels"; + }); + + ///See + public static Task Channels_ConvertToGigagroup(this Client client, InputChannelBase channel) + => client.CallAsync(writer => + { + writer.Write(0x0B290C69); + writer.WriteTLObject(channel); + return "Channels_ConvertToGigagroup"; + }); + + ///See + public static Task Channels_ViewSponsoredMessage(this Client client, InputChannelBase channel, byte[] random_id) + => client.CallAsync(writer => + { + writer.Write(0xBEAEDB94); + writer.WriteTLObject(channel); + writer.WriteTLBytes(random_id); + return "Channels_ViewSponsoredMessage"; + }); + + ///See + public static Task Channels_GetSponsoredMessages(this Client client, InputChannelBase channel) + => client.CallAsync(writer => + { + writer.Write(0xEC210FBF); + writer.WriteTLObject(channel); + return "Channels_GetSponsoredMessages"; + }); + + ///See + public static Task Bots_SendCustomRequest(this Client client, string custom_method, DataJSON params_) + => client.CallAsync(writer => + { + writer.Write(0xAA2769ED); + writer.WriteTLString(custom_method); + writer.WriteTLObject(params_); + return "Bots_SendCustomRequest"; + }); + + ///See + public static Task Bots_AnswerWebhookJSONQuery(this Client client, long query_id, DataJSON data) + => client.CallAsync(writer => + { + writer.Write(0xE6213F4D); + writer.Write(query_id); + writer.WriteTLObject(data); + return "Bots_AnswerWebhookJSONQuery"; + }); + + ///See + public static Task Bots_SetBotCommands(this Client client, BotCommandScope scope, string lang_code, BotCommand[] commands) + => client.CallAsync(writer => + { + writer.Write(0x0517165A); + writer.WriteTLObject(scope); + writer.WriteTLString(lang_code); + writer.WriteTLVector(commands); + return "Bots_SetBotCommands"; + }); + + ///See + public static Task Bots_ResetBotCommands(this Client client, BotCommandScope scope, string lang_code) + => client.CallAsync(writer => + { + writer.Write(0x3D8DE0F9); + writer.WriteTLObject(scope); + writer.WriteTLString(lang_code); + return "Bots_ResetBotCommands"; + }); + + ///See + public static Task Bots_GetBotCommands(this Client client, BotCommandScope scope, string lang_code) + => client.CallAsync(writer => + { + writer.Write(0xE34C0DD6); + writer.WriteTLObject(scope); + writer.WriteTLString(lang_code); + return "Bots_GetBotCommands"; + }); + + ///See + public static Task Payments_GetPaymentForm(this Client client, InputPeer peer, int msg_id, DataJSON theme_params = null) + => client.CallAsync(writer => + { + writer.Write(0x8A333C8D); + writer.Write(theme_params != null ? 0x1 : 0); + writer.WriteTLObject(peer); + writer.Write(msg_id); + if (theme_params != null) + writer.WriteTLObject(theme_params); + return "Payments_GetPaymentForm"; + }); + + ///See + public static Task Payments_GetPaymentReceipt(this Client client, InputPeer peer, int msg_id) + => client.CallAsync(writer => + { + writer.Write(0x2478D1CC); + writer.WriteTLObject(peer); + writer.Write(msg_id); + return "Payments_GetPaymentReceipt"; + }); + + ///See + public static Task Payments_ValidateRequestedInfo(this Client client, InputPeer peer, int msg_id, PaymentRequestedInfo info, bool save = false) + => client.CallAsync(writer => + { + writer.Write(0xDB103170); + writer.Write(save ? 0x1 : 0); + writer.WriteTLObject(peer); + writer.Write(msg_id); + writer.WriteTLObject(info); + return "Payments_ValidateRequestedInfo"; + }); + + ///See + public static Task Payments_SendPaymentForm(this Client client, long form_id, InputPeer peer, int msg_id, InputPaymentCredentialsBase credentials, string requested_info_id = null, string shipping_option_id = null, long? tip_amount = null) + => client.CallAsync(writer => + { + writer.Write(0x30C3BC9D); + writer.Write((requested_info_id != null ? 0x1 : 0) | (shipping_option_id != null ? 0x2 : 0) | (tip_amount != null ? 0x4 : 0)); + writer.Write(form_id); + writer.WriteTLObject(peer); + writer.Write(msg_id); + if (requested_info_id != null) + writer.WriteTLString(requested_info_id); + if (shipping_option_id != null) + writer.WriteTLString(shipping_option_id); + writer.WriteTLObject(credentials); + if (tip_amount != null) + writer.Write(tip_amount.Value); + return "Payments_SendPaymentForm"; + }); + + ///See + public static Task Payments_GetSavedInfo(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x227D824B); + return "Payments_GetSavedInfo"; + }); + + ///See + public static Task Payments_ClearSavedInfo(this Client client, bool credentials = false, bool info = false) + => client.CallAsync(writer => + { + writer.Write(0xD83D70C1); + writer.Write((credentials ? 0x1 : 0) | (info ? 0x2 : 0)); + return "Payments_ClearSavedInfo"; + }); + + ///See + public static Task Payments_GetBankCardData(this Client client, string number) + => client.CallAsync(writer => + { + writer.Write(0x2E79D779); + writer.WriteTLString(number); + return "Payments_GetBankCardData"; + }); + + ///See + public static Task Stickers_CreateStickerSet(this Client client, InputUserBase user_id, string title, string short_name, InputStickerSetItem[] stickers, bool masks = false, bool animated = false, InputDocument thumb = null, string software = null) + => client.CallAsync(writer => + { + writer.Write(0x9021AB67); + writer.Write((masks ? 0x1 : 0) | (animated ? 0x2 : 0) | (thumb != null ? 0x4 : 0) | (software != null ? 0x8 : 0)); + writer.WriteTLObject(user_id); + writer.WriteTLString(title); + writer.WriteTLString(short_name); + if (thumb != null) + writer.WriteTLObject(thumb); + writer.WriteTLVector(stickers); + if (software != null) + writer.WriteTLString(software); + return "Stickers_CreateStickerSet"; + }); + + ///See + public static Task Stickers_RemoveStickerFromSet(this Client client, InputDocument sticker) + => client.CallAsync(writer => + { + writer.Write(0xF7760F51); + writer.WriteTLObject(sticker); + return "Stickers_RemoveStickerFromSet"; + }); + + ///See + public static Task Stickers_ChangeStickerPosition(this Client client, InputDocument sticker, int position) + => client.CallAsync(writer => + { + writer.Write(0xFFB6D4CA); + writer.WriteTLObject(sticker); + writer.Write(position); + return "Stickers_ChangeStickerPosition"; + }); + + ///See + public static Task Stickers_AddStickerToSet(this Client client, InputStickerSet stickerset, InputStickerSetItem sticker) + => client.CallAsync(writer => + { + writer.Write(0x8653FEBE); + writer.WriteTLObject(stickerset); + writer.WriteTLObject(sticker); + return "Stickers_AddStickerToSet"; + }); + + ///See + public static Task Stickers_SetStickerSetThumb(this Client client, InputStickerSet stickerset, InputDocument thumb) + => client.CallAsync(writer => + { + writer.Write(0x9A364E30); + writer.WriteTLObject(stickerset); + writer.WriteTLObject(thumb); + return "Stickers_SetStickerSetThumb"; + }); + + ///See + public static Task Stickers_CheckShortName(this Client client, string short_name) + => client.CallAsync(writer => + { + writer.Write(0x284B3639); + writer.WriteTLString(short_name); + return "Stickers_CheckShortName"; + }); + + ///See + public static Task Stickers_SuggestShortName(this Client client, string title) + => client.CallAsync(writer => + { + writer.Write(0x4DAFC503); + writer.WriteTLString(title); + return "Stickers_SuggestShortName"; + }); + + ///See + public static Task Phone_GetCallConfig(this Client client) + => client.CallAsync(writer => + { + writer.Write(0x55451FA9); + return "Phone_GetCallConfig"; + }); + + ///See + public static Task Phone_RequestCall(this Client client, InputUserBase user_id, int random_id, byte[] g_a_hash, PhoneCallProtocol protocol, bool video = false) + => client.CallAsync(writer => + { + writer.Write(0x42FF96ED); + writer.Write(video ? 0x1 : 0); + writer.WriteTLObject(user_id); + writer.Write(random_id); + writer.WriteTLBytes(g_a_hash); + writer.WriteTLObject(protocol); + return "Phone_RequestCall"; + }); + + ///See + public static Task Phone_AcceptCall(this Client client, InputPhoneCall peer, byte[] g_b, PhoneCallProtocol protocol) + => client.CallAsync(writer => + { + writer.Write(0x3BD2B4A0); + writer.WriteTLObject(peer); + writer.WriteTLBytes(g_b); + writer.WriteTLObject(protocol); + return "Phone_AcceptCall"; + }); + + ///See + public static Task Phone_ConfirmCall(this Client client, InputPhoneCall peer, byte[] g_a, long key_fingerprint, PhoneCallProtocol protocol) + => client.CallAsync(writer => + { + writer.Write(0x2EFE1722); + writer.WriteTLObject(peer); + writer.WriteTLBytes(g_a); + writer.Write(key_fingerprint); + writer.WriteTLObject(protocol); + return "Phone_ConfirmCall"; + }); + + ///See + public static Task Phone_ReceivedCall(this Client client, InputPhoneCall peer) + => client.CallAsync(writer => + { + writer.Write(0x17D54F61); + writer.WriteTLObject(peer); + return "Phone_ReceivedCall"; + }); + + ///See + public static Task Phone_DiscardCall(this Client client, InputPhoneCall peer, int duration, PhoneCallDiscardReason reason, long connection_id, bool video = false) + => client.CallAsync(writer => + { + writer.Write(0xB2CBC1C0); + writer.Write(video ? 0x1 : 0); + writer.WriteTLObject(peer); + writer.Write(duration); + writer.Write((uint)reason); + writer.Write(connection_id); + return "Phone_DiscardCall"; + }); + + ///See + public static Task Phone_SetCallRating(this Client client, InputPhoneCall peer, int rating, string comment, bool user_initiative = false) + => client.CallAsync(writer => + { + writer.Write(0x59EAD627); + writer.Write(user_initiative ? 0x1 : 0); + writer.WriteTLObject(peer); + writer.Write(rating); + writer.WriteTLString(comment); + return "Phone_SetCallRating"; + }); + + ///See + public static Task Phone_SaveCallDebug(this Client client, InputPhoneCall peer, DataJSON debug) + => client.CallAsync(writer => + { + writer.Write(0x277ADD7E); + writer.WriteTLObject(peer); + writer.WriteTLObject(debug); + return "Phone_SaveCallDebug"; + }); + + ///See + public static Task Phone_SendSignalingData(this Client client, InputPhoneCall peer, byte[] data) + => client.CallAsync(writer => + { + writer.Write(0xFF7A9383); + writer.WriteTLObject(peer); + writer.WriteTLBytes(data); + return "Phone_SendSignalingData"; + }); + + ///See + public static Task Phone_CreateGroupCall(this Client client, InputPeer peer, int random_id, string title = null, DateTime? schedule_date = null) + => client.CallAsync(writer => + { + writer.Write(0x48CDC6D8); + writer.Write((title != null ? 0x1 : 0) | (schedule_date != null ? 0x2 : 0)); + writer.WriteTLObject(peer); + writer.Write(random_id); + if (title != null) + writer.WriteTLString(title); + if (schedule_date != null) + writer.WriteTLStamp(schedule_date.Value); + return "Phone_CreateGroupCall"; + }); + + ///See + 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) + => client.CallAsync(writer => + { + writer.Write(0xB132FF7B); + writer.Write((muted ? 0x1 : 0) | (video_stopped ? 0x4 : 0) | (invite_hash != null ? 0x2 : 0)); + writer.WriteTLObject(call); + writer.WriteTLObject(join_as); + if (invite_hash != null) + writer.WriteTLString(invite_hash); + writer.WriteTLObject(params_); + return "Phone_JoinGroupCall"; + }); + + ///See + public static Task Phone_LeaveGroupCall(this Client client, InputGroupCall call, int source) + => client.CallAsync(writer => + { + writer.Write(0x500377F9); + writer.WriteTLObject(call); + writer.Write(source); + return "Phone_LeaveGroupCall"; + }); + + ///See + public static Task Phone_InviteToGroupCall(this Client client, InputGroupCall call, InputUserBase[] users) + => client.CallAsync(writer => + { + writer.Write(0x7B393160); + writer.WriteTLObject(call); + writer.WriteTLVector(users); + return "Phone_InviteToGroupCall"; + }); + + ///See + public static Task Phone_DiscardGroupCall(this Client client, InputGroupCall call) + => client.CallAsync(writer => + { + writer.Write(0x7A777135); + writer.WriteTLObject(call); + return "Phone_DiscardGroupCall"; + }); + + ///See + public static Task Phone_ToggleGroupCallSettings(this Client client, InputGroupCall call, bool reset_invite_hash = false, bool? join_muted = null) + => client.CallAsync(writer => + { + writer.Write(0x74BBB43D); + writer.Write((reset_invite_hash ? 0x2 : 0) | (join_muted != null ? 0x1 : 0)); + writer.WriteTLObject(call); + if (join_muted != null) + writer.Write(join_muted.Value ? 0x997275B5 : 0xBC799737); + return "Phone_ToggleGroupCallSettings"; + }); + + ///See + public static Task Phone_GetGroupCall(this Client client, InputGroupCall call, int limit) + => client.CallAsync(writer => + { + writer.Write(0x041845DB); + writer.WriteTLObject(call); + writer.Write(limit); + return "Phone_GetGroupCall"; + }); + + ///See + public static Task Phone_GetGroupParticipants(this Client client, InputGroupCall call, InputPeer[] ids, int[] sources, string offset, int limit) + => client.CallAsync(writer => + { + writer.Write(0xC558D8AB); + writer.WriteTLObject(call); + writer.WriteTLVector(ids); + writer.WriteTLVector(sources); + writer.WriteTLString(offset); + writer.Write(limit); + return "Phone_GetGroupParticipants"; + }); + + ///See + public static Task Phone_CheckGroupCall(this Client client, InputGroupCall call, int[] sources) + => client.CallAsync(writer => + { + writer.Write(0xB59CF977); + writer.WriteTLObject(call); + writer.WriteTLVector(sources); + return "Phone_CheckGroupCall"; + }); + + ///See + public static Task Phone_ToggleGroupCallRecord(this Client client, InputGroupCall call, bool start = false, bool video = false, string title = null, bool? video_portrait = null) + => client.CallAsync(writer => + { + writer.Write(0xF128C708); + writer.Write((start ? 0x1 : 0) | (video ? 0x4 : 0) | (title != null ? 0x2 : 0) | (video_portrait != null ? 0x4 : 0)); + writer.WriteTLObject(call); + if (title != null) + writer.WriteTLString(title); + if (video_portrait != null) + writer.Write(video_portrait.Value ? 0x997275B5 : 0xBC799737); + return "Phone_ToggleGroupCallRecord"; + }); + + ///See + public static Task Phone_EditGroupCallParticipant(this Client client, InputGroupCall call, InputPeer participant, bool? muted = null, int? volume = null, bool? raise_hand = null, bool? video_stopped = null, bool? video_paused = null, bool? presentation_paused = null) + => client.CallAsync(writer => + { + writer.Write(0xA5273ABF); + writer.Write((muted != null ? 0x1 : 0) | (volume != null ? 0x2 : 0) | (raise_hand != null ? 0x4 : 0) | (video_stopped != null ? 0x8 : 0) | (video_paused != null ? 0x10 : 0) | (presentation_paused != null ? 0x20 : 0)); + writer.WriteTLObject(call); + writer.WriteTLObject(participant); + if (muted != null) + writer.Write(muted.Value ? 0x997275B5 : 0xBC799737); + if (volume != null) + writer.Write(volume.Value); + if (raise_hand != null) + writer.Write(raise_hand.Value ? 0x997275B5 : 0xBC799737); + if (video_stopped != null) + writer.Write(video_stopped.Value ? 0x997275B5 : 0xBC799737); + if (video_paused != null) + writer.Write(video_paused.Value ? 0x997275B5 : 0xBC799737); + if (presentation_paused != null) + writer.Write(presentation_paused.Value ? 0x997275B5 : 0xBC799737); + return "Phone_EditGroupCallParticipant"; + }); + + ///See + public static Task Phone_EditGroupCallTitle(this Client client, InputGroupCall call, string title) + => client.CallAsync(writer => + { + writer.Write(0x1CA6AC0A); + writer.WriteTLObject(call); + writer.WriteTLString(title); + return "Phone_EditGroupCallTitle"; + }); + + ///See + public static Task Phone_GetGroupCallJoinAs(this Client client, InputPeer peer) + => client.CallAsync(writer => + { + writer.Write(0xEF7C213A); + writer.WriteTLObject(peer); + return "Phone_GetGroupCallJoinAs"; + }); + + ///See + public static Task Phone_ExportGroupCallInvite(this Client client, InputGroupCall call, bool can_self_unmute = false) + => client.CallAsync(writer => + { + writer.Write(0xE6AA647F); + writer.Write(can_self_unmute ? 0x1 : 0); + writer.WriteTLObject(call); + return "Phone_ExportGroupCallInvite"; + }); + + ///See + public static Task Phone_ToggleGroupCallStartSubscription(this Client client, InputGroupCall call, bool subscribed) + => client.CallAsync(writer => + { + writer.Write(0x219C34E6); + writer.WriteTLObject(call); + writer.Write(subscribed ? 0x997275B5 : 0xBC799737); + return "Phone_ToggleGroupCallStartSubscription"; + }); + + ///See + public static Task Phone_StartScheduledGroupCall(this Client client, InputGroupCall call) + => client.CallAsync(writer => + { + writer.Write(0x5680E342); + writer.WriteTLObject(call); + return "Phone_StartScheduledGroupCall"; + }); + + ///See + public static Task Phone_SaveDefaultGroupCallJoinAs(this Client client, InputPeer peer, InputPeer join_as) + => client.CallAsync(writer => + { + writer.Write(0x575E1F8C); + writer.WriteTLObject(peer); + writer.WriteTLObject(join_as); + return "Phone_SaveDefaultGroupCallJoinAs"; + }); + + ///See + public static Task Phone_JoinGroupCallPresentation(this Client client, InputGroupCall call, DataJSON params_) + => client.CallAsync(writer => + { + writer.Write(0xCBEA6BC4); + writer.WriteTLObject(call); + writer.WriteTLObject(params_); + return "Phone_JoinGroupCallPresentation"; + }); + + ///See + public static Task Phone_LeaveGroupCallPresentation(this Client client, InputGroupCall call) + => client.CallAsync(writer => + { + writer.Write(0x1C50D144); + writer.WriteTLObject(call); + return "Phone_LeaveGroupCallPresentation"; + }); + + ///See + public static Task Langpack_GetLangPack(this Client client, string lang_pack, string lang_code) + => client.CallAsync(writer => + { + writer.Write(0xF2F2330A); + writer.WriteTLString(lang_pack); + writer.WriteTLString(lang_code); + return "Langpack_GetLangPack"; + }); + + ///See + public static Task Langpack_GetStrings(this Client client, string lang_pack, string lang_code, string[] keys) + => client.CallAsync(writer => + { + writer.Write(0xEFEA3803); + writer.WriteTLString(lang_pack); + writer.WriteTLString(lang_code); + writer.WriteTLVector(keys); + return "Langpack_GetStrings"; + }); + + ///See + public static Task Langpack_GetDifference(this Client client, string lang_pack, string lang_code, int from_version) + => client.CallAsync(writer => + { + writer.Write(0xCD984AA5); + writer.WriteTLString(lang_pack); + writer.WriteTLString(lang_code); + writer.Write(from_version); + return "Langpack_GetDifference"; + }); + + ///See + public static Task Langpack_GetLanguages(this Client client, string lang_pack) + => client.CallAsync(writer => + { + writer.Write(0x42C6978F); + writer.WriteTLString(lang_pack); + return "Langpack_GetLanguages"; + }); + + ///See + public static Task Langpack_GetLanguage(this Client client, string lang_pack, string lang_code) + => client.CallAsync(writer => + { + writer.Write(0x6A596502); + writer.WriteTLString(lang_pack); + writer.WriteTLString(lang_code); + return "Langpack_GetLanguage"; + }); + + ///See + public static Task Folders_EditPeerFolders(this Client client, InputFolderPeer[] folder_peers) + => client.CallAsync(writer => + { + writer.Write(0x6847D0AB); + writer.WriteTLVector(folder_peers); + return "Folders_EditPeerFolders"; + }); + + ///See + public static Task Folders_DeleteFolder(this Client client, int folder_id) + => client.CallAsync(writer => + { + writer.Write(0x1C295881); + writer.Write(folder_id); + return "Folders_DeleteFolder"; + }); + + ///See + public static Task Stats_GetBroadcastStats(this Client client, InputChannelBase channel, bool dark = false) + => client.CallAsync(writer => + { + writer.Write(0xAB42441A); + writer.Write(dark ? 0x1 : 0); + writer.WriteTLObject(channel); + return "Stats_GetBroadcastStats"; + }); + + ///See + public static Task Stats_LoadAsyncGraph(this Client client, string token, long? x = null) + => client.CallAsync(writer => + { + writer.Write(0x621D5FA0); + writer.Write(x != null ? 0x1 : 0); + writer.WriteTLString(token); + if (x != null) + writer.Write(x.Value); + return "Stats_LoadAsyncGraph"; + }); + + ///See + public static Task Stats_GetMegagroupStats(this Client client, InputChannelBase channel, bool dark = false) + => client.CallAsync(writer => + { + writer.Write(0xDCDF8607); + writer.Write(dark ? 0x1 : 0); + writer.WriteTLObject(channel); + return "Stats_GetMegagroupStats"; + }); + + ///See + public static Task Stats_GetMessagePublicForwards(this Client client, InputChannelBase channel, int msg_id, int offset_rate, InputPeer offset_peer, int offset_id, int limit) + => client.CallAsync(writer => + { + writer.Write(0x5630281B); + writer.WriteTLObject(channel); + writer.Write(msg_id); + writer.Write(offset_rate); + writer.WriteTLObject(offset_peer); + writer.Write(offset_id); + writer.Write(limit); + return "Stats_GetMessagePublicForwards"; + }); + + ///See + public static Task Stats_GetMessageStats(this Client client, InputChannelBase channel, int msg_id, bool dark = false) + => client.CallAsync(writer => + { + writer.Write(0xB6E0A3F5); + writer.Write(dark ? 0x1 : 0); + writer.WriteTLObject(channel); + writer.Write(msg_id); + return "Stats_GetMessageStats"; + }); } } diff --git a/src/TL.SchemaFuncs.cs b/src/TL.SchemaFuncs.cs deleted file mode 100644 index 985dec3..0000000 --- a/src/TL.SchemaFuncs.cs +++ /dev/null @@ -1,15337 +0,0 @@ -using System; -using System.Threading.Tasks; -using TL.Methods; -using Client = WTelegram.Client; - -namespace TL -{ - public static class SchemaExtensions - { - /// Invokes a query after successful completion of one of the previous queries. See [bots: ✓] - /// Message identifier on which a current query depends - /// The query itself - public static Task InvokeAfterMsg(this Client client, long msg_id, IMethod query) - => client.Invoke(new InvokeAfterMsg - { - msg_id = msg_id, - query = query, - }); - - /// Invokes a query after a successful completion of previous queries See [bots: ✓] - /// List of messages on which a current query depends - /// The query itself - public static Task InvokeAfterMsgs(this Client client, long[] msg_ids, IMethod query) - => client.Invoke(new InvokeAfterMsgs - { - msg_ids = msg_ids, - query = query, - }); - - /// Initialize connection See [bots: ✓] Possible codes: 400 (details) - /// Application identifier (see. App configuration) - /// Device model - /// Operation system version - /// Application version - /// Code for the language used on the device's OS, ISO 639-1 standard - /// Platform identifier (i.e. android, tdesktop, etc). - /// Either an ISO 639-1 language code or a language pack name obtained from a language pack link. - /// Info about an MTProto proxy - /// Additional initConnection parameters.
For now, only the tz_offset field is supported, for specifying the timezone offset in seconds. - /// The query itself - public static Task InitConnection(this Client client, int api_id, string device_model, string system_version, string app_version, string system_lang_code, string lang_pack, string lang_code, IMethod query, InputClientProxy proxy = null, JSONValue params_ = null) - => client.Invoke(new InitConnection - { - flags = (InitConnection.Flags)((proxy != null ? 0x1 : 0) | (params_ != null ? 0x2 : 0)), - api_id = api_id, - device_model = device_model, - system_version = system_version, - app_version = app_version, - system_lang_code = system_lang_code, - lang_pack = lang_pack, - lang_code = lang_code, - proxy = proxy, - params_ = params_, - query = query, - }); - - /// Invoke the specified query using the specified API layer See [bots: ✓] Possible codes: 400,403,406 (details) - /// The layer to use - /// The query - public static Task InvokeWithLayer(this Client client, int layer, IMethod query) - => client.Invoke(new InvokeWithLayer - { - layer = layer, - query = query, - }); - - /// Invoke a request without subscribing the used connection for updates (this is enabled by default for file queries). See [bots: ✓] - /// The query - public static Task InvokeWithoutUpdates(this Client client, IMethod query) - => client.Invoke(new InvokeWithoutUpdates - { - query = query, - }); - - /// Invoke with the given message range See [bots: ✓] - /// Message range - /// Query - public static Task InvokeWithMessagesRange(this Client client, MessageRange range, IMethod query) - => client.Invoke(new InvokeWithMessagesRange - { - range = range, - query = query, - }); - - /// Invoke a method within a takeout session, see here » for more info. See [bots: ✓] - /// Takeout session ID » - /// Query - public static Task InvokeWithTakeout(this Client client, long takeout_id, IMethod query) - => client.Invoke(new InvokeWithTakeout - { - takeout_id = takeout_id, - query = query, - }); - - /// Invoke a method using a Telegram Business Bot connection, see here » for more info, including a list of the methods that can be wrapped in this constructor. See [bots: ✓] - /// Business connection ID. - /// The actual query. - public static Task InvokeWithBusinessConnection(this Client client, string connection_id, IMethod query) - => client.Invoke(new InvokeWithBusinessConnection - { - connection_id = connection_id, - query = query, - }); - - /// Official clients only, invoke with Google Play Integrity token. See [bots: ✓] - /// Nonce. - /// Token. - /// Query. - public static Task InvokeWithGooglePlayIntegrity(this Client client, string nonce, string token, IMethod query) - => client.Invoke(new InvokeWithGooglePlayIntegrity - { - nonce = nonce, - token = token, - query = query, - }); - - /// Official clients only, invoke with Apple push verification. See [bots: ✓] - /// Nonce. - /// Secret. - /// Query. - public static Task InvokeWithApnsSecret(this Client client, string nonce, string secret, IMethod query) - => client.Invoke(new InvokeWithApnsSecret - { - nonce = nonce, - secret = secret, - query = query, - }); - - /// Official clients only: re-execute a method call that required reCAPTCHA verification via a RECAPTCHA_CHECK_%s__%s, where the first placeholder is the action, and the second one is the reCAPTCHA key ID. See [bots: ✓] - /// reCAPTCHA token received after verification. - /// The original method call. - public static Task InvokeWithReCaptcha(this Client client, string token, IMethod query) - => client.Invoke(new InvokeWithReCaptcha - { - token = token, - query = query, - }); - - /// Send the verification code for login See Possible codes: 400,406,500 (details) - /// Phone number in international format - /// 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://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 - { - phone_number = phone_number, - api_id = api_id, - api_hash = api_hash, - settings = settings, - }); - - /// Registers a validated phone number in the system. See Possible codes: 400,406 (details) - /// If set, users on Telegram that have already added phone_number to their contacts will not receive signup notifications about this user. - /// Phone number in the international format - /// SMS-message ID - /// New user first name - /// New user last name - [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, bool no_joined_notifications = false) - => client.Invoke(new Auth_SignUp - { - flags = (Auth_SignUp.Flags)(no_joined_notifications ? 0x1 : 0), - phone_number = phone_number, - phone_code_hash = phone_code_hash, - first_name = first_name, - last_name = last_name, - }); - - /// 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 - /// 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")] - 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 - { - flags = (Auth_SignIn.Flags)((phone_code != null ? 0x1 : 0) | (email_verification != null ? 0x2 : 0)), - phone_number = phone_number, - phone_code_hash = phone_code_hash, - phone_code = phone_code, - email_verification = email_verification, - }); - - /// Logs out the user. See [bots: ✓] - public static Task Auth_LogOut(this Client client) - => client.Invoke(new Auth_LogOut - { - }); - - /// Terminates all user's authorized sessions except for the current one. See Possible codes: 406 (details) - public static Task Auth_ResetAuthorizations(this Client client) - => client.Invoke(new Auth_ResetAuthorizations - { - }); - - /// Returns data for copying authorization to another data-center. See [bots: ✓] Possible codes: 400 (details) - /// Number of a target data-center - public static Task Auth_ExportAuthorization(this Client client, int dc_id) - => client.Invoke(new Auth_ExportAuthorization - { - dc_id = dc_id, - }); - - /// Logs in a user using a key transmitted from his native data-center. See [bots: ✓] Possible codes: 400 (details) - /// User ID - /// Authorization key - public static Task Auth_ImportAuthorization(this Client client, long id, byte[] bytes) - => client.Invoke(new Auth_ImportAuthorization - { - id = id, - bytes = bytes, - }); - - /// Binds a temporary authorization key temp_auth_key_id to the permanent authorization key perm_auth_key_id. Each permanent key may only be bound to one temporary key at a time, binding a new temporary key overwrites the previous one. See [bots: ✓] Possible codes: 400 (details) - /// Permanent auth_key_id to bind to - /// Random long from Binding message contents - /// Unix timestamp to invalidate temporary key, see Binding message contents - /// See Generating encrypted_message - public static Task Auth_BindTempAuthKey(this Client client, long perm_auth_key_id, long nonce, DateTime expires_at, byte[] encrypted_message) - => client.Invoke(new Auth_BindTempAuthKey - { - perm_auth_key_id = perm_auth_key_id, - nonce = nonce, - expires_at = expires_at, - encrypted_message = encrypted_message, - }); - - /// Login as a bot See [bots: ✓] Possible codes: 400 (details) - /// Reserved for future use - /// Application identifier (see. App configuration) - /// Application identifier hash (see. App configuration) - /// Bot token (see bots) - public static Task Auth_ImportBotAuthorization(this Client client, int flags, int api_id, string api_hash, string bot_auth_token) - => client.Invoke(new Auth_ImportBotAuthorization - { - flags = flags, - api_id = api_id, - api_hash = api_hash, - bot_auth_token = bot_auth_token, - }); - - /// Try logging to an account protected by a 2FA password. See Possible codes: 400,500 (details) - /// The account's password (see SRP) - public static Task Auth_CheckPassword(this Client client, InputCheckPasswordSRP password) - => client.Invoke(new Auth_CheckPassword - { - password = password, - }); - - /// Request recovery code of a 2FA password, only for accounts with a recovery email configured. See Possible codes: 400 (details) - public static Task Auth_RequestPasswordRecovery(this Client client) - => client.Invoke(new Auth_RequestPasswordRecovery - { - }); - - /// 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) - => client.Invoke(new Auth_RecoverPassword - { - flags = (Auth_RecoverPassword.Flags)(new_settings != null ? 0x1 : 0), - code = code, - new_settings = new_settings, - }); - - /// 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 - /// Official clients only, used if the device integrity verification failed, and no secret could be obtained to invoke Auth_RequestFirebaseSms: in this case, the device integrity verification failure reason must be passed here. - [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, string reason = null) - => client.Invoke(new Auth_ResendCode - { - flags = (Auth_ResendCode.Flags)(reason != null ? 0x1 : 0), - phone_number = phone_number, - phone_code_hash = phone_code_hash, - reason = reason, - }); - - /// 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://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 - { - phone_number = phone_number, - phone_code_hash = phone_code_hash, - }); - - /// Delete all temporary authorization keys except for the ones specified See [bots: ✓] - /// The auth keys that shouldn't be dropped. - public static Task Auth_DropTempAuthKeys(this Client client, long[] except_auth_keys = null) - => client.Invoke(new Auth_DropTempAuthKeys - { - except_auth_keys = except_auth_keys, - }); - - /// Generate a login token, for login via QR code.
The generated login token should be encoded using base64url, then shown as a tg://login?token=base64encodedtoken deep link » in the QR code. See Possible codes: 400 (details)
- /// Application identifier (see. App configuration) - /// Application identifier hash (see. App configuration) - /// List of already logged-in user IDs, to prevent logging in twice with the same user - public static Task Auth_ExportLoginToken(this Client client, int api_id, string api_hash, long[] except_ids = null) - => client.Invoke(new Auth_ExportLoginToken - { - api_id = api_id, - api_hash = api_hash, - except_ids = except_ids, - }); - - /// Login using a redirected login token, generated in case of DC mismatch during QR code login. See Possible codes: 400 (details) - /// Login token - public static Task Auth_ImportLoginToken(this Client client, byte[] token) - => client.Invoke(new Auth_ImportLoginToken - { - token = token, - }); - - /// Accept QR code login token, logging in the app that generated it. See Possible codes: 400 (details) - /// Login token embedded in QR code, for more info, see login via QR code. - public static Task Auth_AcceptLoginToken(this Client client, byte[] token) - => client.Invoke(new Auth_AcceptLoginToken - { - 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) - /// Code received via email - public static Task Auth_CheckRecoveryPassword(this Client client, string code) - => client.Invoke(new Auth_CheckRecoveryPassword - { - code = code, - }); - - /// Login by importing an authorization token See Possible codes: 400 (details) - /// API ID - /// API hash - /// The authorization token - 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, - }); - - /// Request an SMS code via Firebase. See Possible codes: 400 (details) - /// Phone number - /// Phone code hash returned by Auth_SendCode - /// On Android, a JWS object obtained as described in the auth documentation » - /// On Android, an object obtained as described in the auth documentation » - /// Secret token received via an apple push notification - public static Task Auth_RequestFirebaseSms(this Client client, string phone_number, string phone_code_hash, string safety_net_token = null, string ios_push_secret = null, string play_integrity_token = null) - => client.Invoke(new Auth_RequestFirebaseSms - { - flags = (Auth_RequestFirebaseSms.Flags)((safety_net_token != null ? 0x1 : 0) | (ios_push_secret != null ? 0x2 : 0) | (play_integrity_token != null ? 0x4 : 0)), - phone_number = phone_number, - phone_code_hash = phone_code_hash, - safety_net_token = safety_net_token, - play_integrity_token = play_integrity_token, - ios_push_secret = ios_push_secret, - }); - - /// Reset the login email ». See Possible codes: 400 (details) - /// Phone number of the account - /// Phone code hash, obtained as described in the documentation » - public static Task Auth_ResetLoginEmail(this Client client, string phone_number, string phone_code_hash) - => client.Invoke(new Auth_ResetLoginEmail - { - phone_number = phone_number, - phone_code_hash = phone_code_hash, - }); - - /// Official apps only, reports that the SMS authentication code wasn't delivered. See Possible codes: 400 (details) - /// Phone number where we were supposed to receive the code - /// The phone code hash obtained from Auth_SendCode - /// MNC of the current network operator. - public static Task Auth_ReportMissingCode(this Client client, string phone_number, string phone_code_hash, string mnc) - => client.Invoke(new Auth_ReportMissingCode - { - phone_number = phone_number, - phone_code_hash = phone_code_hash, - mnc = mnc, - }); - - /// See Possible codes: 400 (details) - public static Task Auth_CheckPaidAuth(this Client client, string phone_number, string phone_code_hash, long form_id) - => client.Invoke(new Auth_CheckPaidAuth - { - phone_number = phone_number, - phone_code_hash = phone_code_hash, - form_id = form_id, - }); - - /// See Possible codes: 400,500 (details) - public static Task Auth_InitPasskeyLogin(this Client client, int api_id, string api_hash) - => client.Invoke(new Auth_InitPasskeyLogin - { - api_id = api_id, - api_hash = api_hash, - }); - - /// See Possible codes: 400,500 (details) - public static Task Auth_FinishPasskeyLogin(this Client client, InputPasskeyCredential credential, int? from_dc_id = null, long? from_auth_key_id = null) - => client.Invoke(new Auth_FinishPasskeyLogin - { - flags = (Auth_FinishPasskeyLogin.Flags)((from_dc_id != null ? 0x1 : 0) | (from_auth_key_id != null ? 0x1 : 0)), - credential = credential, - from_dc_id = from_dc_id ?? default, - from_auth_key_id = from_auth_key_id ?? default, - }); - - /// 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. - /// Device token, see PUSH updates for the possible values. - /// 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) - => client.Invoke(new Account_RegisterDevice - { - flags = (Account_RegisterDevice.Flags)(no_muted ? 0x1 : 0), - token_type = token_type, - token = token, - app_sandbox = app_sandbox, - secret = secret, - other_uids = other_uids, - }); - - /// Deletes a device by its token, stops sending PUSH-notifications to it. See Possible codes: 400 (details) - /// Device token type, see PUSH updates for the possible values. - /// Device token, see PUSH updates for the possible values. - /// List of user identifiers of other users currently using the client - public static Task Account_UnregisterDevice(this Client client, int token_type, string token, params long[] other_uids) - => client.Invoke(new Account_UnregisterDevice - { - token_type = token_type, - token = token, - other_uids = other_uids, - }); - - /// Edits notification settings from a given user/group, from all users/all groups. See Possible codes: 400 (details) - /// Notification source - /// Notification settings - public static Task Account_UpdateNotifySettings(this Client client, InputNotifyPeerBase peer, InputPeerNotifySettings settings) - => client.Invoke(new Account_UpdateNotifySettings - { - peer = peer, - settings = settings, - }); - - /// Gets current notification settings for a given user/group, from all users/all groups. See Possible codes: 400 (details) - /// Notification source - public static Task Account_GetNotifySettings(this Client client, InputNotifyPeerBase peer) - => client.Invoke(new Account_GetNotifySettings - { - peer = peer, - }); - - /// Resets all notification settings from users and groups. See - public static Task Account_ResetNotifySettings(this Client client) - => client.Invoke(new Account_ResetNotifySettings - { - }); - - /// Updates user profile. See Possible codes: 400 (details) - /// New user first name - /// New user last name - /// New bio - public static Task Account_UpdateProfile(this Client client, string first_name = null, string last_name = null, string about = null) - => client.Invoke(new Account_UpdateProfile - { - flags = (Account_UpdateProfile.Flags)((first_name != null ? 0x1 : 0) | (last_name != null ? 0x2 : 0) | (about != null ? 0x4 : 0)), - first_name = first_name, - last_name = last_name, - about = about, - }); - - /// Updates online user status. See - /// If is transmitted, user status will change to . - public static Task Account_UpdateStatus(this Client client, bool offline) - => client.Invoke(new Account_UpdateStatus - { - offline = offline, - }); - - /// Returns a list of available wallpapers. See - /// Hash used for caching, for more info click here. - /// a null value means account.wallPapersNotModified - public static Task Account_GetWallPapers(this Client client, long hash = default) - => client.Invoke(new Account_GetWallPapers - { - hash = hash, - }); - - /// Report a peer for violation of telegram's Terms of Service See Possible codes: 400 (details) - /// The peer to report - /// The reason why this peer is being reported - /// Comment for report moderation - public static Task Account_ReportPeer(this Client client, InputPeer peer, ReportReason reason, string message) - => client.Invoke(new Account_ReportPeer - { - peer = peer, - reason = reason, - message = message, - }); - - /// Validates a username and checks availability. See Possible codes: 400 (details) - /// username
Accepted characters: A-z (case-insensitive), 0-9 and underscores.
Length: 5-32 characters. - public static Task Account_CheckUsername(this Client client, string username) - => client.Invoke(new Account_CheckUsername - { - username = username, - }); - - /// Changes username for the current user. See Possible codes: 400 (details) - /// username or empty string if username is to be removed
Accepted characters: a-z (case-insensitive), 0-9 and underscores.
Length: 5-32 characters. - public static Task Account_UpdateUsername(this Client client, string username) - => client.Invoke(new Account_UpdateUsername - { - username = username, - }); - - /// Get privacy settings of current account See Possible codes: 400 (details) - /// Peer category whose privacy settings should be fetched - public static Task Account_GetPrivacy(this Client client, InputPrivacyKey key) - => client.Invoke(new Account_GetPrivacy - { - key = key, - }); - - /// Change privacy settings of current account See Possible codes: 400 (details) - /// New privacy rule - /// Peers to which the privacy rule will apply. - public static Task Account_SetPrivacy(this Client client, InputPrivacyKey key, params InputPrivacyRule[] rules) - => client.Invoke(new Account_SetPrivacy - { - key = key, - rules = rules, - }); - - /// Delete the user's account from the telegram servers. See Possible codes: 400,420 (details) - /// Why is the account being deleted, can be empty - /// 2FA password: this field can be omitted even for accounts with 2FA enabled: in this case account account deletion will be delayed by 7 days as specified in the docs » - public static Task Account_DeleteAccount(this Client client, string reason, InputCheckPasswordSRP password = null) - => client.Invoke(new Account_DeleteAccount - { - flags = (Account_DeleteAccount.Flags)(password != null ? 0x1 : 0), - reason = reason, - password = password, - }); - - /// Get days to live of account See - public static Task Account_GetAccountTTL(this Client client) - => client.Invoke(new Account_GetAccountTTL - { - }); - - /// Set account self-destruction period See Possible codes: 400 (details) - /// Time to live in days - public static Task Account_SetAccountTTL(this Client client, AccountDaysTTL ttl) - => client.Invoke(new Account_SetAccountTTL - { - ttl = ttl, - }); - - /// Verify a new phone number to associate to the current account See Possible codes: 400,406 (details) - /// New phone number - /// Phone code settings - public static Task Account_SendChangePhoneCode(this Client client, string phone_number, CodeSettings settings) - => client.Invoke(new Account_SendChangePhoneCode - { - phone_number = phone_number, - settings = settings, - }); - - /// 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 - public static Task Account_ChangePhone(this Client client, string phone_number, string phone_code_hash, string phone_code) - => client.Invoke(new Account_ChangePhone - { - phone_number = phone_number, - phone_code_hash = phone_code_hash, - phone_code = phone_code, - }); - - /// When client-side passcode lock feature is enabled, will not show message texts in incoming PUSH notifications. See - /// Inactivity period after which to start hiding message texts in PUSH notifications. - public static Task Account_UpdateDeviceLocked(this Client client, int period) - => client.Invoke(new Account_UpdateDeviceLocked - { - period = period, - }); - - /// Get logged-in sessions See - public static Task Account_GetAuthorizations(this Client client) - => client.Invoke(new Account_GetAuthorizations - { - }); - - /// Log out an active authorized session by its hash See Possible codes: 400,406 (details) - /// Session hash - public static Task Account_ResetAuthorization(this Client client, long hash) - => client.Invoke(new Account_ResetAuthorization - { - hash = hash, - }); - - /// Obtain configuration for two-factor authorization with password See - public static Task Account_GetPassword(this Client client) - => client.Invoke(new Account_GetPassword - { - }); - - /// Get private info associated to the password info (recovery email, telegram passport info & so on) See Possible codes: 400 (details) - /// The password (see SRP) - public static Task Account_GetPasswordSettings(this Client client, InputCheckPasswordSRP password) - => client.Invoke(new Account_GetPasswordSettings - { - password = password, - }); - - /// Set a new 2FA password See Possible codes: 400 (details) - /// The old password (see SRP) - /// The new password (see SRP) - public static Task Account_UpdatePasswordSettings(this Client client, InputCheckPasswordSRP password, Account_PasswordInputSettings new_settings) - => client.Invoke(new Account_UpdatePasswordSettings - { - password = password, - new_settings = new_settings, - }); - - /// Send confirmation code to cancel account deletion, for more info click here » See Possible codes: 400 (details) - /// The hash from the service notification, for more info click here » - /// Phone code settings - public static Task Account_SendConfirmPhoneCode(this Client client, string hash, CodeSettings settings) - => client.Invoke(new Account_SendConfirmPhoneCode - { - hash = hash, - settings = settings, - }); - - /// Confirm a phone number to cancel account deletion, for more info click here » See Possible codes: 400 (details) - /// Phone code hash, for more info click here » - /// SMS code, for more info click here » - public static Task Account_ConfirmPhone(this Client client, string phone_code_hash, string phone_code) - => client.Invoke(new Account_ConfirmPhone - { - phone_code_hash = phone_code_hash, - phone_code = phone_code, - }); - - /// Get temporary payment password See Possible codes: 400 (details) - /// SRP password parameters - /// Time during which the temporary password will be valid, in seconds; should be between 60 and 86400 - public static Task Account_GetTmpPassword(this Client client, InputCheckPasswordSRP password, int period) - => client.Invoke(new Account_GetTmpPassword - { - password = password, - period = period, - }); - - /// Get web login widget authorizations See - public static Task Account_GetWebAuthorizations(this Client client) - => client.Invoke(new Account_GetWebAuthorizations - { - }); - - /// Log out an active web telegram login session See Possible codes: 400 (details) - /// Session hash - public static Task Account_ResetWebAuthorization(this Client client, long hash) - => client.Invoke(new Account_ResetWebAuthorization - { - hash = hash, - }); - - /// Reset all active web telegram login sessions See - public static Task Account_ResetWebAuthorizations(this Client client) - => client.Invoke(new Account_ResetWebAuthorizations - { - }); - - /// Get all saved Telegram Passport documents, for more info see the passport docs » See - public static Task Account_GetAllSecureValues(this Client client) - => client.Invoke(new Account_GetAllSecureValues - { - }); - - /// Get saved Telegram Passport document, for more info see the passport docs » See - /// Requested value types - public static Task Account_GetSecureValue(this Client client, params SecureValueType[] types) - => client.Invoke(new Account_GetSecureValue - { - types = types, - }); - - /// Securely save Telegram Passport document, for more info see the passport docs » See Possible codes: 400 (details) - /// Secure value, for more info see the passport docs » - /// Passport secret hash, for more info see the passport docs » - public static Task Account_SaveSecureValue(this Client client, InputSecureValue value, long secure_secret_id) - => client.Invoke(new Account_SaveSecureValue - { - value = value, - secure_secret_id = secure_secret_id, - }); - - /// Delete stored Telegram Passport documents, for more info see the passport docs » See - /// Document types to delete - public static Task Account_DeleteSecureValue(this Client client, params SecureValueType[] types) - => client.Invoke(new Account_DeleteSecureValue - { - types = types, - }); - - /// Returns a Telegram Passport authorization form for sharing data with a service See Possible codes: 400 (details) - /// User identifier of the service's bot - /// Telegram Passport element types requested by the service - /// Service's public key - public static Task Account_GetAuthorizationForm(this Client client, long bot_id, string scope, string public_key) - => client.Invoke(new Account_GetAuthorizationForm - { - bot_id = bot_id, - scope = scope, - public_key = public_key, - }); - - /// Sends a Telegram Passport authorization form, effectively sharing data with the service See Possible codes: 400 (details) - /// Bot ID - /// Telegram Passport element types requested by the service - /// Service's public key - /// Types of values sent and their hashes - /// Encrypted values - public static Task Account_AcceptAuthorization(this Client client, long bot_id, string scope, string public_key, SecureValueHash[] value_hashes, SecureCredentialsEncrypted credentials) - => client.Invoke(new Account_AcceptAuthorization - { - bot_id = bot_id, - scope = scope, - public_key = public_key, - value_hashes = value_hashes, - credentials = credentials, - }); - - /// Send the verification phone code for telegram passport. See Possible codes: 400 (details) - /// The phone number to verify - /// Phone code settings - public static Task Account_SendVerifyPhoneCode(this Client client, string phone_number, CodeSettings settings) - => client.Invoke(new Account_SendVerifyPhoneCode - { - phone_number = phone_number, - settings = settings, - }); - - /// 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 - public static Task Account_VerifyPhone(this Client client, string phone_number, string phone_code_hash, string phone_code) - => client.Invoke(new Account_VerifyPhone - { - phone_number = phone_number, - phone_code_hash = phone_code_hash, - phone_code = phone_code, - }); - - /// Send an email verification code. See Possible codes: 400 (details) - /// Verification purpose. - /// The email where to send the code. - public static Task Account_SendVerifyEmailCode(this Client client, EmailVerifyPurpose purpose, string email) - => client.Invoke(new Account_SendVerifyEmailCode - { - purpose = purpose, - email = email, - }); - - /// Verify an email address. See Possible codes: 400 (details) - /// Verification purpose - /// Email verification code or token - public static Task Account_VerifyEmail(this Client client, EmailVerifyPurpose purpose, EmailVerification verification) - => client.Invoke(new Account_VerifyEmail - { - purpose = purpose, - verification = verification, - }); - - /// Initialize a takeout session, see here » for more info. See Possible codes: 420 (details) - /// Whether to export contacts - /// Whether to export messages in private chats - /// Whether to export messages in basic groups - /// Whether to export messages in supergroups - /// Whether to export messages in channels - /// Whether to export files - /// Maximum size of files to export - 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)((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 ?? default, - }); - - /// Terminate a takeout session, see here » for more info. See Possible codes: 403 (details) - /// Data exported successfully - public static Task Account_FinishTakeoutSession(this Client client, bool success = false) - => client.Invoke(new Account_FinishTakeoutSession - { - flags = (Account_FinishTakeoutSession.Flags)(success ? 0x1 : 0), - }); - - /// Verify an email to use as 2FA recovery method. See Possible codes: 400 (details) - /// The phone code that was received after setting a recovery email - public static Task Account_ConfirmPasswordEmail(this Client client, string code) - => client.Invoke(new Account_ConfirmPasswordEmail - { - code = code, - }); - - /// Resend the code to verify an email to use as 2FA recovery method. See Possible codes: 400 (details) - public static Task Account_ResendPasswordEmail(this Client client) - => client.Invoke(new Account_ResendPasswordEmail - { - }); - - /// Cancel the code that was sent to verify an email to use as 2FA recovery method. See Possible codes: 400 (details) - public static Task Account_CancelPasswordEmail(this Client client) - => client.Invoke(new Account_CancelPasswordEmail - { - }); - - /// Whether the user will receive notifications when contacts sign up See - public static Task Account_GetContactSignUpNotification(this Client client) - => client.Invoke(new Account_GetContactSignUpNotification - { - }); - - /// Toggle contact sign up notifications See - /// Whether to disable contact sign up notifications - public static Task Account_SetContactSignUpNotification(this Client client, bool silent) - => client.Invoke(new Account_SetContactSignUpNotification - { - silent = silent, - }); - - /// Returns list of chats with non-default notification settings See - /// If set, chats with non-default sound will be returned - /// If set, chats with non-default notification settings for stories will be returned - /// If specified, only chats of the specified category will be returned - public static Task Account_GetNotifyExceptions(this Client client, InputNotifyPeerBase peer = null, bool compare_sound = false, bool compare_stories = false) - => client.Invoke(new Account_GetNotifyExceptions - { - flags = (Account_GetNotifyExceptions.Flags)((peer != null ? 0x1 : 0) | (compare_sound ? 0x2 : 0) | (compare_stories ? 0x4 : 0)), - peer = peer, - }); - - /// Get info about a certain wallpaper See Possible codes: 400 (details) - /// The wallpaper to get info about - public static Task Account_GetWallPaper(this Client client, InputWallPaperBase wallpaper) - => client.Invoke(new Account_GetWallPaper - { - wallpaper = wallpaper, - }); - - /// Create and upload a new wallpaper See Possible codes: 400 (details) - /// Set this flag when uploading wallpapers to be passed to Messages_SetChatWallPaper. - /// The JPG/PNG wallpaper - /// MIME type of uploaded wallpaper - /// Wallpaper settings - public static Task Account_UploadWallPaper(this Client client, InputFileBase file, string mime_type, WallPaperSettings settings, bool for_chat = false) - => client.Invoke(new Account_UploadWallPaper - { - flags = (Account_UploadWallPaper.Flags)(for_chat ? 0x1 : 0), - file = file, - mime_type = mime_type, - settings = settings, - }); - - /// Install/uninstall wallpaper See Possible codes: 400 (details) - /// Wallpaper to install or uninstall - /// Uninstall wallpaper? - /// Wallpaper settings - public static Task Account_SaveWallPaper(this Client client, InputWallPaperBase wallpaper, bool unsave, WallPaperSettings settings) - => client.Invoke(new Account_SaveWallPaper - { - wallpaper = wallpaper, - unsave = unsave, - settings = settings, - }); - - /// Install wallpaper See Possible codes: 400 (details) - /// Wallpaper to install - /// Wallpaper settings - public static Task Account_InstallWallPaper(this Client client, InputWallPaperBase wallpaper, WallPaperSettings settings) - => client.Invoke(new Account_InstallWallPaper - { - wallpaper = wallpaper, - settings = settings, - }); - - /// Delete all installed wallpapers, reverting to the default wallpaper set. See - public static Task Account_ResetWallPapers(this Client client) - => client.Invoke(new Account_ResetWallPapers - { - }); - - /// Get media autodownload settings See - public static Task Account_GetAutoDownloadSettings(this Client client) - => client.Invoke(new Account_GetAutoDownloadSettings - { - }); - - /// Change media autodownload settings See - /// Whether to save media in the low data usage preset - /// Whether to save media in the high data usage preset - /// Media autodownload settings - public static Task Account_SaveAutoDownloadSettings(this Client client, AutoDownloadSettings settings, bool low = false, bool high = false) - => client.Invoke(new Account_SaveAutoDownloadSettings - { - flags = (Account_SaveAutoDownloadSettings.Flags)((low ? 0x1 : 0) | (high ? 0x2 : 0)), - settings = settings, - }); - - /// Upload theme See Possible codes: 400 (details) - /// Previously uploaded theme file with platform-specific colors for UI components, can be left unset when creating themes that only modify the wallpaper or accent colors. - /// Thumbnail - /// File name - /// MIME type, must be application/x-tgtheme-{format}, where format depends on the client - public static Task Account_UploadTheme(this Client client, InputFileBase file, string file_name, string mime_type, InputFileBase thumb = null) - => client.Invoke(new Account_UploadTheme - { - flags = (Account_UploadTheme.Flags)(thumb != null ? 0x1 : 0), - file = file, - thumb = thumb, - file_name = file_name, - mime_type = mime_type, - }); - - /// Create a theme See Possible codes: 400 (details) - /// Unique theme ID used to generate theme deep links, can be empty to autogenerate a random ID. - /// Theme name - /// Theme file - /// Theme settings, multiple values can be provided for the different base themes (day/night mode, etc). - public static Task Account_CreateTheme(this Client client, string slug, string title, InputDocument document = null, InputThemeSettings[] settings = null) - => client.Invoke(new Account_CreateTheme - { - flags = (Account_CreateTheme.Flags)((document != null ? 0x4 : 0) | (settings != null ? 0x8 : 0)), - slug = slug, - title = title, - document = document, - settings = settings, - }); - - /// Update theme See Possible codes: 400 (details) - /// Theme format, a string that identifies the theming engines supported by the client - /// Theme to update - /// Unique theme ID - /// Theme name - /// Theme file - /// Theme settings - public static Task Account_UpdateTheme(this Client client, string format, InputThemeBase theme, string slug = null, string title = null, InputDocument document = null, InputThemeSettings[] settings = null) - => client.Invoke(new Account_UpdateTheme - { - flags = (Account_UpdateTheme.Flags)((slug != null ? 0x1 : 0) | (title != null ? 0x2 : 0) | (document != null ? 0x4 : 0) | (settings != null ? 0x8 : 0)), - format = format, - theme = theme, - slug = slug, - title = title, - document = document, - settings = settings, - }); - - /// Save a theme See Possible codes: 400 (details) - /// Theme to save - /// Unsave - public static Task Account_SaveTheme(this Client client, InputThemeBase theme, bool unsave) - => client.Invoke(new Account_SaveTheme - { - theme = theme, - unsave = unsave, - }); - - /// Install a theme See - /// Whether to install the dark version - /// 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, InputThemeBase theme = null, string format = null, BaseTheme base_theme = default, bool dark = false) - => client.Invoke(new Account_InstallTheme - { - 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, - }); - - /// Get theme information See Possible codes: 400 (details) - /// Theme format, a string that identifies the theming engines supported by the client - /// Theme - public static Task Account_GetTheme(this Client client, string format, InputThemeBase theme) - => client.Invoke(new Account_GetTheme - { - format = format, - theme = theme, - }); - - /// Get installed themes See - /// Theme format, a string that identifies the theming engines supported by the client - /// Hash used for caching, for more info click here. - /// a null value means account.themesNotModified - public static Task Account_GetThemes(this Client client, string format, long hash = default) - => client.Invoke(new Account_GetThemes - { - format = format, - hash = hash, - }); - - /// Set sensitive content settings (for viewing or hiding NSFW content) See Possible codes: 403 (details) - /// Enable NSFW content - public static Task Account_SetContentSettings(this Client client, bool sensitive_enabled = false) - => client.Invoke(new Account_SetContentSettings - { - flags = (Account_SetContentSettings.Flags)(sensitive_enabled ? 0x1 : 0), - }); - - /// Get sensitive content settings See - public static Task Account_GetContentSettings(this Client client) - => client.Invoke(new Account_GetContentSettings - { - }); - - /// Get info about multiple wallpapers See Possible codes: 400 (details) - /// Wallpapers to fetch info about - public static Task Account_GetMultiWallPapers(this Client client, params InputWallPaperBase[] wallpapers) - => client.Invoke(new Account_GetMultiWallPapers - { - wallpapers = wallpapers, - }); - - /// Get global privacy settings See - public static Task Account_GetGlobalPrivacySettings(this Client client) - => client.Invoke(new Account_GetGlobalPrivacySettings - { - }); - - /// Set global privacy settings See Possible codes: 400,403 (details) - /// Global privacy settings - public static Task Account_SetGlobalPrivacySettings(this Client client, GlobalPrivacySettings settings) - => client.Invoke(new Account_SetGlobalPrivacySettings - { - settings = settings, - }); - - /// Report a profile photo of a dialog See Possible codes: 400 (details) - /// The dialog - /// Dialog photo ID - /// Report reason - /// Comment for report moderation - public static Task Account_ReportProfilePhoto(this Client client, InputPeer peer, InputPhoto photo_id, ReportReason reason, string message) - => client.Invoke(new Account_ReportProfilePhoto - { - peer = peer, - photo_id = photo_id, - reason = reason, - message = message, - }); - - /// Initiate a 2FA password reset: can only be used if the user is already logged-in, see here for more info » See Possible codes: 400 (details) - public static Task Account_ResetPassword(this Client client) - => client.Invoke(new Account_ResetPassword - { - }); - - /// Abort a pending 2FA password reset, see here for more info » See Possible codes: 400 (details) - public static Task Account_DeclinePasswordReset(this Client client) - => client.Invoke(new Account_DeclinePasswordReset - { - }); - - /// Get all available chat themes ». See - /// Hash used for caching, for more info click here. - /// a null value means account.themesNotModified - public static Task Account_GetChatThemes(this Client client, long hash = default) - => client.Invoke(new Account_GetChatThemes - { - hash = hash, - }); - - /// Set time-to-live of current session See Possible codes: 400,406 (details) - /// Time-to-live of current session in days - public static Task Account_SetAuthorizationTTL(this Client client, int authorization_ttl_days) - => client.Invoke(new Account_SetAuthorizationTTL - { - authorization_ttl_days = authorization_ttl_days, - }); - - /// Change settings related to a session. See Possible codes: 400 (details) - /// If set, confirms a newly logged in session ». - /// 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, bool confirmed = false) - => client.Invoke(new Account_ChangeAuthorizationSettings - { - flags = (Account_ChangeAuthorizationSettings.Flags)((encrypted_requests_disabled != default ? 0x1 : 0) | (call_requests_disabled != default ? 0x2 : 0) | (confirmed ? 0x8 : 0)), - hash = hash, - encrypted_requests_disabled = encrypted_requests_disabled ?? default, - call_requests_disabled = call_requests_disabled ?? default, - }); - - /// Fetch saved notification sounds See - /// Hash used for caching, for more info click here. - /// a null value means account.savedRingtonesNotModified - public static Task Account_GetSavedRingtones(this Client client, long hash = default) - => client.Invoke(new Account_GetSavedRingtones - { - hash = hash, - }); - - /// Save or remove saved notification sound. See Possible codes: 400 (details) - /// 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 - { - id = id, - unsave = unsave, - }); - - /// Upload notification sound, use Account_SaveRingtone to convert it and add it to the list of saved notification sounds. See Possible codes: 400 (details) - /// Notification sound - /// File name - /// MIME type of file - public static Task Account_UploadRingtone(this Client client, InputFileBase file, string file_name, string mime_type) - => client.Invoke(new Account_UploadRingtone - { - file = file, - file_name = file_name, - mime_type = mime_type, - }); - - /// Set an emoji status See Possible codes: 400 (details) - /// Emoji status to set - public static Task Account_UpdateEmojiStatus(this Client client, EmojiStatusBase emoji_status) - => client.Invoke(new Account_UpdateEmojiStatus - { - emoji_status = emoji_status, - }); - - /// Get a list of default suggested emoji statuses See - /// Hash used for caching, for more info click here. - /// a null value means account.emojiStatusesNotModified - public static Task Account_GetDefaultEmojiStatuses(this Client client, long hash = default) - => client.Invoke(new Account_GetDefaultEmojiStatuses - { - hash = hash, - }); - - /// Get recently used emoji statuses See - /// Hash used for caching, for more info click here. - /// a null value means account.emojiStatusesNotModified - public static Task Account_GetRecentEmojiStatuses(this Client client, long hash = default) - => client.Invoke(new Account_GetRecentEmojiStatuses - { - hash = hash, - }); - - /// Clears list of recently used emoji statuses See - public static Task Account_ClearRecentEmojiStatuses(this Client client) - => client.Invoke(new Account_ClearRecentEmojiStatuses - { - }); - - /// Reorder usernames associated with the currently logged-in user. See Possible codes: 400 (details) - /// The new order for active usernames. All active usernames must be specified. - public static Task Account_ReorderUsernames(this Client client, params string[] order) - => client.Invoke(new Account_ReorderUsernames - { - order = order, - }); - - /// Activate or deactivate a purchased fragment.com username associated to the currently logged-in user. See Possible codes: 400 (details) - /// Username - /// Whether to activate or deactivate it - public static Task Account_ToggleUsername(this Client client, string username, bool active) - => client.Invoke(new Account_ToggleUsername - { - username = username, - active = active, - }); - - /// Get a set of suggested custom emoji stickers that can be used as profile picture See - /// Hash used for caching, for more info click here. - /// a null value means emojiListNotModified - public static Task Account_GetDefaultProfilePhotoEmojis(this Client client, long hash = default) - => client.Invoke(new Account_GetDefaultProfilePhotoEmojis - { - hash = hash, - }); - - /// Get a set of suggested custom emoji stickers that can be used as group picture See - /// Hash used for caching, for more info click here. - /// a null value means emojiListNotModified - public static Task Account_GetDefaultGroupPhotoEmojis(this Client client, long hash = default) - => client.Invoke(new Account_GetDefaultGroupPhotoEmojis - { - hash = hash, - }); - - /// Get autosave settings See - public static Task Account_GetAutoSaveSettings(this Client client) - => client.Invoke(new Account_GetAutoSaveSettings - { - }); - - /// Modify autosave settings See Possible codes: 400 (details) - /// Whether the new settings should affect all private chats - /// Whether the new settings should affect all groups - /// Whether the new settings should affect all channels - /// Whether the new settings should affect a specific peer - /// The new autosave settings - public static Task Account_SaveAutoSaveSettings(this Client client, AutoSaveSettings settings, InputPeer peer = null, bool users = false, bool chats = false, bool broadcasts = false) - => client.Invoke(new Account_SaveAutoSaveSettings - { - flags = (Account_SaveAutoSaveSettings.Flags)((peer != null ? 0x8 : 0) | (users ? 0x1 : 0) | (chats ? 0x2 : 0) | (broadcasts ? 0x4 : 0)), - peer = peer, - settings = settings, - }); - - /// Clear all peer-specific autosave settings. See - public static Task Account_DeleteAutoSaveExceptions(this Client client) - => client.Invoke(new Account_DeleteAutoSaveExceptions - { - }); - - /// Invalidate the specified login codes, see here » for more info. See - /// The login codes to invalidate. - public static Task Account_InvalidateSignInCodes(this Client client, params string[] codes) - => client.Invoke(new Account_InvalidateSignInCodes - { - codes = codes, - }); - - /// Update the accent color and background custom emoji » of the current account. See Possible codes: 400,403 (details) - /// Whether to change the accent color emoji pattern of the profile page; otherwise, the accent color and emoji pattern of messages will be changed. - /// ID of the accent color palette » to use (not RGB24, see here » for more info). - public static Task Account_UpdateColor(this Client client, PeerColorBase color = null, bool for_profile = false) - => client.Invoke(new Account_UpdateColor - { - flags = (Account_UpdateColor.Flags)((color != null ? 0x4 : 0) | (for_profile ? 0x2 : 0)), - color = color, - }); - - /// Get a set of suggested custom emoji stickers that can be used in an accent color pattern. See - /// Hash used for caching, for more info click here. - /// a null value means emojiListNotModified - public static Task Account_GetDefaultBackgroundEmojis(this Client client, long hash = default) - => client.Invoke(new Account_GetDefaultBackgroundEmojis - { - hash = hash, - }); - - /// Get a list of default suggested channel emoji statuses. See - /// Hash used for caching, for more info click here. - /// a null value means account.emojiStatusesNotModified - public static Task Account_GetChannelDefaultEmojiStatuses(this Client client, long hash = default) - => client.Invoke(new Account_GetChannelDefaultEmojiStatuses - { - hash = hash, - }); - - /// Returns fetch the full list of custom emoji IDs » that cannot be used in channel emoji statuses ». See - /// Hash used for caching, for more info click here. - /// a null value means emojiListNotModified - public static Task Account_GetChannelRestrictedStatusEmojis(this Client client, long hash = default) - => client.Invoke(new Account_GetChannelRestrictedStatusEmojis - { - hash = hash, - }); - - /// Specify a set of Telegram Business opening hours.
This info will be contained in .business_work_hours. See Possible codes: 400 (details)
- /// Opening hours (optional, if not set removes all opening hours). - public static Task Account_UpdateBusinessWorkHours(this Client client, BusinessWorkHours business_work_hours = null) - => client.Invoke(new Account_UpdateBusinessWorkHours - { - flags = (Account_UpdateBusinessWorkHours.Flags)(business_work_hours != null ? 0x1 : 0), - business_work_hours = business_work_hours, - }); - - /// Businesses » may advertise their location using this method, see here » for more info. See - /// Optional, contains a set of geographical coordinates. - /// Mandatory when setting/updating the location, contains a textual description of the address (max 96 UTF-8 chars). - public static Task Account_UpdateBusinessLocation(this Client client, string address = null, InputGeoPoint geo_point = null) - => client.Invoke(new Account_UpdateBusinessLocation - { - flags = (Account_UpdateBusinessLocation.Flags)((address != null ? 0x1 : 0) | (geo_point != null ? 0x2 : 0)), - geo_point = geo_point, - address = address, - }); - - /// Set a list of Telegram Business greeting messages. See - /// Greeting message configuration and contents. - public static Task Account_UpdateBusinessGreetingMessage(this Client client, InputBusinessGreetingMessage message = null) - => client.Invoke(new Account_UpdateBusinessGreetingMessage - { - flags = (Account_UpdateBusinessGreetingMessage.Flags)(message != null ? 0x1 : 0), - message = message, - }); - - /// Set a list of Telegram Business away messages. See - /// Away message configuration and contents. - public static Task Account_UpdateBusinessAwayMessage(this Client client, InputBusinessAwayMessage message = null) - => client.Invoke(new Account_UpdateBusinessAwayMessage - { - flags = (Account_UpdateBusinessAwayMessage.Flags)(message != null ? 0x1 : 0), - message = message, - }); - - /// Connect a business bot » to the current account, or to change the current connection settings. See Possible codes: 400,403 (details) - /// Whether to fully disconnect the bot from the current account. - /// Business bot rights. - /// The bot to connect or disconnect - /// Configuration for the business connection - public static Task Account_UpdateConnectedBot(this Client client, InputUserBase bot, InputBusinessBotRecipients recipients, BusinessBotRights rights = null, bool deleted = false) - => client.Invoke(new Account_UpdateConnectedBot - { - flags = (Account_UpdateConnectedBot.Flags)((rights != null ? 0x1 : 0) | (deleted ? 0x2 : 0)), - rights = rights, - bot = bot, - recipients = recipients, - }); - - /// List all currently connected business bots » See - public static Task Account_GetConnectedBots(this Client client) - => client.Invoke(new Account_GetConnectedBots - { - }); - - /// Bots may invoke this method to re-fetch the associated with a specific business connection_id, see here » for more info on connected business bots.
This is needed for example for freshly logged in bots that are receiving some , etc. updates because some users have already connected to the bot before it could login.
In this case, the bot is receiving messages from the business connection, but it hasn't cached the associated with info about the connection (can it reply to messages? etc.) yet, and cannot receive the old ones because they were sent when the bot wasn't logged into the session yet.
This method can be used to fetch info about a not-yet-cached business connection, and should not be invoked if the info is already cached or to fetch changes, as eventual changes will automatically be sent as new updates to the bot using the usual update delivery methods ». See [bots: ✓] Possible codes: 400 (details)
- /// Business connection ID ». - public static Task Account_GetBotBusinessConnection(this Client client, string connection_id) - => client.Invoke(new Account_GetBotBusinessConnection - { - connection_id = connection_id, - }); - - /// Set or remove the Telegram Business introduction ». See - /// Telegram Business introduction, to remove it call the method without setting this flag. - public static Task Account_UpdateBusinessIntro(this Client client, InputBusinessIntro intro = null) - => client.Invoke(new Account_UpdateBusinessIntro - { - flags = (Account_UpdateBusinessIntro.Flags)(intro != null ? 0x1 : 0), - intro = intro, - }); - - /// Pause or unpause a specific chat, temporarily disconnecting it from all business bots ». See Possible codes: 400 (details) - /// The chat to pause - /// Whether to pause or unpause the chat - public static Task Account_ToggleConnectedBotPaused(this Client client, InputPeer peer, bool paused) - => client.Invoke(new Account_ToggleConnectedBotPaused - { - peer = peer, - paused = paused, - }); - - /// Permanently disconnect a specific chat from all business bots » (equivalent to specifying it in recipients.exclude_users during initial configuration with Account_UpdateConnectedBot); to reconnect of a chat disconnected using this method the user must reconnect the entire bot by invoking Account_UpdateConnectedBot. See Possible codes: 400 (details) - /// The chat to disconnect - public static Task Account_DisablePeerConnectedBot(this Client client, InputPeer peer) - => client.Invoke(new Account_DisablePeerConnectedBot - { - peer = peer, - }); - - /// Update our birthday, see here » for more info. See Possible codes: 400 (details) - /// Birthday. - public static Task Account_UpdateBirthday(this Client client, Birthday birthday = null) - => client.Invoke(new Account_UpdateBirthday - { - flags = (Account_UpdateBirthday.Flags)(birthday != null ? 0x1 : 0), - birthday = birthday, - }); - - /// Create a business chat deep link ». See Possible codes: 400,403 (details) - /// Info about the link to create. - public static Task Account_CreateBusinessChatLink(this Client client, InputBusinessChatLink link) - => client.Invoke(new Account_CreateBusinessChatLink - { - link = link, - }); - - /// Edit a created business chat deep link ». See Possible codes: 400,403 (details) - /// Slug of the link, obtained as specified here ». - /// New link information. - public static Task Account_EditBusinessChatLink(this Client client, string slug, InputBusinessChatLink link) - => client.Invoke(new Account_EditBusinessChatLink - { - slug = slug, - link = link, - }); - - /// Delete a business chat deep link ». See Possible codes: 400 (details) - /// Slug of the link, obtained as specified here ». - public static Task Account_DeleteBusinessChatLink(this Client client, string slug) - => client.Invoke(new Account_DeleteBusinessChatLink - { - slug = slug, - }); - - /// List all created business chat deep links ». See - public static Task Account_GetBusinessChatLinks(this Client client) - => client.Invoke(new Account_GetBusinessChatLinks - { - }); - - /// Resolve a business chat deep link ». See Possible codes: 400 (details) - /// Slug of the link, obtained as specified here ». - public static Task Account_ResolveBusinessChatLink(this Client client, string slug) - => client.Invoke(new Account_ResolveBusinessChatLink - { - slug = slug, - }); - - /// Associate (or remove) a personal channel », that will be listed on our personal profile page ». See - /// The channel, pass to remove it. - public static Task Account_UpdatePersonalChannel(this Client client, InputChannelBase channel) - => client.Invoke(new Account_UpdatePersonalChannel - { - channel = channel, - }); - - /// Disable or re-enable Telegram ads for the current Premium account. See - /// Enable or disable ads. - public static Task Account_ToggleSponsoredMessages(this Client client, bool enabled) - => client.Invoke(new Account_ToggleSponsoredMessages - { - enabled = enabled, - }); - - /// Get the current reaction notification settings ». See - public static Task Account_GetReactionsNotifySettings(this Client client) - => client.Invoke(new Account_GetReactionsNotifySettings - { - }); - - /// Change the reaction notification settings ». See - /// New reaction notification settings. - public static Task Account_SetReactionsNotifySettings(this Client client, ReactionsNotifySettings settings) - => client.Invoke(new Account_SetReactionsNotifySettings - { - settings = settings, - }); - - /// Obtain a list of emoji statuses » for owned collectible gifts. See - /// Hash for pagination - /// a null value means account.emojiStatusesNotModified - public static Task Account_GetCollectibleEmojiStatuses(this Client client, long hash = default) - => client.Invoke(new Account_GetCollectibleEmojiStatuses - { - hash = hash, - }); - - /// Get the number of stars we have received from the specified user thanks to paid messages »; the received amount will be equal to the sent amount multiplied by stars_paid_message_commission_permille divided by 1000. See Possible codes: 400 (details) - /// If set, can contain the ID of a monoforum (channel direct messages) to obtain the number of stars the user has spent to send us direct messages via the channel. - /// The user that paid to send us messages. - public static Task Account_GetPaidMessagesRevenue(this Client client, InputUserBase user_id, InputPeer parent_peer = null) - => client.Invoke(new Account_GetPaidMessagesRevenue - { - flags = (Account_GetPaidMessagesRevenue.Flags)(parent_peer != null ? 0x1 : 0), - parent_peer = parent_peer, - user_id = user_id, - }); - - /// Allow a user to send us messages without paying if paid messages » are enabled. See Possible codes: 400 (details) - /// If set and require_payment is not set, refunds the amounts the user has already paid us to send us messages (directly or via a monoforum). - /// If set, requires the user to pay in order to send us messages.
Can only be set by monoforums, not users, i.e. parent_peer must be set if this flag is set; users must instead use the privacy setting to remove a previously added exemption.
If not set, allows the user to send us messages without paying (can be unset by both monoforums and users). - /// If set, applies the setting within the monoforum aka direct messages » (pass the ID of the monoforum, not the ID of the associated channel). - /// The user to exempt or unexempt. - public static Task Account_ToggleNoPaidMessagesException(this Client client, InputUserBase user_id, InputPeer parent_peer = null, bool refund_charged = false, bool require_payment = false) - => client.Invoke(new Account_ToggleNoPaidMessagesException - { - flags = (Account_ToggleNoPaidMessagesException.Flags)((parent_peer != null ? 0x2 : 0) | (refund_charged ? 0x1 : 0) | (require_payment ? 0x4 : 0)), - parent_peer = parent_peer, - user_id = user_id, - }); - - /// Changes the main profile tab of the current user, see here » for more info. See - /// The tab to set as main tab. - public static Task Account_SetMainProfileTab(this Client client, ProfileTab tab) - => client.Invoke(new Account_SetMainProfileTab - { - tab = tab, - }); - - /// Adds or removes a song from the current user's profile see here » for more info on the music tab of the profile page. See Possible codes: 400 (details) - /// If set, removes the song. - /// The song to add or remove; can be an already added song when reordering songs with after_id. Adding an already added song will never re-add it, only move it to the top of the song list (or after the song passed in after_id). - /// If set, the song will be added after the passed song (must be already pinned on the profile). - public static Task Account_SaveMusic(this Client client, InputDocument id, InputDocument after_id = null, bool unsave = false) - => client.Invoke(new Account_SaveMusic - { - flags = (Account_SaveMusic.Flags)((after_id != null ? 0x2 : 0) | (unsave ? 0x1 : 0)), - id = id, - after_id = after_id, - }); - - /// Fetch the full list of only the IDs of songs currently added to the profile, see here » for more info. See - /// Hash generated » from the previously returned list of IDs. - /// a null value means account.savedMusicIdsNotModified - public static Task Account_GetSavedMusicIds(this Client client, long hash = default) - => client.Invoke(new Account_GetSavedMusicIds - { - hash = hash, - }); - - /// Obtain all chat themes » associated to owned collectible gifts ». See - /// Offset for pagination. - /// Maximum number of results to return, see pagination - /// Hash from a previously returned , to avoid returning any result if the theme list hasn't changed. - /// a null value means account.chatThemesNotModified - public static Task Account_GetUniqueGiftChatThemes(this Client client, string offset, int limit = int.MaxValue, long hash = default) - => client.Invoke(new Account_GetUniqueGiftChatThemes - { - offset = offset, - limit = limit, - hash = hash, - }); - - /// See Possible codes: 403 (details) - public static Task Account_InitPasskeyRegistration(this Client client) - => client.Invoke(new Account_InitPasskeyRegistration - { - }); - - /// See Possible codes: 400 (details) - public static Task Account_RegisterPasskey(this Client client, InputPasskeyCredential credential) - => client.Invoke(new Account_RegisterPasskey - { - credential = credential, - }); - - /// See - public static Task Account_GetPasskeys(this Client client) - => client.Invoke(new Account_GetPasskeys - { - }); - - /// See - public static Task Account_DeletePasskey(this Client client, string id) - => client.Invoke(new Account_DeletePasskey - { - id = id, - }); - - /// 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) - => client.Invoke(new Users_GetUsers - { - id = id, - }); - - /// Returns extended user info by ID. See [bots: ✓] Possible codes: 400 (details) - /// User ID - public static Task Users_GetFullUser(this Client client, InputUserBase id) - => client.Invoke(new Users_GetFullUser - { - id = id, - }); - - /// Notify the user that the sent passport data contains some errors The user will not be able to re-submit their Passport data to you until the errors are fixed (the contents of the field for which you returned the error must change). See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// The user - /// Errors - public static Task Users_SetSecureValueErrors(this Client client, InputUserBase id, params SecureValueErrorBase[] errors) - => client.Invoke(new Users_SetSecureValueErrors - { - id = id, - errors = errors, - }); - - /// Check whether we can write to the specified users, used to implement bulk checks for Premium-only messages » and paid messages ». See - /// Users to check. - public static Task Users_GetRequirementsToContact(this Client client, params InputUserBase[] id) - => client.Invoke(new Users_GetRequirementsToContact - { - id = id, - }); - - /// Get songs pinned to the user's profile, see here » for more info. See [bots: ✓] Possible codes: 400 (details) - /// The ID of the user. - /// Offset for pagination. - /// Maximum number of results to return, see pagination - /// Hash » of the IDs of previously added songs, to avoid returning any result if there was no change. - public static Task Users_GetSavedMusic(this Client client, InputUserBase id, int offset = default, int limit = int.MaxValue, long hash = default) - => client.Invoke(new Users_GetSavedMusic - { - id = id, - offset = offset, - limit = limit, - hash = hash, - }); - - /// Check if the passed songs are still pinned to the user's profile, or refresh the file references of songs pinned on a user's profile see here » for more info. See Possible codes: 400 (details) - /// The ID of the user. - /// The songs (here, file_reference can be empty to refresh file references). - public static Task Users_GetSavedMusicByID(this Client client, InputUserBase id, params InputDocument[] documents) - => client.Invoke(new Users_GetSavedMusicByID - { - id = id, - documents = documents, - }); - - /// See Possible codes: 400 (details) - public static Task Users_SuggestBirthday(this Client client, InputUserBase id, Birthday birthday) - => client.Invoke(new Users_SuggestBirthday - { - id = id, - birthday = birthday, - }); - - /// Get the telegram IDs of all contacts.
Returns an array of Telegram user IDs for all contacts (0 if a contact does not have an associated Telegram account or have hidden their account using privacy settings). See
- /// Hash used for caching, for more info click here - public static Task Contacts_GetContactIDs(this Client client, long hash = default) - => client.Invoke(new Contacts_GetContactIDs - { - hash = hash, - }); - - /// Use this method to obtain the online statuses of all contacts with an accessible Telegram account. See - public static Task Contacts_GetStatuses(this Client client) - => client.Invoke(new Contacts_GetStatuses - { - }); - - /// Returns the current user's contact list. See - /// Hash used for caching, for more info click here.
Note that the hash is computed using the usual algorithm, passing to the algorithm first the previously returned .saved_count field, then max 100000 sorted user IDs from the contact list, including the ID of the currently logged in user if it is saved as a contact.
Example: tdlib implementation. - /// a null value means contacts.contactsNotModified - public static Task Contacts_GetContacts(this Client client, long hash = default) - => client.Invoke(new Contacts_GetContacts - { - hash = hash, - }); - - /// Imports contacts: saves a full list on the server, adds already registered contacts to the contact list, returns added contacts and their info. See - /// List of contacts to import - public static Task Contacts_ImportContacts(this Client client, params InputContact[] contacts) - => client.Invoke(new Contacts_ImportContacts - { - contacts = contacts, - }); - - /// Deletes several contacts from the list. See Possible codes: 400 (details) - /// User ID list - public static Task Contacts_DeleteContacts(this Client client, params InputUserBase[] id) - => client.Invoke(new Contacts_DeleteContacts - { - id = id, - }); - - /// Delete contacts by phone number See - /// Phone numbers - public static Task Contacts_DeleteByPhones(this Client client, params string[] phones) - => client.Invoke(new Contacts_DeleteByPhones - { - phones = phones, - }); - - /// Adds a peer to a blocklist, see here » for more info. See Possible codes: 400 (details) - /// Whether the peer should be added to the story blocklist; if not set, the peer will be added to the main blocklist, see here » for more info. - /// Peer - public static Task Contacts_Block(this Client client, InputPeer id, bool my_stories_from = false) - => client.Invoke(new Contacts_Block - { - flags = (Contacts_Block.Flags)(my_stories_from ? 0x1 : 0), - id = id, - }); - - /// Deletes a peer from a blocklist, see here » for more info. See Possible codes: 400 (details) - /// Whether the peer should be removed from the story blocklist; if not set, the peer will be removed from the main blocklist, see here » for more info. - /// Peer - public static Task Contacts_Unblock(this Client client, InputPeer id, bool my_stories_from = false) - => client.Invoke(new Contacts_Unblock - { - flags = (Contacts_Unblock.Flags)(my_stories_from ? 0x1 : 0), - id = id, - }); - - /// Returns the list of blocked users. See - /// Whether to fetch the story blocklist; if not set, will fetch the main blocklist. See here » for differences between the two. - /// The number of list elements to be skipped - /// The number of list elements to be returned - public static Task Contacts_GetBlocked(this Client client, int offset = default, int limit = int.MaxValue, bool my_stories_from = false) - => client.Invoke(new Contacts_GetBlocked - { - flags = (Contacts_GetBlocked.Flags)(my_stories_from ? 0x1 : 0), - offset = offset, - limit = limit, - }); - - /// Returns users found by username substring. See Possible codes: 400 (details) - /// Target substring - /// Maximum number of users to be returned - public static Task Contacts_Search(this Client client, string q, int limit = int.MaxValue) - => client.Invoke(new Contacts_Search - { - q = q, - limit = limit, - }); - - /// Resolve a @username to get peer info See [bots: ✓] Possible codes: 400 (details) - /// @username to resolve - /// Referrer ID from referral links ». - public static Task Contacts_ResolveUsername(this Client client, string username, string referer = null) - => client.Invoke(new Contacts_ResolveUsername - { - flags = (Contacts_ResolveUsername.Flags)(referer != null ? 0x1 : 0), - username = username, - referer = referer, - }); - - /// Get most used peers See Possible codes: 400 (details) - /// Users we've chatted most frequently with - /// Most used bots - /// Most used inline bots - /// Most frequently called users - /// Users to which the users often forwards messages to - /// Chats to which the users often forwards messages to - /// Often-opened groups and supergroups - /// Most frequently visited channels - /// Most frequently used Main Mini Bot Apps. - /// Offset for pagination - /// Maximum number of results to return, see pagination - /// Hash used for caching, for more info click here - /// a null value means contacts.topPeersNotModified - public static Task Contacts_GetTopPeers(this Client client, int offset = default, int limit = int.MaxValue, long hash = default, bool correspondents = false, bool bots_pm = false, bool bots_inline = false, bool phone_calls = false, bool forward_users = false, bool forward_chats = false, bool groups = false, bool channels = false, bool bots_app = false) - => client.Invoke(new Contacts_GetTopPeers - { - flags = (Contacts_GetTopPeers.Flags)((correspondents ? 0x1 : 0) | (bots_pm ? 0x2 : 0) | (bots_inline ? 0x4 : 0) | (phone_calls ? 0x8 : 0) | (forward_users ? 0x10 : 0) | (forward_chats ? 0x20 : 0) | (groups ? 0x400 : 0) | (channels ? 0x8000 : 0) | (bots_app ? 0x10000 : 0)), - offset = offset, - limit = limit, - hash = hash, - }); - - /// Reset rating of top peer See Possible codes: 400 (details) - /// Top peer category - /// Peer whose rating should be reset - public static Task Contacts_ResetTopPeerRating(this Client client, TopPeerCategory category, InputPeer peer) - => client.Invoke(new Contacts_ResetTopPeerRating - { - category = category, - peer = peer, - }); - - /// Removes all contacts without an associated Telegram account. See - public static Task Contacts_ResetSaved(this Client client) - => client.Invoke(new Contacts_ResetSaved - { - }); - - /// Get all contacts, requires a takeout session, see here » for more info. See Possible codes: 400,403 (details) - public static Task Contacts_GetSaved(this Client client) - => client.Invoke(new Contacts_GetSaved - { - }); - - /// Enable/disable top peers See - /// Enable/disable - public static Task Contacts_ToggleTopPeers(this Client client, bool enabled) - => client.Invoke(new Contacts_ToggleTopPeers - { - enabled = enabled, - }); - - /// Add an existing telegram user as contact. See Possible codes: 400 (details) - /// Allow the other user to see our phone number? - /// Telegram ID of the other user - /// First name - /// Last name - /// User's phone number, may be omitted to simply add the user to the contact list, without a phone number. - public static Task Contacts_AddContact(this Client client, InputUserBase id, string first_name, string last_name, string phone, TextWithEntities note = null, bool add_phone_privacy_exception = false) - => client.Invoke(new Contacts_AddContact - { - flags = (Contacts_AddContact.Flags)((note != null ? 0x2 : 0) | (add_phone_privacy_exception ? 0x1 : 0)), - id = id, - first_name = first_name, - last_name = last_name, - phone = phone, - note = note, - }); - - /// If the add contact action bar is active, add that user as contact See Possible codes: 400 (details) - /// The user to add as contact - public static Task Contacts_AcceptContact(this Client client, InputUserBase id) - => client.Invoke(new Contacts_AcceptContact - { - id = id, - }); - - /// Get users and geochats near you, see here » for more info. See Possible codes: 400,406 (details) - /// 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, int? self_expires = null, bool background = false) - => client.Invoke(new Contacts_GetLocated - { - flags = (Contacts_GetLocated.Flags)((self_expires != null ? 0x1 : 0) | (background ? 0x2 : 0)), - geo_point = geo_point, - self_expires = self_expires ?? default, - }); - - /// Stop getting notifications about discussion replies of a certain user in @replies See Possible codes: 400 (details) - /// Whether to delete the specified message as well - /// Whether to delete all @replies messages from this user as well - /// Whether to also report this user for spam - /// ID of the message in the @replies chat - public static Task Contacts_BlockFromReplies(this Client client, int msg_id, bool delete_message = false, bool delete_history = false, bool report_spam = false) - => client.Invoke(new Contacts_BlockFromReplies - { - flags = (Contacts_BlockFromReplies.Flags)((delete_message ? 0x1 : 0) | (delete_history ? 0x2 : 0) | (report_spam ? 0x4 : 0)), - msg_id = msg_id, - }); - - /// Resolve a phone number to get user info, if their privacy settings allow it. See Possible codes: 400 (details) - /// Phone number in international format, possibly obtained from a phone number deep link. - public static Task Contacts_ResolvePhone(this Client client, string phone) - => client.Invoke(new Contacts_ResolvePhone - { - phone = phone, - }); - - /// Generates a temporary profile link for the currently logged-in user. See - public static Task Contacts_ExportContactToken(this Client client) - => client.Invoke(new Contacts_ExportContactToken - { - }); - - /// Obtain user info from a temporary profile link. See Possible codes: 400 (details) - /// The token extracted from the temporary profile link. - public static Task Contacts_ImportContactToken(this Client client, string token) - => client.Invoke(new Contacts_ImportContactToken - { - token = token, - }); - - /// Edit the close friends list, see here » for more info. See - /// Full list of user IDs of close friends, see here for more info. - public static Task Contacts_EditCloseFriends(this Client client, params long[] id) - => client.Invoke(new Contacts_EditCloseFriends - { - id = id, - }); - - /// Replace the contents of an entire blocklist, see here for more info ». See - /// Whether to edit the story blocklist; if not set, will edit the main blocklist. See here » for differences between the two. - /// Full content of the blocklist. - /// Maximum number of results to return, see pagination - public static Task Contacts_SetBlocked(this Client client, InputPeer[] id, int limit = int.MaxValue, bool my_stories_from = false) - => client.Invoke(new Contacts_SetBlocked - { - flags = (Contacts_SetBlocked.Flags)(my_stories_from ? 0x1 : 0), - id = id, - limit = limit, - }); - - /// Fetch all users with birthdays that fall within +1/-1 days, relative to the current day: this method should be invoked by clients every 6-8 hours, and if the result is non-empty, it should be used to appropriately update locally cached birthday information in .birthday. See - public static Task Contacts_GetBirthdays(this Client client) - => client.Invoke(new Contacts_GetBirthdays - { - }); - - /// Obtain a list of sponsored peer search results for a given query See Possible codes: 400 (details) - /// The query - /// a null value means contacts.sponsoredPeersEmpty - public static Task Contacts_GetSponsoredPeers(this Client client, string q) - => client.Invoke(new Contacts_GetSponsoredPeers - { - q = q, - }); - - /// See Possible codes: 400 (details) - public static Task Contacts_UpdateContactNote(this Client client, InputUserBase id, TextWithEntities note) - => client.Invoke(new Contacts_UpdateContactNote - { - id = id, - note = note, - }); - - /// This method is only for basic Chat. See Terminology in the README 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 - { - id = id, - }); - - /// Returns the current user dialog list. See Possible codes: 400,403 (details) - /// Exclude pinned dialogs - /// Peer folder ID, for more info click here - /// Offsets for pagination, for more info click here - /// Offsets for pagination, for more info click here (top_message ID used for pagination) - /// Offset peer for pagination - /// Number of list elements to be returned - /// Hash used for caching, 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, int? folder_id = null, bool exclude_pinned = false) - => client.Invoke(new Messages_GetDialogs - { - flags = (Messages_GetDialogs.Flags)((folder_id != null ? 0x2 : 0) | (exclude_pinned ? 0x1 : 0)), - folder_id = folder_id ?? default, - offset_date = offset_date, - offset_id = offset_id, - offset_peer = offset_peer, - limit = limit, - hash = hash, - }); - - /// Returns the conversation history with one interlocutor / within a chat See Possible codes: 400,406,500 (details) - /// Target peer - /// Only return messages starting from the specified message ID - /// Only return messages sent before the specified date - /// Number of list elements to be skipped, negative values are also accepted. - /// Number of results to return - /// If a positive value was transferred, the method will return only messages with IDs less than max_id - /// If a positive value was transferred, the method will return only messages with IDs more than min_id - /// Result hash - public static Task Messages_GetHistory(this Client client, InputPeer peer, int offset_id = default, DateTime offset_date = default, int add_offset = default, int limit = int.MaxValue, int max_id = default, int min_id = default, long hash = default) - => client.Invoke(new Messages_GetHistory - { - peer = peer, - offset_id = offset_id, - offset_date = offset_date, - add_offset = add_offset, - limit = limit, - max_id = max_id, - min_id = min_id, - hash = hash, - }); - - /// Search for messages. See Possible codes: 400,403 (details) - /// User or chat, histories with which are searched, or to search in all private chats and normal groups (not channels) ». Use Messages_SearchGlobal to search globally in all chats, groups, supergroups and channels. - /// Text search request - /// Only return messages sent by the specified user ID - /// Search within the saved message dialog » with this ID. - /// You may search for saved messages tagged » with one or more reactions using this flag. - /// Thread ID - /// Filter to return only specified message types - /// If a positive value was transferred, only messages with a sending date bigger than the transferred one will be returned - /// If a positive value was transferred, only messages with a sending date smaller than the transferred one will be returned - /// Only return messages starting from the specified message ID - /// Additional offset - /// Number of results to return, can be 0 to only return the message counter. - /// Maximum message ID to return - /// Minimum message ID to return - /// Hash - public static Task Messages_Search(this Client client, InputPeer peer, string q, MessagesFilter filter = null, DateTime min_date = default, DateTime max_date = default, int offset_id = default, int add_offset = default, int limit = int.MaxValue, int max_id = default, int min_id = default, long hash = default, InputPeer from_id = null, int? top_msg_id = null, InputPeer saved_peer_id = null, Reaction[] saved_reaction = null) - => client.Invoke(new Messages_Search - { - flags = (Messages_Search.Flags)((from_id != null ? 0x1 : 0) | (top_msg_id != null ? 0x2 : 0) | (saved_peer_id != null ? 0x4 : 0) | (saved_reaction != null ? 0x8 : 0)), - peer = peer, - q = q, - from_id = from_id, - saved_peer_id = saved_peer_id, - saved_reaction = saved_reaction, - top_msg_id = top_msg_id ?? default, - filter = filter, - min_date = min_date, - max_date = max_date, - offset_id = offset_id, - add_offset = add_offset, - limit = limit, - max_id = max_id, - min_id = min_id, - hash = hash, - }); - - /// Marks message history as read. See Possible codes: 400 (details) - /// Target user or group - /// If a positive value is passed, only messages with identifiers less or equal than the given one will be read - public static Task Messages_ReadHistory(this Client client, InputPeer peer, int max_id = default) - => client.InvokeAffected(new Messages_ReadHistory - { - peer = peer, - max_id = max_id, - }, peer is InputPeerChannel ipc ? ipc.channel_id : 0); - - /// Deletes communication history. See Possible codes: 400 (details) - /// Just clear history for the current user, without actually removing messages for every chat user - /// Whether to delete the message history for all chat participants - /// User or chat, communication history of which will be deleted - /// 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, DateTime? min_date = null, DateTime? max_date = null, bool just_clear = false, bool revoke = false) - => client.InvokeAffected(new Messages_DeleteHistory - { - 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 ?? default, - max_date = max_date ?? default, - }, peer is InputPeerChannel ipc ? ipc.channel_id : 0); - - /// This method is only for basic Chat. See Terminology in the README 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) - => client.InvokeAffected(new Messages_DeleteMessages - { - flags = (Messages_DeleteMessages.Flags)(revoke ? 0x1 : 0), - id = id, - }, 0); - - /// This method is only for basic Chat. See Terminology in the README 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 - { - max_id = max_id, - }); - - /// Sends a current user typing event (see for all event types) to a conversation partner or group. See [bots: ✓] Possible codes: 400,403,406 (details) - /// Target user or group - /// Topic ID - /// Type of action - public static Task Messages_SetTyping(this Client client, InputPeer peer, SendMessageAction action, int? top_msg_id = null) - => client.Invoke(new Messages_SetTyping - { - flags = (Messages_SetTyping.Flags)(top_msg_id != null ? 0x1 : 0), - peer = peer, - top_msg_id = top_msg_id ?? default, - action = action, - }); - - /// Sends a message to a chat See [bots: ✓] Possible codes: 400,403,404,406,420,500 (details) - /// Set this flag to disable generation of the webpage preview - /// Send this message silently (no notifications for the receivers) - /// Send this message as background message - /// Clear the draft field - /// Only for bots, disallows forwarding and saving of the messages, even if the destination chat doesn't have content protection enabled - /// Whether to move used stickersets to top, see here for more info on this flag » - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - /// Bots only: if set, allows sending up to 1000 messages per second, ignoring broadcasting limits for a fee of 0.1 Telegram Stars per message. The relevant Stars will be withdrawn from the bot's balance. - /// The destination where the message will be sent - /// If set, indicates that the message should be sent in reply to the specified message or story.
Also used to quote other messages. - /// The message - /// Unique client message ID required to prevent message resending You can use - /// Reply markup for sending bot buttons - /// Message entities for sending styled text - /// Scheduled message date for scheduled messages - /// Send this message as the specified peer - /// Add the message to the specified quick reply shortcut », instead. - /// Specifies a message effect » to use for the message. - /// For paid messages », specifies the amount of Telegram Stars the user has agreed to pay in order to send the message. - /// Used to suggest a post to a channel, see here » for more info on the full flow. - public static Task Messages_SendMessage(this Client client, InputPeer peer, string message, long random_id, InputReplyTo reply_to = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null, InputPeer send_as = null, InputQuickReplyShortcutBase quick_reply_shortcut = null, long? effect = null, long? allow_paid_stars = null, SuggestedPost suggested_post = null, int? schedule_repeat_period = null, bool no_webpage = false, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, bool invert_media = false, bool allow_paid_floodskip = false) - => client.Invoke(new Messages_SendMessage - { - flags = (Messages_SendMessage.Flags)((reply_to != null ? 0x1 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0) | (quick_reply_shortcut != null ? 0x20000 : 0) | (effect != null ? 0x40000 : 0) | (allow_paid_stars != null ? 0x200000 : 0) | (suggested_post != null ? 0x400000 : 0) | (schedule_repeat_period != null ? 0x1000000 : 0) | (no_webpage ? 0x2 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0) | (invert_media ? 0x10000 : 0) | (allow_paid_floodskip ? 0x80000 : 0)), - peer = peer, - reply_to = reply_to, - message = message, - random_id = random_id, - reply_markup = reply_markup, - entities = entities, - schedule_date = schedule_date ?? default, - schedule_repeat_period = schedule_repeat_period ?? default, - send_as = send_as, - quick_reply_shortcut = quick_reply_shortcut, - effect = effect ?? default, - allow_paid_stars = allow_paid_stars ?? default, - suggested_post = suggested_post, - }); - - /// Send a media See [bots: ✓] Possible codes: 400,403,406,420,500 (details) - /// Send message silently (no notification should be triggered) - /// Send message in background - /// Clear the draft - /// Only for bots, disallows forwarding and saving of the messages, even if the destination chat doesn't have content protection enabled - /// Whether to move used stickersets to top, see here for more info on this flag » - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - /// Bots only: if set, allows sending up to 1000 messages per second, ignoring broadcasting limits for a fee of 0.1 Telegram Stars per message. The relevant Stars will be withdrawn from the bot's balance. - /// Destination - /// If set, indicates that the message should be sent in reply to the specified message or story. - /// Attached media - /// Caption - /// Random ID to avoid resending the same message You can use - /// Reply markup for bot keyboards - /// Message entities for styled text - /// Scheduled message date for scheduled messages - /// Send this message as the specified peer - /// Add the message to the specified quick reply shortcut », instead. - /// Specifies a message effect » to use for the message. - /// For paid messages », specifies the amount of Telegram Stars the user has agreed to pay in order to send the message. - /// Used to suggest a post to a channel, see here » for more info on the full flow. - public static Task Messages_SendMedia(this Client client, InputPeer peer, InputMedia media, string message, long random_id, InputReplyTo reply_to = null, ReplyMarkup reply_markup = null, MessageEntity[] entities = null, DateTime? schedule_date = null, InputPeer send_as = null, InputQuickReplyShortcutBase quick_reply_shortcut = null, long? effect = null, long? allow_paid_stars = null, SuggestedPost suggested_post = null, int? schedule_repeat_period = null, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, bool invert_media = false, bool allow_paid_floodskip = false) - => client.Invoke(new Messages_SendMedia - { - flags = (Messages_SendMedia.Flags)((reply_to != null ? 0x1 : 0) | (reply_markup != null ? 0x4 : 0) | (entities != null ? 0x8 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0) | (quick_reply_shortcut != null ? 0x20000 : 0) | (effect != null ? 0x40000 : 0) | (allow_paid_stars != null ? 0x200000 : 0) | (suggested_post != null ? 0x400000 : 0) | (schedule_repeat_period != null ? 0x1000000 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0) | (invert_media ? 0x10000 : 0) | (allow_paid_floodskip ? 0x80000 : 0)), - peer = peer, - reply_to = reply_to, - media = media, - message = message, - random_id = random_id, - reply_markup = reply_markup, - entities = entities, - schedule_date = schedule_date ?? default, - schedule_repeat_period = schedule_repeat_period ?? default, - send_as = send_as, - quick_reply_shortcut = quick_reply_shortcut, - effect = effect ?? default, - allow_paid_stars = allow_paid_stars ?? default, - suggested_post = suggested_post, - }); - - /// Forwards messages by their IDs. See [bots: ✓] Possible codes: 400,403,406,420,500 (details) - /// Whether to send messages silently (no notification will be triggered on the destination clients) - /// Whether to send the message in background - /// When forwarding games, whether to include your score in the game - /// Whether to forward messages without quoting the original author - /// Whether to strip captions from media - /// Only for bots, disallows further re-forwarding and saving of the messages, even if the destination chat doesn't have content protection enabled - /// Bots only: if set, allows sending up to 1000 messages per second, ignoring broadcasting limits for a fee of 0.1 Telegram Stars per message. The relevant Stars will be withdrawn from the bot's balance. - /// Source of messages - /// IDs of messages - /// Random ID to prevent resending of messages You can use - /// Destination peer - /// Destination forum topic - /// Can only contain an , to forward messages to a monoforum topic (mutually exclusive with top_msg_id). - /// Scheduled message date for scheduled messages - /// Forward the messages as the specified peer - /// Add the messages to the specified quick reply shortcut », instead. - /// Start playing the video at the specified timestamp (seconds). - /// For paid messages », specifies the amount of Telegram Stars the user has agreed to pay in order to send the message. - /// Used to suggest a post to a channel, see here » for more info on the full flow. - 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, InputQuickReplyShortcutBase quick_reply_shortcut = null, long? effect = null, int? video_timestamp = null, long? allow_paid_stars = null, InputReplyTo reply_to = null, SuggestedPost suggested_post = null, int? schedule_repeat_period = null, bool silent = false, bool background = false, bool with_my_score = false, bool drop_author = false, bool drop_media_captions = false, bool noforwards = false, bool allow_paid_floodskip = false) - => client.Invoke(new Messages_ForwardMessages - { - flags = (Messages_ForwardMessages.Flags)((top_msg_id != null ? 0x200 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0) | (quick_reply_shortcut != null ? 0x20000 : 0) | (effect != null ? 0x40000 : 0) | (video_timestamp != null ? 0x100000 : 0) | (allow_paid_stars != null ? 0x200000 : 0) | (reply_to != null ? 0x400000 : 0) | (suggested_post != null ? 0x800000 : 0) | (schedule_repeat_period != null ? 0x1000000 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (with_my_score ? 0x100 : 0) | (drop_author ? 0x800 : 0) | (drop_media_captions ? 0x1000 : 0) | (noforwards ? 0x4000 : 0) | (allow_paid_floodskip ? 0x80000 : 0)), - from_peer = from_peer, - id = id, - random_id = random_id, - to_peer = to_peer, - top_msg_id = top_msg_id ?? default, - reply_to = reply_to, - schedule_date = schedule_date ?? default, - schedule_repeat_period = schedule_repeat_period ?? default, - send_as = send_as, - quick_reply_shortcut = quick_reply_shortcut, - effect = effect ?? default, - video_timestamp = video_timestamp ?? default, - allow_paid_stars = allow_paid_stars ?? default, - suggested_post = suggested_post, - }); - - /// Report a new incoming chat for spam, if the of the chat allow us to do that See Possible codes: 400 (details) - /// Peer to report - public static Task Messages_ReportSpam(this Client client, InputPeer peer) - => client.Invoke(new Messages_ReportSpam - { - peer = peer, - }); - - /// Get peer settings See Possible codes: 400 (details) - /// The peer - public static Task Messages_GetPeerSettings(this Client client, InputPeer peer) - => client.Invoke(new Messages_GetPeerSettings - { - peer = peer, - }); - - /// Report a message in a chat for violation of telegram's Terms of Service See Possible codes: 400 (details) - /// Peer - /// IDs of messages to report - /// Menu option, intially empty - /// Comment for report moderation - public static Task Messages_Report(this Client client, InputPeer peer, int[] id, byte[] option, string message) - => client.Invoke(new Messages_Report - { - peer = peer, - id = id, - option = option, - message = message, - }); - - /// This method is only for basic Chat. See Terminology in the README 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 - { - id = id, - }); - - /// This method is only for basic Chat. See Terminology in the README 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 - { - chat_id = chat_id, - }); - - /// This method is only for basic Chat. See Terminology in the README 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) - => client.Invoke(new Messages_EditChatTitle - { - chat_id = chat_id, - title = title, - }); - - /// This method is only for basic Chat. See Terminology in the README 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) - => client.Invoke(new Messages_EditChatPhoto - { - chat_id = chat_id, - photo = photo, - }); - - /// This method is only for basic Chat. See Terminology in the README 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 - public static Task Messages_AddChatUser(this Client client, long chat_id, InputUserBase user_id, int fwd_limit) - => client.Invoke(new Messages_AddChatUser - { - chat_id = chat_id, - user_id = user_id, - fwd_limit = fwd_limit, - }); - - /// This method is only for basic Chat. See Terminology in the README 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 - public static Task Messages_DeleteChatUser(this Client client, long chat_id, InputUserBase user_id, bool revoke_history = false) - => client.Invoke(new Messages_DeleteChatUser - { - flags = (Messages_DeleteChatUser.Flags)(revoke_history ? 0x1 : 0), - chat_id = chat_id, - user_id = user_id, - }); - - /// Creates a new chat. See Possible codes: 400,406,500 (details) - /// List of user IDs to be invited - /// Chat name - /// Time-to-live of all messages that will be sent in the chat: once message.date+message.ttl_period === time(), the message will be deleted on the server, and must be deleted locally as well. You can use Messages_SetDefaultHistoryTTL to edit this value later. - 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 ?? default, - }); - - /// Returns configuration parameters for Diffie-Hellman key generation. Can also return a random sequence of bytes of required length. See Possible codes: 400 (details) - /// Value of the version parameter from , available at the client - /// Length of the required random sequence - public static Task Messages_GetDhConfig(this Client client, int version, int random_length) - => client.Invoke(new Messages_GetDhConfig - { - version = version, - random_length = random_length, - }); - - /// Sends a request to start a secret chat to the user. See Possible codes: 400,403 (details) - /// User ID - /// Unique client request ID required to prevent resending. This also doubles as the chat ID. - /// A = g ^ a mod p, see Wikipedia - public static Task Messages_RequestEncryption(this Client client, InputUserBase user_id, int random_id, byte[] g_a) - => client.Invoke(new Messages_RequestEncryption - { - user_id = user_id, - random_id = random_id, - g_a = g_a, - }); - - /// Confirms creation of a secret chat See Possible codes: 400 (details) - /// Secret chat ID - /// B = g ^ b mod p, see Wikipedia - /// 64-bit fingerprint of the received key - public static Task Messages_AcceptEncryption(this Client client, InputEncryptedChat peer, byte[] g_b, long key_fingerprint) - => client.Invoke(new Messages_AcceptEncryption - { - peer = peer, - g_b = g_b, - key_fingerprint = key_fingerprint, - }); - - /// Cancels a request for creation and/or delete info on secret chat. See Possible codes: 400,500 (details) - /// Whether to delete the entire chat history for the other user as well - /// Secret chat ID - public static Task Messages_DiscardEncryption(this Client client, int chat_id, bool delete_history = false) - => client.Invoke(new Messages_DiscardEncryption - { - flags = (Messages_DiscardEncryption.Flags)(delete_history ? 0x1 : 0), - chat_id = chat_id, - }); - - /// 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 - public static Task Messages_SetEncryptedTyping(this Client client, InputEncryptedChat peer, bool typing) - => client.Invoke(new Messages_SetEncryptedTyping - { - peer = peer, - typing = typing, - }); - - /// Marks message history within a secret chat as read. See Possible codes: 400 (details) - /// Secret chat ID - /// Maximum date value for received messages in history - public static Task Messages_ReadEncryptedHistory(this Client client, InputEncryptedChat peer, DateTime max_date = default) - => client.Invoke(new Messages_ReadEncryptedHistory - { - peer = peer, - max_date = max_date, - }); - - /// Sends a text message to a secret chat. See Possible codes: 400,403,500 (details) - /// Send encrypted message without a notification - /// Secret chat ID - /// Unique client message ID, necessary to avoid message resending You can use - /// TL-serialization of type, encrypted with a key that was created during chat initialization - public static Task Messages_SendEncrypted(this Client client, InputEncryptedChat peer, long random_id, byte[] data, bool silent = false) - => client.Invoke(new Messages_SendEncrypted - { - flags = (Messages_SendEncrypted.Flags)(silent ? 0x1 : 0), - peer = peer, - random_id = random_id, - data = data, - }); - - /// Sends a message with a file attachment to a secret chat See Possible codes: 400 (details) - /// Whether to send the file without triggering a notification - /// Secret chat ID - /// Unique client message ID necessary to prevent message resending You can use - /// TL-serialization of type, encrypted with a key generated during chat initialization - /// File attachment for the secret chat - public static Task Messages_SendEncryptedFile(this Client client, InputEncryptedChat peer, long random_id, byte[] data, InputEncryptedFileBase file, bool silent = false) - => client.Invoke(new Messages_SendEncryptedFile - { - flags = (Messages_SendEncryptedFile.Flags)(silent ? 0x1 : 0), - peer = peer, - random_id = random_id, - data = data, - file = file, - }); - - /// Sends a service message to a secret chat. See Possible codes: 400,403,500 (details) - /// Secret chat ID - /// Unique client message ID required to prevent message resending You can use - /// TL-serialization of type, encrypted with a key generated during chat initialization - public static Task Messages_SendEncryptedService(this Client client, InputEncryptedChat peer, long random_id, byte[] data) - => client.Invoke(new Messages_SendEncryptedService - { - peer = peer, - random_id = random_id, - data = data, - }); - - /// Confirms receipt of messages in a secret chat by client, cancels push notifications.
The method returns a list of random_ids of messages for which push notifications were cancelled. See Possible codes: 400,500 (details)
- /// Maximum qts value available at the client - public static Task Messages_ReceivedQueue(this Client client, int max_qts) - => client.Invoke(new Messages_ReceivedQueue - { - max_qts = max_qts, - }); - - /// Report a secret chat for spam See Possible codes: 400 (details) - /// The secret chat to report - public static Task Messages_ReportEncryptedSpam(this Client client, InputEncryptedChat peer) - => client.Invoke(new Messages_ReportEncryptedSpam - { - peer = peer, - }); - - /// This method is only for basic Chat. See Terminology in the README 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, emitting an . See
- /// Message ID list - public static Task Messages_ReadMessageContents(this Client client, params int[] id) - => client.InvokeAffected(new Messages_ReadMessageContents - { - id = id, - }, 0); - - /// Get stickers by emoji See Possible codes: 400 (details) - /// The emoji - /// Hash used for caching, for more info click here. - /// a null value means messages.stickersNotModified - public static Task Messages_GetStickers(this Client client, string emoticon, long hash = default) - => client.Invoke(new Messages_GetStickers - { - emoticon = emoticon, - hash = hash, - }); - - /// Get all installed stickers See - /// Hash used for caching, for more info click here. - /// a null value means messages.allStickersNotModified - public static Task Messages_GetAllStickers(this Client client, long hash = default) - => client.Invoke(new Messages_GetAllStickers - { - hash = hash, - }); - - /// Get preview of webpage See Possible codes: 400 (details) - /// Message from which to extract the preview - /// Message entities for styled text - public static Task Messages_GetWebPagePreview(this Client client, string message, MessageEntity[] entities = null) - => client.Invoke(new Messages_GetWebPagePreview - { - flags = (Messages_GetWebPagePreview.Flags)(entities != null ? 0x8 : 0), - message = message, - entities = entities, - }); - - /// Export an invite link for a chat See [bots: ✓] Possible codes: 400,403 (details) - /// Legacy flag, reproducing legacy behavior of this method: if set, revokes all previous links before creating a new one. Kept for bot API BC, should not be used by modern clients. - /// Whether admin confirmation is required before admitting each separate user into the chat - /// Chat - /// Expiration date - /// Maximum number of users that can join using this link - /// Description of the invite link, visible only to administrators - /// For Telegram Star subscriptions », contains the pricing of the subscription the user must activate to join the private channel. - public static Task Messages_ExportChatInvite(this Client client, InputPeer peer, DateTime? expire_date = null, int? usage_limit = null, string title = null, StarsSubscriptionPricing subscription_pricing = null, bool legacy_revoke_permanent = false, bool request_needed = false) - => client.Invoke(new Messages_ExportChatInvite - { - flags = (Messages_ExportChatInvite.Flags)((expire_date != null ? 0x1 : 0) | (usage_limit != null ? 0x2 : 0) | (title != null ? 0x10 : 0) | (subscription_pricing != null ? 0x20 : 0) | (legacy_revoke_permanent ? 0x4 : 0) | (request_needed ? 0x8 : 0)), - peer = peer, - expire_date = expire_date ?? default, - usage_limit = usage_limit ?? default, - title = title, - subscription_pricing = subscription_pricing, - }); - - /// Check the validity of a chat invite link and get basic info about it See Possible codes: 400,406 (details) - /// Invite hash from chat invite deep link ». - public static Task Messages_CheckChatInvite(this Client client, string hash) - => client.Invoke(new Messages_CheckChatInvite - { - hash = hash, - }); - - /// Import a chat invite and join a private chat/supergroup/channel See Possible codes: 400,406 (details) - /// hash from a chat invite deep link - public static Task Messages_ImportChatInvite(this Client client, string hash) - => client.Invoke(new Messages_ImportChatInvite - { - hash = hash, - }); - - /// Get info about a stickerset See [bots: ✓] Possible codes: 400,406 (details) - /// Stickerset - /// Hash used for caching, for more info click here - /// a null value means messages.stickerSetNotModified - public static Task Messages_GetStickerSet(this Client client, InputStickerSet stickerset, int hash = default) - => client.Invoke(new Messages_GetStickerSet - { - stickerset = stickerset, - hash = hash, - }); - - /// Install a stickerset See Possible codes: 406 (details) - /// Stickerset to install - /// Whether to archive stickerset - public static Task Messages_InstallStickerSet(this Client client, InputStickerSet stickerset, bool archived) - => client.Invoke(new Messages_InstallStickerSet - { - stickerset = stickerset, - archived = archived, - }); - - /// Uninstall a stickerset See Possible codes: 406 (details) - /// The stickerset to uninstall - public static Task Messages_UninstallStickerSet(this Client client, InputStickerSet stickerset) - => client.Invoke(new Messages_UninstallStickerSet - { - stickerset = stickerset, - }); - - /// Start a conversation with a bot using a deep linking parameter See Possible codes: 400,403,500 (details) - /// The bot - /// The chat where to start the bot, can be the bot's private chat or a group - /// Random ID to avoid resending the same message You can use - /// Deep linking parameter - public static Task Messages_StartBot(this Client client, InputUserBase bot, InputPeer peer, long random_id, string start_param) - => client.Invoke(new Messages_StartBot - { - bot = bot, - peer = peer, - random_id = random_id, - start_param = start_param, - }); - - /// Get and increase the view counter of a message sent or forwarded from a channel See Possible codes: 400,406 (details) - /// Peer where the message was found - /// ID of message - /// Whether to mark the message as viewed and increment the view counter - public static Task Messages_GetMessagesViews(this Client client, InputPeer peer, int[] id, bool increment) - => client.Invoke(new Messages_GetMessagesViews - { - peer = peer, - id = id, - increment = increment, - }); - - /// This method is only for basic Chat. See Terminology in the README 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 - public static Task Messages_EditChatAdmin(this Client client, long chat_id, InputUserBase user_id, bool is_admin) - => client.Invoke(new Messages_EditChatAdmin - { - chat_id = chat_id, - user_id = user_id, - is_admin = is_admin, - }); - - /// This method is only for basic Chat. See Terminology in the README 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,500 (details)
- /// Basic group to migrate - public static Task Messages_MigrateChat(this Client client, long chat_id) - => client.Invoke(new Messages_MigrateChat - { - chat_id = chat_id, - }); - - /// Search for messages and peers globally See Possible codes: 400 (details) - /// If set, only returns results from channels (used in the global channel search tab »). - /// Whether to search only in groups - /// Whether to search only in private chats - /// Peer folder ID, for more info click here - /// Query - /// 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 next_rate parameter of messages.messagesSlice, or if that is absent, the date of the last returned message. - /// Offsets for pagination, for more info click here - /// Offsets for pagination, for more info click here - /// Offsets for pagination, for more info click here - public static Task Messages_SearchGlobal(this Client client, string q, MessagesFilter filter = null, DateTime min_date = default, DateTime max_date = default, int offset_rate = default, InputPeer offset_peer = null, int offset_id = default, int limit = int.MaxValue, int? folder_id = null, bool broadcasts_only = false, bool groups_only = false, bool users_only = false) - => client.Invoke(new Messages_SearchGlobal - { - flags = (Messages_SearchGlobal.Flags)((folder_id != null ? 0x1 : 0) | (broadcasts_only ? 0x2 : 0) | (groups_only ? 0x4 : 0) | (users_only ? 0x8 : 0)), - folder_id = folder_id ?? default, - q = q, - filter = filter, - min_date = min_date, - max_date = max_date, - offset_rate = offset_rate, - offset_peer = offset_peer, - offset_id = offset_id, - limit = limit, - }); - - /// Reorder installed stickersets See - /// Reorder mask stickersets - /// Reorder custom emoji stickersets - /// New stickerset order by stickerset IDs - public static Task Messages_ReorderStickerSets(this Client client, long[] order, bool masks = false, bool emojis = false) - => client.Invoke(new Messages_ReorderStickerSets - { - flags = (Messages_ReorderStickerSets.Flags)((masks ? 0x1 : 0) | (emojis ? 0x2 : 0)), - order = order, - }); - - /// Get a document by its SHA256 hash, mainly used for gifs See [bots: ✓] Possible codes: 400 (details) - /// SHA256 of file - /// Size of the file in bytes - /// Mime type - public static Task Messages_GetDocumentByHash(this Client client, byte[] sha256, long size, string mime_type) - => client.Invoke(new Messages_GetDocumentByHash - { - sha256 = sha256, - size = size, - mime_type = mime_type, - }); - - /// Get saved GIFs. See - /// Hash used for caching, for more info click here. - /// a null value means messages.savedGifsNotModified - public static Task Messages_GetSavedGifs(this Client client, long hash = default) - => client.Invoke(new Messages_GetSavedGifs - { - hash = hash, - }); - - /// Add GIF to saved gifs list See Possible codes: 400 (details) - /// GIF to save - /// Whether to remove GIF from saved gifs list - public static Task Messages_SaveGif(this Client client, InputDocument id, bool unsave) - => client.Invoke(new Messages_SaveGif - { - id = id, - unsave = unsave, - }); - - /// Query an inline bot See Possible codes: -503,400,406 (details) - /// The bot to query - /// The currently opened chat - /// The geolocation, if requested - /// The query - /// The offset within the results, will be passed directly as-is to the bot. - public static Task Messages_GetInlineBotResults(this Client client, InputUserBase bot, InputPeer peer, string query, string offset, InputGeoPoint geo_point = null) - => client.Invoke(new Messages_GetInlineBotResults - { - flags = (Messages_GetInlineBotResults.Flags)(geo_point != null ? 0x1 : 0), - bot = bot, - peer = peer, - geo_point = geo_point, - query = query, - offset = offset, - }); - - /// Answer an inline query, for bots only See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Set this flag if the results are composed of media files - /// Set this flag if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query - /// Unique identifier for the answered query - /// Vector of results for the inline query - /// 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 on top of the remaining inline result list with the specified text, that switches the user to a private chat with the bot and sends the bot a start message with a certain parameter. - /// If passed, clients will display a button on top of the remaining inline result list with the specified text, that switches the user to the specified inline mode mini app. - public static Task Messages_SetInlineBotResults(this Client client, long query_id, InputBotInlineResultBase[] results, int cache_time, string next_offset = null, InlineBotSwitchPM switch_pm = null, InlineBotWebView switch_webview = null, bool gallery = false, bool private_ = false) - => client.Invoke(new Messages_SetInlineBotResults - { - flags = (Messages_SetInlineBotResults.Flags)((next_offset != null ? 0x4 : 0) | (switch_pm != null ? 0x8 : 0) | (switch_webview != null ? 0x10 : 0) | (gallery ? 0x1 : 0) | (private_ ? 0x2 : 0)), - query_id = query_id, - results = results, - cache_time = cache_time, - next_offset = next_offset, - switch_pm = switch_pm, - switch_webview = switch_webview, - }); - - /// Send a result obtained using Messages_GetInlineBotResults. See Possible codes: 400,403,420,500 (details) - /// 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 - /// Whether to hide the via @botname in the resulting message (only for bot usernames encountered in the ) - /// Destination - /// If set, indicates that the message should be sent in reply to the specified message or story. - /// Random ID to avoid resending the same query You can use - /// Query ID from Messages_GetInlineBotResults - /// Result ID from Messages_GetInlineBotResults - /// Scheduled message date for scheduled messages - /// Send this message as the specified peer - /// Add the message to the specified quick reply shortcut », instead. - /// For paid messages », specifies the amount of Telegram Stars the user has agreed to pay in order to send the message. - public static Task Messages_SendInlineBotResult(this Client client, InputPeer peer, long random_id, long query_id, string id, InputReplyTo reply_to = null, DateTime? schedule_date = null, InputPeer send_as = null, InputQuickReplyShortcutBase quick_reply_shortcut = null, long? allow_paid_stars = null, bool silent = false, bool background = false, bool clear_draft = false, bool hide_via = false) - => client.Invoke(new Messages_SendInlineBotResult - { - flags = (Messages_SendInlineBotResult.Flags)((reply_to != null ? 0x1 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0) | (quick_reply_shortcut != null ? 0x20000 : 0) | (allow_paid_stars != null ? 0x200000 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (hide_via ? 0x800 : 0)), - peer = peer, - reply_to = reply_to, - random_id = random_id, - query_id = query_id, - id = id, - schedule_date = schedule_date ?? default, - send_as = send_as, - quick_reply_shortcut = quick_reply_shortcut, - allow_paid_stars = allow_paid_stars ?? default, - }); - - /// Find out if a media message's caption can be edited See Possible codes: 400,403 (details) - /// Peer where the media was sent - /// ID of message - public static Task Messages_GetMessageEditData(this Client client, InputPeer peer, int id) - => client.Invoke(new Messages_GetMessageEditData - { - peer = peer, - id = id, - }); - - /// Edit message See [bots: ✓] Possible codes: 400,403,406,500 (details) - /// Disable webpage preview - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - /// Where was the message sent - /// ID of the message to edit - /// New message - /// New attached media - /// Reply markup for inline keyboards - /// Message entities for styled text - /// Scheduled message date for scheduled messages - /// If specified, edits a quick reply shortcut message, instead ». - 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, int? schedule_repeat_period = null, int? quick_reply_shortcut_id = null, bool no_webpage = false, bool invert_media = false) - => client.Invoke(new Messages_EditMessage - { - 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) | (schedule_repeat_period != null ? 0x40000 : 0) | (quick_reply_shortcut_id != null ? 0x20000 : 0) | (no_webpage ? 0x2 : 0) | (invert_media ? 0x10000 : 0)), - peer = peer, - id = id, - message = message, - media = media, - reply_markup = reply_markup, - entities = entities, - schedule_date = schedule_date ?? default, - schedule_repeat_period = schedule_repeat_period ?? default, - quick_reply_shortcut_id = quick_reply_shortcut_id ?? default, - }); - - /// Edit an inline bot message See [bots: ✓] Possible codes: 400 (details) - /// Disable webpage preview - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - /// Sent inline message ID - /// Message - /// Media - /// Reply markup for inline keyboards - /// Message entities for styled text - 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, bool invert_media = false) - => client.Invoke(new Messages_EditInlineBotMessage - { - 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) | (invert_media ? 0x10000 : 0)), - id = id, - message = message, - media = media, - reply_markup = reply_markup, - entities = entities, - }); - - /// Press an inline callback button and get a callback answer from the bot See Possible codes: -503,400 (details) - /// Whether this is a "play game" button - /// Where was the inline keyboard sent - /// 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, byte[] data = null, InputCheckPasswordSRP password = null, bool game = false) - => client.Invoke(new Messages_GetBotCallbackAnswer - { - flags = (Messages_GetBotCallbackAnswer.Flags)((data != null ? 0x1 : 0) | (password != null ? 0x4 : 0) | (game ? 0x2 : 0)), - peer = peer, - msg_id = msg_id, - data = data, - password = password, - }); - - /// Set the callback answer to a user button press (bots only) See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Whether to show the message as a popup instead of a toast notification - /// Query ID - /// Popup to show - /// URL to open - /// Cache validity - public static Task Messages_SetBotCallbackAnswer(this Client client, long query_id, int cache_time, string message = null, string url = null, bool alert = false) - => client.Invoke(new Messages_SetBotCallbackAnswer - { - flags = (Messages_SetBotCallbackAnswer.Flags)((message != null ? 0x1 : 0) | (url != null ? 0x4 : 0) | (alert ? 0x2 : 0)), - query_id = query_id, - message = message, - url = url, - cache_time = cache_time, - }); - - /// Get dialog info of specified peers See Possible codes: 400,406 (details) - /// Peers - public static Task Messages_GetPeerDialogs(this Client client, params InputDialogPeerBase[] peers) - => client.Invoke(new Messages_GetPeerDialogs - { - peers = peers, - }); - - /// Save a message draft associated to a chat. See Possible codes: 400 (details) - /// Disable generation of the webpage preview - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - /// If set, indicates that the message should be sent in reply to the specified message or story. - /// Destination of the message that should be sent - /// The draft - /// Message entities for styled text - /// Attached media - /// Specifies a message effect » to use for the message. - /// Used to suggest a post to a channel, see here » for more info on the full flow. - public static Task Messages_SaveDraft(this Client client, InputPeer peer, string message, MessageEntity[] entities = null, InputReplyTo reply_to = null, InputMedia media = null, long? effect = null, SuggestedPost suggested_post = null, bool no_webpage = false, bool invert_media = false) - => client.Invoke(new Messages_SaveDraft - { - flags = (Messages_SaveDraft.Flags)((entities != null ? 0x8 : 0) | (reply_to != null ? 0x10 : 0) | (media != null ? 0x20 : 0) | (effect != null ? 0x80 : 0) | (suggested_post != null ? 0x100 : 0) | (no_webpage ? 0x2 : 0) | (invert_media ? 0x40 : 0)), - reply_to = reply_to, - peer = peer, - message = message, - entities = entities, - media = media, - effect = effect ?? default, - suggested_post = suggested_post, - }); - - /// Return all message drafts.
Returns all the latest updates related to all chats with drafts. See
- public static Task Messages_GetAllDrafts(this Client client) - => client.Invoke(new Messages_GetAllDrafts - { - }); - - /// Get featured stickers See - /// Hash used for caching, for more info click here. - public static Task Messages_GetFeaturedStickers(this Client client, long hash = default) - => client.Invoke(new Messages_GetFeaturedStickers - { - hash = hash, - }); - - /// Mark new featured stickers as read See - /// IDs of stickersets to mark as read - public static Task Messages_ReadFeaturedStickers(this Client client, params long[] id) - => client.Invoke(new Messages_ReadFeaturedStickers - { - id = id, - }); - - /// Get recent stickers See - /// Get stickers recently attached to photo or video files - /// Hash used for caching, for more info click here. - /// a null value means messages.recentStickersNotModified - public static Task Messages_GetRecentStickers(this Client client, long hash = default, bool attached = false) - => client.Invoke(new Messages_GetRecentStickers - { - flags = (Messages_GetRecentStickers.Flags)(attached ? 0x1 : 0), - hash = hash, - }); - - /// Add/remove sticker from recent stickers list See Possible codes: 400 (details) - /// Whether to add/remove stickers recently attached to photo or video files - /// Sticker - /// Whether to save or unsave the sticker - public static Task Messages_SaveRecentSticker(this Client client, InputDocument id, bool unsave, bool attached = false) - => client.Invoke(new Messages_SaveRecentSticker - { - flags = (Messages_SaveRecentSticker.Flags)(attached ? 0x1 : 0), - id = id, - unsave = unsave, - }); - - /// Clear recent stickers See - /// Set this flag to clear the list of stickers recently attached to photo or video files - public static Task Messages_ClearRecentStickers(this Client client, bool attached = false) - => client.Invoke(new Messages_ClearRecentStickers - { - flags = (Messages_ClearRecentStickers.Flags)(attached ? 0x1 : 0), - }); - - /// Get all archived stickers See - /// Get mask stickers - /// Get custom emoji stickers - /// Offsets for pagination, for more info click here - /// Maximum number of results to return, see pagination - public static Task Messages_GetArchivedStickers(this Client client, long offset_id = default, int limit = int.MaxValue, bool masks = false, bool emojis = false) - => client.Invoke(new Messages_GetArchivedStickers - { - flags = (Messages_GetArchivedStickers.Flags)((masks ? 0x1 : 0) | (emojis ? 0x2 : 0)), - offset_id = offset_id, - limit = limit, - }); - - /// Get installed mask stickers See - /// Hash used for caching, for more info click here. - /// a null value means messages.allStickersNotModified - public static Task Messages_GetMaskStickers(this Client client, long hash = default) - => client.Invoke(new Messages_GetMaskStickers - { - hash = hash, - }); - - /// Get stickers attached to a photo or video See Possible codes: 400 (details) - /// Stickered media - public static Task Messages_GetAttachedStickers(this Client client, InputStickeredMedia media) - => client.Invoke(new Messages_GetAttachedStickers - { - media = media, - }); - - /// Use this method to set the score of the specified user in a game sent as a normal message (bots only). See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Set this flag if the game message should be automatically edited to include the current scoreboard - /// Set this flag if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters - /// Unique identifier of target chat - /// Identifier of the sent message - /// User identifier - /// New score - public static Task Messages_SetGameScore(this Client client, InputPeer peer, int id, InputUserBase user_id, int score, bool edit_message = false, bool force = false) - => client.Invoke(new Messages_SetGameScore - { - flags = (Messages_SetGameScore.Flags)((edit_message ? 0x1 : 0) | (force ? 0x2 : 0)), - peer = peer, - id = id, - user_id = user_id, - score = score, - }); - - /// Use this method to set the score of the specified user in a game sent as an inline message (bots only). See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Set this flag if the game message should be automatically edited to include the current scoreboard - /// Set this flag if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters - /// ID of the inline message - /// User identifier - /// New score - public static Task Messages_SetInlineGameScore(this Client client, InputBotInlineMessageIDBase id, InputUserBase user_id, int score, bool edit_message = false, bool force = false) - => client.Invoke(new Messages_SetInlineGameScore - { - flags = (Messages_SetInlineGameScore.Flags)((edit_message ? 0x1 : 0) | (force ? 0x2 : 0)), - id = id, - user_id = user_id, - score = score, - }); - - /// Get highscores of a game See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Where was the game sent - /// ID of message with game media attachment - /// Get high scores made by a certain user - public static Task Messages_GetGameHighScores(this Client client, InputPeer peer, int id, InputUserBase user_id) - => client.Invoke(new Messages_GetGameHighScores - { - peer = peer, - id = id, - user_id = user_id, - }); - - /// Get highscores of a game sent using an inline bot See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// ID of inline message - /// Get high scores of a certain user - public static Task Messages_GetInlineGameHighScores(this Client client, InputBotInlineMessageIDBase id, InputUserBase user_id) - => client.Invoke(new Messages_GetInlineGameHighScores - { - id = id, - user_id = user_id, - }); - - /// Get chats in common with a user See Possible codes: 400 (details) - /// User ID - /// Maximum ID of chat to return (see pagination) - /// Maximum number of results to return, see pagination - public static Task Messages_GetCommonChats(this Client client, InputUserBase user_id, long max_id = default, int limit = int.MaxValue) - => client.Invoke(new Messages_GetCommonChats - { - user_id = user_id, - max_id = max_id, - limit = limit, - }); - - /// Get instant view page See Possible codes: 400 (details) - /// URL of IV page to fetch - /// Hash used for caching, for more info click here.
Note: the usual hash generation algorithm cannot be used in this case, please re-use the .hash field returned by a previous call to the method, or pass 0 if this is the first call or if the previous call did not return a . - public static Task Messages_GetWebPage(this Client client, string url, int hash = default) - => client.Invoke(new Messages_GetWebPage - { - url = url, - hash = hash, - }); - - /// Pin/unpin a dialog See Possible codes: 400 (details) - /// Whether to pin or unpin the dialog - /// The dialog to pin - public static Task Messages_ToggleDialogPin(this Client client, InputDialogPeerBase peer, bool pinned = false) - => client.Invoke(new Messages_ToggleDialogPin - { - flags = (Messages_ToggleDialogPin.Flags)(pinned ? 0x1 : 0), - peer = peer, - }); - - /// Reorder pinned dialogs See Possible codes: 400 (details) - /// If set, dialogs pinned server-side but not present in the order field will be unpinned. - /// Peer folder ID, for more info click here - /// New dialog order - public static Task Messages_ReorderPinnedDialogs(this Client client, int folder_id, InputDialogPeerBase[] order, bool force = false) - => client.Invoke(new Messages_ReorderPinnedDialogs - { - flags = (Messages_ReorderPinnedDialogs.Flags)(force ? 0x1 : 0), - folder_id = folder_id, - order = order, - }); - - /// Get pinned dialogs See Possible codes: 400 (details) - /// Peer folder ID, for more info click here - public static Task Messages_GetPinnedDialogs(this Client client, int folder_id) - => client.Invoke(new Messages_GetPinnedDialogs - { - folder_id = folder_id, - }); - - /// If you sent an invoice requesting a shipping address and the parameter is_flexible was specified, the bot will receive an update. Use this method to reply to shipping queries. See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Unique identifier for the query to be answered - /// Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable"). Telegram will display this message to the user. - /// A vector of available shipping options. - public static Task Messages_SetBotShippingResults(this Client client, long query_id, string error = null, ShippingOption[] shipping_options = null) - => client.Invoke(new Messages_SetBotShippingResults - { - flags = (Messages_SetBotShippingResults.Flags)((error != null ? 0x1 : 0) | (shipping_options != null ? 0x2 : 0)), - query_id = query_id, - error = error, - shipping_options = shipping_options, - }); - - /// Once the user has confirmed their payment and shipping details, the bot receives an update.
Use this method to respond to such pre-checkout queries.
Note: Telegram must receive an answer within 10 seconds after the pre-checkout query was sent. See [bots: ✓ users: ✗] Possible codes: 400 (details)
- /// 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, string error = null, bool success = false) - => client.Invoke(new Messages_SetBotPrecheckoutResults - { - flags = (Messages_SetBotPrecheckoutResults.Flags)((error != null ? 0x1 : 0) | (success ? 0x2 : 0)), - query_id = query_id, - error = error, - }); - - /// Upload a file and associate it to a chat (without actually sending it to the chat) See [bots: ✓] Possible codes: 400,403 (details) - /// Whether the media will be used only in the specified business connection », and not directly by the bot. - /// The chat, can be for bots and for users. - /// File uploaded in chunks as described in files » - /// a null value means messageMediaEmpty - public static Task Messages_UploadMedia(this Client client, InputPeer peer, InputMedia media, string business_connection_id = null) - => client.Invoke(new Messages_UploadMedia - { - flags = (Messages_UploadMedia.Flags)(business_connection_id != null ? 0x1 : 0), - business_connection_id = business_connection_id, - peer = peer, - media = media, - }); - - /// Notify the other user in a private chat that a screenshot of the chat was taken See Possible codes: 400 (details) - /// Other user - /// Indicates the message that was screenshotted (the specified message ID can also be 0 to avoid indicating any specific message). - /// Random ID to avoid message resending You can use - public static Task Messages_SendScreenshotNotification(this Client client, InputPeer peer, InputReplyTo reply_to, long random_id) - => client.Invoke(new Messages_SendScreenshotNotification - { - peer = peer, - reply_to = reply_to, - random_id = random_id, - }); - - /// Get faved stickers See - /// Hash used for caching, for more info click here. - /// a null value means messages.favedStickersNotModified - public static Task Messages_GetFavedStickers(this Client client, long hash = default) - => client.Invoke(new Messages_GetFavedStickers - { - hash = hash, - }); - - /// Mark or unmark a sticker as favorite See Possible codes: 400 (details) - /// Sticker in question - /// Whether to add or remove a sticker from favorites - public static Task Messages_FaveSticker(this Client client, InputDocument id, bool unfave) - => client.Invoke(new Messages_FaveSticker - { - id = id, - unfave = unfave, - }); - - /// Get unread messages where we were mentioned See Possible codes: 400 (details) - /// Peer where to look for mentions - /// If set, considers only messages within the specified forum topic - /// Offsets for pagination, for more info click here - /// Offsets for pagination, for more info click here - /// 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, 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 ?? default, - offset_id = offset_id, - add_offset = add_offset, - limit = limit, - max_id = max_id, - min_id = min_id, - }); - - /// Mark mentions as read See Possible codes: 400 (details) - /// Dialog - /// Mark as read only mentions within the specified forum topic - public static Task Messages_ReadMentions(this Client client, InputPeer peer, int? top_msg_id = null) - => client.InvokeAffected(new Messages_ReadMentions - { - flags = (Messages_ReadMentions.Flags)(top_msg_id != null ? 0x1 : 0), - peer = peer, - top_msg_id = top_msg_id ?? default, - }, peer is InputPeerChannel ipc ? ipc.channel_id : 0); - - /// Get live location history of a certain user See - /// User - /// Maximum number of results to return, see pagination - /// Hash used for caching, for more info click here - public static Task Messages_GetRecentLocations(this Client client, InputPeer peer, int limit = int.MaxValue, long hash = default) - => client.Invoke(new Messages_GetRecentLocations - { - peer = peer, - limit = limit, - hash = hash, - }); - - /// Send an album or grouped media See [bots: ✓] Possible codes: 400,403,406,420,500 (details) - /// Whether to send the album silently (no notification triggered) - /// Send in background? - /// Whether to clear drafts - /// Only for bots, disallows forwarding and saving of the messages, even if the destination chat doesn't have content protection enabled - /// Whether to move used stickersets to top, see here for more info on this flag » - /// If set, any eventual webpage preview will be shown on top of the message instead of at the bottom. - /// Bots only: if set, allows sending up to 1000 messages per second, ignoring broadcasting limits for a fee of 0.1 Telegram Stars per message. The relevant Stars will be withdrawn from the bot's balance. - /// The destination chat - /// If set, indicates that the message should be sent in reply to the specified message or story. - /// 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 - /// Add the message to the specified quick reply shortcut », instead. - /// Specifies a message effect » to use for the message. - /// For paid messages », specifies the amount of Telegram Stars the user has agreed to pay in order to send the message. - public static Task Messages_SendMultiMedia(this Client client, InputPeer peer, InputSingleMedia[] multi_media, InputReplyTo reply_to = null, DateTime? schedule_date = null, InputPeer send_as = null, InputQuickReplyShortcutBase quick_reply_shortcut = null, long? effect = null, long? allow_paid_stars = null, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, bool invert_media = false, bool allow_paid_floodskip = false) - => client.Invoke(new Messages_SendMultiMedia - { - flags = (Messages_SendMultiMedia.Flags)((reply_to != null ? 0x1 : 0) | (schedule_date != null ? 0x400 : 0) | (send_as != null ? 0x2000 : 0) | (quick_reply_shortcut != null ? 0x20000 : 0) | (effect != null ? 0x40000 : 0) | (allow_paid_stars != null ? 0x200000 : 0) | (silent ? 0x20 : 0) | (background ? 0x40 : 0) | (clear_draft ? 0x80 : 0) | (noforwards ? 0x4000 : 0) | (update_stickersets_order ? 0x8000 : 0) | (invert_media ? 0x10000 : 0) | (allow_paid_floodskip ? 0x80000 : 0)), - peer = peer, - reply_to = reply_to, - multi_media = multi_media, - schedule_date = schedule_date ?? default, - send_as = send_as, - quick_reply_shortcut = quick_reply_shortcut, - effect = effect ?? default, - allow_paid_stars = allow_paid_stars ?? default, - }); - - /// Upload encrypted file and associate it to a secret chat (without actually sending it to the chat). See Possible codes: 400 (details) - /// The secret chat to associate the file to - /// The file - /// a null value means encryptedFileEmpty - public static Task Messages_UploadEncryptedFile(this Client client, InputEncryptedChat peer, InputEncryptedFileBase file) - => client.Invoke(new Messages_UploadEncryptedFile - { - peer = peer, - file = file, - }); - - /// Search for stickersets See - /// Exclude featured stickersets from results - /// Query string - /// Hash used for caching, for more info click here. - /// a null value means messages.foundStickerSetsNotModified - public static Task Messages_SearchStickerSets(this Client client, string q, long hash = default, bool exclude_featured = false) - => client.Invoke(new Messages_SearchStickerSets - { - flags = (Messages_SearchStickerSets.Flags)(exclude_featured ? 0x1 : 0), - q = q, - hash = hash, - }); - - /// Get message ranges for saving the user's chat history See - public static Task Messages_GetSplitRanges(this Client client) - => client.Invoke(new Messages_GetSplitRanges - { - }); - - /// Manually mark dialog as unread See Possible codes: 400 (details) - /// Mark as unread/read - /// If set, must be equal to the ID of a monoforum, and will affect the monoforum topic passed in peer. - /// Dialog - public static Task Messages_MarkDialogUnread(this Client client, InputDialogPeerBase peer, InputPeer parent_peer = null, bool unread = false) - => client.Invoke(new Messages_MarkDialogUnread - { - flags = (Messages_MarkDialogUnread.Flags)((parent_peer != null ? 0x2 : 0) | (unread ? 0x1 : 0)), - parent_peer = parent_peer, - peer = peer, - }); - - /// Get dialogs manually marked as unread See - /// Can be equal to the ID of a monoforum, to fetch monoforum topics manually marked as unread. - public static Task Messages_GetDialogUnreadMarks(this Client client, InputPeer parent_peer = null) - => client.Invoke(new Messages_GetDialogUnreadMarks - { - flags = (Messages_GetDialogUnreadMarks.Flags)(parent_peer != null ? 0x1 : 0), - parent_peer = parent_peer, - }); - - /// Clear all drafts. See - public static Task Messages_ClearAllDrafts(this Client client) - => client.Invoke(new Messages_ClearAllDrafts - { - }); - - /// Pin a message See [bots: ✓] Possible codes: 400,403 (details) - /// Pin the message silently, without triggering a notification - /// Whether the message should unpinned or pinned - /// Whether the message should only be pinned on the local side of a one-to-one chat - /// The peer where to pin the message - /// The message to pin or unpin - public static Task Messages_UpdatePinnedMessage(this Client client, InputPeer peer, int id, bool silent = false, bool unpin = false, bool pm_oneside = false) - => client.Invoke(new Messages_UpdatePinnedMessage - { - flags = (Messages_UpdatePinnedMessage.Flags)((silent ? 0x1 : 0) | (unpin ? 0x2 : 0) | (pm_oneside ? 0x4 : 0)), - peer = peer, - id = id, - }); - - /// Vote in a See Possible codes: 400 (details) - /// The chat where the poll was sent - /// The message ID of the poll - /// The options that were chosen - public static Task Messages_SendVote(this Client client, InputPeer peer, int msg_id, params byte[][] options) - => client.Invoke(new Messages_SendVote - { - peer = peer, - msg_id = msg_id, - options = options, - }); - - /// Get poll results See Possible codes: 400 (details) - /// Peer where the poll was found - /// Message ID of poll message - public static Task Messages_GetPollResults(this Client client, InputPeer peer, int msg_id) - => client.Invoke(new Messages_GetPollResults - { - peer = peer, - msg_id = msg_id, - }); - - /// Get count of online users in a chat See Possible codes: 400 (details) - /// The chat - public static Task Messages_GetOnlines(this Client client, InputPeer peer) - => client.Invoke(new Messages_GetOnlines - { - peer = peer, - }); - - /// Edit the description of a group/supergroup/channel. See [bots: ✓] Possible codes: 400,403 (details) - /// The group/supergroup/channel. - /// The new description - public static Task Messages_EditChatAbout(this Client client, InputPeer peer, string about) - => client.Invoke(new Messages_EditChatAbout - { - peer = peer, - about = about, - }); - - /// Edit the default banned rights of a channel/supergroup/group. See [bots: ✓] Possible codes: 400,403 (details) - /// The peer - /// The new global rights - public static Task Messages_EditChatDefaultBannedRights(this Client client, InputPeer peer, ChatBannedRights banned_rights) - => client.Invoke(new Messages_EditChatDefaultBannedRights - { - peer = peer, - banned_rights = banned_rights, - }); - - /// Get localized emoji keywords ». See - /// Language code - public static Task Messages_GetEmojiKeywords(this Client client, string lang_code) - => client.Invoke(new Messages_GetEmojiKeywords - { - lang_code = lang_code, - }); - - /// Get changed emoji keywords ». See - /// Language code - /// Previous stored emoji keyword list version - public static Task Messages_GetEmojiKeywordsDifference(this Client client, string lang_code, int from_version) - => client.Invoke(new Messages_GetEmojiKeywordsDifference - { - lang_code = lang_code, - from_version = from_version, - }); - - /// Obtain a list of related languages that must be used when fetching emoji keyword lists ». See - /// The user's language codes - public static Task Messages_GetEmojiKeywordsLanguages(this Client client, params string[] lang_codes) - => client.Invoke(new Messages_GetEmojiKeywordsLanguages - { - lang_codes = lang_codes, - }); - - /// Returns an HTTP URL which can be used to automatically log in into translation platform and suggest new emoji keywords ». The URL will be valid for 30 seconds after generation. See - /// Language code for which the emoji keywords will be suggested - public static Task Messages_GetEmojiURL(this Client client, string lang_code) - => client.Invoke(new Messages_GetEmojiURL - { - 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) - /// Peer where to search - /// Search within the saved message dialog » with this ID. - /// If set, consider only messages within the specified forum topic - /// Search filters - public static Task Messages_GetSearchCounters(this Client client, InputPeer peer, MessagesFilter[] filters, int? top_msg_id = null, InputPeer saved_peer_id = null) - => client.Invoke(new Messages_GetSearchCounters - { - flags = (Messages_GetSearchCounters.Flags)((top_msg_id != null ? 0x1 : 0) | (saved_peer_id != null ? 0x4 : 0)), - peer = peer, - saved_peer_id = saved_peer_id, - top_msg_id = top_msg_id ?? default, - filters = filters, - }); - - /// Get more info about a Seamless Telegram Login authorization request, for more info click here » See - /// Peer where the message is located - /// 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, string in_app_origin = null) - => client.Invoke(new Messages_RequestUrlAuth - { - flags = (Messages_RequestUrlAuth.Flags)((peer != null ? 0x2 : 0) | (msg_id != null ? 0x2 : 0) | (button_id != null ? 0x2 : 0) | (url != null ? 0x4 : 0) | (in_app_origin != null ? 0x8 : 0)), - peer = peer, - msg_id = msg_id ?? default, - button_id = button_id ?? default, - url = url, - in_app_origin = in_app_origin, - }); - - /// Use this to accept a Seamless Telegram Login authorization request, for more info click here » See - /// Set this flag to allow the bot to send messages to you (if requested) - /// The location of the message - /// 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, InputPeer peer = null, int? msg_id = null, int? button_id = null, string url = null, string match_code = null, bool write_allowed = false, bool share_phone_number = false) - => client.Invoke(new Messages_AcceptUrlAuth - { - flags = (Messages_AcceptUrlAuth.Flags)((peer != null ? 0x2 : 0) | (msg_id != null ? 0x2 : 0) | (button_id != null ? 0x2 : 0) | (url != null ? 0x4 : 0) | (match_code != null ? 0x10 : 0) | (write_allowed ? 0x1 : 0) | (share_phone_number ? 0x8 : 0)), - peer = peer, - msg_id = msg_id ?? default, - button_id = button_id ?? default, - url = url, - match_code = match_code, - }); - - /// 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 action bar ». See Possible codes: 400 (details) - /// Peer - public static Task Messages_HidePeerSettingsBar(this Client client, InputPeer peer) - => client.Invoke(new Messages_HidePeerSettingsBar - { - peer = peer, - }); - - /// Get scheduled messages See Possible codes: 400 (details) - /// Peer - /// Hash used for caching, for more info click here.
To generate the hash, populate the ids array with the id, edit_date (0 if unedited) and date (in this order) of the previously returned messages (in order, i.e. ids = [id1, (edit_date1 ?? 0), date1, id2, (edit_date2 ?? 0), date2, ...]). - public static Task Messages_GetScheduledHistory(this Client client, InputPeer peer, long hash = default) - => client.Invoke(new Messages_GetScheduledHistory - { - peer = peer, - hash = hash, - }); - - /// Get scheduled messages See Possible codes: 400 (details) - /// Peer - /// IDs of scheduled messages - public static Task Messages_GetScheduledMessages(this Client client, InputPeer peer, params int[] id) - => client.Invoke(new Messages_GetScheduledMessages - { - peer = peer, - id = id, - }); - - /// Send scheduled messages right away See Possible codes: 400,500 (details) - /// Peer - /// Scheduled message IDs - public static Task Messages_SendScheduledMessages(this Client client, InputPeer peer, params int[] id) - => client.Invoke(new Messages_SendScheduledMessages - { - peer = peer, - id = id, - }); - - /// Delete scheduled messages See Possible codes: 400,403 (details) - /// Peer - /// Scheduled message IDs - public static Task Messages_DeleteScheduledMessages(this Client client, InputPeer peer, params int[] id) - => client.Invoke(new Messages_DeleteScheduledMessages - { - peer = peer, - id = id, - }); - - /// Get poll results for non-anonymous polls See Possible codes: 400,403 (details) - /// Chat where the poll was sent - /// Message ID - /// Get only results for the specified poll option - /// Offset for results, taken from the next_offset field of , initially an empty string.
Note: if no more results are available, the method call will return an empty next_offset; thus, avoid providing the next_offset returned in if it is empty, to avoid an infinite loop. - /// Number of results to return - public static Task Messages_GetPollVotes(this Client client, InputPeer peer, int id, int limit = int.MaxValue, byte[] option = null, string offset = null) - => client.Invoke(new Messages_GetPollVotes - { - flags = (Messages_GetPollVotes.Flags)((option != null ? 0x1 : 0) | (offset != null ? 0x2 : 0)), - peer = peer, - id = id, - option = option, - offset = offset, - limit = limit, - }); - - /// Apply changes to multiple stickersets See - /// Uninstall the specified stickersets - /// Archive the specified stickersets - /// Unarchive the specified stickersets - /// Stickersets to act upon - public static Task Messages_ToggleStickerSets(this Client client, InputStickerSet[] stickersets, bool uninstall = false, bool archive = false, bool unarchive = false) - => client.Invoke(new Messages_ToggleStickerSets - { - flags = (Messages_ToggleStickerSets.Flags)((uninstall ? 0x1 : 0) | (archive ? 0x2 : 0) | (unarchive ? 0x4 : 0)), - stickersets = stickersets, - }); - - /// Get folders See - public static Task Messages_GetDialogFilters(this Client client) - => client.Invoke(new Messages_GetDialogFilters - { - }); - - /// Get suggested folders See - public static Task Messages_GetSuggestedDialogFilters(this Client client) - => client.Invoke(new Messages_GetSuggestedDialogFilters - { - }); - - /// Update folder See Possible codes: 400 (details) - /// Folder ID - /// Folder info - public static Task Messages_UpdateDialogFilter(this Client client, int id, DialogFilterBase filter = null) - => client.Invoke(new Messages_UpdateDialogFilter - { - flags = (Messages_UpdateDialogFilter.Flags)(filter != null ? 0x1 : 0), - id = id, - filter = filter, - }); - - /// Reorder folders See - /// New folder order - public static Task Messages_UpdateDialogFiltersOrder(this Client client, params int[] order) - => client.Invoke(new Messages_UpdateDialogFiltersOrder - { - order = order, - }); - - /// Method for fetching previously featured stickers See - /// Offset - /// Maximum number of results to return, see pagination - /// Hash used for caching, for more info click here. - public static Task Messages_GetOldFeaturedStickers(this Client client, int offset = default, int limit = int.MaxValue, long hash = default) - => client.Invoke(new Messages_GetOldFeaturedStickers - { - offset = offset, - limit = limit, - hash = hash, - }); - - /// Get messages in a reply thread See Possible codes: 400 (details) - /// Peer - /// Message ID - /// Offsets for pagination, for more info click here - /// Offsets for pagination, for more info click here - /// Offsets for pagination, for more info click here - /// Maximum number of results to return, see pagination - /// If a positive value was transferred, the method will return only messages with ID smaller than max_id - /// If a positive value was transferred, the method will return only messages with ID bigger than min_id - /// Hash used for caching, for more info click here - public static Task Messages_GetReplies(this Client client, InputPeer peer, int msg_id, int offset_id = default, DateTime offset_date = default, int add_offset = default, int limit = int.MaxValue, int max_id = default, int min_id = default, long hash = default) - => client.Invoke(new Messages_GetReplies - { - peer = peer, - msg_id = msg_id, - offset_id = offset_id, - offset_date = offset_date, - add_offset = add_offset, - limit = limit, - max_id = max_id, - min_id = min_id, - hash = hash, - }); - - /// Get discussion message from the associated discussion group of a channel to show it on top of the comment section, without actually joining the group See Possible codes: 400 (details) - /// Channel ID - /// Message ID - public static Task Messages_GetDiscussionMessage(this Client client, InputPeer peer, int msg_id) - => client.Invoke(new Messages_GetDiscussionMessage - { - peer = peer, - msg_id = msg_id, - }); - - /// Mark a thread as read See Possible codes: 400 (details) - /// Group ID - /// ID of message that started the thread - /// ID up to which thread messages were read - public static Task Messages_ReadDiscussion(this Client client, InputPeer peer, int msg_id, int read_max_id) - => client.Invoke(new Messages_ReadDiscussion - { - peer = peer, - msg_id = msg_id, - read_max_id = read_max_id, - }); - - /// Unpin all pinned messages See [bots: ✓] Possible codes: 400 (details) - /// Chat where to unpin - /// Forum topic where to unpin - /// If set, must be equal to the ID of a monoforum topic, and will unpin all messages pinned in the passed monoforum topic. - public static Task Messages_UnpinAllMessages(this Client client, InputPeer peer, int? top_msg_id = null, InputPeer saved_peer_id = null) - => client.InvokeAffected(new Messages_UnpinAllMessages - { - flags = (Messages_UnpinAllMessages.Flags)((top_msg_id != null ? 0x1 : 0) | (saved_peer_id != null ? 0x2 : 0)), - peer = peer, - top_msg_id = top_msg_id ?? default, - saved_peer_id = saved_peer_id, - }, peer is InputPeerChannel ipc ? ipc.channel_id : 0); - - /// This method is only for basic Chat. See Terminology in the README 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 - { - chat_id = chat_id, - }); - - /// Delete the entire phone call history. See - /// Whether to remove phone call history for participants as well - public static Task Messages_DeletePhoneCallHistory(this Client client, bool revoke = false) - => client.InvokeAffected(new Messages_DeletePhoneCallHistory - { - flags = (Messages_DeletePhoneCallHistory.Flags)(revoke ? 0x1 : 0), - }, 0); - - /// Obtains information about a chat export file, generated by a foreign chat app, click here for more info about imported chats ». See Possible codes: 400 (details) - /// Beginning of the message file; up to 100 lines. - public static Task Messages_CheckHistoryImport(this Client client, string import_head) - => client.Invoke(new Messages_CheckHistoryImport - { - import_head = import_head, - }); - - /// 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. - public static Task Messages_InitHistoryImport(this Client client, InputPeer peer, InputFileBase file, int media_count) - => client.Invoke(new Messages_InitHistoryImport - { - peer = peer, - file = file, - media_count = media_count, - }); - - /// Upload a media file associated with an imported chat, click here for more info ». See Possible codes: 400 (details) - /// The Telegram chat where the media will be imported - /// Identifier of a history import session, returned by Messages_InitHistoryImport - /// File name - /// Media metadata - /// a null value means messageMediaEmpty - public static Task Messages_UploadImportedMedia(this Client client, InputPeer peer, long import_id, string file_name, InputMedia media) - => client.Invoke(new Messages_UploadImportedMedia - { - peer = peer, - import_id = import_id, - file_name = file_name, - 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)
- /// The Telegram chat where the messages should be imported, click here for more info » - /// 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 - { - peer = peer, - import_id = import_id, - }); - - /// Get info about the chat invites of a specific chat See Possible codes: 400,403 (details) - /// Whether to fetch revoked chat invites - /// Chat - /// Whether to only fetch chat invites from this admin - /// 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, DateTime? offset_date = null, string offset_link = null, bool revoked = false) - => client.Invoke(new Messages_GetExportedChatInvites - { - 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 ?? default, - offset_link = offset_link, - limit = limit, - }); - - /// Get info about a chat invite See Possible codes: 400,403 (details) - /// Chat - /// Invite link - public static Task Messages_GetExportedChatInvite(this Client client, InputPeer peer, string link) - => client.Invoke(new Messages_GetExportedChatInvite - { - peer = peer, - link = link, - }); - - /// Edit an exported chat invite See [bots: ✓] Possible codes: 400,403 (details) - /// Whether to revoke the chat invite - /// Chat - /// Invite link - /// New expiration date - /// 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, 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)((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 ?? default, - usage_limit = usage_limit ?? default, - request_needed = request_needed ?? default, - title = title, - }); - - /// Delete all revoked chat invites See Possible codes: 400 (details) - /// Chat - /// ID of the admin that originally generated the revoked chat invites - public static Task Messages_DeleteRevokedExportedChatInvites(this Client client, InputPeer peer, InputUserBase admin_id) - => client.Invoke(new Messages_DeleteRevokedExportedChatInvites - { - peer = peer, - admin_id = admin_id, - }); - - /// Delete a chat invite See Possible codes: 400 (details) - /// Peer - /// Invite link - public static Task Messages_DeleteExportedChatInvite(this Client client, InputPeer peer, string link) - => client.Invoke(new Messages_DeleteExportedChatInvite - { - peer = peer, - link = link, - }); - - /// Get info about chat invites generated by admins. See Possible codes: 400,403 (details) - /// Chat - public static Task Messages_GetAdminsWithInvites(this Client client, InputPeer peer) - => client.Invoke(new Messages_GetAdminsWithInvites - { - peer = peer, - }); - - /// Get info about the users that joined the chat using a specific chat invite See Possible codes: 400,403 (details) - /// If set, only returns info about users with pending join requests » - /// Set this flag if the link is a Telegram Star subscription link » and only members with already expired subscription must be returned. - /// Chat - /// Invite link - /// Search for a user in the pending join requests » list: only available when the requested flag is set, cannot be used together with a specific link. - /// Offsets for pagination, for more info click here - /// User ID for pagination: if set, offset_date must also be set. - /// 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, string link = null, string q = null, bool requested = false, bool subscription_expired = false) - => client.Invoke(new Messages_GetChatInviteImporters - { - flags = (Messages_GetChatInviteImporters.Flags)((link != null ? 0x2 : 0) | (q != null ? 0x4 : 0) | (requested ? 0x1 : 0) | (subscription_expired ? 0x8 : 0)), - peer = peer, - link = link, - q = q, - offset_date = offset_date, - offset_user = offset_user, - limit = limit, - }); - - /// Set maximum Time-To-Live of all messages in the specified chat See Possible codes: 400 (details) - /// The dialog - /// Automatically delete all messages sent in the chat after this many seconds - public static Task Messages_SetHistoryTTL(this Client client, InputPeer peer, int period) - => client.Invoke(new Messages_SetHistoryTTL - { - peer = peer, - period = period, - }); - - /// Check whether chat history exported from another chat app can be imported into a specific Telegram chat, click here for more info ». See Possible codes: 400 (details) - /// The chat where we want to import history ». - public static Task Messages_CheckHistoryImportPeer(this Client client, InputPeer peer) - => client.Invoke(new Messages_CheckHistoryImportPeer - { - peer = peer, - }); - - /// Change the chat theme of a certain chat, see here » for more info. See Possible codes: 400 (details) - /// Private chat where to change theme - /// The theme to set. - public static Task Messages_SetChatTheme(this Client client, InputPeer peer, InputChatThemeBase theme) - => client.Invoke(new Messages_SetChatTheme - { - peer = peer, - theme = theme, - }); - - /// Get which users read a specific message: only available for groups and supergroups with less than chat_read_mark_size_threshold members, read receipts will be stored for chat_read_mark_expire_period seconds after the message was sent, see client configuration for more info ». See Possible codes: 400 (details) - /// Dialog - /// Message ID - public static Task Messages_GetMessageReadParticipants(this Client client, InputPeer peer, int msg_id) - => client.Invoke(new Messages_GetMessageReadParticipants - { - peer = peer, - msg_id = msg_id, - }); - - /// Returns information about the next messages of the specified type in the chat split by days. See Possible codes: 400 (details) - /// Peer where to search - /// Search within the saved message dialog » with this ID. - /// Message filter, , filters are not supported by this method. - /// Offsets for pagination, for more info click here - /// Offsets for pagination, for more info click here - public static Task Messages_GetSearchResultsCalendar(this Client client, InputPeer peer, MessagesFilter filter = null, int offset_id = default, DateTime offset_date = default, InputPeer saved_peer_id = null) - => client.Invoke(new Messages_GetSearchResultsCalendar - { - flags = (Messages_GetSearchResultsCalendar.Flags)(saved_peer_id != null ? 0x4 : 0), - peer = peer, - saved_peer_id = saved_peer_id, - filter = filter, - offset_id = offset_id, - offset_date = offset_date, - }); - - /// Returns sparse positions of messages of the specified type in the chat to be used for shared media scroll implementation. See Possible codes: 400 (details) - /// Peer where to search - /// Search within the saved message dialog » with this ID. - /// Message filter, , filters are not supported by this method. - /// Offsets for pagination, for more info click here - /// Maximum number of results to return, see pagination - public static Task Messages_GetSearchResultsPositions(this Client client, InputPeer peer, MessagesFilter filter = null, int offset_id = default, int limit = int.MaxValue, InputPeer saved_peer_id = null) - => client.Invoke(new Messages_GetSearchResultsPositions - { - flags = (Messages_GetSearchResultsPositions.Flags)(saved_peer_id != null ? 0x4 : 0), - peer = peer, - saved_peer_id = saved_peer_id, - filter = filter, - offset_id = offset_id, - limit = limit, - }); - - /// Dismiss or approve a chat join request related to a specific chat or channel. See [bots: ✓] Possible codes: 400,403 (details) - /// Whether to dismiss or approve the chat join request » - /// The chat or channel - /// The user whose join request » should be dismissed or approved - public static Task Messages_HideChatJoinRequest(this Client client, InputPeer peer, InputUserBase user_id, bool approved = false) - => client.Invoke(new Messages_HideChatJoinRequest - { - flags = (Messages_HideChatJoinRequest.Flags)(approved ? 0x1 : 0), - peer = peer, - user_id = user_id, - }); - - /// Dismiss or approve all join requests related to a specific chat or channel. See Possible codes: 400,403 (details) - /// 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, string link = null, bool approved = false) - => client.Invoke(new Messages_HideAllChatJoinRequests - { - flags = (Messages_HideAllChatJoinRequests.Flags)((link != null ? 0x2 : 0) | (approved ? 0x1 : 0)), - peer = peer, - link = link, - }); - - /// Enable or disable content protection on a channel or chat See Possible codes: 400 (details) - /// The chat or channel - /// Enable or disable content protection - public static Task Messages_ToggleNoForwards(this Client client, InputPeer peer, bool enabled, int? request_msg_id = null) - => client.Invoke(new Messages_ToggleNoForwards - { - flags = (Messages_ToggleNoForwards.Flags)(request_msg_id != null ? 0x1 : 0), - peer = peer, - enabled = enabled, - request_msg_id = request_msg_id ?? default, - }); - - /// Change the default peer that should be used when sending messages, reactions, poll votes to a specific group See Possible codes: 400 (details) - /// Group - /// The default peer that should be used when sending messages to the group - public static Task Messages_SaveDefaultSendAs(this Client client, InputPeer peer, InputPeer send_as) - => client.Invoke(new Messages_SaveDefaultSendAs - { - peer = peer, - send_as = send_as, - }); - - /// React to message. See [bots: ✓] Possible codes: 400,403 (details) - /// Whether a bigger and longer reaction should be shown - /// Whether to add this reaction to the recent reactions list ». - /// Peer - /// Message ID to react to - /// A list of reactions (doesn't accept s, use Messages_SendPaidReaction to send paid reactions, instead). - 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)((reaction != null ? 0x1 : 0) | (big ? 0x2 : 0) | (add_to_recent ? 0x4 : 0)), - peer = peer, - msg_id = msg_id, - reaction = reaction, - }); - - /// Get message reactions » See Possible codes: 400 (details) - /// Peer - /// Message IDs - public static Task Messages_GetMessagesReactions(this Client client, InputPeer peer, params int[] id) - => client.Invoke(new Messages_GetMessagesReactions - { - peer = peer, - id = id, - }); - - /// Get message reaction list, along with the sender of each reaction. See Possible codes: 400,403 (details) - /// Peer - /// Message ID - /// Get only reactions of this type - /// Offset for pagination (taken from the next_offset field of the returned ); empty in the first request. - /// Maximum number of results to return, see pagination - public static Task Messages_GetMessageReactionsList(this Client client, InputPeer peer, int id, int limit = int.MaxValue, Reaction reaction = null, string offset = null) - => client.Invoke(new Messages_GetMessageReactionsList - { - flags = (Messages_GetMessageReactionsList.Flags)((reaction != null ? 0x1 : 0) | (offset != null ? 0x2 : 0)), - peer = peer, - id = id, - reaction = reaction, - offset = offset, - limit = limit, - }); - - /// Change the set of message reactions » that can be used in a certain group, supergroup or channel See Possible codes: 400 (details) - /// Group where to apply changes - /// Allowed reaction emojis - /// This flag may be used to impose a custom limit of unique reactions (i.e. a customizable version of appConfig.reactions_uniq_max); this field and the other info set by the method will then be available to users in and .
If this flag is not set, the previously configured reactions_limit will not be altered. - /// If this flag is set and a is passed, the method will enable or disable paid message reactions ». If this flag is not set, the previously stored setting will not be changed. - public static Task Messages_SetChatAvailableReactions(this Client client, InputPeer peer, ChatReactions available_reactions, int? reactions_limit = null, bool? paid_enabled = default) - => client.Invoke(new Messages_SetChatAvailableReactions - { - flags = (Messages_SetChatAvailableReactions.Flags)((reactions_limit != null ? 0x1 : 0) | (paid_enabled != default ? 0x2 : 0)), - peer = peer, - available_reactions = available_reactions, - reactions_limit = reactions_limit ?? default, - paid_enabled = paid_enabled ?? default, - }); - - /// Obtain available message reactions » See - /// Hash used for caching, for more info click here. - /// a null value means messages.availableReactionsNotModified - public static Task Messages_GetAvailableReactions(this Client client, int hash = default) - => client.Invoke(new Messages_GetAvailableReactions - { - 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. See Possible codes: 400 (details) - /// New emoji reaction - public static Task Messages_SetDefaultReaction(this Client client, Reaction reaction) - => client.Invoke(new Messages_SetDefaultReaction - { - reaction = reaction, - }); - - /// Translate a given text. See Possible codes: 400,406,500 (details) - /// If the text is a chat message, the peer ID - /// A list of message IDs to translate - /// A list of styled messages to translate - /// Two-letter ISO 639-1 language code of the language to which the message is translated - public static Task Messages_TranslateText(this Client client, string to_lang, InputPeer peer = null, int[] id = null, TextWithEntities[] text = null) - => client.Invoke(new Messages_TranslateText - { - flags = (Messages_TranslateText.Flags)((peer != null ? 0x1 : 0) | (id != null ? 0x1 : 0) | (text != null ? 0x2 : 0)), - peer = peer, - id = id, - text = text, - to_lang = to_lang, - }); - - /// Get unread reactions to messages you sent See Possible codes: 400 (details) - /// Peer - /// If set, considers only reactions to messages within the specified forum topic - /// If set, must be equal to the ID of a monoforum topic: will affect that topic in the monoforum passed in peer. - /// Offsets for pagination, for more info click here - /// Offsets for pagination, for more info click here - /// 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, int? top_msg_id = null, InputPeer saved_peer_id = null) - => client.Invoke(new Messages_GetUnreadReactions - { - flags = (Messages_GetUnreadReactions.Flags)((top_msg_id != null ? 0x1 : 0) | (saved_peer_id != null ? 0x2 : 0)), - peer = peer, - top_msg_id = top_msg_id ?? default, - saved_peer_id = saved_peer_id, - offset_id = offset_id, - add_offset = add_offset, - limit = limit, - max_id = max_id, - min_id = min_id, - }); - - /// Mark message reactions » as read See Possible codes: 400 (details) - /// Peer - /// Mark as read only reactions to messages within the specified forum topic - /// If set, must be equal to the ID of a monoforum topic: will affect that topic in the monoforum passed in peer. - public static Task Messages_ReadReactions(this Client client, InputPeer peer, int? top_msg_id = null, InputPeer saved_peer_id = null) - => client.InvokeAffected(new Messages_ReadReactions - { - flags = (Messages_ReadReactions.Flags)((top_msg_id != null ? 0x1 : 0) | (saved_peer_id != null ? 0x2 : 0)), - peer = peer, - top_msg_id = top_msg_id ?? default, - saved_peer_id = saved_peer_id, - }, peer is InputPeerChannel ipc ? ipc.channel_id : 0); - - /// View and search recently sent media.
This method does not support pagination. See Possible codes: 400 (details)
- /// Optional search query - /// Message filter - /// Maximum number of results to return (max 100). - public static Task Messages_SearchSentMedia(this Client client, string q, MessagesFilter filter = null, int limit = int.MaxValue) - => client.Invoke(new Messages_SearchSentMedia - { - q = q, - filter = filter, - limit = limit, - }); - - /// Returns installed attachment menu bot mini apps » See - /// Hash used for caching, for more info click here. - /// a null value means attachMenuBotsNotModified - public static Task Messages_GetAttachMenuBots(this Client client, long hash = default) - => client.Invoke(new Messages_GetAttachMenuBots - { - hash = hash, - }); - - /// Returns attachment menu entry for a bot mini app that can be launched from the attachment menu » See Possible codes: 400 (details) - /// Bot ID - public static Task Messages_GetAttachMenuBot(this Client client, InputUserBase bot) - => client.Invoke(new Messages_GetAttachMenuBot - { - bot = bot, - }); - - /// Enable or disable web bot attachment menu » See Possible codes: 400 (details) - /// Whether the user authorizes the bot to write messages to them, if requested by .request_write_access - /// Bot ID - /// Toggle - 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, - }); - - /// Open a bot mini app, sending over user information after user confirmation. See Possible codes: 400,403 (details) - /// 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 Messages_SendWebViewResultMessage should be sent silently (no notifications for the receivers). - /// If set, requests to open the mini app in compact mode (as opposed to normal or fullscreen mode). Must be set if the mode parameter of the attachment menu deep link is equal to compact. - /// If set, requests to open the mini app in fullscreen mode (as opposed to normal or compact mode). Must be set if the mode parameter of the attachment menu deep link is equal to fullscreen. - /// 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 - /// If set, indicates that 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 the specified message or story. - /// 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, InputReplyTo reply_to = null, string url = null, DataJSON theme_params = null, string start_param = null, InputPeer send_as = null, bool from_bot_menu = false, bool silent = false, bool compact = false, bool fullscreen = false) - => client.Invoke(new Messages_RequestWebView - { - flags = (Messages_RequestWebView.Flags)((reply_to != null ? 0x1 : 0) | (url != null ? 0x2 : 0) | (theme_params != null ? 0x4 : 0) | (start_param != null ? 0x8 : 0) | (send_as != null ? 0x2000 : 0) | (from_bot_menu ? 0x10 : 0) | (silent ? 0x20 : 0) | (compact ? 0x80 : 0) | (fullscreen ? 0x100 : 0)), - peer = peer, - bot = bot, - url = url, - start_param = start_param, - theme_params = theme_params, - platform = platform, - reply_to = reply_to, - send_as = send_as, - }); - - /// Indicate to the server (from the user side) that the user is still using a web app. See Possible codes: 400 (details) - /// 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 - /// If set, indicates that 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 the specified message or story. - /// Open the web app as the specified peer - public static Task Messages_ProlongWebView(this Client client, InputPeer peer, InputUserBase bot, long query_id, InputReplyTo reply_to = null, InputPeer send_as = null, bool silent = false) - => client.Invoke(new Messages_ProlongWebView - { - flags = (Messages_ProlongWebView.Flags)((reply_to != null ? 0x1 : 0) | (send_as != null ? 0x2000 : 0) | (silent ? 0x20 : 0)), - peer = peer, - bot = bot, - query_id = query_id, - reply_to = reply_to, - send_as = send_as, - }); - - /// Open a bot mini app. See Possible codes: 400 (details) - /// Whether the webapp was opened by clicking on the switch_webview button shown on top of the inline results list returned by Messages_GetInlineBotResults. - /// Set this flag if opening the Mini App from the installed side menu entry ». - /// Deprecated. - /// Requests to open the app in fullscreen mode. - /// Bot that owns the mini app - /// Web app URL, if opening from a keyboard button or inline result - /// Deprecated. - /// 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 platform, DataJSON theme_params = null, string url = null, string start_param = null, bool from_switch_webview = false, bool from_side_menu = false, bool compact = false, bool fullscreen = false) - => client.Invoke(new Messages_RequestSimpleWebView - { - flags = (Messages_RequestSimpleWebView.Flags)((theme_params != null ? 0x1 : 0) | (url != null ? 0x8 : 0) | (start_param != null ? 0x10 : 0) | (from_switch_webview ? 0x2 : 0) | (from_side_menu ? 0x4 : 0) | (compact ? 0x80 : 0) | (fullscreen ? 0x100 : 0)), - bot = bot, - url = url, - start_param = start_param, - theme_params = theme_params, - platform = platform, - }); - - /// This method is only for basic Chat. See Terminology in the README 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: ✓ users: ✗] 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 - { - bot_query_id = bot_query_id, - result = result, - }); - - /// Used by the user to relay data from an opened reply keyboard bot mini app to the bot that owns it. See Possible codes: 400 (details) - /// Bot that owns the web app - /// Unique client message ID to prevent duplicate sending of the same event You can use - /// Text of the that was pressed to open the web app. - /// Data to relay to the bot, obtained from a web_app_data_send JS event. - public static Task Messages_SendWebViewData(this Client client, InputUserBase bot, long random_id, string button_text, string data) - => client.Invoke(new Messages_SendWebViewData - { - bot = bot, - random_id = random_id, - button_text = button_text, - data = data, - }); - - /// Transcribe voice message See Possible codes: 400,403 (details) - /// Peer ID where the voice message was sent - /// Voice message ID - public static Task Messages_TranscribeAudio(this Client client, InputPeer peer, int msg_id) - => client.Invoke(new Messages_TranscribeAudio - { - peer = peer, - msg_id = msg_id, - }); - - /// Rate transcribed voice message See - /// Peer where the voice message was sent - /// Message ID - /// Transcription ID - /// Whether the transcription was correct - public static Task Messages_RateTranscribedAudio(this Client client, InputPeer peer, int msg_id, long transcription_id, bool good) - => client.Invoke(new Messages_RateTranscribedAudio - { - peer = peer, - msg_id = msg_id, - transcription_id = transcription_id, - good = good, - }); - - /// Fetch custom emoji stickers ». See [bots: ✓] - /// Custom emoji IDs from a . - public static Task Messages_GetCustomEmojiDocuments(this Client client, params long[] document_id) - => client.Invoke(new Messages_GetCustomEmojiDocuments - { - document_id = document_id, - }); - - /// Gets the list of currently installed custom emoji stickersets. See - /// Hash used for caching, for more info click here. - /// a null value means messages.allStickersNotModified - public static Task Messages_GetEmojiStickers(this Client client, long hash = default) - => client.Invoke(new Messages_GetEmojiStickers - { - hash = hash, - }); - - /// Gets featured custom emoji stickersets. See - /// Hash used for caching, for more info click here. - public static Task Messages_GetFeaturedEmojiStickers(this Client client, long hash = default) - => client.Invoke(new Messages_GetFeaturedEmojiStickers - { - hash = hash, - }); - - /// Report a message reaction See Possible codes: 400 (details) - /// Peer where the message was sent - /// Message ID - /// Peer that sent the reaction - public static Task Messages_ReportReaction(this Client client, InputPeer peer, int id, InputPeer reaction_peer) - => client.Invoke(new Messages_ReportReaction - { - peer = peer, - id = id, - reaction_peer = reaction_peer, - }); - - /// Got popular message reactions See - /// Maximum number of results to return, see pagination - /// Hash used for caching, for more info click here. - /// a null value means messages.reactionsNotModified - public static Task Messages_GetTopReactions(this Client client, int limit = int.MaxValue, long hash = default) - => client.Invoke(new Messages_GetTopReactions - { - limit = limit, - hash = hash, - }); - - /// Get recently used message reactions See - /// Maximum number of results to return, see pagination - /// Hash used for caching, for more info click here. - /// a null value means messages.reactionsNotModified - public static Task Messages_GetRecentReactions(this Client client, int limit = int.MaxValue, long hash = default) - => client.Invoke(new Messages_GetRecentReactions - { - limit = limit, - hash = hash, - }); - - /// Clear recently used message reactions See - public static Task Messages_ClearRecentReactions(this Client client) - => client.Invoke(new Messages_ClearRecentReactions - { - }); - - /// Fetch updated information about paid media, see here » for the full flow. See - /// Peer with visible paid media messages. - /// IDs of currently visible messages containing paid media. - public static Task Messages_GetExtendedMedia(this Client client, InputPeer peer, params int[] id) - => client.Invoke(new Messages_GetExtendedMedia - { - peer = peer, - id = id, - }); - - /// Changes the default value of the Time-To-Live setting, applied to all new chats. See Possible codes: 400 (details) - /// The new default Time-To-Live of all messages sent in new chats, in seconds. - public static Task Messages_SetDefaultHistoryTTL(this Client client, int period) - => client.Invoke(new Messages_SetDefaultHistoryTTL - { - period = period, - }); - - /// Gets the default value of the Time-To-Live setting, applied to all new chats. See - public static Task Messages_GetDefaultHistoryTTL(this Client client) - => client.Invoke(new Messages_GetDefaultHistoryTTL - { - }); - - /// Send one or more chosen peers, as requested by a button. See Possible codes: 400 (details) - /// The bot that sent the button. - /// ID of the message that contained the reply keyboard with the button. - /// The button_id field from the . - /// The chosen peers. - public static Task Messages_SendBotRequestedPeer(this Client client, InputPeer peer, int msg_id, int button_id, params InputPeer[] requested_peers) - => client.Invoke(new Messages_SendBotRequestedPeer - { - peer = peer, - msg_id = msg_id, - button_id = button_id, - requested_peers = requested_peers, - }); - - /// Represents a list of emoji categories. See - /// Hash used for caching, for more info click here. - /// a null value means messages.emojiGroupsNotModified - public static Task Messages_GetEmojiGroups(this Client client, int hash = default) - => client.Invoke(new Messages_GetEmojiGroups - { - hash = hash, - }); - - /// Represents a list of emoji categories, to be used when selecting custom emojis to set as custom emoji status. See - /// Hash used for caching, for more info click here. - /// a null value means messages.emojiGroupsNotModified - public static Task Messages_GetEmojiStatusGroups(this Client client, int hash = default) - => client.Invoke(new Messages_GetEmojiStatusGroups - { - hash = hash, - }); - - /// Represents a list of emoji categories, to be used when selecting custom emojis to set as profile picture. See - /// Hash used for caching, for more info click here. - /// a null value means messages.emojiGroupsNotModified - public static Task Messages_GetEmojiProfilePhotoGroups(this Client client, int hash = default) - => client.Invoke(new Messages_GetEmojiProfilePhotoGroups - { - hash = hash, - }); - - /// Look for custom emojis associated to a UTF8 emoji See Possible codes: 400 (details) - /// The emoji - /// Hash used for caching, for more info click here. - /// a null value means emojiListNotModified - public static Task Messages_SearchCustomEmoji(this Client client, string emoticon, long hash = default) - => client.Invoke(new Messages_SearchCustomEmoji - { - emoticon = emoticon, - hash = hash, - }); - - /// Show or hide the real-time chat translation popup for a certain chat See Possible codes: 400 (details) - /// Whether to disable or enable the real-time chat translation popup - /// The peer - public static Task Messages_TogglePeerTranslations(this Client client, InputPeer peer, bool disabled = false) - => client.Invoke(new Messages_TogglePeerTranslations - { - flags = (Messages_TogglePeerTranslations.Flags)(disabled ? 0x1 : 0), - peer = peer, - }); - - /// Obtain information about a direct link Mini App See Possible codes: 400 (details) - /// Bot app information obtained from a Direct Mini App deep link ». - /// Hash used for caching, for more info click here - public static Task Messages_GetBotApp(this Client client, InputBotApp app, long hash = default) - => client.Invoke(new Messages_GetBotApp - { - app = app, - hash = hash, - }); - - /// Open a bot mini app from a direct Mini App deep link, sending over user information after user confirmation. See Possible codes: 400 (details) - /// Set this flag if the bot is asking permission to send messages to the user as specified in the direct Mini App deep link docs, and the user agreed. - /// If set, requests to open the mini app in compact mode (as opposed to normal or fullscreen mode). Must be set if the mode parameter of the direct Mini App deep link is equal to compact. - /// If set, requests to open the mini app in fullscreen mode (as opposed to compact or normal mode). Must be set if the mode parameter of the direct Mini App deep link is equal to fullscreen. - /// If the client has clicked on the link in a Telegram chat, pass the chat's peer information; otherwise pass the bot's peer information, instead. - /// The app obtained by invoking Messages_GetBotApp as specified in the direct Mini App deep link docs. - /// If the startapp query string parameter is present in the direct Mini App deep link, pass it to start_param. - /// Theme parameters » - /// Short name of the application; 0-64 English letters, digits, and underscores - public static Task Messages_RequestAppWebView(this Client client, InputPeer peer, InputBotApp app, string platform, string start_param = null, DataJSON theme_params = null, bool write_allowed = false, bool compact = false, bool fullscreen = false) - => client.Invoke(new Messages_RequestAppWebView - { - flags = (Messages_RequestAppWebView.Flags)((start_param != null ? 0x2 : 0) | (theme_params != null ? 0x4 : 0) | (write_allowed ? 0x1 : 0) | (compact ? 0x80 : 0) | (fullscreen ? 0x100 : 0)), - peer = peer, - app = app, - start_param = start_param, - theme_params = theme_params, - platform = platform, - }); - - /// Set a custom wallpaper » in a specific private chat with another user. See Possible codes: 400 (details) - /// Only for Premium users, sets the specified wallpaper for both users of the chat, without requiring confirmation from the other user. - /// If we don't like the new wallpaper the other user of the chat has chosen for us using the for_both flag, we can re-set our previous wallpaper just on our side using this flag. - /// The private chat where the wallpaper will be set - /// The wallpaper », obtained as described in the wallpaper documentation »; must not be provided when installing a wallpaper obtained from a service message (id must be provided, instead). - /// Wallpaper settings, obtained as described in the wallpaper documentation » or from .wallpaper.settings. - /// If the wallpaper was obtained from a service message, must contain the ID of that message. - public static Task Messages_SetChatWallPaper(this Client client, InputPeer peer, InputWallPaperBase wallpaper = null, int? id = null, WallPaperSettings settings = null, bool for_both = false, bool revert = false) - => client.Invoke(new Messages_SetChatWallPaper - { - flags = (Messages_SetChatWallPaper.Flags)((wallpaper != null ? 0x1 : 0) | (id != null ? 0x2 : 0) | (settings != null ? 0x4 : 0) | (for_both ? 0x8 : 0) | (revert ? 0x10 : 0)), - peer = peer, - wallpaper = wallpaper, - settings = settings, - id = id ?? default, - }); - - /// Search for custom emoji stickersets » See - /// Exclude featured stickersets from results - /// Query string - /// Hash used for caching, for more info click here. - /// a null value means messages.foundStickerSetsNotModified - public static Task Messages_SearchEmojiStickerSets(this Client client, string q, long hash = default, bool exclude_featured = false) - => client.Invoke(new Messages_SearchEmojiStickerSets - { - flags = (Messages_SearchEmojiStickerSets.Flags)(exclude_featured ? 0x1 : 0), - q = q, - hash = hash, - }); - - /// Returns the current saved dialog list » or monoforum topic list ». See - /// Exclude pinned dialogs - /// If set, fetches the topic list of the passed monoforum, otherwise fetches the saved dialog list. - /// Offsets for pagination, for more info click here - /// Offsets for pagination, for more info click here (top_message ID used for pagination) - /// Offset peer for pagination - /// Number of list elements to be returned - /// Hash used for caching, for more info click here - public static Task Messages_GetSavedDialogs(this Client client, DateTime offset_date = default, int offset_id = default, InputPeer offset_peer = null, int limit = int.MaxValue, long hash = default, InputPeer parent_peer = null, bool exclude_pinned = false) - => client.Invoke(new Messages_GetSavedDialogs - { - flags = (Messages_GetSavedDialogs.Flags)((parent_peer != null ? 0x2 : 0) | (exclude_pinned ? 0x1 : 0)), - parent_peer = parent_peer, - offset_date = offset_date, - offset_id = offset_id, - offset_peer = offset_peer, - limit = limit, - hash = hash, - }); - - /// Fetch saved messages » forwarded from a specific peer, or fetch messages from a monoforum topic ». See Possible codes: 400 (details) - /// If set, fetches messages from the specified monoforum, otherwise fetches from saved messages. - /// Target peer (or topic) - /// Only return messages starting from the specified message ID - /// Only return messages sent before the specified date - /// Number of list elements to be skipped, negative values are also accepted. - /// Number of results to return - /// If a positive value was transferred, the method will return only messages with IDs less than max_id - /// If a positive value was transferred, the method will return only messages with IDs more than min_id - /// Result hash - public static Task Messages_GetSavedHistory(this Client client, InputPeer peer, int offset_id = default, DateTime offset_date = default, int add_offset = default, int limit = int.MaxValue, int max_id = default, int min_id = default, long hash = default, InputPeer parent_peer = null) - => client.Invoke(new Messages_GetSavedHistory - { - flags = (Messages_GetSavedHistory.Flags)(parent_peer != null ? 0x1 : 0), - parent_peer = parent_peer, - peer = peer, - offset_id = offset_id, - offset_date = offset_date, - add_offset = add_offset, - limit = limit, - max_id = max_id, - min_id = min_id, - hash = hash, - }); - - /// Deletes messages from a monoforum topic », or deletes messages forwarded from a specific peer to saved messages ». See Possible codes: 400 (details) - /// If set, affects the messages of the passed monoforum topic », otherwise affects saved messages ». - /// Peer, whose messages will be deleted from saved messages », or the ID of the topic. - /// 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_DeleteSavedHistory(this Client client, InputPeer peer, int max_id = default, InputPeer parent_peer = null, DateTime? min_date = null, DateTime? max_date = null) - => client.InvokeAffected(new Messages_DeleteSavedHistory - { - flags = (Messages_DeleteSavedHistory.Flags)((parent_peer != null ? 0x1 : 0) | (min_date != null ? 0x4 : 0) | (max_date != null ? 0x8 : 0)), - parent_peer = parent_peer, - peer = peer, - max_id = max_id, - min_date = min_date ?? default, - max_date = max_date ?? default, - }, peer is InputPeerChannel ipc ? ipc.channel_id : 0); - - /// Get pinned saved dialogs, see here » for more info. See - public static Task Messages_GetPinnedSavedDialogs(this Client client) - => client.Invoke(new Messages_GetPinnedSavedDialogs - { - }); - - /// Pin or unpin a saved message dialog ». See Possible codes: 400 (details) - /// Whether to pin or unpin the dialog - /// The dialog to pin - public static Task Messages_ToggleSavedDialogPin(this Client client, InputDialogPeerBase peer, bool pinned = false) - => client.Invoke(new Messages_ToggleSavedDialogPin - { - flags = (Messages_ToggleSavedDialogPin.Flags)(pinned ? 0x1 : 0), - peer = peer, - }); - - /// Reorder pinned saved message dialogs ». See - /// If set, dialogs pinned server-side but not present in the order field will be unpinned. - /// New dialog order - public static Task Messages_ReorderPinnedSavedDialogs(this Client client, InputDialogPeerBase[] order, bool force = false) - => client.Invoke(new Messages_ReorderPinnedSavedDialogs - { - flags = (Messages_ReorderPinnedSavedDialogs.Flags)(force ? 0x1 : 0), - order = order, - }); - - /// Fetch the full list of saved message tags created by the user. See Possible codes: 400 (details) - /// If set, returns tags only used in the specified saved message dialog. - /// Hash used for caching, for more info click here. - /// a null value means messages.savedReactionTagsNotModified - public static Task Messages_GetSavedReactionTags(this Client client, long hash = default, InputPeer peer = null) - => client.Invoke(new Messages_GetSavedReactionTags - { - flags = (Messages_GetSavedReactionTags.Flags)(peer != null ? 0x1 : 0), - peer = peer, - hash = hash, - }); - - /// Update the description of a saved message tag ». See Possible codes: 400,403 (details) - /// Reaction associated to the tag - /// Tag description, max 12 UTF-8 characters; to remove the description call the method without setting this flag. - public static Task Messages_UpdateSavedReactionTag(this Client client, Reaction reaction, string title = null) - => client.Invoke(new Messages_UpdateSavedReactionTag - { - flags = (Messages_UpdateSavedReactionTag.Flags)(title != null ? 0x1 : 0), - reaction = reaction, - title = title, - }); - - /// Fetch a default recommended list of saved message tag reactions. See - /// Hash used for caching, for more info click here. - /// a null value means messages.reactionsNotModified - public static Task Messages_GetDefaultTagReactions(this Client client, long hash = default) - => client.Invoke(new Messages_GetDefaultTagReactions - { - hash = hash, - }); - - /// Get the exact read date of one of our messages, sent to a private chat with another user. See Possible codes: 400,403 (details) - /// The user to whom we sent the message. - /// The message ID. - public static Task Messages_GetOutboxReadDate(this Client client, InputPeer peer, int msg_id) - => client.Invoke(new Messages_GetOutboxReadDate - { - peer = peer, - msg_id = msg_id, - }); - - /// Fetch basic info about all existing quick reply shortcuts. See - /// Hash for pagination, generated as specified here » (not the usual algorithm used for hash generation.) - /// a null value means messages.quickRepliesNotModified - public static Task Messages_GetQuickReplies(this Client client, long hash = default) - => client.Invoke(new Messages_GetQuickReplies - { - hash = hash, - }); - - /// Reorder quick reply shortcuts. See Possible codes: 403 (details) - /// IDs of all created quick reply shortcuts, in the desired order. - public static Task Messages_ReorderQuickReplies(this Client client, params int[] order) - => client.Invoke(new Messages_ReorderQuickReplies - { - order = order, - }); - - /// Before offering the user the choice to add a message to a quick reply shortcut, to make sure that none of the limits specified here » were reached. See Possible codes: 403 (details) - /// Shorcut name (not ID!). - public static Task Messages_CheckQuickReplyShortcut(this Client client, string shortcut) - => client.Invoke(new Messages_CheckQuickReplyShortcut - { - shortcut = shortcut, - }); - - /// Rename a quick reply shortcut.
This will emit an update to other logged-in sessions. See Possible codes: 400,403 (details)
- /// Shortcut ID. - /// New shortcut name. - public static Task Messages_EditQuickReplyShortcut(this Client client, int shortcut_id, string shortcut) - => client.Invoke(new Messages_EditQuickReplyShortcut - { - shortcut_id = shortcut_id, - shortcut = shortcut, - }); - - /// Completely delete a quick reply shortcut.
This will also emit an update to other logged-in sessions (and no updates, even if all the messages in the shortcuts are also deleted by this method). See Possible codes: 400 (details)
- /// Shortcut ID - public static Task Messages_DeleteQuickReplyShortcut(this Client client, int shortcut_id) - => client.Invoke(new Messages_DeleteQuickReplyShortcut - { - shortcut_id = shortcut_id, - }); - - /// This method is only for basic Chat. See Terminology in the README to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a
Fetch (a subset or all) messages in a quick reply shortcut ». See Possible codes: 400 (details)
- /// Quick reply shortcut ID. - /// IDs of the messages to fetch, if empty fetches all of them. - /// Hash for pagination, generated as specified here » (not the usual algorithm used for hash generation). - public static Task Messages_GetQuickReplyMessages(this Client client, int shortcut_id, long hash = default, int[] id = null) - => client.Invoke(new Messages_GetQuickReplyMessages - { - flags = (Messages_GetQuickReplyMessages.Flags)(id != null ? 0x1 : 0), - shortcut_id = shortcut_id, - id = id, - hash = hash, - }); - - /// Send a quick reply shortcut ». See Possible codes: 400,403 (details) - /// The peer where to send the shortcut (users only, for now). - /// The ID of the quick reply shortcut to send. - /// Specify a subset of messages from the shortcut to send; if empty, defaults to all of them. - /// Unique client IDs required to prevent message resending, one for each message we're sending, may be empty (but not recommended). You can use - public static Task Messages_SendQuickReplyMessages(this Client client, InputPeer peer, int shortcut_id, int[] id, params long[] random_id) - => client.Invoke(new Messages_SendQuickReplyMessages - { - peer = peer, - shortcut_id = shortcut_id, - id = id, - random_id = random_id, - }); - - /// This method is only for basic Chat. See Terminology in the README to understand what this means
Search for a similar method name starting with Channels_ if you're dealing with a
Delete one or more messages from a quick reply shortcut. This will also emit an update. See Possible codes: 400 (details)
- /// Shortcut ID. - /// IDs of shortcut messages to delete. - public static Task Messages_DeleteQuickReplyMessages(this Client client, int shortcut_id, params int[] id) - => client.Invoke(new Messages_DeleteQuickReplyMessages - { - shortcut_id = shortcut_id, - id = id, - }); - - /// Enable or disable folder tags ». See Possible codes: 403 (details) - /// Enable or disable folder tags. - public static Task Messages_ToggleDialogFilterTags(this Client client, bool enabled) - => client.Invoke(new Messages_ToggleDialogFilterTags - { - enabled = enabled, - }); - - /// Fetch all stickersets » owned by the current user. See - /// Offsets for pagination, for more info click here - /// Maximum number of results to return, see pagination - public static Task Messages_GetMyStickers(this Client client, long offset_id = default, int limit = int.MaxValue) - => client.Invoke(new Messages_GetMyStickers - { - offset_id = offset_id, - limit = limit, - }); - - /// Represents a list of emoji categories, to be used when choosing a sticker. See - /// Hash used for caching, for more info click here. - /// a null value means messages.emojiGroupsNotModified - public static Task Messages_GetEmojiStickerGroups(this Client client, int hash = default) - => client.Invoke(new Messages_GetEmojiStickerGroups - { - hash = hash, - }); - - /// Fetch the full list of usable animated message effects ». See - /// Hash used for caching, for more info click here. - /// a null value means messages.availableEffectsNotModified - public static Task Messages_GetAvailableEffects(this Client client, int hash = default) - => client.Invoke(new Messages_GetAvailableEffects - { - hash = hash, - }); - - /// Edit/create a fact-check on a message. See Possible codes: 400,403 (details) - /// Peer where the message was sent - /// Message ID - /// Fact-check (maximum UTF-8 length specified in appConfig.factcheck_length_limit). - public static Task Messages_EditFactCheck(this Client client, InputPeer peer, int msg_id, TextWithEntities text) - => client.Invoke(new Messages_EditFactCheck - { - peer = peer, - msg_id = msg_id, - text = text, - }); - - /// Delete a fact-check from a message. See Possible codes: 400,403 (details) - /// Peer where the message was sent. - /// Message ID - public static Task Messages_DeleteFactCheck(this Client client, InputPeer peer, int msg_id) - => client.Invoke(new Messages_DeleteFactCheck - { - peer = peer, - msg_id = msg_id, - }); - - /// Fetch one or more factchecks, see here » for the full flow. See Possible codes: 400 (details) - /// Peer where the messages were sent. - /// Messages that have associated s with the need_check flag set. - public static Task Messages_GetFactCheck(this Client client, InputPeer peer, params int[] msg_id) - => client.Invoke(new Messages_GetFactCheck - { - peer = peer, - msg_id = msg_id, - }); - - /// Open a Main Mini App. See Possible codes: 400 (details) - /// If set, requests to open the mini app in compact mode (as opposed to normal or fullscreen mode). Must be set if the mode parameter of the Main Mini App link is equal to compact. - /// If set, requests to open the mini app in fullscreen mode (as opposed to compact or normal mode). Must be set if the mode parameter of the Main Mini App link is equal to fullscreen. - /// Currently open chat, may be if no chat is currently open. - /// Bot that owns the main mini app. - /// Start parameter, if opening from a Main Mini App link ». - /// Theme parameters » - /// Short name of the application; 0-64 English letters, digits, and underscores - public static Task Messages_RequestMainWebView(this Client client, InputPeer peer, InputUserBase bot, string platform, DataJSON theme_params = null, string start_param = null, bool compact = false, bool fullscreen = false) - => client.Invoke(new Messages_RequestMainWebView - { - flags = (Messages_RequestMainWebView.Flags)((theme_params != null ? 0x1 : 0) | (start_param != null ? 0x2 : 0) | (compact ? 0x80 : 0) | (fullscreen ? 0x100 : 0)), - peer = peer, - bot = bot, - start_param = start_param, - theme_params = theme_params, - platform = platform, - }); - - /// Sends one or more paid Telegram Star reactions », transferring Telegram Stars » to a channel's balance. See Possible codes: 400,403 (details) - /// The channel - /// The message to react to - /// The number of stars to send (each will increment the reaction counter by one). - /// Unique client message ID required to prevent message resending.
Note: this argument must be composed of a 64-bit integer where the lower 32 bits are random, and the higher 32 bits are equal to the current unixtime, i.e. uint64_t random_id = (time() << 32) | ((uint64_t)random_uint32_t()): this differs from the random_id format of all other methods in the API, which just take 64 random bits. You can use - /// Each post with star reactions has a leaderboard with the top senders, but users can opt out of appearing there if they prefer more privacy. Not populating this field will use the default reaction privacy, stored on the server and synced to clients using (see here for more info). - public static Task Messages_SendPaidReaction(this Client client, InputPeer peer, int msg_id, int count, long random_id, PaidReactionPrivacy private_ = null) - => client.Invoke(new Messages_SendPaidReaction - { - flags = (Messages_SendPaidReaction.Flags)(private_ != null ? 0x1 : 0), - peer = peer, - msg_id = msg_id, - count = count, - random_id = random_id, - private_ = private_, - }); - - /// Changes the privacy of already sent paid reactions on a specific message. See Possible codes: 400 (details) - /// The channel - /// The ID of the message to which we sent the paid reactions - /// If true, makes the current anonymous in the top sender leaderboard for this message; otherwise, does the opposite. - public static Task Messages_TogglePaidReactionPrivacy(this Client client, InputPeer peer, int msg_id, PaidReactionPrivacy private_) - => client.Invoke(new Messages_TogglePaidReactionPrivacy - { - peer = peer, - msg_id = msg_id, - private_ = private_, - }); - - /// Fetches an update with the current default paid reaction privacy, see here » for more info. See - public static Task Messages_GetPaidReactionPrivacy(this Client client) - => client.Invoke(new Messages_GetPaidReactionPrivacy - { - }); - - /// Mark a specific sponsored message » as read See - /// The ad's unique ID. - public static Task Messages_ViewSponsoredMessage(this Client client, byte[] random_id) - => client.Invoke(new Messages_ViewSponsoredMessage - { - random_id = random_id, - }); - - /// Informs the server that the user has interacted with a sponsored message in one of the ways listed here ». See - /// The user clicked on the media - /// The user expanded the video to full screen, and then clicked on it. - /// The ad's unique ID. - public static Task Messages_ClickSponsoredMessage(this Client client, byte[] random_id, bool media = false, bool fullscreen = false) - => client.Invoke(new Messages_ClickSponsoredMessage - { - flags = (Messages_ClickSponsoredMessage.Flags)((media ? 0x1 : 0) | (fullscreen ? 0x2 : 0)), - random_id = random_id, - }); - - /// Report a sponsored message », see here » for more info on the full flow. See - /// The ad's unique ID. - /// Chosen report option, initially an empty string, see here » for more info on the full flow. - public static Task Messages_ReportSponsoredMessage(this Client client, byte[] random_id, byte[] option) - => client.Invoke(new Messages_ReportSponsoredMessage - { - random_id = random_id, - option = option, - }); - - /// Get a list of sponsored messages for a peer, see here » for more info. See Possible codes: 400 (details) - /// The currently open channel/bot. - /// Must be set when fetching sponsored messages to show on channel videos ». - /// a null value means messages.sponsoredMessagesEmpty - public static Task Messages_GetSponsoredMessages(this Client client, InputPeer peer, int? msg_id = null) - => client.Invoke(new Messages_GetSponsoredMessages - { - flags = (Messages_GetSponsoredMessages.Flags)(msg_id != null ? 0x1 : 0), - peer = peer, - msg_id = msg_id ?? default, - }); - - /// Save a prepared inline message, to be shared by the user of the mini app using a web_app_send_prepared_message event See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// The message - /// The user to whom the web_app_send_prepared_message event event will be sent - /// Types of chats where this message can be sent - public static Task Messages_SavePreparedInlineMessage(this Client client, InputBotInlineResultBase result, InputUserBase user_id, InlineQueryPeerType[] peer_types = null) - => client.Invoke(new Messages_SavePreparedInlineMessage - { - flags = (Messages_SavePreparedInlineMessage.Flags)(peer_types != null ? 0x1 : 0), - result = result, - user_id = user_id, - peer_types = peer_types, - }); - - /// Obtain a prepared inline message generated by a mini app: invoked when handling web_app_send_prepared_message events See Possible codes: 400 (details) - /// The bot that owns the mini app that emitted the web_app_send_prepared_message event - /// The id from the web_app_send_prepared_message event - public static Task Messages_GetPreparedInlineMessage(this Client client, InputUserBase bot, string id) - => client.Invoke(new Messages_GetPreparedInlineMessage - { - bot = bot, - id = id, - }); - - /// Search for stickers using AI-powered keyword search See - /// If set, returns custom emoji stickers - /// The search term - /// Space-separated list of emojis to search for - /// List of possible IETF language tags of the user's input language; may be empty if unknown - /// Offset for pagination - /// Maximum number of results to return, see pagination - /// Hash used for caching, for more info click here.
The hash may be generated locally by using the ids of the returned or stored sticker s. - public static Task Messages_SearchStickers(this Client client, string q, string emoticon, string[] lang_code, int offset = default, int limit = int.MaxValue, long hash = default, bool emojis = false) - => client.Invoke(new Messages_SearchStickers - { - flags = (Messages_SearchStickers.Flags)(emojis ? 0x1 : 0), - q = q, - emoticon = emoticon, - lang_code = lang_code, - offset = offset, - limit = limit, - hash = hash, - }); - - /// Used for Telegram Gateway verification messages »: indicate to the server that one or more s were received by the client, if requested by the .report_delivery_until_date flag or the equivalent flag in push notifications. See Possible codes: 400 (details) - /// Must be set if the messages were received from a push notification. - /// The peer where the messages were received. - /// The IDs of the received messages. - public static Task Messages_ReportMessagesDelivery(this Client client, InputPeer peer, int[] id, bool push = false) - => client.Invoke(new Messages_ReportMessagesDelivery - { - flags = (Messages_ReportMessagesDelivery.Flags)(push ? 0x1 : 0), - peer = peer, - id = id, - }); - - /// Obtain information about specific saved message dialogs » or monoforum topics ». See - /// If set, fetches monoforum topics », otherwise fetches saved message dialogs ». - /// IDs of dialogs (topics) to fetch. - public static Task Messages_GetSavedDialogsByID(this Client client, InputPeer[] ids, InputPeer parent_peer = null) - => client.Invoke(new Messages_GetSavedDialogsByID - { - flags = (Messages_GetSavedDialogsByID.Flags)(parent_peer != null ? 0x2 : 0), - parent_peer = parent_peer, - ids = ids, - }); - - /// Mark messages as read in a monoforum topic ». See Possible codes: 400 (details) - /// ID of the monoforum group. - /// ID of the topic. - /// If a positive value is passed, only messages with identifiers less or equal than the given one will be read. - public static Task Messages_ReadSavedHistory(this Client client, InputPeer parent_peer, InputPeer peer, int max_id = default) - => client.Invoke(new Messages_ReadSavedHistory - { - parent_peer = parent_peer, - peer = peer, - max_id = max_id, - }); - - /// Mark one or more items of a todo list » as completed or not completed. See Possible codes: 400 (details) - /// Peer where the todo list was posted. - /// ID of the message with the todo list. - /// Items to mark as completed. - /// Items to mark as not completed. - public static Task Messages_ToggleTodoCompleted(this Client client, InputPeer peer, int msg_id, int[] completed, params int[] incompleted) - => client.Invoke(new Messages_ToggleTodoCompleted - { - peer = peer, - msg_id = msg_id, - completed = completed, - incompleted = incompleted, - }); - - /// Appends one or more items to a todo list ». See Possible codes: 400 (details) - /// Peer where the todo list was posted. - /// ID of the message with the todo list. - /// Items to append. - public static Task Messages_AppendTodoList(this Client client, InputPeer peer, int msg_id, params TodoItem[] list) - => client.Invoke(new Messages_AppendTodoList - { - peer = peer, - msg_id = msg_id, - list = list, - }); - - /// Approve or reject a suggested post ». See [bots: ✓] Possible codes: 400 (details) - /// Reject the suggested post. - /// Both for users and channels, must contain the ID of the direct messages monoforum » (for channels, the topic ID is extracted automatically from the msg_id). - /// ID of the suggestion message. - /// Custom scheduling date. - /// Optional comment for rejections (can only be used if reject is set). - public static Task Messages_ToggleSuggestedPostApproval(this Client client, InputPeer peer, int msg_id, DateTime? schedule_date = null, string reject_comment = null, bool reject = false) - => client.Invoke(new Messages_ToggleSuggestedPostApproval - { - flags = (Messages_ToggleSuggestedPostApproval.Flags)((schedule_date != null ? 0x1 : 0) | (reject_comment != null ? 0x4 : 0) | (reject ? 0x2 : 0)), - peer = peer, - msg_id = msg_id, - schedule_date = schedule_date ?? default, - reject_comment = reject_comment, - }); - - /// Get topics of a forum See Possible codes: 400 (details) - /// Peer - /// Search query - /// Offsets for pagination, for more info click here, date of the last message of the last found topic. Use 0 or any date in the future to get results from the last topic. - /// Offsets for pagination, for more info click here, ID of the last message of the last found topic (or initially 0). - /// Offsets for pagination, for more info click here, ID of the last found topic (or initially 0). - /// Maximum number of results to return, see pagination. For optimal performance, the number of returned topics is chosen by the server and can be smaller than the specified limit. - public static Task Messages_GetForumTopics(this Client client, InputPeer peer, DateTime offset_date = default, int offset_id = default, int offset_topic = default, int limit = int.MaxValue, string q = null) - => client.Invoke(new Messages_GetForumTopics - { - flags = (Messages_GetForumTopics.Flags)(q != null ? 0x1 : 0), - peer = peer, - q = q, - offset_date = offset_date, - offset_id = offset_id, - offset_topic = offset_topic, - limit = limit, - }); - - /// Get forum topics by their ID See Possible codes: 400 (details) - /// Peer - /// Topic IDs - public static Task Messages_GetForumTopicsByID(this Client client, InputPeer peer, params int[] topics) - => client.Invoke(new Messages_GetForumTopicsByID - { - peer = peer, - topics = topics, - }); - - /// Edit forum topic; requires manage_topics rights. See [bots: ✓] Possible codes: 400,403 (details) - /// Peer - /// Topic ID - /// If present, will update the topic title (maximum UTF-8 length: 128). - /// If present, updates the custom emoji used as topic icon. Telegram Premium users can use any custom emoji, other users can only use the custom emojis contained in the emoji pack. Pass 0 to switch to the fallback topic icon. - /// If present, will update the open/closed status of the topic. - /// If present, will hide/unhide the topic (only valid for the "General" topic, id=1). - public static Task Messages_EditForumTopic(this Client client, InputPeer peer, int topic_id, string title = null, long? icon_emoji_id = null, bool? closed = default, bool? hidden = default) - => client.Invoke(new Messages_EditForumTopic - { - flags = (Messages_EditForumTopic.Flags)((title != null ? 0x1 : 0) | (icon_emoji_id != null ? 0x2 : 0) | (closed != default ? 0x4 : 0) | (hidden != default ? 0x8 : 0)), - peer = peer, - topic_id = topic_id, - title = title, - icon_emoji_id = icon_emoji_id ?? default, - closed = closed ?? default, - hidden = hidden ?? default, - }); - - /// Pin or unpin forum topics See Possible codes: 400 (details) - /// Peer - /// Forum topic ID - /// Whether to pin or unpin the topic - public static Task Messages_UpdatePinnedForumTopic(this Client client, InputPeer peer, int topic_id, bool pinned) - => client.Invoke(new Messages_UpdatePinnedForumTopic - { - peer = peer, - topic_id = topic_id, - pinned = pinned, - }); - - /// Reorder pinned forum topics See Possible codes: 400 (details) - /// If not set, the order of only the topics present both server-side and in order will be changed (i.e. mentioning topics not pinned server-side in order will not pin them, and not mentioning topics pinned server-side will not unpin them).
If set, the entire server-side pinned topic list will be replaced with order (i.e. mentioning topics not pinned server-side in order will pin them, and not mentioning topics pinned server-side will unpin them) - /// Peer - /// Topic IDs » - public static Task Messages_ReorderPinnedForumTopics(this Client client, InputPeer peer, int[] order, bool force = false) - => client.Invoke(new Messages_ReorderPinnedForumTopics - { - flags = (Messages_ReorderPinnedForumTopics.Flags)(force ? 0x1 : 0), - peer = peer, - order = order, - }); - - /// Create a forum topic; requires manage_topics rights. See [bots: ✓] Possible codes: 400,403 (details) - /// Peer - /// Topic title (maximum UTF-8 length: 128) - /// If no custom emoji icon is specified, specifies the color of the fallback topic icon (RGB), one of 0x6FB9F0, 0xFFD67E, 0xCB86DB, 0x8EEE98, 0xFF93B2, or 0xFB6F5F. - /// ID of the custom emoji used as topic icon. Telegram Premium users can use any custom emoji, other users can only use the custom emojis contained in the emoji pack. - /// Unique client message ID to prevent duplicate sending of the same event You can use - /// Create the topic as the specified peer - public static Task Messages_CreateForumTopic(this Client client, InputPeer peer, string title, long random_id, int? icon_color = null, InputPeer send_as = null, long? icon_emoji_id = null, bool title_missing = false) - => client.Invoke(new Messages_CreateForumTopic - { - flags = (Messages_CreateForumTopic.Flags)((icon_color != null ? 0x1 : 0) | (send_as != null ? 0x4 : 0) | (icon_emoji_id != null ? 0x8 : 0) | (title_missing ? 0x10 : 0)), - peer = peer, - title = title, - icon_color = icon_color ?? default, - icon_emoji_id = icon_emoji_id ?? default, - random_id = random_id, - send_as = send_as, - }); - - /// See - /// Delete message history of a forum topic See [bots: ✓] Possible codes: 400,403 (details) - /// Peer - /// Topic ID - public static Task Messages_DeleteTopicHistory(this Client client, InputPeer peer, int top_msg_id) - => client.InvokeAffected(new Messages_DeleteTopicHistory - { - peer = peer, - top_msg_id = top_msg_id, - }, peer is InputPeerChannel ipc ? ipc.channel_id : 0); - - /// See - public static Task Messages_GetEmojiGameInfo(this Client client) - => client.Invoke(new Messages_GetEmojiGameInfo - { - }); - - /// See Possible codes: 400 (details) - public static Task Messages_SummarizeText(this Client client, InputPeer peer, int id, string to_lang = null) - => client.Invoke(new Messages_SummarizeText - { - flags = (Messages_SummarizeText.Flags)(to_lang != null ? 0x1 : 0), - peer = peer, - id = id, - to_lang = to_lang, - }); - - /// See [bots: ✓] - public static Task Messages_EditChatCreator(this Client client, InputPeer peer, InputUserBase user_id, InputCheckPasswordSRP password) - => client.Invoke(new Messages_EditChatCreator - { - peer = peer, - user_id = user_id, - password = password, - }); - - /// See [bots: ✓] - public static Task Messages_GetFutureChatCreatorAfterLeave(this Client client, InputPeer peer) - => client.Invoke(new Messages_GetFutureChatCreatorAfterLeave - { - peer = peer, - }); - - /// See [bots: ✓] - public static Task Messages_EditChatParticipantRank(this Client client, InputPeer peer, InputPeer participant, string rank) - => client.Invoke(new Messages_EditChatParticipantRank - { - peer = peer, - participant = participant, - rank = rank, - }); - - /// See [bots: ✓] - public static Task Messages_DeclineUrlAuth(this Client client, string url) - => client.Invoke(new Messages_DeclineUrlAuth - { - url = url, - }); - - /// See [bots: ✓] - public static Task Messages_CheckUrlAuthMatchCode(this Client client, string url, string match_code) - => client.Invoke(new Messages_CheckUrlAuthMatchCode - { - url = url, - match_code = match_code, - }); - - /// Returns a current state of updates. See [bots: ✓] - public static Task Updates_GetState(this Client client) - => client.Invoke(new Updates_GetState - { - }); - - /// Get new updates. See [bots: ✓] Possible codes: 400,403,500 (details) - /// PTS, see updates. - /// PTS limit - /// For fast updating: if provided and pts + pts_total_limit < remote pts, will be returned.
Simply tells the server to not return the difference if it is bigger than pts_total_limit
If the remote pts is too big (> ~4000000), this field will default to 1000000 - /// date, see updates. - /// QTS, see updates. - /// QTS limit - public static Task Updates_GetDifference(this Client client, int pts, DateTime date, int qts, int? pts_total_limit = null, int? pts_limit = null, int? qts_limit = null) - => client.Invoke(new Updates_GetDifference - { - flags = (Updates_GetDifference.Flags)((pts_total_limit != null ? 0x1 : 0) | (pts_limit != null ? 0x2 : 0) | (qts_limit != null ? 0x4 : 0)), - pts = pts, - pts_limit = pts_limit ?? default, - pts_total_limit = pts_total_limit ?? default, - date = date, - qts = qts, - qts_limit = qts_limit ?? default, - }); - - /// Returns the difference between the current state of updates of a certain channel and transmitted. See [bots: ✓] Possible codes: 400,403,406,500 (details) - /// Set to true to skip some possibly unneeded updates and reduce server-side load - /// The channel - /// Messsage filter - /// Persistent timestamp (see updates) - /// How many updates to fetch, max 100000
Ordinary (non-bot) users are supposed to pass 10-100 - public static Task Updates_GetChannelDifference(this Client client, InputChannelBase channel, ChannelMessagesFilter filter, int pts, int limit = int.MaxValue, bool force = false) - => client.Invoke(new Updates_GetChannelDifference - { - flags = (Updates_GetChannelDifference.Flags)(force ? 0x1 : 0), - channel = channel, - filter = filter, - pts = pts, - limit = limit, - }); - - /// Installs a previously uploaded photo as a profile photo. See [bots: ✓] Possible codes: 400 (details) - /// If set, the chosen profile photo will be shown to users that can't display your main profile photo due to your privacy settings. - /// Can contain info of a bot we own, to change the profile photo of that bot, instead of the current user. - /// Input photo - public static Task Photos_UpdateProfilePhoto(this Client client, InputPhoto id, InputUserBase bot = null, bool fallback = false) - => client.Invoke(new Photos_UpdateProfilePhoto - { - flags = (Photos_UpdateProfilePhoto.Flags)((bot != null ? 0x2 : 0) | (fallback ? 0x1 : 0)), - bot = bot, - id = id, - }); - - /// Updates current user profile photo. See [bots: ✓] Possible codes: 400 (details) - /// If set, the chosen profile photo will be shown to users that can't display your main profile photo due to your privacy settings. - /// Can contain info of a bot we own, to change the profile photo of that bot, instead of the current user. - /// Profile photo - /// Animated profile picture video - /// Floating point UNIX timestamp in seconds, indicating the frame of the video/sticker that should be used as static preview; can only be used if video or video_emoji_markup is set. - /// Animated sticker profile picture, must contain either a or a . - public static Task Photos_UploadProfilePhoto(this Client client, InputFileBase file = null, InputFileBase video = null, double? video_start_ts = null, VideoSizeBase video_emoji_markup = null, InputUserBase bot = 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) | (video_emoji_markup != null ? 0x10 : 0) | (bot != null ? 0x20 : 0) | (fallback ? 0x8 : 0)), - bot = bot, - file = file, - video = video, - video_start_ts = video_start_ts ?? default, - video_emoji_markup = video_emoji_markup, - }); - - /// Deletes profile photos. The method returns a list of successfully deleted photo IDs. See - /// Input photos to delete - public static Task Photos_DeletePhotos(this Client client, params InputPhoto[] id) - => client.Invoke(new Photos_DeletePhotos - { - id = id, - }); - - /// Returns the list of user photos. See [bots: ✓] Possible codes: 400 (details) - /// User ID - /// Number of list elements to be skipped - /// If a positive value was transferred, the method will return only photos with IDs less than the set one. This parameter is often useful when refetching file references », as in conjuction with limit=1 and offset=-1 the object with the id specified in max_id can be fetched. - /// Number of list elements to be returned - public static Task Photos_GetUserPhotos(this Client client, InputUserBase user_id, int offset = default, long max_id = default, int limit = int.MaxValue) - => client.Invoke(new Photos_GetUserPhotos - { - user_id = user_id, - offset = offset, - max_id = max_id, - limit = limit, - }); - - /// Upload a custom profile picture for a contact, or suggest a new profile picture to a contact. See Possible codes: 400 (details) - /// If set, will send a service message to user_id, suggesting them to use the specified profile picture; otherwise, will set a personal profile picture for the user (only visible to the current user). - /// If set, removes a previously set personal profile picture (does not affect suggested profile pictures, to remove them simply delete the service message with Messages_DeleteMessages). - /// The contact - /// Profile photo - /// Animated profile picture video - /// Floating point UNIX timestamp in seconds, indicating the frame of the video/sticker that should be used as static preview; can only be used if video or video_emoji_markup is set. - /// Animated sticker profile picture, must contain either a or a . - public static Task Photos_UploadContactProfilePhoto(this Client client, InputUserBase user_id, InputFileBase file = null, InputFileBase video = null, double? video_start_ts = null, VideoSizeBase video_emoji_markup = null, bool suggest = false, bool save = false) - => client.Invoke(new Photos_UploadContactProfilePhoto - { - flags = (Photos_UploadContactProfilePhoto.Flags)((file != null ? 0x1 : 0) | (video != null ? 0x2 : 0) | (video_start_ts != null ? 0x4 : 0) | (video_emoji_markup != null ? 0x20 : 0) | (suggest ? 0x8 : 0) | (save ? 0x10 : 0)), - user_id = user_id, - file = file, - video = video, - video_start_ts = video_start_ts ?? default, - video_emoji_markup = video_emoji_markup, - }); - - /// Saves a part of file for further sending to one of the methods. See [bots: ✓] Possible codes: 400 (details) - /// Random file identifier created by the client - /// Numerical order of a part - /// Binary data, content of a part - public static Task Upload_SaveFilePart(this Client client, long file_id, int file_part, byte[] bytes) - => client.Invoke(new Upload_SaveFilePart - { - file_id = file_id, - file_part = file_part, - bytes = bytes, - }); - - /// Returns content of a whole file or its part. See [bots: ✓] Possible codes: 400,406,420 (details) - /// Disable some checks on limit and offset values, useful for example to stream videos by keyframes - /// Whether the current client supports CDN downloads - /// File location - /// Number of bytes to be skipped - /// Number of bytes to be returned - public static Task Upload_GetFile(this Client client, InputFileLocationBase location, long offset = default, int limit = int.MaxValue, bool precise = false, bool cdn_supported = false) - => client.Invoke(new Upload_GetFile - { - flags = (Upload_GetFile.Flags)((precise ? 0x1 : 0) | (cdn_supported ? 0x2 : 0)), - location = location, - offset = offset, - limit = limit, - }); - - /// Saves a part of a large file (over 10 MB in size) to be later passed to one of the methods. See [bots: ✓] Possible codes: 400 (details) - /// Random file id, created by the client - /// Part sequence number - /// Total number of parts - /// Binary data, part contents - public static Task Upload_SaveBigFilePart(this Client client, long file_id, int file_part, int file_total_parts, byte[] bytes) - => client.Invoke(new Upload_SaveBigFilePart - { - file_id = file_id, - file_part = file_part, - file_total_parts = file_total_parts, - bytes = bytes, - }); - - /// Returns content of a web file, by proxying the request through telegram, see the webfile docs for more info. See Possible codes: 400 (details) - /// The file to download - /// Number of bytes to be skipped - /// Number of bytes to be returned - public static Task Upload_GetWebFile(this Client client, InputWebFileLocationBase location, int offset = default, int limit = int.MaxValue) - => client.Invoke(new Upload_GetWebFile - { - location = location, - offset = offset, - limit = limit, - }); - - /// Download a CDN file. See Possible codes: 400,404 (details) - /// File token - /// Offset of chunk to download - /// Length of chunk to download - public static Task Upload_GetCdnFile(this Client client, byte[] file_token, long offset = default, int limit = int.MaxValue) - => client.Invoke(new Upload_GetCdnFile - { - file_token = file_token, - offset = offset, - limit = limit, - }); - - /// Request a reupload of a certain file to a CDN DC. See [bots: ✓] Possible codes: 400,500 (details) - /// File token - /// Request token - public static Task Upload_ReuploadCdnFile(this Client client, byte[] file_token, byte[] request_token) - => client.Invoke(new Upload_ReuploadCdnFile - { - file_token = file_token, - request_token = request_token, - }); - - /// Get SHA256 hashes for verifying downloaded CDN files See [bots: ✓] Possible codes: 400 (details) - /// File - /// Offset from which to start getting hashes - public static Task Upload_GetCdnFileHashes(this Client client, byte[] file_token, long offset = default) - => client.Invoke(new Upload_GetCdnFileHashes - { - file_token = file_token, - offset = offset, - }); - - /// Get SHA256 hashes for verifying downloaded files See [bots: ✓] Possible codes: 400 (details) - /// File - /// Offset from which to get file hashes - public static Task Upload_GetFileHashes(this Client client, InputFileLocationBase location, long offset = default) - => client.Invoke(new Upload_GetFileHashes - { - location = location, - offset = offset, - }); - - /// Returns current configuration, including data center configuration. See [bots: ✓] Possible codes: 400,403 (details) - public static Task Help_GetConfig(this Client client) - => client.Invoke(new Help_GetConfig - { - }); - - /// Returns info on data center nearest to the user. See - public static Task Help_GetNearestDc(this Client client) - => client.Invoke(new Help_GetNearestDc - { - }); - - /// Returns information on update availability for the current application. See - /// Source - /// a null value means help.noAppUpdate - public static Task Help_GetAppUpdate(this Client client, string source) - => client.Invoke(new Help_GetAppUpdate - { - source = source, - }); - - /// Returns localized text of a text message with an invitation. See - public static Task Help_GetInviteText(this Client client) - => client.Invoke(new Help_GetInviteText - { - }); - - /// Returns the support user for the "ask a question" feature. See - public static Task Help_GetSupport(this Client client) - => client.Invoke(new Help_GetSupport - { - }); - - /// Informs the server about the number of pending bot updates if they haven't been processed for a long time; for bots only See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Number of pending updates - /// Error message, if present - public static Task Help_SetBotUpdatesStatus(this Client client, int pending_updates_count, string message) - => client.Invoke(new Help_SetBotUpdatesStatus - { - pending_updates_count = pending_updates_count, - message = message, - }); - - /// Get configuration for CDN file downloads. See [bots: ✓] - public static Task Help_GetCdnConfig(this Client client) - => client.Invoke(new Help_GetCdnConfig - { - }); - - /// Get recently used t.me links. See - /// Referrer - public static Task Help_GetRecentMeUrls(this Client client, string referer) - => client.Invoke(new Help_GetRecentMeUrls - { - referer = referer, - }); - - /// Look for updates of telegram's terms of service See - public static Task Help_GetTermsOfServiceUpdate(this Client client) - => client.Invoke(new Help_GetTermsOfServiceUpdate - { - }); - - /// Accept the new terms of service See Possible codes: 400 (details) - /// ID of terms of service - public static Task Help_AcceptTermsOfService(this Client client, DataJSON id) - => client.Invoke(new Help_AcceptTermsOfService - { - id = id, - }); - - /// Get info about an unsupported deep link, see here for more info ». See - /// Path component of a tg: link - /// a null value means help.deepLinkInfoEmpty - public static Task Help_GetDeepLinkInfo(this Client client, string path) - => client.Invoke(new Help_GetDeepLinkInfo - { - path = path, - }); - - /// Get app-specific configuration, see client configuration for more info on the result. See - /// Hash used for caching, for more info click here. - /// a null value means help.appConfigNotModified - public static Task Help_GetAppConfig(this Client client, int hash = default) - => client.Invoke(new Help_GetAppConfig - { - hash = hash, - }); - - /// Saves logs of application on the server. See - /// List of input events - public static Task Help_SaveAppLog(this Client client, params InputAppEvent[] events) - => client.Invoke(new Help_SaveAppLog - { - events = events, - }); - - /// Get passport configuration See - /// Hash used for caching, for more info click here. - /// a null value means help.passportConfigNotModified - public static Task Help_GetPassportConfig(this Client client, int hash = default) - => client.Invoke(new Help_GetPassportConfig - { - hash = hash, - }); - - /// Get localized name of the telegram support user See Possible codes: 403 (details) - public static Task Help_GetSupportName(this Client client) - => client.Invoke(new Help_GetSupportName - { - }); - - /// Can only be used by TSF members to obtain internal information. See Possible codes: 403 (details) - /// User ID - /// a null value means help.userInfoEmpty - public static Task Help_GetUserInfo(this Client client, InputUserBase user_id) - => client.Invoke(new Help_GetUserInfo - { - user_id = user_id, - }); - - /// Internal use See Possible codes: 400,403 (details) - /// User - /// Message - /// Message entities for styled text - /// a null value means help.userInfoEmpty - public static Task Help_EditUserInfo(this Client client, InputUserBase user_id, string message, params MessageEntity[] entities) - => client.Invoke(new Help_EditUserInfo - { - user_id = user_id, - message = message, - entities = entities, - }); - - /// Returns a set of useful suggestions and PSA/MTProxy sponsored peers, see here » for more info. See - public static Task Help_GetPromoData(this Client client) - => client.Invoke(new Help_GetPromoData - { - }); - - /// Hide MTProxy/Public Service Announcement information See - /// Peer to hide - public static Task Help_HidePromoData(this Client client, InputPeer peer) - => client.Invoke(new Help_HidePromoData - { - peer = peer, - }); - - /// Dismiss a suggestion, see here for more info ». See - /// 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 - { - peer = peer, - suggestion = suggestion, - }); - - /// Get name, ISO code, localized name and phone codes/patterns of all available countries See - /// Language code of the current user - /// Hash used for caching, for more info click here. - /// a null value means help.countriesListNotModified - public static Task Help_GetCountriesList(this Client client, string lang_code, int hash = default) - => client.Invoke(new Help_GetCountriesList - { - lang_code = lang_code, - hash = hash, - }); - - /// Get Telegram Premium promotion information See - public static Task Help_GetPremiumPromo(this Client client) - => client.Invoke(new Help_GetPremiumPromo - { - }); - - /// Get the set of accent color palettes » that can be used for message accents. See - /// Hash used for caching, for more info click here. - /// a null value means help.peerColorsNotModified - public static Task Help_GetPeerColors(this Client client, int hash = default) - => client.Invoke(new Help_GetPeerColors - { - hash = hash, - }); - - /// Get the set of accent color palettes » that can be used in profile page backgrounds. See - /// Hash used for caching, for more info click here. - /// a null value means help.peerColorsNotModified - public static Task Help_GetPeerProfileColors(this Client client, int hash = default) - => client.Invoke(new Help_GetPeerProfileColors - { - hash = hash, - }); - - /// Returns timezone information that may be used elsewhere in the API, such as to set Telegram Business opening hours ». See - /// Hash used for caching, for more info click here. - /// a null value means help.timezonesListNotModified - public static Task Help_GetTimezonesList(this Client client, int hash = default) - => client.Invoke(new Help_GetTimezonesList - { - hash = hash, - }); - - /// Mark channel/supergroup history as read See Possible codes: 400,406 (details) - /// Channel/supergroup - /// ID of message up to which messages should be marked as read - public static Task Channels_ReadHistory(this Client client, InputChannelBase channel, int max_id = default) - => client.Invoke(new Channels_ReadHistory - { - channel = channel, - max_id = max_id, - }); - - /// Delete messages in a channel/supergroup See [bots: ✓] Possible codes: 400,403,406,420 (details) - /// Channel/supergroup - /// IDs of messages to delete - public static Task Channels_DeleteMessages(this Client client, InputChannelBase channel, params int[] id) - => client.InvokeAffected(new Channels_DeleteMessages - { - channel = channel, - id = id, - }, channel.ChannelId); - - /// Reports some messages from a user in a supergroup as spam; requires administrator rights in the supergroup See Possible codes: 400 (details) - /// Supergroup - /// Participant whose messages should be reported - /// IDs of spam messages - public static Task Channels_ReportSpam(this Client client, InputChannelBase channel, InputPeer participant, params int[] id) - => client.Invoke(new Channels_ReportSpam - { - channel = channel, - participant = participant, - id = id, - }); - - /// Get channel/supergroup messages See [bots: ✓] Possible codes: 400,406 (details) - /// Channel/supergroup - /// IDs of messages to get - public static Task Channels_GetMessages(this Client client, InputChannelBase channel, params InputMessage[] id) - => client.Invoke(new Channels_GetMessages - { - channel = channel, - id = id, - }); - - /// Get the participants of a supergroup/channel See [bots: ✓] Possible codes: 400,403,406 (details) - /// Channel - /// Which participant types to fetch - /// Offset - /// Limit - /// Hash - /// a null value means channels.channelParticipantsNotModified - public static Task Channels_GetParticipants(this Client client, InputChannelBase channel, ChannelParticipantsFilter filter, int offset = default, int limit = int.MaxValue, long hash = default) - => client.Invoke(new Channels_GetParticipants - { - channel = channel, - filter = filter, - offset = offset, - limit = limit, - hash = hash, - }); - - /// Get info about a channel/supergroup participant See [bots: ✓] Possible codes: 400,403,406 (details) - /// Channel/supergroup - /// Participant to get info about - public static Task Channels_GetParticipant(this Client client, InputChannelBase channel, InputPeer participant) - => client.Invoke(new Channels_GetParticipant - { - channel = channel, - participant = participant, - }); - - /// Get info about channels/supergroups See [bots: ✓] Possible codes: 400,406 (details) - /// IDs of channels/supergroups to get info about - public static Task Channels_GetChannels(this Client client, params InputChannelBase[] id) - => client.Invoke(new Channels_GetChannels - { - id = id, - }); - - /// Get full info about a supergroup, gigagroup or channel See [bots: ✓] Possible codes: 400,403,406 (details) - /// The channel, supergroup or gigagroup to get info about - public static Task Channels_GetFullChannel(this Client client, InputChannelBase channel) - => client.Invoke(new Channels_GetFullChannel - { - channel = channel, - }); - - /// Create a supergroup/channel. See Possible codes: 400,406,500 (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 to create a forum - /// Channel title - /// Channel description - /// Geogroup location, see here » for more info on geogroups. - /// Geogroup address, see here » for more info on geogroups. - /// Time-to-live of all messages that will be sent in the supergroup: once message.date+message.ttl_period === time(), the message will be deleted on the server, and must be deleted locally as well. You can use Messages_SetDefaultHistoryTTL to edit this value later. - public static Task Channels_CreateChannel(this Client client, string title, string about, InputGeoPoint geo_point = null, string address = null, int? ttl_period = null, bool broadcast = false, bool megagroup = false, bool for_import = false, bool forum = false) - => client.Invoke(new Channels_CreateChannel - { - flags = (Channels_CreateChannel.Flags)((geo_point != null ? 0x4 : 0) | (address != null ? 0x4 : 0) | (ttl_period != null ? 0x10 : 0) | (broadcast ? 0x1 : 0) | (megagroup ? 0x2 : 0) | (for_import ? 0x8 : 0) | (forum ? 0x20 : 0)), - title = title, - about = about, - geo_point = geo_point, - address = address, - ttl_period = ttl_period ?? default, - }); - - /// Modify the admin rights of a user in a supergroup/channel. See [bots: ✓] Possible codes: 400,403,406 (details) - /// The supergroup/channel. - /// The ID of the user whose admin rights should be modified - /// The admin rights - /// Indicates the role (rank) of the admin in the group: just an arbitrary string - public static Task Channels_EditAdmin(this Client client, InputChannelBase channel, InputUserBase user_id, ChatAdminRights admin_rights, string rank = null) - => client.Invoke(new Channels_EditAdmin - { - flags = (Channels_EditAdmin.Flags)(rank != null ? 0x1 : 0), - channel = channel, - user_id = user_id, - admin_rights = admin_rights, - rank = rank, - }); - - /// Edit the name of a channel/supergroup See [bots: ✓] Possible codes: 400,403 (details) - /// Channel/supergroup - /// New name - public static Task Channels_EditTitle(this Client client, InputChannelBase channel, string title) - => client.Invoke(new Channels_EditTitle - { - channel = channel, - title = title, - }); - - /// Change the photo of a channel/supergroup See [bots: ✓] Possible codes: 400,403 (details) - /// Channel/supergroup whose photo should be edited - /// New photo - public static Task Channels_EditPhoto(this Client client, InputChannelBase channel, InputChatPhotoBase photo) - => client.Invoke(new Channels_EditPhoto - { - channel = channel, - photo = photo, - }); - - /// Check if a username is free and can be assigned to a channel/supergroup See Possible codes: 400 (details) - /// The channel/supergroup that will assigned the specified username - /// The username to check - public static Task Channels_CheckUsername(this Client client, InputChannelBase channel, string username) - => client.Invoke(new Channels_CheckUsername - { - channel = channel, - username = username, - }); - - /// Change or remove the username of a supergroup/channel See Possible codes: 400,403 (details) - /// Channel - /// New username, pass an empty string to remove the username - public static Task Channels_UpdateUsername(this Client client, InputChannelBase channel, string username) - => client.Invoke(new Channels_UpdateUsername - { - channel = channel, - username = username, - }); - - /// Join a channel/supergroup See Possible codes: 400,406,420 (details) - /// Channel/supergroup to join - public static Task Channels_JoinChannel(this Client client, InputChannelBase channel) - => client.Invoke(new Channels_JoinChannel - { - channel = channel, - }); - - /// Leave a channel/supergroup See [bots: ✓] Possible codes: 400,403,406 (details) - /// Channel/supergroup to leave - public static Task Channels_LeaveChannel(this Client client, InputChannelBase channel) - => client.Invoke(new Channels_LeaveChannel - { - channel = channel, - }); - - /// Invite users to a channel/supergroup See Possible codes: 400,403,406 (details) - /// Channel/supergroup - /// Users to invite - public static Task Channels_InviteToChannel(this Client client, InputChannelBase channel, params InputUserBase[] users) - => client.Invoke(new Channels_InviteToChannel - { - channel = channel, - users = users, - }); - - /// Delete a channel/supergroup See Possible codes: 400,403,406 (details) - /// Channel/supergroup to delete - public static Task Channels_DeleteChannel(this Client client, InputChannelBase channel) - => client.Invoke(new Channels_DeleteChannel - { - channel = channel, - }); - - /// Get link and embed info of a message in a channel/supergroup See Possible codes: 400 (details) - /// Whether to include other grouped media (for albums) - /// Whether to also include a thread ID, if available, inside of the link - /// Channel - /// Message ID - public static Task Channels_ExportMessageLink(this Client client, InputChannelBase channel, int id, bool grouped = false, bool thread = false) - => client.Invoke(new Channels_ExportMessageLink - { - flags = (Channels_ExportMessageLink.Flags)((grouped ? 0x1 : 0) | (thread ? 0x2 : 0)), - channel = channel, - id = id, - }); - - /// Enable/disable message signatures in channels See Possible codes: 400 (details) - /// If set, enables message signatures. - /// If set, messages from channel admins will link to their profiles, just like for group messages: can only be set if the signatures_enabled flag is set. - /// Channel - public static Task Channels_ToggleSignatures(this Client client, InputChannelBase channel, bool signatures_enabled = false, bool profiles_enabled = false) - => client.Invoke(new Channels_ToggleSignatures - { - flags = (Channels_ToggleSignatures.Flags)((signatures_enabled ? 0x1 : 0) | (profiles_enabled ? 0x2 : 0)), - channel = channel, - }); - - /// 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. - /// Set this flag to only fetch the full list of channels that may be passed to Account_UpdatePersonalChannel to display them on our profile page. - public static Task Channels_GetAdminedPublicChannels(this Client client, bool by_location = false, bool check_limit = false, bool for_personal = false) - => client.Invoke(new Channels_GetAdminedPublicChannels - { - flags = (Channels_GetAdminedPublicChannels.Flags)((by_location ? 0x1 : 0) | (check_limit ? 0x2 : 0) | (for_personal ? 0x4 : 0)), - }); - - /// Ban/unban/kick a user in a supergroup/channel. See [bots: ✓] Possible codes: 400,403,406 (details) - /// The supergroup/channel. - /// Participant to ban - /// The banned rights - public static Task Channels_EditBanned(this Client client, InputChannelBase channel, InputPeer participant, ChatBannedRights banned_rights) - => client.Invoke(new Channels_EditBanned - { - channel = channel, - participant = participant, - banned_rights = banned_rights, - }); - - /// Get the admin log of a channel/supergroup See Possible codes: 400,403,406 (details) - /// Channel - /// Search query, can be empty - /// Event filter - /// Only show events from these admins - /// Maximum ID of message to return (see pagination) - /// Minimum ID of message to return (see pagination) - /// Maximum number of results to return, see pagination - public static Task Channels_GetAdminLog(this Client client, InputChannelBase channel, string q, long max_id = default, long min_id = default, int limit = int.MaxValue, ChannelAdminLogEventsFilter events_filter = null, InputUserBase[] admins = null) - => client.Invoke(new Channels_GetAdminLog - { - flags = (Channels_GetAdminLog.Flags)((events_filter != null ? 0x1 : 0) | (admins != null ? 0x2 : 0)), - channel = channel, - q = q, - events_filter = events_filter, - admins = admins, - max_id = max_id, - min_id = min_id, - limit = limit, - }); - - /// Associate a stickerset to the supergroup See [bots: ✓] Possible codes: 400,406 (details) - /// Supergroup - /// The stickerset to associate - public static Task Channels_SetStickers(this Client client, InputChannelBase channel, InputStickerSet stickerset) - => client.Invoke(new Channels_SetStickers - { - channel = channel, - stickerset = stickerset, - }); - - /// Mark channel/supergroup message contents as read, emitting an . See Possible codes: 400,406 (details) - /// Channel/supergroup - /// IDs of messages whose contents should be marked as read - public static Task Channels_ReadMessageContents(this Client client, InputChannelBase channel, params int[] id) - => client.Invoke(new Channels_ReadMessageContents - { - channel = channel, - id = id, - }); - - /// Delete the history of a supergroup See Possible codes: 400 (details) - /// Whether the history should be deleted for everyone - /// Supergroup whose history must be deleted - /// ID of message up to which the history must be deleted - public static Task Channels_DeleteHistory(this Client client, InputChannelBase channel, int max_id = default, bool for_everyone = false) - => client.Invoke(new Channels_DeleteHistory - { - flags = (Channels_DeleteHistory.Flags)(for_everyone ? 0x1 : 0), - channel = channel, - max_id = max_id, - }); - - /// Hide/unhide message history for new channel/supergroup users See Possible codes: 400 (details) - /// Channel/supergroup - /// Hide/unhide - public static Task Channels_TogglePreHistoryHidden(this Client client, InputChannelBase channel, bool enabled) - => client.Invoke(new Channels_TogglePreHistoryHidden - { - channel = channel, - enabled = enabled, - }); - - /// Get a list of channels/supergroups we left, requires a takeout session, see here » for more info. See Possible codes: 400,403 (details) - /// Offset for pagination - public static Task Channels_GetLeftChannels(this Client client, int offset = default) - => client.Invoke(new Channels_GetLeftChannels - { - offset = offset, - }); - - /// Get all groups that can be used as discussion groups. See - public static Task Channels_GetGroupsForDiscussion(this Client client) - => client.Invoke(new Channels_GetGroupsForDiscussion - { - }); - - /// Associate a group to a channel as discussion group for that channel See Possible codes: 400,403 (details) - /// Channel - /// Discussion group to associate to the channel - public static Task Channels_SetDiscussionGroup(this Client client, InputChannelBase broadcast, InputChannelBase group) - => client.Invoke(new Channels_SetDiscussionGroup - { - broadcast = broadcast, - group = group, - }); - - /// Edit location of geogroup, see here » for more info on geogroups. See Possible codes: 400 (details) - /// Geogroup - /// New geolocation - /// Address string - public static Task Channels_EditLocation(this Client client, InputChannelBase channel, InputGeoPoint geo_point, string address) - => client.Invoke(new Channels_EditLocation - { - channel = channel, - geo_point = geo_point, - address = address, - }); - - /// Toggle supergroup slow mode: if enabled, users will only be able to send one message every seconds seconds See Possible codes: 400 (details) - /// The supergroup - /// Users will only be able to send one message every seconds seconds, 0 to disable the limitation - public static Task Channels_ToggleSlowMode(this Client client, InputChannelBase channel, int seconds) - => client.Invoke(new Channels_ToggleSlowMode - { - channel = channel, - seconds = seconds, - }); - - /// Get inactive channels and supergroups See - public static Task Channels_GetInactiveChannels(this Client client) - => client.Invoke(new Channels_GetInactiveChannels - { - }); - - /// Convert a supergroup to a gigagroup, when requested by channel suggestions. See Possible codes: 400,403 (details) - /// The supergroup to convert - public static Task Channels_ConvertToGigagroup(this Client client, InputChannelBase channel) - => client.Invoke(new Channels_ConvertToGigagroup - { - channel = channel, - }); - - /// Obtains a list of peers that can be used to send messages in a specific group See Possible codes: 400 (details) - /// If set, fetches the list of peers that can be used to send paid reactions to messages of a specific peer. - /// The group where we intend to send messages - public static Task Channels_GetSendAs(this Client client, InputPeer peer, bool for_paid_reactions = false, bool for_live_stories = false) - => client.Invoke(new Channels_GetSendAs - { - flags = (Channels_GetSendAs.Flags)((for_paid_reactions ? 0x1 : 0) | (for_live_stories ? 0x2 : 0)), - peer = peer, - }); - - /// Delete all messages sent by a specific participant of a given supergroup See Possible codes: 400,403 (details) - /// Supergroup - /// The participant whose messages should be deleted - public static Task Channels_DeleteParticipantHistory(this Client client, InputChannelBase channel, InputPeer participant) - => client.InvokeAffected(new Channels_DeleteParticipantHistory - { - channel = channel, - participant = participant, - }, channel.ChannelId); - - /// Set whether all users should join a discussion group in order to comment on a post » See Possible codes: 400 (details) - /// Discussion group - /// Toggle - public static Task Channels_ToggleJoinToSend(this Client client, InputChannelBase channel, bool enabled) - => client.Invoke(new Channels_ToggleJoinToSend - { - channel = channel, - enabled = enabled, - }); - - /// Set whether all users should request admin approval to join the group ». See Possible codes: 400 (details) - /// Group - /// Toggle - public static Task Channels_ToggleJoinRequest(this Client client, InputChannelBase channel, bool enabled) - => client.Invoke(new Channels_ToggleJoinRequest - { - channel = channel, - enabled = enabled, - }); - - /// Reorder active usernames See Possible codes: 400 (details) - /// The supergroup or channel - /// The new order for active usernames. All active usernames must be specified. - public static Task Channels_ReorderUsernames(this Client client, InputChannelBase channel, params string[] order) - => client.Invoke(new Channels_ReorderUsernames - { - channel = channel, - order = order, - }); - - /// Activate or deactivate a purchased fragment.com username associated to a supergroup or channel we own. See Possible codes: 400 (details) - /// Supergroup or channel - /// Username - /// Whether to activate or deactivate the username - 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, - }); - - /// Disable all purchased usernames of a supergroup or channel See Possible codes: 400 (details) - /// Supergroup or channel - public static Task Channels_DeactivateAllUsernames(this Client client, InputChannelBase channel) - => client.Invoke(new Channels_DeactivateAllUsernames - { - channel = channel, - }); - - /// Enable or disable forum functionality in a supergroup. See Possible codes: 400 (details) - /// Supergroup ID - /// Enable or disable forum functionality - /// If true enables the tabbed forum UI, otherwise enables the list-based forum UI. - public static Task Channels_ToggleForum(this Client client, InputChannelBase channel, bool enabled, bool tabs) - => client.Invoke(new Channels_ToggleForum - { - channel = channel, - enabled = enabled, - tabs = tabs, - }); - - /// Enable or disable the native antispam system. See Possible codes: 400 (details) - /// Supergroup ID. The specified supergroup must have at least telegram_antispam_group_size_min members to enable antispam functionality, as specified by the client configuration parameters. - /// Enable or disable the native antispam system. - public static Task Channels_ToggleAntiSpam(this Client client, InputChannelBase channel, bool enabled) - => client.Invoke(new Channels_ToggleAntiSpam - { - channel = channel, - enabled = enabled, - }); - - /// Report a native antispam false positive See Possible codes: 400 (details) - /// Supergroup ID - /// Message ID that was mistakenly deleted by the native antispam system, taken from the admin log - public static Task Channels_ReportAntiSpamFalsePositive(this Client client, InputChannelBase channel, int msg_id) - => client.Invoke(new Channels_ReportAntiSpamFalsePositive - { - channel = channel, - msg_id = msg_id, - }); - - /// Hide or display the participants list in a supergroup. See Possible codes: 400 (details) - /// Supergroup ID - /// If true, will hide the participants list; otherwise will unhide it. - public static Task Channels_ToggleParticipantsHidden(this Client client, InputChannelBase channel, bool enabled) - => client.Invoke(new Channels_ToggleParticipantsHidden - { - channel = channel, - enabled = enabled, - }); - - /// Update the accent color and background custom emoji » of a channel. See Possible codes: 400 (details) - /// Whether to change the accent color emoji pattern of the profile page; otherwise, the accent color and emoji pattern of messages will be changed.
Channels can change both message and profile palettes; supergroups can only change the profile palette, of course after reaching the appropriate boost level. - /// Channel whose accent color should be changed. - /// ID of the accent color palette » to use (not RGB24, see here » for more info); if not set, the default palette is used. - /// Custom emoji ID used in the accent color pattern. - public static Task Channels_UpdateColor(this Client client, InputChannelBase channel, long? background_emoji_id = null, int? color = null, bool for_profile = false) - => client.Invoke(new Channels_UpdateColor - { - flags = (Channels_UpdateColor.Flags)((background_emoji_id != null ? 0x1 : 0) | (color != null ? 0x4 : 0) | (for_profile ? 0x2 : 0)), - channel = channel, - color = color ?? default, - background_emoji_id = background_emoji_id ?? default, - }); - - /// Users may also choose to display messages from all topics of a forum as if they were sent to a normal group, using a "View as messages" setting in the local client: this setting only affects the current account, and is synced to other logged in sessions using this method. See Possible codes: 400 (details) - /// The forum - /// The new value of the view_forum_as_messages flag. - public static Task Channels_ToggleViewForumAsMessages(this Client client, InputChannelBase channel, bool enabled) - => client.Invoke(new Channels_ToggleViewForumAsMessages - { - channel = channel, - enabled = enabled, - }); - - /// Obtain a list of similarly themed public channels, selected based on similarities in their subscriber bases. See Possible codes: 400 (details) - /// The method will return channels related to the passed channel. If not set, the method will returns channels related to channels the user has joined. - public static Task Channels_GetChannelRecommendations(this Client client, InputChannelBase channel = null) - => client.Invoke(new Channels_GetChannelRecommendations - { - flags = (Channels_GetChannelRecommendations.Flags)(channel != null ? 0x1 : 0), - channel = channel, - }); - - /// Set an emoji status for a channel or supergroup. See Possible codes: 400 (details) - /// The channel/supergroup, must have at least channel_emoji_status_level_min/group_emoji_status_level_min boosts. - /// Emoji status to set - public static Task Channels_UpdateEmojiStatus(this Client client, InputChannelBase channel, EmojiStatusBase emoji_status) - => client.Invoke(new Channels_UpdateEmojiStatus - { - channel = channel, - emoji_status = emoji_status, - }); - - /// Admins with ban_users admin rights » may allow users that apply a certain number of booosts » to the group to bypass Channels_ToggleSlowMode and other » supergroup restrictions, see here » for more info. See Possible codes: 400 (details) - /// The supergroup. - /// The number of required boosts (1-8, 0 to disable). - public static Task Channels_SetBoostsToUnblockRestrictions(this Client client, InputChannelBase channel, int boosts) - => client.Invoke(new Channels_SetBoostsToUnblockRestrictions - { - channel = channel, - boosts = boosts, - }); - - /// Set a custom emoji stickerset for supergroups. Only usable after reaching at least the boost level » specified in the group_emoji_stickers_level_min » config parameter. See Possible codes: 400 (details) - /// The supergroup - /// The custom emoji stickerset to associate to the supergroup - public static Task Channels_SetEmojiStickers(this Client client, InputChannelBase channel, InputStickerSet stickerset) - => client.Invoke(new Channels_SetEmojiStickers - { - channel = channel, - stickerset = stickerset, - }); - - /// Disable ads on the specified channel, for all users. See Possible codes: 400 (details) - /// The channel. - /// Whether to disable or re-enable ads. - public static Task Channels_RestrictSponsoredMessages(this Client client, InputChannelBase channel, bool restricted) - => client.Invoke(new Channels_RestrictSponsoredMessages - { - channel = channel, - restricted = restricted, - }); - - /// Globally search for posts from public channels » (including those we aren't a member of) containing either a specific hashtag, or a full text query. See Possible codes: 403,420 (details) - /// The hashtag to search, without the # character. - /// The full text query: each user has a limited amount of free full text search slots, after which payment is required, see here » for more info on the full flow. - /// Initially 0, then set to the next_rate parameter of messages.messagesSlice, or if that is absent, the date of the last returned message. - /// Offsets for pagination, for more info click here - /// Offsets for pagination, for more info click here - /// Maximum number of results to return, see pagination - /// For full text post searches (query), allows payment of the specified amount of Stars for the search, see here » for more info on the full flow. - public static Task Channels_SearchPosts(this Client client, int offset_rate = default, InputPeer offset_peer = null, int offset_id = default, int limit = int.MaxValue, string hashtag = null, string query = null, long? allow_paid_stars = null) - => client.Invoke(new Channels_SearchPosts - { - flags = (Channels_SearchPosts.Flags)((hashtag != null ? 0x1 : 0) | (query != null ? 0x2 : 0) | (allow_paid_stars != null ? 0x4 : 0)), - hashtag = hashtag, - query = query, - offset_rate = offset_rate, - offset_peer = offset_peer, - offset_id = offset_id, - limit = limit, - allow_paid_stars = allow_paid_stars ?? default, - }); - - /// Enable or disable paid messages » in this supergroup or monoforum. See Possible codes: 400 (details) - /// Only usable for channels, enables or disables the associated monoforum aka direct messages. - /// Pass the supergroup ID for supergroups and the ID of the channel to modify the setting in the associated monoforum. - /// Specifies the required amount of Telegram Stars users must pay to send messages to the supergroup or monoforum. - public static Task Channels_UpdatePaidMessagesPrice(this Client client, InputChannelBase channel, long send_paid_messages_stars, bool broadcast_messages_allowed = false) - => client.Invoke(new Channels_UpdatePaidMessagesPrice - { - flags = (Channels_UpdatePaidMessagesPrice.Flags)(broadcast_messages_allowed ? 0x1 : 0), - channel = channel, - send_paid_messages_stars = send_paid_messages_stars, - }); - - /// Toggle autotranslation in a channel, for all users: see here » for more info. See Possible codes: 400 (details) - /// The channel where to toggle autotranslation. - /// Whether to enable or disable autotranslation. - public static Task Channels_ToggleAutotranslation(this Client client, InputChannelBase channel, bool enabled) - => client.Invoke(new Channels_ToggleAutotranslation - { - channel = channel, - enabled = enabled, - }); - - /// Can only be invoked by non-bot admins of a monoforum », obtains the original sender of a message sent by other monoforum admins to the monoforum, on behalf of the channel associated to the monoforum. See Possible codes: 400 (details) - /// ID of the monoforum. - /// ID of the message sent by a monoforum admin. - public static Task Channels_GetMessageAuthor(this Client client, InputChannelBase channel, int id) - => client.Invoke(new Channels_GetMessageAuthor - { - channel = channel, - id = id, - }); - - /// Check if the specified global post search » requires payment. See - /// The query. - public static Task Channels_CheckSearchPostsFlood(this Client client, string query = null) - => client.Invoke(new Channels_CheckSearchPostsFlood - { - flags = (Channels_CheckSearchPostsFlood.Flags)(query != null ? 0x1 : 0), - query = query, - }); - - /// Changes the main profile tab of a channel, see here » for more info. See Possible codes: 400 (details) - /// The channel. - /// The tab to set as main tab. - public static Task Channels_SetMainProfileTab(this Client client, InputChannelBase channel, ProfileTab tab) - => client.Invoke(new Channels_SetMainProfileTab - { - channel = channel, - tab = tab, - }); - - /// Sends a custom request; for bots only See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// The method name - /// JSON-serialized method parameters - public static Task Bots_SendCustomRequest(this Client client, string custom_method, DataJSON params_) - => client.Invoke(new Bots_SendCustomRequest - { - custom_method = custom_method, - params_ = params_, - }); - - /// Answers a custom query; for bots only See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Identifier of a custom query - /// JSON-serialized answer to the query - public static Task Bots_AnswerWebhookJSONQuery(this Client client, long query_id, DataJSON data) - => client.Invoke(new Bots_AnswerWebhookJSONQuery - { - query_id = query_id, - data = data, - }); - - /// Set bot command list See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Command scope - /// Language code - /// Bot commands - public static Task Bots_SetBotCommands(this Client client, BotCommandScope scope, string lang_code, params BotCommand[] commands) - => client.Invoke(new Bots_SetBotCommands - { - scope = scope, - lang_code = lang_code, - commands = commands, - }); - - /// Clear bot commands for the specified bot scope and language code See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Command scope - /// Language code - public static Task Bots_ResetBotCommands(this Client client, BotCommandScope scope, string lang_code) - => client.Invoke(new Bots_ResetBotCommands - { - scope = scope, - lang_code = lang_code, - }); - - /// Obtain a list of bot commands for the specified bot scope and language code See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Command scope - /// Language code - public static Task Bots_GetBotCommands(this Client client, BotCommandScope scope, string lang_code) - => client.Invoke(new Bots_GetBotCommands - { - scope = scope, - lang_code = lang_code, - }); - - /// Sets the menu button action » for a given user or for all users See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// User ID - /// Bot menu button action - public static Task Bots_SetBotMenuButton(this Client client, InputUserBase user_id, BotMenuButtonBase button) - => client.Invoke(new Bots_SetBotMenuButton - { - user_id = user_id, - 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: ✓ users: ✗] 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 - { - user_id = user_id, - }); - - /// Set the default suggested admin rights for bots being added as admins to channels, see here for more info on how to handle them ». See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Admin rights - public static Task Bots_SetBotBroadcastDefaultAdminRights(this Client client, ChatAdminRights admin_rights) - => client.Invoke(new Bots_SetBotBroadcastDefaultAdminRights - { - admin_rights = admin_rights, - }); - - /// Set the default suggested admin rights for bots being added as admins to groups, see here for more info on how to handle them ». See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Admin rights - public static Task Bots_SetBotGroupDefaultAdminRights(this Client client, ChatAdminRights admin_rights) - => client.Invoke(new Bots_SetBotGroupDefaultAdminRights - { - admin_rights = admin_rights, - }); - - /// Set localized name, about text and description of a bot (or of the current account, if called by a bot). See [bots: ✓] Possible codes: 400 (details) - /// If called by a user, must contain the peer of a bot we own. - /// Language code, if left empty update the fallback about text and description - /// New bot name - /// New about text - /// New description - public static Task Bots_SetBotInfo(this Client client, string lang_code, string about = null, string description = null, InputUserBase bot = null, string name = null) - => client.Invoke(new Bots_SetBotInfo - { - flags = (Bots_SetBotInfo.Flags)((about != null ? 0x1 : 0) | (description != null ? 0x2 : 0) | (bot != null ? 0x4 : 0) | (name != null ? 0x8 : 0)), - bot = bot, - lang_code = lang_code, - name = name, - about = about, - description = description, - }); - - /// Get localized name, about text and description of a bot (or of the current account, if called by a bot). See [bots: ✓] Possible codes: 400 (details) - /// If called by a user, must contain the peer of a bot we own. - /// Language code, if left empty this method will return the fallback about text and description. - public static Task Bots_GetBotInfo(this Client client, string lang_code, InputUserBase bot = null) - => client.Invoke(new Bots_GetBotInfo - { - flags = (Bots_GetBotInfo.Flags)(bot != null ? 0x1 : 0), - bot = bot, - lang_code = lang_code, - }); - - /// Reorder usernames associated to a bot we own. See Possible codes: 400 (details) - /// The bot - /// The new order for active usernames. All active usernames must be specified. - public static Task Bots_ReorderUsernames(this Client client, InputUserBase bot, params string[] order) - => client.Invoke(new Bots_ReorderUsernames - { - bot = bot, - order = order, - }); - - /// Activate or deactivate a purchased fragment.com username associated to a bot we own. See Possible codes: 400 (details) - /// The bot - /// Username - /// Whether to activate or deactivate it - public static Task Bots_ToggleUsername(this Client client, InputUserBase bot, string username, bool active) - => client.Invoke(new Bots_ToggleUsername - { - bot = bot, - username = username, - active = active, - }); - - /// Check whether the specified bot can send us messages See Possible codes: 400 (details) - /// The bot - public static Task Bots_CanSendMessage(this Client client, InputUserBase bot) - => client.Invoke(new Bots_CanSendMessage - { - bot = bot, - }); - - /// Allow the specified bot to send us messages See Possible codes: 400 (details) - /// The bot - public static Task Bots_AllowSendMessage(this Client client, InputUserBase bot) - => client.Invoke(new Bots_AllowSendMessage - { - bot = bot, - }); - - /// Send a custom request from a mini bot app, triggered by a web_app_invoke_custom_method event ». See Possible codes: 400 (details) - /// Identifier of the bot associated to the mini bot app - /// Identifier of the custom method to invoke - /// Method parameters - public static Task Bots_InvokeWebViewCustomMethod(this Client client, InputUserBase bot, string custom_method, DataJSON params_) - => client.Invoke(new Bots_InvokeWebViewCustomMethod - { - bot = bot, - custom_method = custom_method, - params_ = params_, - }); - - /// Fetch popular Main Mini Apps, to be used in the apps tab of global search ». See - /// Offset for pagination, initially an empty string, then re-use the next_offset returned by the previous query. - /// Maximum number of results to return, see pagination - public static Task Bots_GetPopularAppBots(this Client client, string offset, int limit = int.MaxValue) - => client.Invoke(new Bots_GetPopularAppBots - { - offset = offset, - limit = limit, - }); - - /// Add a main mini app preview, see here » for more info. See Possible codes: 400 (details) - /// The bot that owns the Main Mini App. - /// ISO 639-1 language code, indicating the localization of the preview to add. - /// The photo/video preview, uploaded using Messages_UploadMedia. - public static Task Bots_AddPreviewMedia(this Client client, InputUserBase bot, string lang_code, InputMedia media) - => client.Invoke(new Bots_AddPreviewMedia - { - bot = bot, - lang_code = lang_code, - media = media, - }); - - /// Edit a main mini app preview, see here » for more info. See Possible codes: 400 (details) - /// The bot that owns the Main Mini App. - /// ISO 639-1 language code, indicating the localization of the preview to edit. - /// The photo/video preview to replace, previously fetched as specified here ». - /// The new photo/video preview, uploaded using Messages_UploadMedia. - public static Task Bots_EditPreviewMedia(this Client client, InputUserBase bot, string lang_code, InputMedia media, InputMedia new_media) - => client.Invoke(new Bots_EditPreviewMedia - { - bot = bot, - lang_code = lang_code, - media = media, - new_media = new_media, - }); - - /// Delete a main mini app preview, see here » for more info. See Possible codes: 400 (details) - /// The bot that owns the Main Mini App. - /// ISO 639-1 language code, indicating the localization of the preview to delete. - /// The photo/video preview to delete, previously fetched as specified here ». - public static Task Bots_DeletePreviewMedia(this Client client, InputUserBase bot, string lang_code, params InputMedia[] media) - => client.Invoke(new Bots_DeletePreviewMedia - { - bot = bot, - lang_code = lang_code, - media = media, - }); - - /// Reorder a main mini app previews, see here » for more info. See Possible codes: 400 (details) - /// The bot that owns the Main Mini App. - /// ISO 639-1 language code, indicating the localization of the previews to reorder. - /// New order of the previews. - public static Task Bots_ReorderPreviewMedias(this Client client, InputUserBase bot, string lang_code, params InputMedia[] order) - => client.Invoke(new Bots_ReorderPreviewMedias - { - bot = bot, - lang_code = lang_code, - order = order, - }); - - /// Bot owners only, fetch main mini app preview information, see here » for more info. See Possible codes: 400 (details) - /// The bot that owns the Main Mini App. - /// Fetch previews for the specified ISO 639-1 language code. - public static Task Bots_GetPreviewInfo(this Client client, InputUserBase bot, string lang_code) - => client.Invoke(new Bots_GetPreviewInfo - { - bot = bot, - lang_code = lang_code, - }); - - /// Fetch main mini app previews, see here » for more info. See Possible codes: 400 (details) - /// The bot that owns the Main Mini App. - public static Task Bots_GetPreviewMedias(this Client client, InputUserBase bot) - => client.Invoke(new Bots_GetPreviewMedias - { - bot = bot, - }); - - /// Change the emoji status of a user (invoked by bots, see here » for more info on the full flow) See [bots: ✓ users: ✗] Possible codes: 400,403 (details) - /// The user whose emoji status should be changed - /// The emoji status - public static Task Bots_UpdateUserEmojiStatus(this Client client, InputUserBase user_id, EmojiStatusBase emoji_status) - => client.Invoke(new Bots_UpdateUserEmojiStatus - { - user_id = user_id, - emoji_status = emoji_status, - }); - - /// Allow or prevent a bot from changing our emoji status » See Possible codes: 400 (details) - /// The bot - /// Whether to allow or prevent the bot from changing our emoji status - public static Task Bots_ToggleUserEmojiStatusPermission(this Client client, InputUserBase bot, bool enabled) - => client.Invoke(new Bots_ToggleUserEmojiStatusPermission - { - bot = bot, - enabled = enabled, - }); - - /// Check if a mini app can request the download of a specific file: called when handling web_app_request_file_download events » See Possible codes: 400 (details) - /// The bot that owns the mini app that requested the download - /// The filename from the web_app_request_file_download event » - /// The url from the web_app_request_file_download event » - public static Task Bots_CheckDownloadFileParams(this Client client, InputUserBase bot, string file_name, string url) - => client.Invoke(new Bots_CheckDownloadFileParams - { - bot = bot, - file_name = file_name, - url = url, - }); - - /// Get a list of bots owned by the current user See - public static Task Bots_GetAdminedBots(this Client client) - => client.Invoke(new Bots_GetAdminedBots - { - }); - - /// Create, edit or delete the affiliate program of a bot we own See Possible codes: 400 (details) - /// The bot - /// The permille commission rate: it indicates the share of Telegram Stars received by affiliates for every transaction made by users they referred inside of the bot.
The minimum and maximum values for this parameter are contained in the starref_min_commission_permille and starref_max_commission_permille client configuration parameters.
Can be 0 to terminate the affiliate program.
Both the duration and the commission may only be raised after creation of the program: to lower them, the program must first be terminated and a new one created. - /// Indicates the duration of the affiliate program; if not set, there is no expiration date. - public static Task Bots_UpdateStarRefProgram(this Client client, InputUserBase bot, int commission_permille, int? duration_months = null) - => client.Invoke(new Bots_UpdateStarRefProgram - { - flags = (Bots_UpdateStarRefProgram.Flags)(duration_months != null ? 0x1 : 0), - bot = bot, - commission_permille = commission_permille, - duration_months = duration_months ?? default, - }); - - /// Verify a user or chat on behalf of an organization ». See [bots: ✓] Possible codes: 400,403 (details) - /// If set, adds the verification; otherwise removes verification. - /// Must not be set if invoked by a bot, must be set to the ID of an owned bot if invoked by a user. - /// The peer to verify - /// Custom description for the verification, the UTF-8 length limit for this field is contained in bot_verification_description_length_limit ».
If not set, Was verified by organization "organization_name" will be used as description. - public static Task Bots_SetCustomVerification(this Client client, InputPeer peer, InputUserBase bot = null, string custom_description = null, bool enabled = false) - => client.Invoke(new Bots_SetCustomVerification - { - flags = (Bots_SetCustomVerification.Flags)((bot != null ? 0x1 : 0) | (custom_description != null ? 0x4 : 0) | (enabled ? 0x2 : 0)), - bot = bot, - peer = peer, - custom_description = custom_description, - }); - - /// Obtain a list of similarly themed bots, selected based on similarities in their subscriber bases, see here » for more info. See Possible codes: 400 (details) - /// The method will return bots related to the passed bot. - public static Task Bots_GetBotRecommendations(this Client client, InputUserBase bot) - => client.Invoke(new Bots_GetBotRecommendations - { - bot = bot, - }); - - /// Get a payment form See [bots: ✓] Possible codes: 400,403,406 (details) - /// Invoice - /// Theme parameters » - public static Task Payments_GetPaymentForm(this Client client, InputInvoice invoice, DataJSON theme_params = null) - => client.Invoke(new Payments_GetPaymentForm - { - flags = (Payments_GetPaymentForm.Flags)(theme_params != null ? 0x1 : 0), - invoice = invoice, - theme_params = theme_params, - }); - - /// Get payment receipt See Possible codes: 400 (details) - /// The peer where the payment receipt was sent - /// Message ID of receipt - public static Task Payments_GetPaymentReceipt(this Client client, InputPeer peer, int msg_id) - => client.Invoke(new Payments_GetPaymentReceipt - { - peer = peer, - msg_id = msg_id, - }); - - /// Submit requested order information for validation See Possible codes: 400 (details) - /// Save order information to re-use it for future orders - /// Invoice - /// Requested order information - public static Task Payments_ValidateRequestedInfo(this Client client, InputInvoice invoice, PaymentRequestedInfo info, bool save = false) - => client.Invoke(new Payments_ValidateRequestedInfo - { - flags = (Payments_ValidateRequestedInfo.Flags)(save ? 0x1 : 0), - invoice = invoice, - info = info, - }); - - /// Send compiled payment form See Possible codes: 400 (details) - /// Form ID - /// Invoice - /// 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). - public static Task Payments_SendPaymentForm(this Client client, long form_id, InputInvoice invoice, InputPaymentCredentialsBase credentials, string requested_info_id = null, string shipping_option_id = null, long? tip_amount = null) - => client.Invoke(new Payments_SendPaymentForm - { - flags = (Payments_SendPaymentForm.Flags)((requested_info_id != null ? 0x1 : 0) | (shipping_option_id != null ? 0x2 : 0) | (tip_amount != null ? 0x4 : 0)), - form_id = form_id, - invoice = invoice, - requested_info_id = requested_info_id, - shipping_option_id = shipping_option_id, - credentials = credentials, - tip_amount = tip_amount ?? default, - }); - - /// Get saved payment information See - public static Task Payments_GetSavedInfo(this Client client) - => client.Invoke(new Payments_GetSavedInfo - { - }); - - /// Clear saved payment information See - /// Remove saved payment credentials - /// Clear the last order settings saved by the user - public static Task Payments_ClearSavedInfo(this Client client, bool credentials = false, bool info = false) - => client.Invoke(new Payments_ClearSavedInfo - { - flags = (Payments_ClearSavedInfo.Flags)((credentials ? 0x1 : 0) | (info ? 0x2 : 0)), - }); - - /// Get info about a credit card See Possible codes: 400 (details) - /// Credit card number - public static Task Payments_GetBankCardData(this Client client, string number) - => client.Invoke(new Payments_GetBankCardData - { - number = number, - }); - - /// Generate an invoice deep link See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// Invoice - public static Task Payments_ExportInvoice(this Client client, InputMedia invoice_media) - => client.Invoke(new Payments_ExportInvoice - { - invoice_media = invoice_media, - }); - - /// Informs server about a purchase made through the App Store: for official applications only. See Possible codes: 400 (details) - /// Receipt - /// Payment purpose - public static Task Payments_AssignAppStoreTransaction(this Client client, byte[] receipt, InputStorePaymentPurpose purpose) - => client.Invoke(new Payments_AssignAppStoreTransaction - { - receipt = receipt, - purpose = purpose, - }); - - /// Informs server about a purchase made through the Play Store: for official applications only. See Possible codes: 400 (details) - /// Receipt - /// Payment purpose - public static Task Payments_AssignPlayMarketTransaction(this Client client, DataJSON receipt, InputStorePaymentPurpose purpose) - => client.Invoke(new Payments_AssignPlayMarketTransaction - { - receipt = receipt, - purpose = purpose, - }); - - /// Obtain a list of Telegram Premium giveaway/gift code » options. See - /// The channel that will start the giveaway - public static Task Payments_GetPremiumGiftCodeOptions(this Client client, InputPeer boost_peer = null) - => client.Invoke(new Payments_GetPremiumGiftCodeOptions - { - flags = (Payments_GetPremiumGiftCodeOptions.Flags)(boost_peer != null ? 0x1 : 0), - boost_peer = boost_peer, - }); - - /// Obtain information about a Telegram Premium giftcode » See Possible codes: 400 (details) - /// The giftcode to check - public static Task Payments_CheckGiftCode(this Client client, string slug) - => client.Invoke(new Payments_CheckGiftCode - { - slug = slug, - }); - - /// Apply a Telegram Premium giftcode » See Possible codes: 400,420 (details) - /// The code to apply - public static Task Payments_ApplyGiftCode(this Client client, string slug) - => client.Invoke(new Payments_ApplyGiftCode - { - slug = slug, - }); - - /// Obtain information about a Telegram Premium giveaway ». See Possible codes: 400 (details) - /// The peer where the giveaway was posted. - /// Message ID of the service message - public static Task Payments_GetGiveawayInfo(this Client client, InputPeer peer, int msg_id) - => client.Invoke(new Payments_GetGiveawayInfo - { - peer = peer, - msg_id = msg_id, - }); - - /// Launch a prepaid giveaway ». See Possible codes: 400 (details) - /// The peer where to launch the giveaway. - /// The prepaid giveaway ID. - /// Giveway parameters - public static Task Payments_LaunchPrepaidGiveaway(this Client client, InputPeer peer, long giveaway_id, InputStorePaymentPurpose purpose) - => client.Invoke(new Payments_LaunchPrepaidGiveaway - { - peer = peer, - giveaway_id = giveaway_id, - purpose = purpose, - }); - - /// Obtain a list of Telegram Stars topup options » as s. See - public static Task Payments_GetStarsTopupOptions(this Client client) - => client.Invoke(new Payments_GetStarsTopupOptions - { - }); - - /// Get the current Telegram Stars balance of the current account (with peer=), or the stars balance of the bot specified in peer. See Possible codes: 400,403 (details) - /// If set, returns the channel/ad revenue balance in nanotons. - /// Peer of which to get the balance. - public static Task Payments_GetStarsStatus(this Client client, InputPeer peer, bool ton = false) - => client.Invoke(new Payments_GetStarsStatus - { - flags = (Payments_GetStarsStatus.Flags)(ton ? 0x1 : 0), - peer = peer, - }); - - /// Fetch Telegram Stars transactions. See [bots: ✓] Possible codes: 400 (details) - /// If set, fetches only incoming transactions. - /// If set, fetches only outgoing transactions. - /// Return transactions in ascending order by date (instead of descending order by date). - /// If set, returns the channel/ad revenue transactions in nanotons, instead. - /// If set, fetches only transactions for the specified Telegram Star subscription ». - /// Fetch the transaction history of the peer ( or a bot we own). - /// Offset for pagination, obtained from the returned next_offset, initially an empty string ». - /// Maximum number of results to return, see pagination - public static Task Payments_GetStarsTransactions(this Client client, InputPeer peer, string offset, int limit = int.MaxValue, string subscription_id = null, bool inbound = false, bool outbound = false, bool ascending = false, bool ton = false) - => client.Invoke(new Payments_GetStarsTransactions - { - flags = (Payments_GetStarsTransactions.Flags)((subscription_id != null ? 0x8 : 0) | (inbound ? 0x1 : 0) | (outbound ? 0x2 : 0) | (ascending ? 0x4 : 0) | (ton ? 0x10 : 0)), - subscription_id = subscription_id, - peer = peer, - offset = offset, - limit = limit, - }); - - /// Make a payment using Telegram Stars, see here » for more info. See [bots: ✓] Possible codes: 400,403,406 (details) - /// Payment form ID - /// Invoice - public static Task Payments_SendStarsForm(this Client client, long form_id, InputInvoice invoice) - => client.Invoke(new Payments_SendStarsForm - { - form_id = form_id, - invoice = invoice, - }); - - /// Refund a Telegram Stars transaction, see here » for more info. See [bots: ✓ users: ✗] Possible codes: 400 (details) - /// User to refund. - /// Transaction ID. - public static Task Payments_RefundStarsCharge(this Client client, InputUserBase user_id, string charge_id) - => client.Invoke(new Payments_RefundStarsCharge - { - user_id = user_id, - charge_id = charge_id, - }); - - /// Get Telegram Star revenue statistics ». See Possible codes: 400 (details) - /// Whether to enable dark theme for graph colors - /// If set, fetches channel/bot ad revenue statistics in TON. - /// Get statistics for the specified bot, channel or ourselves (). - public static Task Payments_GetStarsRevenueStats(this Client client, InputPeer peer, bool dark = false, bool ton = false) - => client.Invoke(new Payments_GetStarsRevenueStats - { - flags = (Payments_GetStarsRevenueStats.Flags)((dark ? 0x1 : 0) | (ton ? 0x2 : 0)), - peer = peer, - }); - - /// Withdraw funds from a channel or bot's star balance ». See Possible codes: 400 (details) - /// If set, withdraws channel/ad revenue in TON. - /// Channel or bot from which to withdraw funds. - /// The amount of stars or nanotons to withdraw. - /// 2FA password, see here » for more info. - public static Task Payments_GetStarsRevenueWithdrawalUrl(this Client client, InputPeer peer, InputCheckPasswordSRP password, long? amount = null, bool ton = false) - => client.Invoke(new Payments_GetStarsRevenueWithdrawalUrl - { - flags = (Payments_GetStarsRevenueWithdrawalUrl.Flags)((amount != null ? 0x2 : 0) | (ton ? 0x1 : 0)), - peer = peer, - amount = amount ?? default, - password = password, - }); - - /// Returns a URL for a Telegram Ad platform account that can be used to set up advertisements for channel/bot in peer, paid using the Telegram Stars owned by the specified peer, see here » for more info. See Possible codes: 400,403 (details) - /// Channel or bot that owns the stars. - public static Task Payments_GetStarsRevenueAdsAccountUrl(this Client client, InputPeer peer) - => client.Invoke(new Payments_GetStarsRevenueAdsAccountUrl - { - peer = peer, - }); - - /// Obtain info about Telegram Star transactions » using specific transaction IDs. See Possible codes: 400 (details) - /// If set, returns channel/bot ad revenue transactions in nanotons. - /// Channel or bot. - /// Transaction IDs. - public static Task Payments_GetStarsTransactionsByID(this Client client, InputPeer peer, InputStarsTransaction[] id, bool ton = false) - => client.Invoke(new Payments_GetStarsTransactionsByID - { - flags = (Payments_GetStarsTransactionsByID.Flags)(ton ? 0x1 : 0), - peer = peer, - id = id, - }); - - /// Obtain a list of Telegram Stars gift options » as s. See Possible codes: 400 (details) - /// Receiver of the gift (optional). - public static Task Payments_GetStarsGiftOptions(this Client client, InputUserBase user_id = null) - => client.Invoke(new Payments_GetStarsGiftOptions - { - flags = (Payments_GetStarsGiftOptions.Flags)(user_id != null ? 0x1 : 0), - user_id = user_id, - }); - - /// Obtain a list of active, expired or cancelled Telegram Star subscriptions ». See Possible codes: 400 (details) - /// Whether to return only subscriptions expired due to an excessively low Telegram Star balance. - /// Always pass . - /// Offset for pagination, taken from .subscriptions_next_offset. - public static Task Payments_GetStarsSubscriptions(this Client client, InputPeer peer, string offset, bool missing_balance = false) - => client.Invoke(new Payments_GetStarsSubscriptions - { - flags = (Payments_GetStarsSubscriptions.Flags)(missing_balance ? 0x1 : 0), - peer = peer, - offset = offset, - }); - - /// Activate or deactivate a Telegram Star subscription ». See Possible codes: 400 (details) - /// Always pass . - /// ID of the subscription. - /// Whether to cancel or reactivate the subscription. - public static Task Payments_ChangeStarsSubscription(this Client client, InputPeer peer, string subscription_id, bool? canceled = default) - => client.Invoke(new Payments_ChangeStarsSubscription - { - flags = (Payments_ChangeStarsSubscription.Flags)(canceled != default ? 0x1 : 0), - peer = peer, - subscription_id = subscription_id, - canceled = canceled ?? default, - }); - - /// Re-join a private channel associated to an active Telegram Star subscription ». See Possible codes: 400 (details) - /// Always pass . - /// ID of the subscription. - public static Task Payments_FulfillStarsSubscription(this Client client, InputPeer peer, string subscription_id) - => client.Invoke(new Payments_FulfillStarsSubscription - { - peer = peer, - subscription_id = subscription_id, - }); - - /// Fetch a list of star giveaway options ». See - public static Task Payments_GetStarsGiveawayOptions(this Client client) - => client.Invoke(new Payments_GetStarsGiveawayOptions - { - }); - - /// Get a list of available gifts, see here » for more info. See [bots: ✓] - /// Hash used for caching, for more info click here.
The hash may be generated locally by using the ids of the returned or stored sticker s. - /// a null value means payments.starGiftsNotModified - public static Task Payments_GetStarGifts(this Client client, int hash = default) - => client.Invoke(new Payments_GetStarGifts - { - hash = hash, - }); - - /// Display or remove a received gift » from our profile. See Possible codes: 400 (details) - /// If set, hides the gift from our profile. - /// The gift to display or remove. - public static Task Payments_SaveStarGift(this Client client, InputSavedStarGift stargift, bool unsave = false) - => client.Invoke(new Payments_SaveStarGift - { - flags = (Payments_SaveStarGift.Flags)(unsave ? 0x1 : 0), - stargift = stargift, - }); - - /// Convert a received gift » into Telegram Stars: this will permanently destroy the gift, converting it into .convert_stars Telegram Stars, added to the user's balance. See Possible codes: 400 (details) - /// The gift to convert. - public static Task Payments_ConvertStarGift(this Client client, InputSavedStarGift stargift) - => client.Invoke(new Payments_ConvertStarGift - { - stargift = stargift, - }); - - /// Cancel a bot subscription See Possible codes: 400 (details) - /// If not set, disables autorenewal of the subscriptions, and prevents the user from reactivating the subscription once the current period expires: a subscription cancelled by the bot will have the .bot_canceled flag set.
The bot can can partially undo this operation by setting this flag: this will allow the user to reactivate the subscription. - /// The ID of the user whose subscription should be (un)cancelled - /// The provider_charge_id from the service message sent to the bot for the first subscription payment. - public static Task Payments_BotCancelStarsSubscription(this Client client, InputUserBase user_id, string charge_id, bool restore = false) - => client.Invoke(new Payments_BotCancelStarsSubscription - { - flags = (Payments_BotCancelStarsSubscription.Flags)(restore ? 0x1 : 0), - user_id = user_id, - charge_id = charge_id, - }); - - /// Fetch all affiliations we have created for a certain peer See - /// The affiliated peer - /// If set, returns only results older than the specified unixtime - /// Offset for pagination, taken from the last returned .url (initially empty) - /// Maximum number of results to return, see pagination - public static Task Payments_GetConnectedStarRefBots(this Client client, InputPeer peer, int limit = int.MaxValue, DateTime? offset_date = null, string offset_link = null) - => client.Invoke(new Payments_GetConnectedStarRefBots - { - flags = (Payments_GetConnectedStarRefBots.Flags)((offset_date != null ? 0x4 : 0) | (offset_link != null ? 0x4 : 0)), - peer = peer, - offset_date = offset_date ?? default, - offset_link = offset_link, - limit = limit, - }); - - /// Fetch info about a specific bot affiliation » See Possible codes: 400 (details) - /// The affiliated peer - /// The bot that offers the affiliate program - public static Task Payments_GetConnectedStarRefBot(this Client client, InputPeer peer, InputUserBase bot) - => client.Invoke(new Payments_GetConnectedStarRefBot - { - peer = peer, - bot = bot, - }); - - /// Obtain a list of suggested mini apps with available affiliate programs See Possible codes: 403 (details) - /// If set, orders results by the expected revenue - /// If set, orders results by the creation date of the affiliate program - /// The peer that will become the affiliate: star commissions will be transferred to this peer's star balance. - /// Offset for pagination, taken from .next_offset, initially empty. - /// Maximum number of results to return, see pagination - public static Task Payments_GetSuggestedStarRefBots(this Client client, InputPeer peer, string offset, int limit = int.MaxValue, bool order_by_revenue = false, bool order_by_date = false) - => client.Invoke(new Payments_GetSuggestedStarRefBots - { - flags = (Payments_GetSuggestedStarRefBots.Flags)((order_by_revenue ? 0x1 : 0) | (order_by_date ? 0x2 : 0)), - peer = peer, - offset = offset, - limit = limit, - }); - - /// Join a bot's affiliate program, becoming an affiliate » See - /// The peer that will become the affiliate: star commissions will be transferred to this peer's star balance. - /// The bot that offers the affiliate program - public static Task Payments_ConnectStarRefBot(this Client client, InputPeer peer, InputUserBase bot) - => client.Invoke(new Payments_ConnectStarRefBot - { - peer = peer, - bot = bot, - }); - - /// Leave a bot's affiliate program » See Possible codes: 400 (details) - /// If set, leaves the bot's affiliate program - /// The peer that was affiliated - /// The affiliate link to revoke - public static Task Payments_EditConnectedStarRefBot(this Client client, InputPeer peer, string link, bool revoked = false) - => client.Invoke(new Payments_EditConnectedStarRefBot - { - flags = (Payments_EditConnectedStarRefBot.Flags)(revoked ? 0x1 : 0), - peer = peer, - link = link, - }); - - /// Obtain a preview of the possible attributes (chosen randomly) a gift » can receive after upgrading it to a collectible gift », see here » for more info. See Possible codes: 400 (details) - /// The gift to upgrade. - public static Task Payments_GetStarGiftUpgradePreview(this Client client, long gift_id) - => client.Invoke(new Payments_GetStarGiftUpgradePreview - { - gift_id = gift_id, - }); - - /// Upgrade a gift to a collectible gift: can only be used if the upgrade was already paid by the gift sender; see here » for more info on the full flow (including the different flow to use in case the upgrade was not paid by the gift sender). See Possible codes: 400 (details) - /// Set this flag to keep the original gift text, sender and receiver in the upgraded gift as a attribute. - /// The gift to upgrade - public static Task Payments_UpgradeStarGift(this Client client, InputSavedStarGift stargift, bool keep_original_details = false) - => client.Invoke(new Payments_UpgradeStarGift - { - flags = (Payments_UpgradeStarGift.Flags)(keep_original_details ? 0x1 : 0), - stargift = stargift, - }); - - /// Transfer a collectible gift to another user or channel: can only be used if transfer is free (i.e. .transfer_stars is not set); see here » for more info on the full flow (including the different flow to use in case the transfer isn't free). See Possible codes: 400 (details) - /// The gift to transfer. - /// Destination peer. - public static Task Payments_TransferStarGift(this Client client, InputSavedStarGift stargift, InputPeer to_id) - => client.Invoke(new Payments_TransferStarGift - { - stargift = stargift, - to_id = to_id, - }); - - /// Obtain info about a collectible gift » using a slug obtained from a collectible gift link ». See Possible codes: 400 (details) - /// The slug. - public static Task Payments_GetUniqueStarGift(this Client client, string slug) - => client.Invoke(new Payments_GetUniqueStarGift - { - slug = slug, - }); - - /// Fetch the full list of gifts owned by a peer. See [bots: ✓] Possible codes: 400 (details) - /// Exclude gifts not pinned on the profile. - /// Exclude gifts pinned on the profile. - /// Exclude gifts that do not have the .limited flag set. - /// Exclude collectible gifts ». - /// If set, sorts the gifts by price instead of reception date. - /// Exclude gifts that can be upgraded to collectible gifts ». - /// Exclude gifts that cannot be upgraded to collectible gifts ». - /// Fetch only gifts owned by the specified peer, such as: a user, with peer=; a channel, with peer=; a connected business user (when executing the method as a bot, over the business connection), with peer=. - /// Only returns gifts within the specified collection ». - /// Offset for pagination. - /// Maximum number of results to return, see pagination - public static Task Payments_GetSavedStarGifts(this Client client, InputPeer peer, string offset, int limit = int.MaxValue, int? collection_id = null, bool exclude_unsaved = false, bool exclude_saved = false, bool exclude_unlimited = false, bool exclude_unique = false, bool sort_by_value = false, bool exclude_upgradable = false, bool exclude_unupgradable = false, bool peer_color_available = false, bool exclude_hosted = false) - => client.Invoke(new Payments_GetSavedStarGifts - { - flags = (Payments_GetSavedStarGifts.Flags)((collection_id != null ? 0x40 : 0) | (exclude_unsaved ? 0x1 : 0) | (exclude_saved ? 0x2 : 0) | (exclude_unlimited ? 0x4 : 0) | (exclude_unique ? 0x10 : 0) | (sort_by_value ? 0x20 : 0) | (exclude_upgradable ? 0x80 : 0) | (exclude_unupgradable ? 0x100 : 0) | (peer_color_available ? 0x200 : 0) | (exclude_hosted ? 0x400 : 0)), - peer = peer, - collection_id = collection_id ?? default, - offset = offset, - limit = limit, - }); - - /// Fetch info about specific gifts owned by a peer we control. See Possible codes: 400 (details) - /// List of gifts to fetch info about. - public static Task Payments_GetSavedStarGift(this Client client, params InputSavedStarGift[] stargift) - => client.Invoke(new Payments_GetSavedStarGift - { - stargift = stargift, - }); - - /// Convert a collectible gift » to an NFT on the TON blockchain. See Possible codes: 400 (details) - /// The collectible gift to export. - /// The current user's 2FA password, passed as specified here ». - public static Task Payments_GetStarGiftWithdrawalUrl(this Client client, InputSavedStarGift stargift, InputCheckPasswordSRP password) - => client.Invoke(new Payments_GetStarGiftWithdrawalUrl - { - stargift = stargift, - password = password, - }); - - /// Enables or disables the reception of notifications every time a gift » is received by the specified channel, can only be invoked by admins with post_messages admin rights. See Possible codes: 400 (details) - /// Whether to enable or disable reception of notifications in the form of and service messages from the channel. - /// The channel for which to receive or not receive notifications. - public static Task Payments_ToggleChatStarGiftNotifications(this Client client, InputPeer peer, bool enabled = false) - => client.Invoke(new Payments_ToggleChatStarGiftNotifications - { - flags = (Payments_ToggleChatStarGiftNotifications.Flags)(enabled ? 0x1 : 0), - peer = peer, - }); - - /// Pins a received gift on top of the profile of the user or owned channels by using Payments_ToggleStarGiftsPinnedToTop. See Possible codes: 400 (details) - /// The peer where to pin the gift. - /// The gift to pin. - public static Task Payments_ToggleStarGiftsPinnedToTop(this Client client, InputPeer peer, params InputSavedStarGift[] stargift) - => client.Invoke(new Payments_ToggleStarGiftsPinnedToTop - { - peer = peer, - stargift = stargift, - }); - - /// Checks whether a purchase is possible. Must be called before in-store purchase, official apps only. See Possible codes: 400,406 (details) - /// Payment purpose. - public static Task Payments_CanPurchaseStore(this Client client, InputStorePaymentPurpose purpose) - => client.Invoke(new Payments_CanPurchaseStore - { - purpose = purpose, - }); - - /// Get collectible gifts of a specific type currently on resale, see here » for more info. See Possible codes: 400 (details) - /// Sort gifts by price (ascending). - /// Sort gifts by number (ascending). - /// If a previous call to the method was made and .attributes_hash was set, pass it here to avoid returning any results if they haven't changed.
Otherwise, set this flag and pass 0 to return .attributes_hash and .attributes, these two fields will not be set if this flag is not set. - /// Mandatory identifier of the base gift from which the collectible gift was upgraded. - /// Optionally filter gifts with the specified attributes. If no attributes of a specific type are specified, all attributes of that type are allowed. - /// Offset for pagination. If not equal to an empty string, .counters will not be set to avoid returning the counters every time a new page is fetched. - /// Maximum number of results to return, see pagination - public static Task Payments_GetResaleStarGifts(this Client client, long gift_id, string offset, int limit = int.MaxValue, long? attributes_hash = null, StarGiftAttributeId[] attributes = null, bool sort_by_price = false, bool sort_by_num = false, bool for_craft = false) - => client.Invoke(new Payments_GetResaleStarGifts - { - flags = (Payments_GetResaleStarGifts.Flags)((attributes_hash != null ? 0x1 : 0) | (attributes != null ? 0x8 : 0) | (sort_by_price ? 0x2 : 0) | (sort_by_num ? 0x4 : 0) | (for_craft ? 0x10 : 0)), - attributes_hash = attributes_hash ?? default, - gift_id = gift_id, - attributes = attributes, - offset = offset, - limit = limit, - }); - - /// A collectible gift we own » can be put up for sale on the gift marketplace » with this method, see here » for more info. See Possible codes: 400 (details) - /// The gift to resell. - /// Resale price of the gift. - public static Task Payments_UpdateStarGiftPrice(this Client client, InputSavedStarGift stargift, StarsAmountBase resell_amount) - => client.Invoke(new Payments_UpdateStarGiftPrice - { - stargift = stargift, - resell_amount = resell_amount, - }); - - /// Create a star gift collection ». See Possible codes: 400 (details) - /// Peer where to create the collection. - /// Title of the collection. - /// Gifts added to the collection. - public static Task Payments_CreateStarGiftCollection(this Client client, InputPeer peer, string title, params InputSavedStarGift[] stargift) - => client.Invoke(new Payments_CreateStarGiftCollection - { - peer = peer, - title = title, - stargift = stargift, - }); - - /// Add or remove gifts from a star gift collection », or rename the collection. See Possible codes: 400 (details) - /// Peer that owns the collection. - /// Collection ID. - /// Title of the collection, to rename the collection. - /// Can contain a list of gifts to remove from the collection. - /// Can contain a list of gifts to add to the collection. - /// Can contain the new gift order. - public static Task Payments_UpdateStarGiftCollection(this Client client, InputPeer peer, int collection_id, string title = null, InputSavedStarGift[] delete_stargift = null, InputSavedStarGift[] add_stargift = null, InputSavedStarGift[] order = null) - => client.Invoke(new Payments_UpdateStarGiftCollection - { - flags = (Payments_UpdateStarGiftCollection.Flags)((title != null ? 0x1 : 0) | (delete_stargift != null ? 0x2 : 0) | (add_stargift != null ? 0x4 : 0) | (order != null ? 0x8 : 0)), - peer = peer, - collection_id = collection_id, - title = title, - delete_stargift = delete_stargift, - add_stargift = add_stargift, - order = order, - }); - - /// Reorder the star gift collections » on an owned peer's profile. See Possible codes: 400 (details) - /// The owned peer. - /// New collection order. - public static Task Payments_ReorderStarGiftCollections(this Client client, InputPeer peer, params int[] order) - => client.Invoke(new Payments_ReorderStarGiftCollections - { - peer = peer, - order = order, - }); - - /// Delete a star gift collection ». See Possible codes: 400 (details) - /// Peer that owns the collection. - /// ID of the collection. - public static Task Payments_DeleteStarGiftCollection(this Client client, InputPeer peer, int collection_id) - => client.Invoke(new Payments_DeleteStarGiftCollection - { - peer = peer, - collection_id = collection_id, - }); - - /// Fetches all star gift collections » of a peer. See Possible codes: 400 (details) - /// The peer. - /// Hash (generated as specified here ») using the .hash field (not the collection_id field) of all collections returned by a previous method call, to avoid refetching the result if it hasn't changed. - /// a null value means payments.starGiftCollectionsNotModified - public static Task Payments_GetStarGiftCollections(this Client client, InputPeer peer, long hash = default) - => client.Invoke(new Payments_GetStarGiftCollections - { - peer = peer, - hash = hash, - }); - - /// Get information about the value of a collectible gift ». See Possible codes: 400 (details) - /// slug from a . - public static Task Payments_GetUniqueStarGiftValueInfo(this Client client, string slug) - => client.Invoke(new Payments_GetUniqueStarGiftValueInfo - { - slug = slug, - }); - - /// Check if the specified gift » can be sent. See Possible codes: 400 (details) - /// Gift ID. - public static Task Payments_CheckCanSendGift(this Client client, long gift_id) - => client.Invoke(new Payments_CheckCanSendGift - { - gift_id = gift_id, - }); - - /// See Possible codes: 400 (details) - public static Task Payments_GetStarGiftAuctionState(this Client client, InputStarGiftAuctionBase auction, int version) - => client.Invoke(new Payments_GetStarGiftAuctionState - { - auction = auction, - version = version, - }); - - /// See Possible codes: 400 (details) - public static Task Payments_GetStarGiftAuctionAcquiredGifts(this Client client, long gift_id) - => client.Invoke(new Payments_GetStarGiftAuctionAcquiredGifts - { - gift_id = gift_id, - }); - - /// See - /// a null value means payments.starGiftActiveAuctionsNotModified - public static Task Payments_GetStarGiftActiveAuctions(this Client client, long hash = default) - => client.Invoke(new Payments_GetStarGiftActiveAuctions - { - hash = hash, - }); - - /// See [bots: ✓] Possible codes: 400 (details) - public static Task Payments_ResolveStarGiftOffer(this Client client, int offer_msg_id, bool decline = false) - => client.Invoke(new Payments_ResolveStarGiftOffer - { - flags = (Payments_ResolveStarGiftOffer.Flags)(decline ? 0x1 : 0), - offer_msg_id = offer_msg_id, - }); - - /// See Possible codes: 400 (details) - /// You can use - public static Task Payments_SendStarGiftOffer(this Client client, InputPeer peer, string slug, StarsAmountBase price, int duration, long random_id, long? allow_paid_stars = null) - => client.Invoke(new Payments_SendStarGiftOffer - { - flags = (Payments_SendStarGiftOffer.Flags)(allow_paid_stars != null ? 0x1 : 0), - peer = peer, - slug = slug, - price = price, - duration = duration, - random_id = random_id, - allow_paid_stars = allow_paid_stars ?? default, - }); - - /// See Possible codes: 400 (details) - public static Task Payments_GetStarGiftUpgradeAttributes(this Client client, long gift_id) - => client.Invoke(new Payments_GetStarGiftUpgradeAttributes - { - gift_id = gift_id, - }); - - /// See Possible codes: 400 (details) - /// Maximum number of results to return, see pagination - public static Task Payments_GetCraftStarGifts(this Client client, long gift_id, string offset, int limit = int.MaxValue) - => client.Invoke(new Payments_GetCraftStarGifts - { - gift_id = gift_id, - offset = offset, - limit = limit, - }); - - /// See Possible codes: 400 (details) - public static Task Payments_CraftStarGift(this Client client, params InputSavedStarGift[] stargift) - => client.Invoke(new Payments_CraftStarGift - { - stargift = stargift, - }); - - /// Create a stickerset. See [bots: ✓] Possible codes: 400 (details) - /// Whether this is a mask stickerset - /// Whether this is a custom emoji stickerset. - /// Whether the color of TGS custom emojis contained in this set should be changed to the text color when used in messages, the accent color if used as emoji status, white on chat photos, or another appropriate color based on context. For custom emoji stickersets only. - /// Stickerset owner - /// Stickerset name, 1-64 chars - /// Short name of sticker set, to be used in sticker deep links ». Can contain only english letters, digits and underscores. Must begin with a letter, can't contain consecutive underscores and, if called by a bot, must end in "_by_<bot_username>". <bot_username> is case insensitive. 1-64 characters. - /// Thumbnail - /// Stickers - /// Used when importing stickers using the sticker import SDKs, specifies the name of the software that created the stickers - /// a null value means messages.stickerSetNotModified - public static Task Stickers_CreateStickerSet(this Client client, InputUserBase user_id, string title, string short_name, InputStickerSetItem[] stickers, InputDocument thumb = null, string software = null, bool masks = false, bool emojis = false, bool text_color = false) - => client.Invoke(new Stickers_CreateStickerSet - { - flags = (Stickers_CreateStickerSet.Flags)((thumb != null ? 0x4 : 0) | (software != null ? 0x8 : 0) | (masks ? 0x1 : 0) | (emojis ? 0x20 : 0) | (text_color ? 0x40 : 0)), - user_id = user_id, - title = title, - short_name = short_name, - thumb = thumb, - stickers = stickers, - software = software, - }); - - /// Remove a sticker from the set where it belongs. The sticker set must have been created by the current user/bot. See [bots: ✓] Possible codes: 400 (details) - /// The sticker to remove - /// a null value means messages.stickerSetNotModified - public static Task Stickers_RemoveStickerFromSet(this Client client, InputDocument sticker) - => client.Invoke(new Stickers_RemoveStickerFromSet - { - sticker = sticker, - }); - - /// Changes the absolute position of a sticker in the set to which it belongs. The sticker set must have been created by the current user/bot. See [bots: ✓] Possible codes: 400 (details) - /// The sticker - /// The new position of the sticker, zero-based - /// a null value means messages.stickerSetNotModified - public static Task Stickers_ChangeStickerPosition(this Client client, InputDocument sticker, int position) - => client.Invoke(new Stickers_ChangeStickerPosition - { - sticker = sticker, - position = position, - }); - - /// Add a sticker to a stickerset. The sticker set must have been created by the current user/bot. See [bots: ✓] Possible codes: 400,406 (details) - /// The stickerset - /// The sticker - /// a null value means messages.stickerSetNotModified - public static Task Stickers_AddStickerToSet(this Client client, InputStickerSet stickerset, InputStickerSetItem sticker) - => client.Invoke(new Stickers_AddStickerToSet - { - stickerset = stickerset, - sticker = sticker, - }); - - /// Set stickerset thumbnail See [bots: ✓] Possible codes: 400 (details) - /// Stickerset - /// Thumbnail (only for normal stickersets, not custom emoji stickersets). - /// Only for custom emoji stickersets, ID of a custom emoji present in the set to use as thumbnail; pass 0 to fallback to the first custom emoji of the set. - /// a null value means messages.stickerSetNotModified - public static Task Stickers_SetStickerSetThumb(this Client client, InputStickerSet stickerset, InputDocument thumb = null, long? thumb_document_id = null) - => client.Invoke(new Stickers_SetStickerSetThumb - { - flags = (Stickers_SetStickerSetThumb.Flags)((thumb != null ? 0x1 : 0) | (thumb_document_id != null ? 0x2 : 0)), - stickerset = stickerset, - thumb = thumb, - thumb_document_id = thumb_document_id ?? default, - }); - - /// Check whether the given short name is available See Possible codes: 400 (details) - /// Short name - public static Task Stickers_CheckShortName(this Client client, string short_name) - => client.Invoke(new Stickers_CheckShortName - { - short_name = short_name, - }); - - /// Suggests a short name for a given stickerpack name See Possible codes: 400 (details) - /// Sticker pack name - public static Task Stickers_SuggestShortName(this Client client, string title) - => client.Invoke(new Stickers_SuggestShortName - { - title = title, - }); - - /// Update the keywords, emojis or mask coordinates of a sticker. See [bots: ✓] Possible codes: 400 (details) - /// The sticker - /// If set, updates the emoji list associated to the sticker - /// If set, updates the mask coordinates - /// If set, updates the sticker keywords (separated by commas). Can't be provided for mask stickers. - /// a null value means messages.stickerSetNotModified - public static Task Stickers_ChangeSticker(this Client client, InputDocument sticker, string emoji = null, MaskCoords mask_coords = null, string keywords = null) - => client.Invoke(new Stickers_ChangeSticker - { - flags = (Stickers_ChangeSticker.Flags)((emoji != null ? 0x1 : 0) | (mask_coords != null ? 0x2 : 0) | (keywords != null ? 0x4 : 0)), - sticker = sticker, - emoji = emoji, - mask_coords = mask_coords, - keywords = keywords, - }); - - /// Renames a stickerset. See [bots: ✓] Possible codes: 400 (details) - /// Stickerset to rename - /// New stickerset title - /// a null value means messages.stickerSetNotModified - public static Task Stickers_RenameStickerSet(this Client client, InputStickerSet stickerset, string title) - => client.Invoke(new Stickers_RenameStickerSet - { - stickerset = stickerset, - title = title, - }); - - /// Deletes a stickerset we created. See [bots: ✓] Possible codes: 400 (details) - /// Stickerset to delete - public static Task Stickers_DeleteStickerSet(this Client client, InputStickerSet stickerset) - => client.Invoke(new Stickers_DeleteStickerSet - { - stickerset = stickerset, - }); - - /// Replace a sticker in a stickerset ». See [bots: ✓] Possible codes: 400 (details) - /// Old sticker document. - /// New sticker. - /// a null value means messages.stickerSetNotModified - public static Task Stickers_ReplaceSticker(this Client client, InputDocument sticker, InputStickerSetItem new_sticker) - => client.Invoke(new Stickers_ReplaceSticker - { - sticker = sticker, - new_sticker = new_sticker, - }); - - /// Get phone call configuration to be passed to libtgvoip's shared config See - public static Task Phone_GetCallConfig(this Client client) - => client.Invoke(new Phone_GetCallConfig - { - }); - - /// Start a telegram phone call See Possible codes: 400,403,500 (details) - /// Whether to start a video call - /// Destination of the phone call - /// Random ID to avoid resending the same object - /// Parameter for E2E encryption key exchange » - /// Phone call settings - public static Task Phone_RequestCall(this Client client, InputUserBase user_id, int random_id, byte[] g_a_hash, PhoneCallProtocol protocol, bool video = false) - => client.Invoke(new Phone_RequestCall - { - flags = (Phone_RequestCall.Flags)(video ? 0x1 : 0), - user_id = user_id, - random_id = random_id, - g_a_hash = g_a_hash, - protocol = protocol, - }); - - /// Accept incoming call See Possible codes: 400,406,500 (details) - /// The call to accept - /// Parameter for E2E encryption key exchange » - /// Phone call settings - public static Task Phone_AcceptCall(this Client client, InputPhoneCall peer, byte[] g_b, PhoneCallProtocol protocol) - => client.Invoke(new Phone_AcceptCall - { - peer = peer, - g_b = g_b, - protocol = protocol, - }); - - /// Complete phone call E2E encryption key exchange » See Possible codes: 400 (details) - /// The phone call - /// Parameter for E2E encryption key exchange » - /// Key fingerprint - /// Phone call settings - public static Task Phone_ConfirmCall(this Client client, InputPhoneCall peer, byte[] g_a, long key_fingerprint, PhoneCallProtocol protocol) - => client.Invoke(new Phone_ConfirmCall - { - peer = peer, - g_a = g_a, - key_fingerprint = key_fingerprint, - protocol = protocol, - }); - - /// Optional: notify the server that the user is currently busy in a call: this will automatically refuse all incoming phone calls until the current phone call is ended. See Possible codes: 400 (details) - /// The phone call we're currently in - public static Task Phone_ReceivedCall(this Client client, InputPhoneCall peer) - => client.Invoke(new Phone_ReceivedCall - { - peer = peer, - }); - - /// Refuse or end running call See Possible codes: 400,500 (details) - /// Whether this is a video call - /// The phone call - /// Call duration - /// Why was the call discarded - /// Preferred libtgvoip relay ID - public static Task Phone_DiscardCall(this Client client, InputPhoneCall peer, int duration, PhoneCallDiscardReason reason, long connection_id, bool video = false) - => client.Invoke(new Phone_DiscardCall - { - flags = (Phone_DiscardCall.Flags)(video ? 0x1 : 0), - peer = peer, - duration = duration, - reason = reason, - connection_id = connection_id, - }); - - /// Rate a call, returns info about the rating message sent to the official VoIP bot. See Possible codes: 400 (details) - /// Whether the user decided on their own initiative to rate the call - /// The call to rate - /// Rating in 1-5 stars - /// An additional comment - public static Task Phone_SetCallRating(this Client client, InputPhoneCall peer, int rating, string comment, bool user_initiative = false) - => client.Invoke(new Phone_SetCallRating - { - flags = (Phone_SetCallRating.Flags)(user_initiative ? 0x1 : 0), - peer = peer, - rating = rating, - comment = comment, - }); - - /// Send phone call debug data to server See Possible codes: 400 (details) - /// Phone call - /// Debug statistics obtained from libtgvoip - public static Task Phone_SaveCallDebug(this Client client, InputPhoneCall peer, DataJSON debug) - => client.Invoke(new Phone_SaveCallDebug - { - peer = peer, - debug = debug, - }); - - /// Send VoIP signaling data See Possible codes: 400 (details) - /// Phone call - /// Signaling payload - public static Task Phone_SendSignalingData(this Client client, InputPhoneCall peer, byte[] data) - => client.Invoke(new Phone_SendSignalingData - { - peer = peer, - data = data, - }); - - /// Create a group call or livestream See Possible codes: 400 (details) - /// Whether RTMP stream support should be enabled: only the group/supergroup/channel owner can use this flag. - /// Associate the group call or livestream to the provided group/supergroup/channel - /// 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, string title = null, DateTime? schedule_date = null, bool rtmp_stream = false) - => client.Invoke(new Phone_CreateGroupCall - { - 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, - schedule_date = schedule_date ?? default, - }); - - /// Join a group call See Possible codes: 400,403,500 (details) - /// If set, the user will be muted by default upon joining. - /// If set, the user's video will be disabled by default upon joining. - /// The group call - /// 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. - /// For conference calls, your public key. - /// The block containing an appropriate e2e.chain.changeSetGroupState event. - /// WebRTC parameters - public static Task Phone_JoinGroupCall(this Client client, InputGroupCallBase call, InputPeer join_as, DataJSON params_, string invite_hash = null, Int256? public_key = null, byte[] block = null, bool muted = false, bool video_stopped = false) - => client.Invoke(new Phone_JoinGroupCall - { - flags = (Phone_JoinGroupCall.Flags)((invite_hash != null ? 0x2 : 0) | (public_key != null ? 0x8 : 0) | (block != null ? 0x8 : 0) | (muted ? 0x1 : 0) | (video_stopped ? 0x4 : 0)), - call = call, - join_as = join_as, - invite_hash = invite_hash, - public_key = public_key ?? default, - block = block, - params_ = params_, - }); - - /// Leave a group call See Possible codes: 400 (details) - /// The group call - /// Your source ID - public static Task Phone_LeaveGroupCall(this Client client, InputGroupCallBase call, int source) - => client.Invoke(new Phone_LeaveGroupCall - { - call = call, - source = source, - }); - - /// Invite a set of users to a group call. See Possible codes: 400,403 (details) - /// The group call - /// The users to invite. - public static Task Phone_InviteToGroupCall(this Client client, InputGroupCallBase call, params InputUserBase[] users) - => client.Invoke(new Phone_InviteToGroupCall - { - call = call, - users = users, - }); - - /// Terminate a group call See Possible codes: 400,403 (details) - /// The group call to terminate - public static Task Phone_DiscardGroupCall(this Client client, InputGroupCallBase call) - => client.Invoke(new Phone_DiscardGroupCall - { - call = call, - }); - - /// Change group call settings See Possible codes: 400 (details) - /// 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, InputGroupCallBase call, bool? join_muted = default, bool? messages_enabled = default, long? send_paid_messages_stars = null, bool reset_invite_hash = false) - => client.Invoke(new Phone_ToggleGroupCallSettings - { - flags = (Phone_ToggleGroupCallSettings.Flags)((join_muted != default ? 0x1 : 0) | (messages_enabled != default ? 0x4 : 0) | (send_paid_messages_stars != null ? 0x8 : 0) | (reset_invite_hash ? 0x2 : 0)), - call = call, - join_muted = join_muted ?? default, - messages_enabled = messages_enabled ?? default, - send_paid_messages_stars = send_paid_messages_stars ?? default, - }); - - /// Get info about a group call See Possible codes: 400,403 (details) - /// The group call - /// Maximum number of results to return, see pagination - public static Task Phone_GetGroupCall(this Client client, InputGroupCallBase call, int limit = int.MaxValue) - => client.Invoke(new Phone_GetGroupCall - { - call = call, - limit = limit, - }); - - /// Get group call participants See Possible codes: 400 (details) - /// Group call - /// If specified, will fetch group participant info about the specified peers - /// If specified, will fetch group participant info about the specified WebRTC source IDs - /// Offset for results, taken from the next_offset field of , initially an empty string.
Note: if no more results are available, the method call will return an empty next_offset; thus, avoid providing the next_offset returned in if it is empty, to avoid an infinite loop. - /// Maximum number of results to return, see pagination - public static Task Phone_GetGroupParticipants(this Client client, InputGroupCallBase call, InputPeer[] ids, int[] sources, string offset, int limit = int.MaxValue) - => client.Invoke(new Phone_GetGroupParticipants - { - call = call, - ids = ids, - sources = sources, - offset = offset, - limit = limit, - }); - - /// Check whether the group call Server Forwarding Unit is currently receiving the streams with the specified WebRTC source IDs.
Returns an intersection of the source IDs specified in sources, and the source IDs currently being forwarded by the SFU. See Possible codes: 400 (details)
- /// Group call - /// Source IDs - public static Task Phone_CheckGroupCall(this Client client, InputGroupCallBase call, params int[] sources) - => client.Invoke(new Phone_CheckGroupCall - { - call = call, - sources = sources, - }); - - /// Start or stop recording a group call: the recorded audio and video streams will be automatically sent to Saved messages (the chat with ourselves). See Possible codes: 400,403 (details) - /// Whether to start or stop recording - /// Whether to also record video streams - /// 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, InputGroupCallBase call, string title = null, bool? video_portrait = default, bool start = false, bool video = false) - => client.Invoke(new Phone_ToggleGroupCallRecord - { - 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 ?? default, - }); - - /// Edit information about a given group call participant See Possible codes: 400,403 (details) - /// The group call - /// The group call participant (can also be the user itself) - /// Whether to mute or unmute the specified participant - /// New volume - /// Raise or lower hand - /// Start or stop the video stream - /// Pause or resume the video stream - /// Pause or resume the screen sharing stream - public static Task Phone_EditGroupCallParticipant(this Client client, InputGroupCallBase call, InputPeer participant, bool? muted = default, int? volume = null, bool? raise_hand = default, bool? video_stopped = default, bool? video_paused = default, bool? presentation_paused = default) - => client.Invoke(new Phone_EditGroupCallParticipant - { - flags = (Phone_EditGroupCallParticipant.Flags)((muted != default ? 0x1 : 0) | (volume != null ? 0x2 : 0) | (raise_hand != default ? 0x4 : 0) | (video_stopped != default ? 0x8 : 0) | (video_paused != default ? 0x10 : 0) | (presentation_paused != default ? 0x20 : 0)), - call = call, - participant = participant, - muted = muted ?? default, - volume = volume ?? default, - raise_hand = raise_hand ?? default, - video_stopped = video_stopped ?? default, - video_paused = video_paused ?? default, - presentation_paused = presentation_paused ?? default, - }); - - /// Edit the title of a group call or livestream See Possible codes: 400,403 (details) - /// Group call - /// New title - public static Task Phone_EditGroupCallTitle(this Client client, InputGroupCallBase call, string title) - => client.Invoke(new Phone_EditGroupCallTitle - { - call = call, - title = title, - }); - - /// Get a list of peers that can be used to join a group call, presenting yourself as a specific user/channel. See Possible codes: 400 (details) - /// The dialog whose group call or livestream we're trying to join - public static Task Phone_GetGroupCallJoinAs(this Client client, InputPeer peer) - => client.Invoke(new Phone_GetGroupCallJoinAs - { - peer = peer, - }); - - /// Get an invite link for a group call or livestream See Possible codes: 400,403 (details) - /// For livestreams or muted group chats, if set, users that join using this link will be able to speak without explicitly requesting permission by (for example by raising their hand). - /// The group call - public static Task Phone_ExportGroupCallInvite(this Client client, InputGroupCallBase call, bool can_self_unmute = false) - => client.Invoke(new Phone_ExportGroupCallInvite - { - flags = (Phone_ExportGroupCallInvite.Flags)(can_self_unmute ? 0x1 : 0), - call = call, - }); - - /// Subscribe or unsubscribe to a scheduled group call See Possible codes: 400,403 (details) - /// Scheduled group call - /// Enable or disable subscription - public static Task Phone_ToggleGroupCallStartSubscription(this Client client, InputGroupCallBase call, bool subscribed) - => client.Invoke(new Phone_ToggleGroupCallStartSubscription - { - call = call, - subscribed = subscribed, - }); - - /// Start a scheduled group call. See Possible codes: 400,403 (details) - /// The scheduled group call - public static Task Phone_StartScheduledGroupCall(this Client client, InputGroupCallBase call) - => client.Invoke(new Phone_StartScheduledGroupCall - { - call = call, - }); - - /// Set the default peer that will be used to join a group call in a specific dialog. See Possible codes: 400 (details) - /// The dialog - /// The default peer that will be used to join group calls in this dialog, presenting yourself as a specific user/channel. - public static Task Phone_SaveDefaultGroupCallJoinAs(this Client client, InputPeer peer, InputPeer join_as) - => client.Invoke(new Phone_SaveDefaultGroupCallJoinAs - { - peer = peer, - join_as = join_as, - }); - - /// Start screen sharing in a call See Possible codes: 400,403 (details) - /// The group call - /// WebRTC parameters - public static Task Phone_JoinGroupCallPresentation(this Client client, InputGroupCallBase call, DataJSON params_) - => client.Invoke(new Phone_JoinGroupCallPresentation - { - call = call, - params_ = params_, - }); - - /// Stop screen sharing in a group call See Possible codes: 400 (details) - /// The group call - public static Task Phone_LeaveGroupCallPresentation(this Client client, InputGroupCallBase call) - => client.Invoke(new Phone_LeaveGroupCallPresentation - { - call = call, - }); - - /// Get info about RTMP streams in a group call or livestream.
This method should be invoked to the same group/channel-related DC used for downloading livestream chunks.
As usual, the media DC is preferred, if available. See Possible codes: 400 (details)
- /// Group call or livestream - public static Task Phone_GetGroupCallStreamChannels(this Client client, InputGroupCallBase call) - => client.Invoke(new Phone_GetGroupCallStreamChannels - { - 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) - /// 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, bool live_story = false) - => client.Invoke(new Phone_GetGroupCallStreamRtmpUrl - { - flags = (Phone_GetGroupCallStreamRtmpUrl.Flags)(live_story ? 0x1 : 0), - peer = peer, - revoke = revoke, - }); - - /// Save phone call debug information See Possible codes: 400 (details) - /// Phone call - /// Logs - public static Task Phone_SaveCallLog(this Client client, InputPhoneCall peer, InputFileBase file) - => client.Invoke(new Phone_SaveCallLog - { - peer = peer, - file = file, - }); - - /// Create and optionally join a new conference call. See - /// If set, mute our microphone when joining the call (can only be used if join is set). - /// If set, our video stream is disabled (can only be used if join is set). - /// If set, also join the call, otherwise just create the call link. - /// Unique client message ID required to prevent creation of duplicate group calls. - /// Public key (can only be used if join is set). - /// Initial blockchain block (can only be used if join is set). - /// Parameters from tgcalls (can only be used if join is set). - public static Task Phone_CreateConferenceCall(this Client client, int random_id, Int256? public_key = null, byte[] block = null, DataJSON params_ = null, bool muted = false, bool video_stopped = false, bool join = false) - => client.Invoke(new Phone_CreateConferenceCall - { - flags = (Phone_CreateConferenceCall.Flags)((public_key != null ? 0x8 : 0) | (block != null ? 0x8 : 0) | (params_ != null ? 0x8 : 0) | (muted ? 0x1 : 0) | (video_stopped ? 0x4 : 0) | (join ? 0x8 : 0)), - random_id = random_id, - public_key = public_key ?? default, - block = block, - params_ = params_, - }); - - /// Remove participants from a conference call. See Possible codes: 400 (details) - /// Whether this is a removal of members that already left the conference call. - /// Whether this is a forced removal of active members in a conference call. - /// The conference call. - /// IDs of users to remove. - /// The block containing an appropriate e2e.chain.changeSetGroupState event - public static Task Phone_DeleteConferenceCallParticipants(this Client client, InputGroupCallBase call, long[] ids, byte[] block, bool only_left = false, bool kick = false) - => client.Invoke(new Phone_DeleteConferenceCallParticipants - { - flags = (Phone_DeleteConferenceCallParticipants.Flags)((only_left ? 0x1 : 0) | (kick ? 0x2 : 0)), - call = call, - ids = ids, - block = block, - }); - - /// Broadcast a blockchain block to all members of a conference call, see here » for more info. See Possible codes: 400 (details) - /// The conference where to broadcast the block. - /// The block to broadcast. - public static Task Phone_SendConferenceCallBroadcast(this Client client, InputGroupCallBase call, byte[] block) - => client.Invoke(new Phone_SendConferenceCallBroadcast - { - call = call, - block = block, - }); - - /// Invite a user to a conference call. See Possible codes: 400 (details) - /// Invite the user to also turn on their video feed. - /// The conference call. - /// The user to invite. - public static Task Phone_InviteConferenceCallParticipant(this Client client, InputGroupCallBase call, InputUserBase user_id, bool video = false) - => client.Invoke(new Phone_InviteConferenceCallParticipant - { - flags = (Phone_InviteConferenceCallParticipant.Flags)(video ? 0x1 : 0), - call = call, - user_id = user_id, - }); - - /// Declines a conference call invite. See Possible codes: 400 (details) - /// The ID of the to decline. - public static Task Phone_DeclineConferenceCallInvite(this Client client, int msg_id) - => client.Invoke(new Phone_DeclineConferenceCallInvite - { - msg_id = msg_id, - }); - - /// Fetch the blocks of a conference blockchain ». See Possible codes: 400 (details) - /// The conference. - /// Subchain ID. - /// Offset for pagination. - /// Maximum number of blocks to return in this call, see pagination - public static Task Phone_GetGroupCallChainBlocks(this Client client, InputGroupCallBase call, int sub_chain_id, int offset = default, int limit = int.MaxValue) - => client.Invoke(new Phone_GetGroupCallChainBlocks - { - call = call, - sub_chain_id = sub_chain_id, - offset = offset, - limit = limit, - }); - - /// See Possible codes: 400 (details) - /// You can use - public static Task Phone_SendGroupCallMessage(this Client client, InputGroupCallBase call, long random_id, TextWithEntities message, long? allow_paid_stars = null, InputPeer send_as = null) - => client.Invoke(new Phone_SendGroupCallMessage - { - flags = (Phone_SendGroupCallMessage.Flags)((allow_paid_stars != null ? 0x1 : 0) | (send_as != null ? 0x2 : 0)), - call = call, - random_id = random_id, - message = message, - allow_paid_stars = allow_paid_stars ?? default, - send_as = send_as, - }); - - /// See Possible codes: 400 (details) - public static Task Phone_SendGroupCallEncryptedMessage(this Client client, InputGroupCallBase call, byte[] encrypted_message) - => client.Invoke(new Phone_SendGroupCallEncryptedMessage - { - call = call, - encrypted_message = encrypted_message, - }); - - /// See Possible codes: 400 (details) - public static Task Phone_DeleteGroupCallMessages(this Client client, InputGroupCallBase call, int[] messages, bool report_spam = false) - => client.Invoke(new Phone_DeleteGroupCallMessages - { - flags = (Phone_DeleteGroupCallMessages.Flags)(report_spam ? 0x1 : 0), - call = call, - messages = messages, - }); - - /// See Possible codes: 400 (details) - public static Task Phone_DeleteGroupCallParticipantMessages(this Client client, InputGroupCallBase call, InputPeer participant, bool report_spam = false) - => client.Invoke(new Phone_DeleteGroupCallParticipantMessages - { - flags = (Phone_DeleteGroupCallParticipantMessages.Flags)(report_spam ? 0x1 : 0), - call = call, - participant = participant, - }); - - /// See Possible codes: 400 (details) - public static Task Phone_GetGroupCallStars(this Client client, InputGroupCallBase call) - => client.Invoke(new Phone_GetGroupCallStars - { - call = call, - }); - - /// See Possible codes: 400 (details) - public static Task Phone_SaveDefaultSendAs(this Client client, InputGroupCallBase call, InputPeer send_as) - => client.Invoke(new Phone_SaveDefaultSendAs - { - call = call, - send_as = send_as, - }); - - /// Get localization pack strings See Possible codes: 400 (details) - /// Platform identifier (i.e. android, tdesktop, etc). - /// Either an ISO 639-1 language code or a language pack name obtained from a language pack link. - public static Task Langpack_GetLangPack(this Client client, string lang_pack, string lang_code) - => client.Invoke(new Langpack_GetLangPack - { - lang_pack = lang_pack, - lang_code = lang_code, - }); - - /// Get strings from a language pack See Possible codes: 400 (details) - /// Platform identifier (i.e. android, tdesktop, etc). - /// Either an ISO 639-1 language code or a language pack name obtained from a language pack link. - /// Strings to get - public static Task Langpack_GetStrings(this Client client, string lang_pack, string lang_code, params string[] keys) - => client.Invoke(new Langpack_GetStrings - { - lang_pack = lang_pack, - lang_code = lang_code, - keys = keys, - }); - - /// Get new strings in language pack See Possible codes: 400 (details) - /// Platform identifier (i.e. android, tdesktop, etc). - /// Either an ISO 639-1 language code or a language pack name obtained from a language pack link. - /// Previous localization pack version - public static Task Langpack_GetDifference(this Client client, string lang_pack, string lang_code, int from_version) - => client.Invoke(new Langpack_GetDifference - { - lang_pack = lang_pack, - lang_code = lang_code, - from_version = from_version, - }); - - /// Get information about all languages in a localization pack See Possible codes: 400 (details) - /// Platform identifier (i.e. android, tdesktop, etc). - public static Task Langpack_GetLanguages(this Client client, string lang_pack) - => client.Invoke(new Langpack_GetLanguages - { - lang_pack = lang_pack, - }); - - /// Get information about a language in a localization pack See Possible codes: 400 (details) - /// Platform identifier (i.e. android, tdesktop, etc). - /// Either an ISO 639-1 language code or a language pack name obtained from a language pack link. - public static Task Langpack_GetLanguage(this Client client, string lang_pack, string lang_code) - => client.Invoke(new Langpack_GetLanguage - { - lang_pack = lang_pack, - lang_code = lang_code, - }); - - /// Edit peers in peer folder See Possible codes: 400 (details) - /// New peer list - public static Task Folders_EditPeerFolders(this Client client, params InputFolderPeer[] folder_peers) - => client.Invoke(new Folders_EditPeerFolders - { - folder_peers = folder_peers, - }); - - /// Get channel statistics See Possible codes: 400,403 (details) - /// Whether to enable dark theme for graph colors - /// The channel - public static Task Stats_GetBroadcastStats(this Client client, InputChannelBase channel, bool dark = false) - => client.Invoke(new Stats_GetBroadcastStats - { - flags = (Stats_GetBroadcastStats.Flags)(dark ? 0x1 : 0), - channel = channel, - }); - - /// Load channel statistics graph asynchronously See Possible codes: 400 (details) - /// Graph token from - /// Zoom value, if required - public static Task Stats_LoadAsyncGraph(this Client client, string token, long? x = null) - => client.Invoke(new Stats_LoadAsyncGraph - { - flags = (Stats_LoadAsyncGraph.Flags)(x != null ? 0x1 : 0), - token = token, - x = x ?? default, - }); - - /// Get supergroup statistics See Possible codes: 400,403 (details) - /// Whether to enable dark theme for graph colors - /// Supergroup ID - public static Task Stats_GetMegagroupStats(this Client client, InputChannelBase channel, bool dark = false) - => client.Invoke(new Stats_GetMegagroupStats - { - flags = (Stats_GetMegagroupStats.Flags)(dark ? 0x1 : 0), - channel = channel, - }); - - /// 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 - /// Offset for pagination, empty string on first call, then use the next_offset field of the returned constructor (if present, otherwise no more results are available). - /// Maximum number of results to return, see pagination - public static Task Stats_GetMessagePublicForwards(this Client client, InputChannelBase channel, int msg_id, string offset, int limit = int.MaxValue) - => client.Invoke(new Stats_GetMessagePublicForwards - { - channel = channel, - msg_id = msg_id, - offset = offset, - limit = limit, - }); - - /// Get message statistics See Possible codes: 400 (details) - /// Whether to enable dark theme for graph colors - /// Channel ID - /// Message ID - public static Task Stats_GetMessageStats(this Client client, InputChannelBase channel, int msg_id, bool dark = false) - => client.Invoke(new Stats_GetMessageStats - { - flags = (Stats_GetMessageStats.Flags)(dark ? 0x1 : 0), - channel = channel, - msg_id = msg_id, - }); - - /// Get statistics for a certain story. See Possible codes: 400 (details) - /// Whether to enable the dark theme for graph colors - /// The peer that posted the story - /// Story ID - public static Task Stats_GetStoryStats(this Client client, InputPeer peer, int id, bool dark = false) - => client.Invoke(new Stats_GetStoryStats - { - flags = (Stats_GetStoryStats.Flags)(dark ? 0x1 : 0), - peer = peer, - id = id, - }); - - /// Obtain forwards of a story as a message to public chats and reposts by public channels. See Possible codes: 400 (details) - /// Peer where the story was originally posted - /// Story ID - /// Offset for pagination, from .next_offset. - /// Maximum number of results to return, see pagination - public static Task Stats_GetStoryPublicForwards(this Client client, InputPeer peer, int id, string offset, int limit = int.MaxValue) - => client.Invoke(new Stats_GetStoryPublicForwards - { - peer = peer, - id = id, - offset = offset, - limit = limit, - }); - - /// Export a folder », creating a chat folder deep link ». See Possible codes: 400 (details) - /// The folder to export - /// An optional name for the link - /// The list of channels, group and supergroups to share with the link. Basic groups will automatically be converted to supergroups when invoking the method. - public static Task Chatlists_ExportChatlistInvite(this Client client, InputChatlist chatlist, string title, params InputPeer[] peers) - => client.Invoke(new Chatlists_ExportChatlistInvite - { - chatlist = chatlist, - title = title, - peers = peers, - }); - - /// Delete a previously created chat folder deep link ». See Possible codes: 400 (details) - /// The related folder - /// slug obtained from the chat folder deep link ». - public static Task Chatlists_DeleteExportedInvite(this Client client, InputChatlist chatlist, string slug) - => client.Invoke(new Chatlists_DeleteExportedInvite - { - chatlist = chatlist, - slug = slug, - }); - - /// Edit a chat folder deep link ». See Possible codes: 400 (details) - /// Folder ID - /// slug obtained from the chat folder deep link ». - /// If set, sets a new name for the link - /// If set, changes the list of peers shared with the link - public static Task Chatlists_EditExportedInvite(this Client client, InputChatlist chatlist, string slug, string title = null, InputPeer[] peers = null) - => client.Invoke(new Chatlists_EditExportedInvite - { - flags = (Chatlists_EditExportedInvite.Flags)((title != null ? 0x2 : 0) | (peers != null ? 0x4 : 0)), - chatlist = chatlist, - slug = slug, - title = title, - peers = peers, - }); - - /// List all chat folder deep links » associated to a folder See Possible codes: 400 (details) - /// The folder - public static Task Chatlists_GetExportedInvites(this Client client, InputChatlist chatlist) - => client.Invoke(new Chatlists_GetExportedInvites - { - chatlist = chatlist, - }); - - /// Obtain information about a chat folder deep link ». See Possible codes: 400 (details) - /// slug obtained from the chat folder deep link » - public static Task Chatlists_CheckChatlistInvite(this Client client, string slug) - => client.Invoke(new Chatlists_CheckChatlistInvite - { - slug = slug, - }); - - /// Import a chat folder deep link », joining some or all the chats in the folder. See Possible codes: 400 (details) - /// slug obtained from a chat folder deep link ». - /// List of new chats to join, fetched using Chatlists_CheckChatlistInvite and filtered as specified in the documentation ». - public static Task Chatlists_JoinChatlistInvite(this Client client, string slug, params InputPeer[] peers) - => client.Invoke(new Chatlists_JoinChatlistInvite - { - slug = slug, - peers = peers, - }); - - /// Fetch new chats associated with an imported chat folder deep link ». Must be invoked at most every chatlist_update_period seconds (as per the related client configuration parameter »). See Possible codes: 400 (details) - /// The folder - public static Task Chatlists_GetChatlistUpdates(this Client client, InputChatlist chatlist) - => client.Invoke(new Chatlists_GetChatlistUpdates - { - chatlist = chatlist, - }); - - /// Join channels and supergroups recently added to a chat folder deep link ». See Possible codes: 400 (details) - /// The folder - /// List of new chats to join, fetched using Chatlists_GetChatlistUpdates and filtered as specified in the documentation ». - public static Task Chatlists_JoinChatlistUpdates(this Client client, InputChatlist chatlist, params InputPeer[] peers) - => client.Invoke(new Chatlists_JoinChatlistUpdates - { - chatlist = chatlist, - peers = peers, - }); - - /// Dismiss new pending peers recently added to a chat folder deep link ». See Possible codes: 400 (details) - /// The folder - public static Task Chatlists_HideChatlistUpdates(this Client client, InputChatlist chatlist) - => client.Invoke(new Chatlists_HideChatlistUpdates - { - chatlist = chatlist, - }); - - /// Returns identifiers of pinned or always included chats from a chat folder imported using a chat folder deep link », which are suggested to be left when the chat folder is deleted. See Possible codes: 400 (details) - /// Folder ID - public static Task Chatlists_GetLeaveChatlistSuggestions(this Client client, InputChatlist chatlist) - => client.Invoke(new Chatlists_GetLeaveChatlistSuggestions - { - chatlist = chatlist, - }); - - /// Delete a folder imported using a chat folder deep link » See Possible codes: 400 (details) - /// Folder ID - /// Also leave the specified channels and groups - public static Task Chatlists_LeaveChatlist(this Client client, InputChatlist chatlist, params InputPeer[] peers) - => client.Invoke(new Chatlists_LeaveChatlist - { - chatlist = chatlist, - peers = peers, - }); - - /// Check whether we can post stories as the specified peer. See Possible codes: 400 (details) - /// The peer from which we wish to post stories. - public static Task Stories_CanSendStory(this Client client, InputPeer peer) - => client.Invoke(new Stories_CanSendStory - { - peer = peer, - }); - - /// Uploads a Telegram Story. See [bots: ✓] Possible codes: 400,403 (details) - /// Whether to add the story to the profile automatically upon expiration. If not set, the story will only be added to the archive, see here » for more info. - /// If set, disables forwards, screenshots, and downloads. - /// Set this flag when reposting stories with fwd_from_id+fwd_from_id, if the media was modified before reposting. - /// The peer to send the story as. - /// The story media. - /// Media areas associated to the story, see here » for more info. - /// Story caption. - /// Message entities for styled text, if allowed by the stories_entities client configuration parameter ». - /// Privacy rules for the story, indicating who can or can't view the story. - /// Unique client message ID required to prevent message resending. You can use - /// Period after which the story is moved to archive (and to the profile if pinned is set), in seconds; must be one of 6 * 3600, 12 * 3600, 86400, or 2 * 86400 for Telegram Premium users, and 86400 otherwise. - /// If set, indicates that this story is a repost of story with ID fwd_from_story posted by the peer in fwd_from_id. - /// If set, indicates that this story is a repost of story with ID fwd_from_story posted by the peer in fwd_from_id. - /// If set, adds the story to the specified albums. - public static Task Stories_SendStory(this Client client, InputPeer peer, InputMedia media, InputPrivacyRule[] privacy_rules, long random_id, string caption = null, MessageEntity[] entities = null, int? period = null, MediaArea[] media_areas = null, InputPeer fwd_from_id = null, int? fwd_from_story = null, int[] albums = null, bool pinned = false, bool noforwards = false, bool fwd_modified = false) - => client.Invoke(new Stories_SendStory - { - flags = (Stories_SendStory.Flags)((caption != null ? 0x1 : 0) | (entities != null ? 0x2 : 0) | (period != null ? 0x8 : 0) | (media_areas != null ? 0x20 : 0) | (fwd_from_id != null ? 0x40 : 0) | (fwd_from_story != null ? 0x40 : 0) | (albums != null ? 0x100 : 0) | (pinned ? 0x4 : 0) | (noforwards ? 0x10 : 0) | (fwd_modified ? 0x80 : 0)), - peer = peer, - media = media, - media_areas = media_areas, - caption = caption, - entities = entities, - privacy_rules = privacy_rules, - random_id = random_id, - period = period ?? default, - fwd_from_id = fwd_from_id, - fwd_from_story = fwd_from_story ?? default, - albums = albums, - }); - - /// Edit an uploaded story See [bots: ✓] Possible codes: 400 (details) - /// Peer where the story was posted. - /// ID of story to edit. - /// If specified, replaces the story media. - /// Media areas associated to the story, see here » for more info. - /// If specified, replaces the story caption. - /// Message entities for styled text in the caption, if allowed by the stories_entities client configuration parameter ». - /// If specified, alters the privacy settings » of the story, changing who can or can't view the story. - public static Task Stories_EditStory(this Client client, InputPeer peer, int id, InputMedia media = null, string caption = null, MessageEntity[] entities = null, InputPrivacyRule[] privacy_rules = null, MediaArea[] media_areas = null) - => client.Invoke(new Stories_EditStory - { - flags = (Stories_EditStory.Flags)((media != null ? 0x1 : 0) | (caption != null ? 0x2 : 0) | (entities != null ? 0x2 : 0) | (privacy_rules != null ? 0x4 : 0) | (media_areas != null ? 0x8 : 0)), - peer = peer, - id = id, - media = media, - media_areas = media_areas, - caption = caption, - entities = entities, - privacy_rules = privacy_rules, - }); - - /// Deletes some posted stories. See Possible codes: 400,403 (details) - /// Channel/user from where to delete stories. - /// IDs of stories to delete. - public static Task Stories_DeleteStories(this Client client, InputPeer peer, params int[] id) - => client.Invoke(new Stories_DeleteStories - { - peer = peer, - id = id, - }); - - /// Pin or unpin one or more stories See Possible codes: 400 (details) - /// Peer where to pin or unpin stories - /// IDs of stories to pin or unpin - /// Whether to pin or unpin the stories - public static Task Stories_TogglePinned(this Client client, InputPeer peer, int[] id, bool pinned) - => client.Invoke(new Stories_TogglePinned - { - peer = peer, - id = id, - pinned = pinned, - }); - - /// Fetch the List of active (or active and hidden) stories, see here » for more info on watching stories. See - /// If next and state are both set, uses the passed state to paginate to the next results; if neither state nor next are set, fetches the initial page; if state is set and next is not set, check for changes in the active/hidden peerset, see here » for more info on the full flow. - /// If set, fetches the hidden active story list, otherwise fetches the active story list, see here » for more info on the full flow. - /// If next and state are both set, uses the passed state to paginate to the next results; if neither state nor next are set, fetches the initial page; if state is set and next is not set, check for changes in the active/hidden peerset, see here » for more info on the full flow. - public static Task Stories_GetAllStories(this Client client, string state = null, bool next = false, bool hidden = false) - => client.Invoke(new Stories_GetAllStories - { - flags = (Stories_GetAllStories.Flags)((state != null ? 0x1 : 0) | (next ? 0x2 : 0) | (hidden ? 0x4 : 0)), - state = state, - }); - - /// Fetch the stories pinned on a peer's profile. See Possible codes: 400 (details) - /// Peer whose pinned stories should be fetched - /// Offsets for pagination, for more info click here - /// Maximum number of results to return, see pagination - public static Task Stories_GetPinnedStories(this Client client, InputPeer peer, int offset_id = default, int limit = int.MaxValue) - => client.Invoke(new Stories_GetPinnedStories - { - peer = peer, - offset_id = offset_id, - limit = limit, - }); - - /// Fetch the story archive » of a peer we control. See Possible codes: 400 (details) - /// Peer whose archived stories should be fetched - /// Offsets for pagination, for more info click here - /// Maximum number of results to return, see pagination - public static Task Stories_GetStoriesArchive(this Client client, InputPeer peer, int offset_id = default, int limit = int.MaxValue) - => client.Invoke(new Stories_GetStoriesArchive - { - peer = peer, - offset_id = offset_id, - limit = limit, - }); - - /// Obtain full info about a set of stories by their IDs. See Possible codes: 400 (details) - /// Peer where the stories were posted - /// Story IDs - public static Task Stories_GetStoriesByID(this Client client, InputPeer peer, params int[] id) - => client.Invoke(new Stories_GetStoriesByID - { - peer = peer, - id = id, - }); - - /// Hide the active stories of a specific peer, preventing them from being displayed on the action bar on the homescreen. See - /// Whether to hide or unhide all active stories of the peer - public static Task Stories_ToggleAllStoriesHidden(this Client client, bool hidden) - => client.Invoke(new Stories_ToggleAllStoriesHidden - { - hidden = hidden, - }); - - /// Mark all stories up to a certain ID as read, for a given peer; will emit an update to all logged-in sessions. See Possible codes: 400 (details) - /// The peer whose stories should be marked as read. - /// Mark all stories up to and including this ID as read - public static Task Stories_ReadStories(this Client client, InputPeer peer, int max_id = default) - => client.Invoke(new Stories_ReadStories - { - peer = peer, - max_id = max_id, - }); - - /// Increment the view counter of one or more stories. See Possible codes: 400 (details) - /// Peer where the stories were posted. - /// IDs of the stories (maximum 200 at a time). - public static Task Stories_IncrementStoryViews(this Client client, InputPeer peer, params int[] id) - => client.Invoke(new Stories_IncrementStoryViews - { - peer = peer, - id = id, - }); - - /// Obtain the list of users that have viewed a specific story we posted See Possible codes: 400 (details) - /// Whether to only fetch view reaction/views made by our contacts - /// Whether to return info about users that reacted to the story (i.e. if set, the server will first sort results by view date as usual, and then also additionally sort the list by putting s with an associated reaction first in the list). Ignored if forwards_first is set. - /// If set, returns forwards and reposts first, then reactions, then other views; otherwise returns interactions sorted just by interaction date. - /// Peer where the story was posted - /// Search for specific peers - /// Story ID - /// Offset for pagination, obtained from .next_offset - /// Maximum number of results to return, see pagination - public static Task Stories_GetStoryViewsList(this Client client, InputPeer peer, int id, string offset, int limit = int.MaxValue, string q = null, bool just_contacts = false, bool reactions_first = false, bool forwards_first = false) - => client.Invoke(new Stories_GetStoryViewsList - { - flags = (Stories_GetStoryViewsList.Flags)((q != null ? 0x2 : 0) | (just_contacts ? 0x1 : 0) | (reactions_first ? 0x4 : 0) | (forwards_first ? 0x8 : 0)), - peer = peer, - q = q, - id = id, - offset = offset, - limit = limit, - }); - - /// Obtain info about the view count, forward count, reactions and recent viewers of one or more stories. See Possible codes: 400 (details) - /// Peer whose stories should be fetched - /// Story IDs - public static Task Stories_GetStoriesViews(this Client client, InputPeer peer, params int[] id) - => client.Invoke(new Stories_GetStoriesViews - { - peer = peer, - id = id, - }); - - /// Generate a story deep link for a specific story See Possible codes: 400 (details) - /// Peer where the story was posted - /// Story ID - public static Task Stories_ExportStoryLink(this Client client, InputPeer peer, int id) - => client.Invoke(new Stories_ExportStoryLink - { - peer = peer, - id = id, - }); - - /// Report a story. See Possible codes: 400 (details) - /// The peer that uploaded the story. - /// IDs of the stories to report. - /// Menu option, intially empty - /// Comment for report moderation - public static Task Stories_Report(this Client client, InputPeer peer, int[] id, byte[] option, string message) - => client.Invoke(new Stories_Report - { - peer = peer, - id = id, - option = option, - message = message, - }); - - /// Activates stories stealth mode, see here » for more info. See Possible codes: 400 (details) - /// Whether to erase views from any stories opened in the past stories_stealth_past_period seconds », as specified by the client configuration. - /// Whether to hide future story views for the next stories_stealth_future_period seconds », as specified by the client configuration. - public static Task Stories_ActivateStealthMode(this Client client, bool past = false, bool future = false) - => client.Invoke(new Stories_ActivateStealthMode - { - flags = (Stories_ActivateStealthMode.Flags)((past ? 0x1 : 0) | (future ? 0x2 : 0)), - }); - - /// React to a story. See Possible codes: 400 (details) - /// Whether to add this reaction to the recent reactions list ». - /// The peer that sent the story - /// ID of the story to react to - /// Reaction - public static Task Stories_SendReaction(this Client client, InputPeer peer, int story_id, Reaction reaction, bool add_to_recent = false) - => client.Invoke(new Stories_SendReaction - { - flags = (Stories_SendReaction.Flags)(add_to_recent ? 0x1 : 0), - peer = peer, - story_id = story_id, - reaction = reaction, - }); - - /// Fetch the full active story list of a specific peer. See Possible codes: 400 (details) - /// Peer whose stories should be fetched - public static Task Stories_GetPeerStories(this Client client, InputPeer peer) - => client.Invoke(new Stories_GetPeerStories - { - peer = peer, - }); - - /// Obtain the latest read story ID for all peers when first logging in, returned as a list of updates, see here » for more info. See - public static Task Stories_GetAllReadPeerStories(this Client client) - => client.Invoke(new Stories_GetAllReadPeerStories - { - }); - - /// Get the IDs of the maximum read stories for a set of peers. See - /// Peers - public static Task Stories_GetPeerMaxIDs(this Client client, params InputPeer[] id) - => client.Invoke(new Stories_GetPeerMaxIDs - { - id = id, - }); - - /// Obtain a list of channels where the user can post stories See - public static Task Stories_GetChatsToSend(this Client client) - => client.Invoke(new Stories_GetChatsToSend - { - }); - - /// Hide the active stories of a user, preventing them from being displayed on the action bar on the homescreen, see here » for more info. See Possible codes: 400 (details) - /// Peer whose stories should be (un)hidden. - /// Whether to hide or unhide stories. - public static Task Stories_TogglePeerStoriesHidden(this Client client, InputPeer peer, bool hidden) - => client.Invoke(new Stories_TogglePeerStoriesHidden - { - peer = peer, - hidden = hidden, - }); - - /// Get the reaction and interaction list of a story posted to a channel, along with the sender of each reaction. See Possible codes: 400 (details) - /// If set, returns forwards and reposts first, then reactions, then other views; otherwise returns interactions sorted just by interaction date. - /// Channel - /// Story ID - /// Get only reactions of this type - /// Offset for pagination (taken from the next_offset field of the returned ); empty in the first request. - /// Maximum number of results to return, see pagination - public static Task Stories_GetStoryReactionsList(this Client client, InputPeer peer, int id, int limit = int.MaxValue, Reaction reaction = null, string offset = null, bool forwards_first = false) - => client.Invoke(new Stories_GetStoryReactionsList - { - flags = (Stories_GetStoryReactionsList.Flags)((reaction != null ? 0x1 : 0) | (offset != null ? 0x2 : 0) | (forwards_first ? 0x4 : 0)), - peer = peer, - id = id, - reaction = reaction, - offset = offset, - limit = limit, - }); - - /// Pin some stories to the top of the profile, see here » for more info. See Possible codes: 400 (details) - /// Peer where to pin stories. - /// IDs of the stories to pin (max stories_pinned_to_top_count_max). - public static Task Stories_TogglePinnedToTop(this Client client, InputPeer peer, params int[] id) - => client.Invoke(new Stories_TogglePinnedToTop - { - peer = peer, - id = id, - }); - - /// Globally search for stories using a hashtag or a location media area, see here » for more info on the full flow. See Possible codes: 400 (details) - /// Hashtag (without the #) - /// A or a .
Note areas may be searched only if they have an associated address. - /// If set, returns only stories posted by this peer. - /// Offset for pagination: initially an empty string, then the next_offset from the previously returned . - /// Maximum number of results to return, see pagination - public static Task Stories_SearchPosts(this Client client, string offset, int limit = int.MaxValue, string hashtag = null, MediaArea area = null, InputPeer peer = null) - => client.Invoke(new Stories_SearchPosts - { - flags = (Stories_SearchPosts.Flags)((hashtag != null ? 0x1 : 0) | (area != null ? 0x2 : 0) | (peer != null ? 0x4 : 0)), - hashtag = hashtag, - area = area, - peer = peer, - offset = offset, - limit = limit, - }); - - /// Creates a story album. See Possible codes: 400 (details) - /// The owned peer where to create the album. - /// Album name. - /// Stories to add to the album. - public static Task Stories_CreateAlbum(this Client client, InputPeer peer, string title, params int[] stories) - => client.Invoke(new Stories_CreateAlbum - { - peer = peer, - title = title, - stories = stories, - }); - - /// Rename a story albums », or add, delete or reorder stories in it. See Possible codes: 400 (details) - /// Peer where the album is posted. - /// Album ID. - /// New album title. - /// If set, deletes the specified stories from the album. - /// If set, adds the specified stories to the album. - /// If set, reorders the stories in the album by their IDs. - public static Task Stories_UpdateAlbum(this Client client, InputPeer peer, int album_id, string title = null, int[] delete_stories = null, int[] add_stories = null, int[] order = null) - => client.Invoke(new Stories_UpdateAlbum - { - flags = (Stories_UpdateAlbum.Flags)((title != null ? 0x1 : 0) | (delete_stories != null ? 0x2 : 0) | (add_stories != null ? 0x4 : 0) | (order != null ? 0x8 : 0)), - peer = peer, - album_id = album_id, - title = title, - delete_stories = delete_stories, - add_stories = add_stories, - order = order, - }); - - /// Reorder story albums on a profile ». See Possible codes: 400 (details) - /// Peer where the albums are located. - /// New order of the albums. - public static Task Stories_ReorderAlbums(this Client client, InputPeer peer, params int[] order) - => client.Invoke(new Stories_ReorderAlbums - { - peer = peer, - order = order, - }); - - /// Delete a story album. See Possible codes: 400 (details) - /// Owned peer where the album is located. - /// ID of the album to delete. - public static Task Stories_DeleteAlbum(this Client client, InputPeer peer, int album_id) - => client.Invoke(new Stories_DeleteAlbum - { - peer = peer, - album_id = album_id, - }); - - /// Get story albums created by a peer. See Possible codes: 400 (details) - /// The peer. - /// The hash from a previously returned , to avoid returning any results if they haven't changed. - /// a null value means stories.albumsNotModified - public static Task Stories_GetAlbums(this Client client, InputPeer peer, long hash = default) - => client.Invoke(new Stories_GetAlbums - { - peer = peer, - hash = hash, - }); - - /// Get stories in a story album ». See Possible codes: 400 (details) - /// Peer where the album is posted. - /// ID of the album. - /// Offset for pagination. - /// Maximum number of results to return, see pagination - public static Task Stories_GetAlbumStories(this Client client, InputPeer peer, int album_id, int offset = default, int limit = int.MaxValue) - => client.Invoke(new Stories_GetAlbumStories - { - peer = peer, - album_id = album_id, - offset = offset, - limit = limit, - }); - - /// See Possible codes: 400 (details) - /// Message entities for styled text - /// You can use - public static Task Stories_StartLive(this Client client, InputPeer peer, InputPrivacyRule[] privacy_rules, long random_id, string caption = null, MessageEntity[] entities = null, bool? messages_enabled = default, long? send_paid_messages_stars = null, bool pinned = false, bool noforwards = false, bool rtmp_stream = false) - => client.Invoke(new Stories_StartLive - { - flags = (Stories_StartLive.Flags)((caption != null ? 0x1 : 0) | (entities != null ? 0x2 : 0) | (messages_enabled != default ? 0x40 : 0) | (send_paid_messages_stars != null ? 0x80 : 0) | (pinned ? 0x4 : 0) | (noforwards ? 0x10 : 0) | (rtmp_stream ? 0x20 : 0)), - peer = peer, - caption = caption, - entities = entities, - privacy_rules = privacy_rules, - random_id = random_id, - messages_enabled = messages_enabled ?? default, - send_paid_messages_stars = send_paid_messages_stars ?? default, - }); - - /// Obtains info about the boosts that were applied to a certain channel or supergroup (admins only) See Possible codes: 400 (details) - /// Whether to return only info about boosts received from gift codes and giveaways created by the channel/supergroup » - /// The channel/supergroup - /// Offset for pagination, obtained from .next_offset - /// Maximum number of results to return, see pagination - public static Task Premium_GetBoostsList(this Client client, InputPeer peer, string offset, int limit = int.MaxValue, bool gifts = false) - => client.Invoke(new Premium_GetBoostsList - { - flags = (Premium_GetBoostsList.Flags)(gifts ? 0x1 : 0), - peer = peer, - offset = offset, - limit = limit, - }); - - /// Obtain which peers are we currently boosting, and how many boost slots we have left. See - public static Task Premium_GetMyBoosts(this Client client) - => client.Invoke(new Premium_GetMyBoosts - { - }); - - /// Apply one or more boosts » to a peer. See Possible codes: 400 (details) - /// Which boost slots to assign to this peer. - /// The peer to boost. - public static Task Premium_ApplyBoost(this Client client, InputPeer peer, int[] slots = null) - => client.Invoke(new Premium_ApplyBoost - { - flags = (Premium_ApplyBoost.Flags)(slots != null ? 0x1 : 0), - slots = slots, - peer = peer, - }); - - /// Gets the current number of boosts of a channel/supergroup. See Possible codes: 400 (details) - /// The peer. - public static Task Premium_GetBoostsStatus(this Client client, InputPeer peer) - => client.Invoke(new Premium_GetBoostsStatus - { - peer = peer, - }); - - /// Returns the lists of boost that were applied to a channel/supergroup by a specific user (admins only) See [bots: ✓] Possible codes: 400 (details) - /// The channel/supergroup - /// The user - public static Task Premium_GetUserBoosts(this Client client, InputPeer peer, InputUserBase user_id) - => client.Invoke(new Premium_GetUserBoosts - { - peer = peer, - user_id = user_id, - }); - - /// Check if we can process SMS jobs (official clients only). See Possible codes: 403 (details) - public static Task Smsjobs_IsEligibleToJoin(this Client client) - => client.Invoke(new Smsjobs_IsEligibleToJoin - { - }); - - /// Enable SMS jobs (official clients only). See Possible codes: 400 (details) - public static Task Smsjobs_Join(this Client client) - => client.Invoke(new Smsjobs_Join - { - }); - - /// Disable SMS jobs (official clients only). See Possible codes: 400 (details) - public static Task Smsjobs_Leave(this Client client) - => client.Invoke(new Smsjobs_Leave - { - }); - - /// Update SMS job settings (official clients only). See Possible codes: 400 (details) - /// Allow international numbers? - public static Task Smsjobs_UpdateSettings(this Client client, bool allow_international = false) - => client.Invoke(new Smsjobs_UpdateSettings - { - flags = (Smsjobs_UpdateSettings.Flags)(allow_international ? 0x1 : 0), - }); - - /// Get SMS jobs status (official clients only). See Possible codes: 400 (details) - public static Task Smsjobs_GetStatus(this Client client) - => client.Invoke(new Smsjobs_GetStatus - { - }); - - /// Get info about an SMS job (official clients only). See Possible codes: 400 (details) - /// Job ID - public static Task Smsjobs_GetSmsJob(this Client client, string job_id) - => client.Invoke(new Smsjobs_GetSmsJob - { - job_id = job_id, - }); - - /// Finish an SMS job (official clients only). See Possible codes: 400 (details) - /// Job ID. - /// If failed, the error. - public static Task Smsjobs_FinishJob(this Client client, string job_id, string error = null) - => client.Invoke(new Smsjobs_FinishJob - { - flags = (Smsjobs_FinishJob.Flags)(error != null ? 0x1 : 0), - job_id = job_id, - error = error, - }); - - /// Fetch information about a fragment collectible, see here » for more info on the full flow. See Possible codes: 400 (details) - /// Collectible to fetch info about. - public static Task Fragment_GetCollectibleInfo(this Client client, InputCollectible collectible) - => client.Invoke(new Fragment_GetCollectibleInfo - { - collectible = collectible, - }); - } -} - -namespace TL.Methods -{ - #pragma warning disable IDE1006 - [TLDef(0xCB9F372D)] - public sealed partial class InvokeAfterMsg : IMethod - { - public long msg_id; - public IMethod query; - } - - [TLDef(0x3DC4B4F0)] - public sealed partial class InvokeAfterMsgs : IMethod - { - public long[] msg_ids; - public IMethod query; - } - - [TLDef(0xC1CD5EA9)] - public sealed partial class InitConnection : IMethod - { - public Flags flags; - public int api_id; - public string device_model; - public string system_version; - public string app_version; - public string system_lang_code; - public string lang_pack; - public string lang_code; - [IfFlag(0)] public InputClientProxy proxy; - [IfFlag(1)] public JSONValue params_; - public IMethod query; - - [Flags] public enum Flags : uint - { - has_proxy = 0x1, - has_params = 0x2, - } - } - - [TLDef(0xDA9B0D0D)] - public sealed partial class InvokeWithLayer : IMethod - { - public int layer; - public IMethod query; - } - - [TLDef(0xBF9459B7)] - public sealed partial class InvokeWithoutUpdates : IMethod - { - public IMethod query; - } - - [TLDef(0x365275F2)] - public sealed partial class InvokeWithMessagesRange : IMethod - { - public MessageRange range; - public IMethod query; - } - - [TLDef(0xACA9FD2E)] - public sealed partial class InvokeWithTakeout : IMethod - { - public long takeout_id; - public IMethod query; - } - - [TLDef(0xDD289F8E)] - public sealed partial class InvokeWithBusinessConnection : IMethod - { - public string connection_id; - public IMethod query; - } - - [TLDef(0x1DF92984)] - public sealed partial class InvokeWithGooglePlayIntegrity : IMethod - { - public string nonce; - public string token; - public IMethod query; - } - - [TLDef(0x0DAE54F8)] - public sealed partial class InvokeWithApnsSecret : IMethod - { - public string nonce; - public string secret; - public IMethod query; - } - - [TLDef(0xADBB0F94)] - public sealed partial class InvokeWithReCaptcha : IMethod - { - public string token; - public IMethod query; - } - - [TLDef(0xA677244F)] - public sealed partial class Auth_SendCode : IMethod - { - public string phone_number; - public int api_id; - public string api_hash; - public CodeSettings settings; - } - - [TLDef(0xAAC7B717)] - public sealed partial class Auth_SignUp : IMethod - { - public Flags flags; - public string phone_number; - public string phone_code_hash; - public string first_name; - public string last_name; - - [Flags] public enum Flags : uint - { - no_joined_notifications = 0x1, - } - } - - [TLDef(0x8D52A951)] - public sealed partial class Auth_SignIn : IMethod - { - public Flags flags; - public string phone_number; - public string phone_code_hash; - [IfFlag(0)] public string phone_code; - [IfFlag(1)] public EmailVerification email_verification; - - [Flags] public enum Flags : uint - { - has_phone_code = 0x1, - has_email_verification = 0x2, - } - } - - [TLDef(0x3E72BA19)] - public sealed partial class Auth_LogOut : IMethod { } - - [TLDef(0x9FAB0D1A)] - public sealed partial class Auth_ResetAuthorizations : IMethod { } - - [TLDef(0xE5BFFFCD)] - public sealed partial class Auth_ExportAuthorization : IMethod - { - public int dc_id; - } - - [TLDef(0xA57A7DAD)] - public sealed partial class Auth_ImportAuthorization : IMethod - { - public long id; - public byte[] bytes; - } - - [TLDef(0xCDD42A05)] - public sealed partial class Auth_BindTempAuthKey : IMethod - { - public long perm_auth_key_id; - public long nonce; - public DateTime expires_at; - public byte[] encrypted_message; - } - - [TLDef(0x67A3FF2C)] - public sealed partial class Auth_ImportBotAuthorization : IMethod - { - public int flags; - public int api_id; - public string api_hash; - public string bot_auth_token; - } - - [TLDef(0xD18B4D16)] - public sealed partial class Auth_CheckPassword : IMethod - { - public InputCheckPasswordSRP password; - } - - [TLDef(0xD897BC66)] - public sealed partial class Auth_RequestPasswordRecovery : IMethod { } - - [TLDef(0x37096C70)] - public sealed partial class Auth_RecoverPassword : IMethod - { - public Flags flags; - public string code; - [IfFlag(0)] public Account_PasswordInputSettings new_settings; - - [Flags] public enum Flags : uint - { - has_new_settings = 0x1, - } - } - - [TLDef(0xCAE47523)] - public sealed partial class Auth_ResendCode : IMethod - { - public Flags flags; - public string phone_number; - public string phone_code_hash; - [IfFlag(0)] public string reason; - - [Flags] public enum Flags : uint - { - has_reason = 0x1, - } - } - - [TLDef(0x1F040578)] - public sealed partial class Auth_CancelCode : IMethod - { - public string phone_number; - public string phone_code_hash; - } - - [TLDef(0x8E48A188)] - public sealed partial class Auth_DropTempAuthKeys : IMethod - { - public long[] except_auth_keys; - } - - [TLDef(0xB7E085FE)] - public sealed partial class Auth_ExportLoginToken : IMethod - { - public int api_id; - public string api_hash; - public long[] except_ids; - } - - [TLDef(0x95AC5CE4)] - public sealed partial class Auth_ImportLoginToken : IMethod - { - public byte[] token; - } - - [TLDef(0xE894AD4D)] - public sealed partial class Auth_AcceptLoginToken : IMethod - { - public byte[] token; - } - - [TLDef(0x0D36BF79)] - public sealed partial class Auth_CheckRecoveryPassword : IMethod - { - public string code; - } - - [TLDef(0x2DB873A9)] - public sealed partial class Auth_ImportWebTokenAuthorization : IMethod - { - public int api_id; - public string api_hash; - public string web_auth_token; - } - - [TLDef(0x8E39261E)] - public sealed partial class Auth_RequestFirebaseSms : IMethod - { - public Flags flags; - public string phone_number; - public string phone_code_hash; - [IfFlag(0)] public string safety_net_token; - [IfFlag(2)] public string play_integrity_token; - [IfFlag(1)] public string ios_push_secret; - - [Flags] public enum Flags : uint - { - has_safety_net_token = 0x1, - has_ios_push_secret = 0x2, - has_play_integrity_token = 0x4, - } - } - - [TLDef(0x7E960193)] - public sealed partial class Auth_ResetLoginEmail : IMethod - { - public string phone_number; - public string phone_code_hash; - } - - [TLDef(0xCB9DEFF6)] - public sealed partial class Auth_ReportMissingCode : IMethod - { - public string phone_number; - public string phone_code_hash; - public string mnc; - } - - [TLDef(0x56E59F9C)] - public sealed partial class Auth_CheckPaidAuth : IMethod - { - public string phone_number; - public string phone_code_hash; - public long form_id; - } - - [TLDef(0x518AD0B7)] - public sealed partial class Auth_InitPasskeyLogin : IMethod - { - public int api_id; - public string api_hash; - } - - [TLDef(0x9857AD07)] - public sealed partial class Auth_FinishPasskeyLogin : IMethod - { - public Flags flags; - public InputPasskeyCredential credential; - [IfFlag(0)] public int from_dc_id; - [IfFlag(0)] public long from_auth_key_id; - - [Flags] public enum Flags : uint - { - has_from_dc_id = 0x1, - } - } - - [TLDef(0xEC86017A)] - public sealed partial class Account_RegisterDevice : IMethod - { - public Flags flags; - public int token_type; - public string token; - public bool app_sandbox; - public byte[] secret; - public long[] other_uids; - - [Flags] public enum Flags : uint - { - no_muted = 0x1, - } - } - - [TLDef(0x6A0D3206)] - public sealed partial class Account_UnregisterDevice : IMethod - { - public int token_type; - public string token; - public long[] other_uids; - } - - [TLDef(0x84BE5B93)] - public sealed partial class Account_UpdateNotifySettings : IMethod - { - public InputNotifyPeerBase peer; - public InputPeerNotifySettings settings; - } - - [TLDef(0x12B3AD31)] - public sealed partial class Account_GetNotifySettings : IMethod - { - public InputNotifyPeerBase peer; - } - - [TLDef(0xDB7E1747)] - public sealed partial class Account_ResetNotifySettings : IMethod { } - - [TLDef(0x78515775)] - public sealed partial class Account_UpdateProfile : IMethod - { - public Flags flags; - [IfFlag(0)] public string first_name; - [IfFlag(1)] public string last_name; - [IfFlag(2)] public string about; - - [Flags] public enum Flags : uint - { - has_first_name = 0x1, - has_last_name = 0x2, - has_about = 0x4, - } - } - - [TLDef(0x6628562C)] - public sealed partial class Account_UpdateStatus : IMethod - { - public bool offline; - } - - [TLDef(0x07967D36)] - public sealed partial class Account_GetWallPapers : IMethod - { - public long hash; - } - - [TLDef(0xC5BA3D86)] - public sealed partial class Account_ReportPeer : IMethod - { - public InputPeer peer; - public ReportReason reason; - public string message; - } - - [TLDef(0x2714D86C)] - public sealed partial class Account_CheckUsername : IMethod - { - public string username; - } - - [TLDef(0x3E0BDD7C)] - public sealed partial class Account_UpdateUsername : IMethod - { - public string username; - } - - [TLDef(0xDADBC950)] - public sealed partial class Account_GetPrivacy : IMethod - { - public InputPrivacyKey key; - } - - [TLDef(0xC9F81CE8)] - public sealed partial class Account_SetPrivacy : IMethod - { - public InputPrivacyKey key; - public InputPrivacyRule[] rules; - } - - [TLDef(0xA2C0CF74)] - public sealed partial class Account_DeleteAccount : IMethod - { - public Flags flags; - public string reason; - [IfFlag(0)] public InputCheckPasswordSRP password; - - [Flags] public enum Flags : uint - { - has_password = 0x1, - } - } - - [TLDef(0x08FC711D)] - public sealed partial class Account_GetAccountTTL : IMethod { } - - [TLDef(0x2442485E)] - public sealed partial class Account_SetAccountTTL : IMethod - { - public AccountDaysTTL ttl; - } - - [TLDef(0x82574AE5)] - public sealed partial class Account_SendChangePhoneCode : IMethod - { - public string phone_number; - public CodeSettings settings; - } - - [TLDef(0x70C32EDB)] - public sealed partial class Account_ChangePhone : IMethod - { - public string phone_number; - public string phone_code_hash; - public string phone_code; - } - - [TLDef(0x38DF3532)] - public sealed partial class Account_UpdateDeviceLocked : IMethod - { - public int period; - } - - [TLDef(0xE320C158)] - public sealed partial class Account_GetAuthorizations : IMethod { } - - [TLDef(0xDF77F3BC)] - public sealed partial class Account_ResetAuthorization : IMethod - { - public long hash; - } - - [TLDef(0x548A30F5)] - public sealed partial class Account_GetPassword : IMethod { } - - [TLDef(0x9CD4EAF9)] - public sealed partial class Account_GetPasswordSettings : IMethod - { - public InputCheckPasswordSRP password; - } - - [TLDef(0xA59B102F)] - public sealed partial class Account_UpdatePasswordSettings : IMethod - { - public InputCheckPasswordSRP password; - public Account_PasswordInputSettings new_settings; - } - - [TLDef(0x1B3FAA88)] - public sealed partial class Account_SendConfirmPhoneCode : IMethod - { - public string hash; - public CodeSettings settings; - } - - [TLDef(0x5F2178C3)] - public sealed partial class Account_ConfirmPhone : IMethod - { - public string phone_code_hash; - public string phone_code; - } - - [TLDef(0x449E0B51)] - public sealed partial class Account_GetTmpPassword : IMethod - { - public InputCheckPasswordSRP password; - public int period; - } - - [TLDef(0x182E6D6F)] - public sealed partial class Account_GetWebAuthorizations : IMethod { } - - [TLDef(0x2D01B9EF)] - public sealed partial class Account_ResetWebAuthorization : IMethod - { - public long hash; - } - - [TLDef(0x682D2594)] - public sealed partial class Account_ResetWebAuthorizations : IMethod { } - - [TLDef(0xB288BC7D)] - public sealed partial class Account_GetAllSecureValues : IMethod { } - - [TLDef(0x73665BC2)] - public sealed partial class Account_GetSecureValue : IMethod - { - public SecureValueType[] types; - } - - [TLDef(0x899FE31D)] - public sealed partial class Account_SaveSecureValue : IMethod - { - public InputSecureValue value; - public long secure_secret_id; - } - - [TLDef(0xB880BC4B)] - public sealed partial class Account_DeleteSecureValue : IMethod - { - public SecureValueType[] types; - } - - [TLDef(0xA929597A)] - public sealed partial class Account_GetAuthorizationForm : IMethod - { - public long bot_id; - public string scope; - public string public_key; - } - - [TLDef(0xF3ED4C73)] - public sealed partial class Account_AcceptAuthorization : IMethod - { - public long bot_id; - public string scope; - public string public_key; - public SecureValueHash[] value_hashes; - public SecureCredentialsEncrypted credentials; - } - - [TLDef(0xA5A356F9)] - public sealed partial class Account_SendVerifyPhoneCode : IMethod - { - public string phone_number; - public CodeSettings settings; - } - - [TLDef(0x4DD3A7F6)] - public sealed partial class Account_VerifyPhone : IMethod - { - public string phone_number; - public string phone_code_hash; - public string phone_code; - } - - [TLDef(0x98E037BB)] - public sealed partial class Account_SendVerifyEmailCode : IMethod - { - public EmailVerifyPurpose purpose; - public string email; - } - - [TLDef(0x032DA4CF)] - public sealed partial class Account_VerifyEmail : IMethod - { - public EmailVerifyPurpose purpose; - public EmailVerification verification; - } - - [TLDef(0x8EF3EAB0)] - public sealed partial class Account_InitTakeoutSession : IMethod - { - public Flags flags; - [IfFlag(5)] public long file_max_size; - - [Flags] public enum Flags : uint - { - contacts = 0x1, - message_users = 0x2, - message_chats = 0x4, - message_megagroups = 0x8, - message_channels = 0x10, - files = 0x20, - } - } - - [TLDef(0x1D2652EE)] - public sealed partial class Account_FinishTakeoutSession : IMethod - { - public Flags flags; - - [Flags] public enum Flags : uint - { - success = 0x1, - } - } - - [TLDef(0x8FDF1920)] - public sealed partial class Account_ConfirmPasswordEmail : IMethod - { - public string code; - } - - [TLDef(0x7A7F2A15)] - public sealed partial class Account_ResendPasswordEmail : IMethod { } - - [TLDef(0xC1CBD5B6)] - public sealed partial class Account_CancelPasswordEmail : IMethod { } - - [TLDef(0x9F07C728)] - public sealed partial class Account_GetContactSignUpNotification : IMethod { } - - [TLDef(0xCFF43F61)] - public sealed partial class Account_SetContactSignUpNotification : IMethod - { - public bool silent; - } - - [TLDef(0x53577479)] - public sealed partial class Account_GetNotifyExceptions : IMethod - { - public Flags flags; - [IfFlag(0)] public InputNotifyPeerBase peer; - - [Flags] public enum Flags : uint - { - has_peer = 0x1, - compare_sound = 0x2, - compare_stories = 0x4, - } - } - - [TLDef(0xFC8DDBEA)] - public sealed partial class Account_GetWallPaper : IMethod - { - public InputWallPaperBase wallpaper; - } - - [TLDef(0xE39A8F03)] - public sealed partial class Account_UploadWallPaper : IMethod - { - public Flags flags; - public InputFileBase file; - public string mime_type; - public WallPaperSettings settings; - - [Flags] public enum Flags : uint - { - for_chat = 0x1, - } - } - - [TLDef(0x6C5A5B37)] - public sealed partial class Account_SaveWallPaper : IMethod - { - public InputWallPaperBase wallpaper; - public bool unsave; - public WallPaperSettings settings; - } - - [TLDef(0xFEED5769)] - public sealed partial class Account_InstallWallPaper : IMethod - { - public InputWallPaperBase wallpaper; - public WallPaperSettings settings; - } - - [TLDef(0xBB3B9804)] - public sealed partial class Account_ResetWallPapers : IMethod { } - - [TLDef(0x56DA0B3F)] - public sealed partial class Account_GetAutoDownloadSettings : IMethod { } - - [TLDef(0x76F36233)] - public sealed partial class Account_SaveAutoDownloadSettings : IMethod - { - public Flags flags; - public AutoDownloadSettings settings; - - [Flags] public enum Flags : uint - { - low = 0x1, - high = 0x2, - } - } - - [TLDef(0x1C3DB333)] - public sealed partial class Account_UploadTheme : IMethod - { - public Flags flags; - public InputFileBase file; - [IfFlag(0)] public InputFileBase thumb; - public string file_name; - public string mime_type; - - [Flags] public enum Flags : uint - { - has_thumb = 0x1, - } - } - - [TLDef(0x652E4400)] - public sealed partial class Account_CreateTheme : IMethod - { - public Flags flags; - public string slug; - public string title; - [IfFlag(2)] public InputDocument document; - [IfFlag(3)] public InputThemeSettings[] settings; - - [Flags] public enum Flags : uint - { - has_document = 0x4, - has_settings = 0x8, - } - } - - [TLDef(0x2BF40CCC)] - public sealed partial class Account_UpdateTheme : IMethod - { - public Flags flags; - public string format; - public InputThemeBase theme; - [IfFlag(0)] public string slug; - [IfFlag(1)] public string title; - [IfFlag(2)] public InputDocument document; - [IfFlag(3)] public InputThemeSettings[] settings; - - [Flags] public enum Flags : uint - { - has_slug = 0x1, - has_title = 0x2, - has_document = 0x4, - has_settings = 0x8, - } - } - - [TLDef(0xF257106C)] - public sealed partial class Account_SaveTheme : IMethod - { - public InputThemeBase theme; - public bool unsave; - } - - [TLDef(0xC727BB3B)] - public sealed partial class Account_InstallTheme : IMethod - { - public Flags flags; - [IfFlag(1)] public InputThemeBase theme; - [IfFlag(2)] public string format; - [IfFlag(3)] public BaseTheme base_theme; - - [Flags] public enum Flags : uint - { - dark = 0x1, - has_theme = 0x2, - has_format = 0x4, - has_base_theme = 0x8, - } - } - - [TLDef(0x3A5869EC)] - public sealed partial class Account_GetTheme : IMethod - { - public string format; - public InputThemeBase theme; - } - - [TLDef(0x7206E458)] - public sealed partial class Account_GetThemes : IMethod - { - public string format; - public long hash; - } - - [TLDef(0xB574B16B)] - public sealed partial class Account_SetContentSettings : IMethod - { - public Flags flags; - - [Flags] public enum Flags : uint - { - sensitive_enabled = 0x1, - } - } - - [TLDef(0x8B9B4DAE)] - public sealed partial class Account_GetContentSettings : IMethod { } - - [TLDef(0x65AD71DC)] - public sealed partial class Account_GetMultiWallPapers : IMethod - { - public InputWallPaperBase[] wallpapers; - } - - [TLDef(0xEB2B4CF6)] - public sealed partial class Account_GetGlobalPrivacySettings : IMethod { } - - [TLDef(0x1EDAAAC2)] - public sealed partial class Account_SetGlobalPrivacySettings : IMethod - { - public GlobalPrivacySettings settings; - } - - [TLDef(0xFA8CC6F5)] - public sealed partial class Account_ReportProfilePhoto : IMethod - { - public InputPeer peer; - public InputPhoto photo_id; - public ReportReason reason; - public string message; - } - - [TLDef(0x9308CE1B)] - public sealed partial class Account_ResetPassword : IMethod { } - - [TLDef(0x4C9409F6)] - public sealed partial class Account_DeclinePasswordReset : IMethod { } - - [TLDef(0xD638DE89)] - public sealed partial class Account_GetChatThemes : IMethod - { - public long hash; - } - - [TLDef(0xBF899AA0)] - public sealed partial class Account_SetAuthorizationTTL : IMethod - { - public int authorization_ttl_days; - } - - [TLDef(0x40F48462)] - public sealed partial class Account_ChangeAuthorizationSettings : IMethod - { - public Flags flags; - public long hash; - [IfFlag(0)] public bool encrypted_requests_disabled; - [IfFlag(1)] public bool call_requests_disabled; - - [Flags] public enum Flags : uint - { - has_encrypted_requests_disabled = 0x1, - has_call_requests_disabled = 0x2, - confirmed = 0x8, - } - } - - [TLDef(0xE1902288)] - public sealed partial class Account_GetSavedRingtones : IMethod - { - public long hash; - } - - [TLDef(0x3DEA5B03)] - public sealed partial class Account_SaveRingtone : IMethod - { - public InputDocument id; - public bool unsave; - } - - [TLDef(0x831A83A2)] - public sealed partial class Account_UploadRingtone : IMethod - { - public InputFileBase file; - public string file_name; - public string mime_type; - } - - [TLDef(0xFBD3DE6B)] - public sealed partial class Account_UpdateEmojiStatus : IMethod - { - public EmojiStatusBase emoji_status; - } - - [TLDef(0xD6753386)] - public sealed partial class Account_GetDefaultEmojiStatuses : IMethod - { - public long hash; - } - - [TLDef(0x0F578105)] - public sealed partial class Account_GetRecentEmojiStatuses : IMethod - { - public long hash; - } - - [TLDef(0x18201AAE)] - public sealed partial class Account_ClearRecentEmojiStatuses : IMethod { } - - [TLDef(0xEF500EAB)] - public sealed partial class Account_ReorderUsernames : IMethod - { - public string[] order; - } - - [TLDef(0x58D6B376)] - public sealed partial class Account_ToggleUsername : IMethod - { - public string username; - public bool active; - } - - [TLDef(0xE2750328)] - public sealed partial class Account_GetDefaultProfilePhotoEmojis : IMethod - { - public long hash; - } - - [TLDef(0x915860AE)] - public sealed partial class Account_GetDefaultGroupPhotoEmojis : IMethod - { - public long hash; - } - - [TLDef(0xADCBBCDA)] - public sealed partial class Account_GetAutoSaveSettings : IMethod { } - - [TLDef(0xD69B8361)] - public sealed partial class Account_SaveAutoSaveSettings : IMethod - { - public Flags flags; - [IfFlag(3)] public InputPeer peer; - public AutoSaveSettings settings; - - [Flags] public enum Flags : uint - { - users = 0x1, - chats = 0x2, - broadcasts = 0x4, - has_peer = 0x8, - } - } - - [TLDef(0x53BC0020)] - public sealed partial class Account_DeleteAutoSaveExceptions : IMethod { } - - [TLDef(0xCA8AE8BA)] - public sealed partial class Account_InvalidateSignInCodes : IMethod - { - public string[] codes; - } - - [TLDef(0x684D214E)] - public sealed partial class Account_UpdateColor : IMethod - { - public Flags flags; - [IfFlag(2)] public PeerColorBase color; - - [Flags] public enum Flags : uint - { - for_profile = 0x2, - has_color = 0x4, - } - } - - [TLDef(0xA60AB9CE)] - public sealed partial class Account_GetDefaultBackgroundEmojis : IMethod - { - public long hash; - } - - [TLDef(0x7727A7D5)] - public sealed partial class Account_GetChannelDefaultEmojiStatuses : IMethod - { - public long hash; - } - - [TLDef(0x35A9E0D5)] - public sealed partial class Account_GetChannelRestrictedStatusEmojis : IMethod - { - public long hash; - } - - [TLDef(0x4B00E066)] - public sealed partial class Account_UpdateBusinessWorkHours : IMethod - { - public Flags flags; - [IfFlag(0)] public BusinessWorkHours business_work_hours; - - [Flags] public enum Flags : uint - { - has_business_work_hours = 0x1, - } - } - - [TLDef(0x9E6B131A)] - public sealed partial class Account_UpdateBusinessLocation : IMethod - { - public Flags flags; - [IfFlag(1)] public InputGeoPoint geo_point; - [IfFlag(0)] public string address; - - [Flags] public enum Flags : uint - { - has_address = 0x1, - has_geo_point = 0x2, - } - } - - [TLDef(0x66CDAFC4)] - public sealed partial class Account_UpdateBusinessGreetingMessage : IMethod - { - public Flags flags; - [IfFlag(0)] public InputBusinessGreetingMessage message; - - [Flags] public enum Flags : uint - { - has_message = 0x1, - } - } - - [TLDef(0xA26A7FA5)] - public sealed partial class Account_UpdateBusinessAwayMessage : IMethod - { - public Flags flags; - [IfFlag(0)] public InputBusinessAwayMessage message; - - [Flags] public enum Flags : uint - { - has_message = 0x1, - } - } - - [TLDef(0x66A08C7E)] - public sealed partial class Account_UpdateConnectedBot : IMethod - { - public Flags flags; - [IfFlag(0)] public BusinessBotRights rights; - public InputUserBase bot; - public InputBusinessBotRecipients recipients; - - [Flags] public enum Flags : uint - { - has_rights = 0x1, - deleted = 0x2, - } - } - - [TLDef(0x4EA4C80F)] - public sealed partial class Account_GetConnectedBots : IMethod { } - - [TLDef(0x76A86270)] - public sealed partial class Account_GetBotBusinessConnection : IMethod - { - public string connection_id; - } - - [TLDef(0xA614D034)] - public sealed partial class Account_UpdateBusinessIntro : IMethod - { - public Flags flags; - [IfFlag(0)] public InputBusinessIntro intro; - - [Flags] public enum Flags : uint - { - has_intro = 0x1, - } - } - - [TLDef(0x646E1097)] - public sealed partial class Account_ToggleConnectedBotPaused : IMethod - { - public InputPeer peer; - public bool paused; - } - - [TLDef(0x5E437ED9)] - public sealed partial class Account_DisablePeerConnectedBot : IMethod - { - public InputPeer peer; - } - - [TLDef(0xCC6E0C11)] - public sealed partial class Account_UpdateBirthday : IMethod - { - public Flags flags; - [IfFlag(0)] public Birthday birthday; - - [Flags] public enum Flags : uint - { - has_birthday = 0x1, - } - } - - [TLDef(0x8851E68E)] - public sealed partial class Account_CreateBusinessChatLink : IMethod - { - public InputBusinessChatLink link; - } - - [TLDef(0x8C3410AF)] - public sealed partial class Account_EditBusinessChatLink : IMethod - { - public string slug; - public InputBusinessChatLink link; - } - - [TLDef(0x60073674)] - public sealed partial class Account_DeleteBusinessChatLink : IMethod - { - public string slug; - } - - [TLDef(0x6F70DDE1)] - public sealed partial class Account_GetBusinessChatLinks : IMethod { } - - [TLDef(0x5492E5EE)] - public sealed partial class Account_ResolveBusinessChatLink : IMethod - { - public string slug; - } - - [TLDef(0xD94305E0)] - public sealed partial class Account_UpdatePersonalChannel : IMethod - { - public InputChannelBase channel; - } - - [TLDef(0xB9D9A38D)] - public sealed partial class Account_ToggleSponsoredMessages : IMethod - { - public bool enabled; - } - - [TLDef(0x06DD654C)] - public sealed partial class Account_GetReactionsNotifySettings : IMethod { } - - [TLDef(0x316CE548)] - public sealed partial class Account_SetReactionsNotifySettings : IMethod - { - public ReactionsNotifySettings settings; - } - - [TLDef(0x2E7B4543)] - public sealed partial class Account_GetCollectibleEmojiStatuses : IMethod - { - public long hash; - } - - [TLDef(0x19BA4A67)] - public sealed partial class Account_GetPaidMessagesRevenue : IMethod - { - public Flags flags; - [IfFlag(0)] public InputPeer parent_peer; - public InputUserBase user_id; - - [Flags] public enum Flags : uint - { - has_parent_peer = 0x1, - } - } - - [TLDef(0xFE2EDA76)] - public sealed partial class Account_ToggleNoPaidMessagesException : IMethod - { - public Flags flags; - [IfFlag(1)] public InputPeer parent_peer; - public InputUserBase user_id; - - [Flags] public enum Flags : uint - { - refund_charged = 0x1, - has_parent_peer = 0x2, - require_payment = 0x4, - } - } - - [TLDef(0x5DEE78B0)] - public sealed partial class Account_SetMainProfileTab : IMethod - { - public ProfileTab tab; - } - - [TLDef(0xB26732A9)] - public sealed partial class Account_SaveMusic : IMethod - { - public Flags flags; - public InputDocument id; - [IfFlag(1)] public InputDocument after_id; - - [Flags] public enum Flags : uint - { - unsave = 0x1, - has_after_id = 0x2, - } - } - - [TLDef(0xE09D5FAF)] - public sealed partial class Account_GetSavedMusicIds : IMethod - { - public long hash; - } - - [TLDef(0xE42CE9C9)] - public sealed partial class Account_GetUniqueGiftChatThemes : IMethod - { - public string offset; - public int limit; - public long hash; - } - - [TLDef(0x429547E8)] - public sealed partial class Account_InitPasskeyRegistration : IMethod { } - - [TLDef(0x55B41FD6)] - public sealed partial class Account_RegisterPasskey : IMethod - { - public InputPasskeyCredential credential; - } - - [TLDef(0xEA1F0C52)] - public sealed partial class Account_GetPasskeys : IMethod { } - - [TLDef(0xF5B5563F)] - public sealed partial class Account_DeletePasskey : IMethod - { - public string id; - } - - [TLDef(0x0D91A548)] - public sealed partial class Users_GetUsers : IMethod - { - public InputUserBase[] id; - } - - [TLDef(0xB60F5918)] - public sealed partial class Users_GetFullUser : IMethod - { - public InputUserBase id; - } - - [TLDef(0x90C894B5)] - public sealed partial class Users_SetSecureValueErrors : IMethod - { - public InputUserBase id; - public SecureValueErrorBase[] errors; - } - - [TLDef(0xD89A83A3)] - public sealed partial class Users_GetRequirementsToContact : IMethod - { - public InputUserBase[] id; - } - - [TLDef(0x788D7FE3)] - public sealed partial class Users_GetSavedMusic : IMethod - { - public InputUserBase id; - public int offset; - public int limit; - public long hash; - } - - [TLDef(0x7573A4E9)] - public sealed partial class Users_GetSavedMusicByID : IMethod - { - public InputUserBase id; - public InputDocument[] documents; - } - - [TLDef(0xFC533372)] - public sealed partial class Users_SuggestBirthday : IMethod - { - public InputUserBase id; - public Birthday birthday; - } - - [TLDef(0x7ADC669D)] - public sealed partial class Contacts_GetContactIDs : IMethod - { - public long hash; - } - - [TLDef(0xC4A353EE)] - public sealed partial class Contacts_GetStatuses : IMethod { } - - [TLDef(0x5DD69E12)] - public sealed partial class Contacts_GetContacts : IMethod - { - public long hash; - } - - [TLDef(0x2C800BE5)] - public sealed partial class Contacts_ImportContacts : IMethod - { - public InputContact[] contacts; - } - - [TLDef(0x096A0E00)] - public sealed partial class Contacts_DeleteContacts : IMethod - { - public InputUserBase[] id; - } - - [TLDef(0x1013FD9E)] - public sealed partial class Contacts_DeleteByPhones : IMethod - { - public string[] phones; - } - - [TLDef(0x2E2E8734)] - public sealed partial class Contacts_Block : IMethod - { - public Flags flags; - public InputPeer id; - - [Flags] public enum Flags : uint - { - my_stories_from = 0x1, - } - } - - [TLDef(0xB550D328)] - public sealed partial class Contacts_Unblock : IMethod - { - public Flags flags; - public InputPeer id; - - [Flags] public enum Flags : uint - { - my_stories_from = 0x1, - } - } - - [TLDef(0x9A868F80)] - public sealed partial class Contacts_GetBlocked : IMethod - { - public Flags flags; - public int offset; - public int limit; - - [Flags] public enum Flags : uint - { - my_stories_from = 0x1, - } - } - - [TLDef(0x11F812D8)] - public sealed partial class Contacts_Search : IMethod - { - public string q; - public int limit; - } - - [TLDef(0x725AFBBC)] - public sealed partial class Contacts_ResolveUsername : IMethod - { - public Flags flags; - public string username; - [IfFlag(0)] public string referer; - - [Flags] public enum Flags : uint - { - has_referer = 0x1, - } - } - - [TLDef(0x973478B6)] - public sealed partial class Contacts_GetTopPeers : IMethod - { - public Flags flags; - public int offset; - public int limit; - public long hash; - - [Flags] public enum Flags : uint - { - correspondents = 0x1, - bots_pm = 0x2, - bots_inline = 0x4, - phone_calls = 0x8, - forward_users = 0x10, - forward_chats = 0x20, - groups = 0x400, - channels = 0x8000, - bots_app = 0x10000, - } - } - - [TLDef(0x1AE373AC)] - public sealed partial class Contacts_ResetTopPeerRating : IMethod - { - public TopPeerCategory category; - public InputPeer peer; - } - - [TLDef(0x879537F1)] - public sealed partial class Contacts_ResetSaved : IMethod { } - - [TLDef(0x82F1E39F)] - public sealed partial class Contacts_GetSaved : IMethod { } - - [TLDef(0x8514BDDA)] - public sealed partial class Contacts_ToggleTopPeers : IMethod - { - public bool enabled; - } - - [TLDef(0xD9BA2E54)] - public sealed partial class Contacts_AddContact : IMethod - { - public Flags flags; - public InputUserBase id; - public string first_name; - public string last_name; - public string phone; - [IfFlag(1)] public TextWithEntities note; - - [Flags] public enum Flags : uint - { - add_phone_privacy_exception = 0x1, - has_note = 0x2, - } - } - - [TLDef(0xF831A20F)] - public sealed partial class Contacts_AcceptContact : IMethod - { - public InputUserBase id; - } - - [TLDef(0xD348BC44)] - public sealed partial class Contacts_GetLocated : IMethod - { - public Flags flags; - public InputGeoPoint geo_point; - [IfFlag(0)] public int self_expires; - - [Flags] public enum Flags : uint - { - has_self_expires = 0x1, - background = 0x2, - } - } - - [TLDef(0x29A8962C)] - public sealed partial class Contacts_BlockFromReplies : IMethod - { - public Flags flags; - public int msg_id; - - [Flags] public enum Flags : uint - { - delete_message = 0x1, - delete_history = 0x2, - report_spam = 0x4, - } - } - - [TLDef(0x8AF94344)] - public sealed partial class Contacts_ResolvePhone : IMethod - { - public string phone; - } - - [TLDef(0xF8654027)] - public sealed partial class Contacts_ExportContactToken : IMethod { } - - [TLDef(0x13005788)] - public sealed partial class Contacts_ImportContactToken : IMethod - { - public string token; - } - - [TLDef(0xBA6705F0)] - public sealed partial class Contacts_EditCloseFriends : IMethod - { - public long[] id; - } - - [TLDef(0x94C65C76)] - public sealed partial class Contacts_SetBlocked : IMethod - { - public Flags flags; - public InputPeer[] id; - public int limit; - - [Flags] public enum Flags : uint - { - my_stories_from = 0x1, - } - } - - [TLDef(0xDAEDA864)] - public sealed partial class Contacts_GetBirthdays : IMethod { } - - [TLDef(0xB6C8C393)] - public sealed partial class Contacts_GetSponsoredPeers : IMethod - { - public string q; - } - - [TLDef(0x139F63FB)] - public sealed partial class Contacts_UpdateContactNote : IMethod - { - public InputUserBase id; - public TextWithEntities note; - } - - [TLDef(0x63C66506)] - public sealed partial class Messages_GetMessages : IMethod - { - public InputMessage[] id; - } - - [TLDef(0xA0F4CB4F)] - public sealed partial class Messages_GetDialogs : IMethod - { - public Flags flags; - [IfFlag(1)] public int folder_id; - public DateTime offset_date; - public int offset_id; - public InputPeer offset_peer; - public int limit; - public long hash; - - [Flags] public enum Flags : uint - { - exclude_pinned = 0x1, - has_folder_id = 0x2, - } - } - - [TLDef(0x4423E6C5)] - public sealed partial class Messages_GetHistory : IMethod - { - public InputPeer peer; - public int offset_id; - public DateTime offset_date; - public int add_offset; - public int limit; - public int max_id; - public int min_id; - public long hash; - } - - [TLDef(0x29EE847A)] - public sealed partial class Messages_Search : IMethod - { - public Flags flags; - public InputPeer peer; - public string q; - [IfFlag(0)] public InputPeer from_id; - [IfFlag(2)] public InputPeer saved_peer_id; - [IfFlag(3)] public Reaction[] saved_reaction; - [IfFlag(1)] public int top_msg_id; - public MessagesFilter filter; - public DateTime min_date; - public DateTime max_date; - public int offset_id; - public int add_offset; - public int limit; - public int max_id; - public int min_id; - public long hash; - - [Flags] public enum Flags : uint - { - has_from_id = 0x1, - has_top_msg_id = 0x2, - has_saved_peer_id = 0x4, - has_saved_reaction = 0x8, - } - } - - [TLDef(0x0E306D3A)] - public sealed partial class Messages_ReadHistory : IMethod - { - public InputPeer peer; - public int max_id; - } - - [TLDef(0xB08F922A)] - public sealed partial class Messages_DeleteHistory : IMethod - { - public Flags flags; - public InputPeer peer; - public int max_id; - [IfFlag(2)] public DateTime min_date; - [IfFlag(3)] public DateTime max_date; - - [Flags] public enum Flags : uint - { - just_clear = 0x1, - revoke = 0x2, - has_min_date = 0x4, - has_max_date = 0x8, - } - } - - [TLDef(0xE58E95D2)] - public sealed partial class Messages_DeleteMessages : IMethod - { - public Flags flags; - public int[] id; - - [Flags] public enum Flags : uint - { - revoke = 0x1, - } - } - - [TLDef(0x05A954C0)] - public sealed partial class Messages_ReceivedMessages : IMethod - { - public int max_id; - } - - [TLDef(0x58943EE2)] - public sealed partial class Messages_SetTyping : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(0)] public int top_msg_id; - public SendMessageAction action; - - [Flags] public enum Flags : uint - { - has_top_msg_id = 0x1, - } - } - - [TLDef(0x545CD15A)] - public sealed partial class Messages_SendMessage : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(0)] public InputReplyTo reply_to; - public string message; - public long random_id; - [IfFlag(2)] public ReplyMarkup reply_markup; - [IfFlag(3)] public MessageEntity[] entities; - [IfFlag(10)] public DateTime schedule_date; - [IfFlag(24)] public int schedule_repeat_period; - [IfFlag(13)] public InputPeer send_as; - [IfFlag(17)] public InputQuickReplyShortcutBase quick_reply_shortcut; - [IfFlag(18)] public long effect; - [IfFlag(21)] public long allow_paid_stars; - [IfFlag(22)] public SuggestedPost suggested_post; - - [Flags] public enum Flags : uint - { - has_reply_to = 0x1, - no_webpage = 0x2, - has_reply_markup = 0x4, - has_entities = 0x8, - silent = 0x20, - background = 0x40, - clear_draft = 0x80, - has_schedule_date = 0x400, - has_send_as = 0x2000, - noforwards = 0x4000, - update_stickersets_order = 0x8000, - invert_media = 0x10000, - has_quick_reply_shortcut = 0x20000, - has_effect = 0x40000, - allow_paid_floodskip = 0x80000, - has_allow_paid_stars = 0x200000, - has_suggested_post = 0x400000, - has_schedule_repeat_period = 0x1000000, - } - } - - [TLDef(0x0330E77F)] - public sealed partial class Messages_SendMedia : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(0)] public InputReplyTo reply_to; - public InputMedia media; - public string message; - public long random_id; - [IfFlag(2)] public ReplyMarkup reply_markup; - [IfFlag(3)] public MessageEntity[] entities; - [IfFlag(10)] public DateTime schedule_date; - [IfFlag(24)] public int schedule_repeat_period; - [IfFlag(13)] public InputPeer send_as; - [IfFlag(17)] public InputQuickReplyShortcutBase quick_reply_shortcut; - [IfFlag(18)] public long effect; - [IfFlag(21)] public long allow_paid_stars; - [IfFlag(22)] public SuggestedPost suggested_post; - - [Flags] public enum Flags : uint - { - has_reply_to = 0x1, - has_reply_markup = 0x4, - has_entities = 0x8, - silent = 0x20, - background = 0x40, - clear_draft = 0x80, - has_schedule_date = 0x400, - has_send_as = 0x2000, - noforwards = 0x4000, - update_stickersets_order = 0x8000, - invert_media = 0x10000, - has_quick_reply_shortcut = 0x20000, - has_effect = 0x40000, - allow_paid_floodskip = 0x80000, - has_allow_paid_stars = 0x200000, - has_suggested_post = 0x400000, - has_schedule_repeat_period = 0x1000000, - } - } - - [TLDef(0x13704A7C)] - public sealed partial class Messages_ForwardMessages : IMethod - { - public Flags flags; - public InputPeer from_peer; - public int[] id; - public long[] random_id; - public InputPeer to_peer; - [IfFlag(9)] public int top_msg_id; - [IfFlag(22)] public InputReplyTo reply_to; - [IfFlag(10)] public DateTime schedule_date; - [IfFlag(24)] public int schedule_repeat_period; - [IfFlag(13)] public InputPeer send_as; - [IfFlag(17)] public InputQuickReplyShortcutBase quick_reply_shortcut; - [IfFlag(18)] public long effect; - [IfFlag(20)] public int video_timestamp; - [IfFlag(21)] public long allow_paid_stars; - [IfFlag(23)] public SuggestedPost suggested_post; - - [Flags] public enum Flags : uint - { - silent = 0x20, - background = 0x40, - with_my_score = 0x100, - has_top_msg_id = 0x200, - has_schedule_date = 0x400, - drop_author = 0x800, - drop_media_captions = 0x1000, - has_send_as = 0x2000, - noforwards = 0x4000, - has_quick_reply_shortcut = 0x20000, - has_effect = 0x40000, - allow_paid_floodskip = 0x80000, - has_video_timestamp = 0x100000, - has_allow_paid_stars = 0x200000, - has_reply_to = 0x400000, - has_suggested_post = 0x800000, - has_schedule_repeat_period = 0x1000000, - } - } - - [TLDef(0xCF1592DB)] - public sealed partial class Messages_ReportSpam : IMethod - { - public InputPeer peer; - } - - [TLDef(0xEFD9A6A2)] - public sealed partial class Messages_GetPeerSettings : IMethod - { - public InputPeer peer; - } - - [TLDef(0xFC78AF9B)] - public sealed partial class Messages_Report : IMethod - { - public InputPeer peer; - public int[] id; - public byte[] option; - public string message; - } - - [TLDef(0x49E9528F)] - public sealed partial class Messages_GetChats : IMethod - { - public long[] id; - } - - [TLDef(0xAEB00B34)] - public sealed partial class Messages_GetFullChat : IMethod - { - public long chat_id; - } - - [TLDef(0x73783FFD)] - public sealed partial class Messages_EditChatTitle : IMethod - { - public long chat_id; - public string title; - } - - [TLDef(0x35DDD674)] - public sealed partial class Messages_EditChatPhoto : IMethod - { - public long chat_id; - public InputChatPhotoBase photo; - } - - [TLDef(0xCBC6D107)] - public sealed partial class Messages_AddChatUser : IMethod - { - public long chat_id; - public InputUserBase user_id; - public int fwd_limit; - } - - [TLDef(0xA2185CAB)] - public sealed partial class Messages_DeleteChatUser : IMethod - { - public Flags flags; - public long chat_id; - public InputUserBase user_id; - - [Flags] public enum Flags : uint - { - revoke_history = 0x1, - } - } - - [TLDef(0x92CEDDD4)] - public sealed partial 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)] - public sealed partial class Messages_GetDhConfig : IMethod - { - public int version; - public int random_length; - } - - [TLDef(0xF64DAF43)] - public sealed partial class Messages_RequestEncryption : IMethod - { - public InputUserBase user_id; - public int random_id; - public byte[] g_a; - } - - [TLDef(0x3DBC0415)] - public sealed partial class Messages_AcceptEncryption : IMethod - { - public InputEncryptedChat peer; - public byte[] g_b; - public long key_fingerprint; - } - - [TLDef(0xF393AEA0)] - public sealed partial class Messages_DiscardEncryption : IMethod - { - public Flags flags; - public int chat_id; - - [Flags] public enum Flags : uint - { - delete_history = 0x1, - } - } - - [TLDef(0x791451ED)] - public sealed partial class Messages_SetEncryptedTyping : IMethod - { - public InputEncryptedChat peer; - public bool typing; - } - - [TLDef(0x7F4B690A)] - public sealed partial class Messages_ReadEncryptedHistory : IMethod - { - public InputEncryptedChat peer; - public DateTime max_date; - } - - [TLDef(0x44FA7A15)] - public sealed partial class Messages_SendEncrypted : IMethod - { - public Flags flags; - public InputEncryptedChat peer; - public long random_id; - public byte[] data; - - [Flags] public enum Flags : uint - { - silent = 0x1, - } - } - - [TLDef(0x5559481D)] - public sealed partial class Messages_SendEncryptedFile : IMethod - { - public Flags flags; - public InputEncryptedChat peer; - public long random_id; - public byte[] data; - public InputEncryptedFileBase file; - - [Flags] public enum Flags : uint - { - silent = 0x1, - } - } - - [TLDef(0x32D439A4)] - public sealed partial class Messages_SendEncryptedService : IMethod - { - public InputEncryptedChat peer; - public long random_id; - public byte[] data; - } - - [TLDef(0x55A5BB66)] - public sealed partial class Messages_ReceivedQueue : IMethod - { - public int max_qts; - } - - [TLDef(0x4B0C8C0F)] - public sealed partial class Messages_ReportEncryptedSpam : IMethod - { - public InputEncryptedChat peer; - } - - [TLDef(0x36A73F77)] - public sealed partial class Messages_ReadMessageContents : IMethod - { - public int[] id; - } - - [TLDef(0xD5A5D3A1)] - public sealed partial class Messages_GetStickers : IMethod - { - public string emoticon; - public long hash; - } - - [TLDef(0xB8A0A1A8)] - public sealed partial class Messages_GetAllStickers : IMethod - { - public long hash; - } - - [TLDef(0x570D6F6F)] - public sealed partial class Messages_GetWebPagePreview : IMethod - { - public Flags flags; - public string message; - [IfFlag(3)] public MessageEntity[] entities; - - [Flags] public enum Flags : uint - { - has_entities = 0x8, - } - } - - [TLDef(0xA455DE90)] - public sealed partial class Messages_ExportChatInvite : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(0)] public DateTime expire_date; - [IfFlag(1)] public int usage_limit; - [IfFlag(4)] public string title; - [IfFlag(5)] public StarsSubscriptionPricing subscription_pricing; - - [Flags] public enum Flags : uint - { - has_expire_date = 0x1, - has_usage_limit = 0x2, - legacy_revoke_permanent = 0x4, - request_needed = 0x8, - has_title = 0x10, - has_subscription_pricing = 0x20, - } - } - - [TLDef(0x3EADB1BB)] - public sealed partial class Messages_CheckChatInvite : IMethod - { - public string hash; - } - - [TLDef(0x6C50051C)] - public sealed partial class Messages_ImportChatInvite : IMethod - { - public string hash; - } - - [TLDef(0xC8A0EC74)] - public sealed partial class Messages_GetStickerSet : IMethod - { - public InputStickerSet stickerset; - public int hash; - } - - [TLDef(0xC78FE460)] - public sealed partial class Messages_InstallStickerSet : IMethod - { - public InputStickerSet stickerset; - public bool archived; - } - - [TLDef(0xF96E55DE)] - public sealed partial class Messages_UninstallStickerSet : IMethod - { - public InputStickerSet stickerset; - } - - [TLDef(0xE6DF7378)] - public sealed partial class Messages_StartBot : IMethod - { - public InputUserBase bot; - public InputPeer peer; - public long random_id; - public string start_param; - } - - [TLDef(0x5784D3E1)] - public sealed partial class Messages_GetMessagesViews : IMethod - { - public InputPeer peer; - public int[] id; - public bool increment; - } - - [TLDef(0xA85BD1C2)] - public sealed partial class Messages_EditChatAdmin : IMethod - { - public long chat_id; - public InputUserBase user_id; - public bool is_admin; - } - - [TLDef(0xA2875319)] - public sealed partial class Messages_MigrateChat : IMethod - { - public long chat_id; - } - - [TLDef(0x4BC6589A)] - public sealed partial class Messages_SearchGlobal : IMethod - { - public Flags flags; - [IfFlag(0)] public int folder_id; - public string q; - public MessagesFilter filter; - public DateTime min_date; - public DateTime max_date; - public int offset_rate; - public InputPeer offset_peer; - public int offset_id; - public int limit; - - [Flags] public enum Flags : uint - { - has_folder_id = 0x1, - broadcasts_only = 0x2, - groups_only = 0x4, - users_only = 0x8, - } - } - - [TLDef(0x78337739)] - public sealed partial class Messages_ReorderStickerSets : IMethod - { - public Flags flags; - public long[] order; - - [Flags] public enum Flags : uint - { - masks = 0x1, - emojis = 0x2, - } - } - - [TLDef(0xB1F2061F)] - public sealed partial class Messages_GetDocumentByHash : IMethod - { - public byte[] sha256; - public long size; - public string mime_type; - } - - [TLDef(0x5CF09635)] - public sealed partial class Messages_GetSavedGifs : IMethod - { - public long hash; - } - - [TLDef(0x327A30CB)] - public sealed partial class Messages_SaveGif : IMethod - { - public InputDocument id; - public bool unsave; - } - - [TLDef(0x514E999D)] - public sealed partial class Messages_GetInlineBotResults : IMethod - { - public Flags flags; - public InputUserBase bot; - public InputPeer peer; - [IfFlag(0)] public InputGeoPoint geo_point; - public string query; - public string offset; - - [Flags] public enum Flags : uint - { - has_geo_point = 0x1, - } - } - - [TLDef(0xBB12A419)] - public sealed partial class Messages_SetInlineBotResults : IMethod - { - public Flags flags; - public long query_id; - public InputBotInlineResultBase[] results; - public int cache_time; - [IfFlag(2)] public string next_offset; - [IfFlag(3)] public InlineBotSwitchPM switch_pm; - [IfFlag(4)] public InlineBotWebView switch_webview; - - [Flags] public enum Flags : uint - { - gallery = 0x1, - private_ = 0x2, - has_next_offset = 0x4, - has_switch_pm = 0x8, - has_switch_webview = 0x10, - } - } - - [TLDef(0xC0CF7646)] - public sealed partial class Messages_SendInlineBotResult : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(0)] public InputReplyTo reply_to; - public long random_id; - public long query_id; - public string id; - [IfFlag(10)] public DateTime schedule_date; - [IfFlag(13)] public InputPeer send_as; - [IfFlag(17)] public InputQuickReplyShortcutBase quick_reply_shortcut; - [IfFlag(21)] public long allow_paid_stars; - - [Flags] public enum Flags : uint - { - has_reply_to = 0x1, - silent = 0x20, - background = 0x40, - clear_draft = 0x80, - has_schedule_date = 0x400, - hide_via = 0x800, - has_send_as = 0x2000, - has_quick_reply_shortcut = 0x20000, - has_allow_paid_stars = 0x200000, - } - } - - [TLDef(0xFDA68D36)] - public sealed partial class Messages_GetMessageEditData : IMethod - { - public InputPeer peer; - public int id; - } - - [TLDef(0x51E842E1)] - public sealed partial class Messages_EditMessage : IMethod - { - public Flags flags; - public InputPeer peer; - public int id; - [IfFlag(11)] public string message; - [IfFlag(14)] public InputMedia media; - [IfFlag(2)] public ReplyMarkup reply_markup; - [IfFlag(3)] public MessageEntity[] entities; - [IfFlag(15)] public DateTime schedule_date; - [IfFlag(18)] public int schedule_repeat_period; - [IfFlag(17)] public int quick_reply_shortcut_id; - - [Flags] public enum Flags : uint - { - no_webpage = 0x2, - has_reply_markup = 0x4, - has_entities = 0x8, - has_message = 0x800, - has_media = 0x4000, - has_schedule_date = 0x8000, - invert_media = 0x10000, - has_quick_reply_shortcut_id = 0x20000, - has_schedule_repeat_period = 0x40000, - } - } - - [TLDef(0x83557DBA)] - public sealed partial class Messages_EditInlineBotMessage : IMethod - { - public Flags flags; - public InputBotInlineMessageIDBase id; - [IfFlag(11)] public string message; - [IfFlag(14)] public InputMedia media; - [IfFlag(2)] public ReplyMarkup reply_markup; - [IfFlag(3)] public MessageEntity[] entities; - - [Flags] public enum Flags : uint - { - no_webpage = 0x2, - has_reply_markup = 0x4, - has_entities = 0x8, - has_message = 0x800, - has_media = 0x4000, - invert_media = 0x10000, - } - } - - [TLDef(0x9342CA07)] - public sealed partial class Messages_GetBotCallbackAnswer : IMethod - { - public Flags flags; - public InputPeer peer; - public int msg_id; - [IfFlag(0)] public byte[] data; - [IfFlag(2)] public InputCheckPasswordSRP password; - - [Flags] public enum Flags : uint - { - has_data = 0x1, - game = 0x2, - has_password = 0x4, - } - } - - [TLDef(0xD58F130A)] - public sealed partial class Messages_SetBotCallbackAnswer : IMethod - { - public Flags flags; - public long query_id; - [IfFlag(0)] public string message; - [IfFlag(2)] public string url; - public int cache_time; - - [Flags] public enum Flags : uint - { - has_message = 0x1, - alert = 0x2, - has_url = 0x4, - } - } - - [TLDef(0xE470BCFD)] - public sealed partial class Messages_GetPeerDialogs : IMethod - { - public InputDialogPeerBase[] peers; - } - - [TLDef(0x54AE308E)] - public sealed partial class Messages_SaveDraft : IMethod - { - public Flags flags; - [IfFlag(4)] public InputReplyTo reply_to; - public InputPeer peer; - public string message; - [IfFlag(3)] public MessageEntity[] entities; - [IfFlag(5)] public InputMedia media; - [IfFlag(7)] public long effect; - [IfFlag(8)] public SuggestedPost suggested_post; - - [Flags] public enum Flags : uint - { - no_webpage = 0x2, - has_entities = 0x8, - has_reply_to = 0x10, - has_media = 0x20, - invert_media = 0x40, - has_effect = 0x80, - has_suggested_post = 0x100, - } - } - - [TLDef(0x6A3F8D65)] - public sealed partial class Messages_GetAllDrafts : IMethod { } - - [TLDef(0x64780B14)] - public sealed partial class Messages_GetFeaturedStickers : IMethod - { - public long hash; - } - - [TLDef(0x5B118126)] - public sealed partial class Messages_ReadFeaturedStickers : IMethod - { - public long[] id; - } - - [TLDef(0x9DA9403B)] - public sealed partial class Messages_GetRecentStickers : IMethod - { - public Flags flags; - public long hash; - - [Flags] public enum Flags : uint - { - attached = 0x1, - } - } - - [TLDef(0x392718F8)] - public sealed partial class Messages_SaveRecentSticker : IMethod - { - public Flags flags; - public InputDocument id; - public bool unsave; - - [Flags] public enum Flags : uint - { - attached = 0x1, - } - } - - [TLDef(0x8999602D)] - public sealed partial class Messages_ClearRecentStickers : IMethod - { - public Flags flags; - - [Flags] public enum Flags : uint - { - attached = 0x1, - } - } - - [TLDef(0x57F17692)] - public sealed partial class Messages_GetArchivedStickers : IMethod - { - public Flags flags; - public long offset_id; - public int limit; - - [Flags] public enum Flags : uint - { - masks = 0x1, - emojis = 0x2, - } - } - - [TLDef(0x640F82B8)] - public sealed partial class Messages_GetMaskStickers : IMethod - { - public long hash; - } - - [TLDef(0xCC5B67CC)] - public sealed partial class Messages_GetAttachedStickers : IMethod - { - public InputStickeredMedia media; - } - - [TLDef(0x8EF8ECC0)] - public sealed partial class Messages_SetGameScore : IMethod - { - public Flags flags; - public InputPeer peer; - public int id; - public InputUserBase user_id; - public int score; - - [Flags] public enum Flags : uint - { - edit_message = 0x1, - force = 0x2, - } - } - - [TLDef(0x15AD9F64)] - public sealed partial class Messages_SetInlineGameScore : IMethod - { - public Flags flags; - public InputBotInlineMessageIDBase id; - public InputUserBase user_id; - public int score; - - [Flags] public enum Flags : uint - { - edit_message = 0x1, - force = 0x2, - } - } - - [TLDef(0xE822649D)] - public sealed partial class Messages_GetGameHighScores : IMethod - { - public InputPeer peer; - public int id; - public InputUserBase user_id; - } - - [TLDef(0x0F635E1B)] - public sealed partial class Messages_GetInlineGameHighScores : IMethod - { - public InputBotInlineMessageIDBase id; - public InputUserBase user_id; - } - - [TLDef(0xE40CA104)] - public sealed partial class Messages_GetCommonChats : IMethod - { - public InputUserBase user_id; - public long max_id; - public int limit; - } - - [TLDef(0x8D9692A3)] - public sealed partial class Messages_GetWebPage : IMethod - { - public string url; - public int hash; - } - - [TLDef(0xA731E257)] - public sealed partial class Messages_ToggleDialogPin : IMethod - { - public Flags flags; - public InputDialogPeerBase peer; - - [Flags] public enum Flags : uint - { - pinned = 0x1, - } - } - - [TLDef(0x3B1ADF37)] - public sealed partial class Messages_ReorderPinnedDialogs : IMethod - { - public Flags flags; - public int folder_id; - public InputDialogPeerBase[] order; - - [Flags] public enum Flags : uint - { - force = 0x1, - } - } - - [TLDef(0xD6B94DF2)] - public sealed partial class Messages_GetPinnedDialogs : IMethod - { - public int folder_id; - } - - [TLDef(0xE5F672FA)] - public sealed partial class Messages_SetBotShippingResults : IMethod - { - public Flags flags; - public long query_id; - [IfFlag(0)] public string error; - [IfFlag(1)] public ShippingOption[] shipping_options; - - [Flags] public enum Flags : uint - { - has_error = 0x1, - has_shipping_options = 0x2, - } - } - - [TLDef(0x09C2DD95)] - public sealed partial class Messages_SetBotPrecheckoutResults : IMethod - { - public Flags flags; - public long query_id; - [IfFlag(0)] public string error; - - [Flags] public enum Flags : uint - { - has_error = 0x1, - success = 0x2, - } - } - - [TLDef(0x14967978)] - public sealed partial class Messages_UploadMedia : IMethod - { - public Flags flags; - [IfFlag(0)] public string business_connection_id; - public InputPeer peer; - public InputMedia media; - - [Flags] public enum Flags : uint - { - has_business_connection_id = 0x1, - } - } - - [TLDef(0xA1405817)] - public sealed partial class Messages_SendScreenshotNotification : IMethod - { - public InputPeer peer; - public InputReplyTo reply_to; - public long random_id; - } - - [TLDef(0x04F1AAA9)] - public sealed partial class Messages_GetFavedStickers : IMethod - { - public long hash; - } - - [TLDef(0xB9FFC55B)] - public sealed partial class Messages_FaveSticker : IMethod - { - public InputDocument id; - public bool unfave; - } - - [TLDef(0xF107E790)] - public sealed partial 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(0x36E5BF4D)] - public sealed partial 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)] - public sealed partial class Messages_GetRecentLocations : IMethod - { - public InputPeer peer; - public int limit; - public long hash; - } - - [TLDef(0x1BF89D74)] - public sealed partial class Messages_SendMultiMedia : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(0)] public InputReplyTo reply_to; - public InputSingleMedia[] multi_media; - [IfFlag(10)] public DateTime schedule_date; - [IfFlag(13)] public InputPeer send_as; - [IfFlag(17)] public InputQuickReplyShortcutBase quick_reply_shortcut; - [IfFlag(18)] public long effect; - [IfFlag(21)] public long allow_paid_stars; - - [Flags] public enum Flags : uint - { - has_reply_to = 0x1, - silent = 0x20, - background = 0x40, - clear_draft = 0x80, - has_schedule_date = 0x400, - has_send_as = 0x2000, - noforwards = 0x4000, - update_stickersets_order = 0x8000, - invert_media = 0x10000, - has_quick_reply_shortcut = 0x20000, - has_effect = 0x40000, - allow_paid_floodskip = 0x80000, - has_allow_paid_stars = 0x200000, - } - } - - [TLDef(0x5057C497)] - public sealed partial class Messages_UploadEncryptedFile : IMethod - { - public InputEncryptedChat peer; - public InputEncryptedFileBase file; - } - - [TLDef(0x35705B8A)] - public sealed partial class Messages_SearchStickerSets : IMethod - { - public Flags flags; - public string q; - public long hash; - - [Flags] public enum Flags : uint - { - exclude_featured = 0x1, - } - } - - [TLDef(0x1CFF7E08)] - public sealed partial class Messages_GetSplitRanges : IMethod { } - - [TLDef(0x8C5006F8)] - public sealed partial class Messages_MarkDialogUnread : IMethod - { - public Flags flags; - [IfFlag(1)] public InputPeer parent_peer; - public InputDialogPeerBase peer; - - [Flags] public enum Flags : uint - { - unread = 0x1, - has_parent_peer = 0x2, - } - } - - [TLDef(0x21202222)] - public sealed partial class Messages_GetDialogUnreadMarks : IMethod - { - public Flags flags; - [IfFlag(0)] public InputPeer parent_peer; - - [Flags] public enum Flags : uint - { - has_parent_peer = 0x1, - } - } - - [TLDef(0x7E58EE9C)] - public sealed partial class Messages_ClearAllDrafts : IMethod { } - - [TLDef(0xD2AAF7EC)] - public sealed partial class Messages_UpdatePinnedMessage : IMethod - { - public Flags flags; - public InputPeer peer; - public int id; - - [Flags] public enum Flags : uint - { - silent = 0x1, - unpin = 0x2, - pm_oneside = 0x4, - } - } - - [TLDef(0x10EA6184)] - public sealed partial class Messages_SendVote : IMethod - { - public InputPeer peer; - public int msg_id; - public byte[][] options; - } - - [TLDef(0x73BB643B)] - public sealed partial class Messages_GetPollResults : IMethod - { - public InputPeer peer; - public int msg_id; - } - - [TLDef(0x6E2BE050)] - public sealed partial class Messages_GetOnlines : IMethod - { - public InputPeer peer; - } - - [TLDef(0xDEF60797)] - public sealed partial class Messages_EditChatAbout : IMethod - { - public InputPeer peer; - public string about; - } - - [TLDef(0xA5866B41)] - public sealed partial class Messages_EditChatDefaultBannedRights : IMethod - { - public InputPeer peer; - public ChatBannedRights banned_rights; - } - - [TLDef(0x35A0E062)] - public sealed partial class Messages_GetEmojiKeywords : IMethod - { - public string lang_code; - } - - [TLDef(0x1508B6AF)] - public sealed partial class Messages_GetEmojiKeywordsDifference : IMethod - { - public string lang_code; - public int from_version; - } - - [TLDef(0x4E9963B2)] - public sealed partial class Messages_GetEmojiKeywordsLanguages : IMethod - { - public string[] lang_codes; - } - - [TLDef(0xD5B10C26)] - public sealed partial class Messages_GetEmojiURL : IMethod - { - public string lang_code; - } - - [TLDef(0x1BBCF300)] - public sealed partial class Messages_GetSearchCounters : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(2)] public InputPeer saved_peer_id; - [IfFlag(0)] public int top_msg_id; - public MessagesFilter[] filters; - - [Flags] public enum Flags : uint - { - has_top_msg_id = 0x1, - has_saved_peer_id = 0x4, - } - } - - [TLDef(0x894CC99C)] - public sealed partial class Messages_RequestUrlAuth : IMethod - { - public Flags flags; - [IfFlag(1)] public InputPeer peer; - [IfFlag(1)] public int msg_id; - [IfFlag(1)] public int button_id; - [IfFlag(2)] public string url; - [IfFlag(3)] public string in_app_origin; - - [Flags] public enum Flags : uint - { - has_peer = 0x2, - has_url = 0x4, - has_in_app_origin = 0x8, - } - } - - [TLDef(0x67A3F0DE)] - public sealed partial class Messages_AcceptUrlAuth : IMethod - { - public Flags flags; - [IfFlag(1)] public InputPeer peer; - [IfFlag(1)] public int msg_id; - [IfFlag(1)] public int button_id; - [IfFlag(2)] public string url; - [IfFlag(4)] public string match_code; - - [Flags] public enum Flags : uint - { - write_allowed = 0x1, - has_peer = 0x2, - has_url = 0x4, - share_phone_number = 0x8, - has_match_code = 0x10, - } - } - - [TLDef(0x4FACB138)] - public sealed partial class Messages_HidePeerSettingsBar : IMethod - { - public InputPeer peer; - } - - [TLDef(0xF516760B)] - public sealed partial class Messages_GetScheduledHistory : IMethod - { - public InputPeer peer; - public long hash; - } - - [TLDef(0xBDBB0464)] - public sealed partial class Messages_GetScheduledMessages : IMethod - { - public InputPeer peer; - public int[] id; - } - - [TLDef(0xBD38850A)] - public sealed partial class Messages_SendScheduledMessages : IMethod - { - public InputPeer peer; - public int[] id; - } - - [TLDef(0x59AE2B16)] - public sealed partial class Messages_DeleteScheduledMessages : IMethod - { - public InputPeer peer; - public int[] id; - } - - [TLDef(0xB86E380E)] - public sealed partial class Messages_GetPollVotes : IMethod - { - public Flags flags; - public InputPeer peer; - public int id; - [IfFlag(0)] public byte[] option; - [IfFlag(1)] public string offset; - public int limit; - - [Flags] public enum Flags : uint - { - has_option = 0x1, - has_offset = 0x2, - } - } - - [TLDef(0xB5052FEA)] - public sealed partial class Messages_ToggleStickerSets : IMethod - { - public Flags flags; - public InputStickerSet[] stickersets; - - [Flags] public enum Flags : uint - { - uninstall = 0x1, - archive = 0x2, - unarchive = 0x4, - } - } - - [TLDef(0xEFD48C89)] - public sealed partial class Messages_GetDialogFilters : IMethod { } - - [TLDef(0xA29CD42C)] - public sealed partial class Messages_GetSuggestedDialogFilters : IMethod { } - - [TLDef(0x1AD4A04A)] - public sealed partial class Messages_UpdateDialogFilter : IMethod - { - public Flags flags; - public int id; - [IfFlag(0)] public DialogFilterBase filter; - - [Flags] public enum Flags : uint - { - has_filter = 0x1, - } - } - - [TLDef(0xC563C1E4)] - public sealed partial class Messages_UpdateDialogFiltersOrder : IMethod - { - public int[] order; - } - - [TLDef(0x7ED094A1)] - public sealed partial class Messages_GetOldFeaturedStickers : IMethod - { - public int offset; - public int limit; - public long hash; - } - - [TLDef(0x22DDD30C)] - public sealed partial class Messages_GetReplies : IMethod - { - public InputPeer peer; - public int msg_id; - public int offset_id; - public DateTime offset_date; - public int add_offset; - public int limit; - public int max_id; - public int min_id; - public long hash; - } - - [TLDef(0x446972FD)] - public sealed partial class Messages_GetDiscussionMessage : IMethod - { - public InputPeer peer; - public int msg_id; - } - - [TLDef(0xF731A9F4)] - public sealed partial class Messages_ReadDiscussion : IMethod - { - public InputPeer peer; - public int msg_id; - public int read_max_id; - } - - [TLDef(0x062DD747)] - public sealed partial class Messages_UnpinAllMessages : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(0)] public int top_msg_id; - [IfFlag(1)] public InputPeer saved_peer_id; - - [Flags] public enum Flags : uint - { - has_top_msg_id = 0x1, - has_saved_peer_id = 0x2, - } - } - - [TLDef(0x5BD0EE50)] - public sealed partial class Messages_DeleteChat : IMethod - { - public long chat_id; - } - - [TLDef(0xF9CBE409)] - public sealed partial class Messages_DeletePhoneCallHistory : IMethod - { - public Flags flags; - - [Flags] public enum Flags : uint - { - revoke = 0x1, - } - } - - [TLDef(0x43FE19F3)] - public sealed partial class Messages_CheckHistoryImport : IMethod - { - public string import_head; - } - - [TLDef(0x34090C3B)] - public sealed partial class Messages_InitHistoryImport : IMethod - { - public InputPeer peer; - public InputFileBase file; - public int media_count; - } - - [TLDef(0x2A862092)] - public sealed partial class Messages_UploadImportedMedia : IMethod - { - public InputPeer peer; - public long import_id; - public string file_name; - public InputMedia media; - } - - [TLDef(0xB43DF344)] - public sealed partial class Messages_StartHistoryImport : IMethod - { - public InputPeer peer; - public long import_id; - } - - [TLDef(0xA2B5A3F6)] - public sealed partial class Messages_GetExportedChatInvites : IMethod - { - public Flags flags; - public InputPeer peer; - public InputUserBase admin_id; - [IfFlag(2)] public DateTime offset_date; - [IfFlag(2)] public string offset_link; - public int limit; - - [Flags] public enum Flags : uint - { - has_offset_date = 0x4, - revoked = 0x8, - } - } - - [TLDef(0x73746F5C)] - public sealed partial class Messages_GetExportedChatInvite : IMethod - { - public InputPeer peer; - public string link; - } - - [TLDef(0xBDCA2F75)] - public sealed partial class Messages_EditExportedChatInvite : IMethod - { - public Flags flags; - public InputPeer peer; - public string link; - [IfFlag(0)] public DateTime expire_date; - [IfFlag(1)] public int usage_limit; - [IfFlag(3)] public bool request_needed; - [IfFlag(4)] public string title; - - [Flags] public enum Flags : uint - { - has_expire_date = 0x1, - has_usage_limit = 0x2, - revoked = 0x4, - has_request_needed = 0x8, - has_title = 0x10, - } - } - - [TLDef(0x56987BD5)] - public sealed partial class Messages_DeleteRevokedExportedChatInvites : IMethod - { - public InputPeer peer; - public InputUserBase admin_id; - } - - [TLDef(0xD464A42B)] - public sealed partial class Messages_DeleteExportedChatInvite : IMethod - { - public InputPeer peer; - public string link; - } - - [TLDef(0x3920E6EF)] - public sealed partial class Messages_GetAdminsWithInvites : IMethod - { - public InputPeer peer; - } - - [TLDef(0xDF04DD4E)] - public sealed partial class Messages_GetChatInviteImporters : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(1)] public string link; - [IfFlag(2)] public string q; - public DateTime offset_date; - public InputUserBase offset_user; - public int limit; - - [Flags] public enum Flags : uint - { - requested = 0x1, - has_link = 0x2, - has_q = 0x4, - subscription_expired = 0x8, - } - } - - [TLDef(0xB80E5FE4)] - public sealed partial class Messages_SetHistoryTTL : IMethod - { - public InputPeer peer; - public int period; - } - - [TLDef(0x5DC60F03)] - public sealed partial class Messages_CheckHistoryImportPeer : IMethod - { - public InputPeer peer; - } - - [TLDef(0x081202C9)] - public sealed partial class Messages_SetChatTheme : IMethod - { - public InputPeer peer; - public InputChatThemeBase theme; - } - - [TLDef(0x31C1C44F)] - public sealed partial class Messages_GetMessageReadParticipants : IMethod - { - public InputPeer peer; - public int msg_id; - } - - [TLDef(0x6AA3F6BD)] - public sealed partial class Messages_GetSearchResultsCalendar : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(2)] public InputPeer saved_peer_id; - public MessagesFilter filter; - public int offset_id; - public DateTime offset_date; - - [Flags] public enum Flags : uint - { - has_saved_peer_id = 0x4, - } - } - - [TLDef(0x9C7F2F10)] - public sealed partial class Messages_GetSearchResultsPositions : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(2)] public InputPeer saved_peer_id; - public MessagesFilter filter; - public int offset_id; - public int limit; - - [Flags] public enum Flags : uint - { - has_saved_peer_id = 0x4, - } - } - - [TLDef(0x7FE7E815)] - public sealed partial class Messages_HideChatJoinRequest : IMethod - { - public Flags flags; - public InputPeer peer; - public InputUserBase user_id; - - [Flags] public enum Flags : uint - { - approved = 0x1, - } - } - - [TLDef(0xE085F4EA)] - public sealed partial class Messages_HideAllChatJoinRequests : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(1)] public string link; - - [Flags] public enum Flags : uint - { - approved = 0x1, - has_link = 0x2, - } - } - - [TLDef(0xB2081A35)] - public sealed partial class Messages_ToggleNoForwards : IMethod - { - public Flags flags; - public InputPeer peer; - public bool enabled; - [IfFlag(0)] public int request_msg_id; - - [Flags] public enum Flags : uint - { - has_request_msg_id = 0x1, - } - } - - [TLDef(0xCCFDDF96)] - public sealed partial class Messages_SaveDefaultSendAs : IMethod - { - public InputPeer peer; - public InputPeer send_as; - } - - [TLDef(0xD30D78D4)] - public sealed partial class Messages_SendReaction : IMethod - { - public Flags flags; - public InputPeer peer; - public int msg_id; - [IfFlag(0)] public Reaction[] reaction; - - [Flags] public enum Flags : uint - { - has_reaction = 0x1, - big = 0x2, - add_to_recent = 0x4, - } - } - - [TLDef(0x8BBA90E6)] - public sealed partial class Messages_GetMessagesReactions : IMethod - { - public InputPeer peer; - public int[] id; - } - - [TLDef(0x461B3F48)] - public sealed partial class Messages_GetMessageReactionsList : IMethod - { - public Flags flags; - public InputPeer peer; - public int id; - [IfFlag(0)] public Reaction reaction; - [IfFlag(1)] public string offset; - public int limit; - - [Flags] public enum Flags : uint - { - has_reaction = 0x1, - has_offset = 0x2, - } - } - - [TLDef(0x864B2581)] - public sealed partial class Messages_SetChatAvailableReactions : IMethod - { - public Flags flags; - public InputPeer peer; - public ChatReactions available_reactions; - [IfFlag(0)] public int reactions_limit; - [IfFlag(1)] public bool paid_enabled; - - [Flags] public enum Flags : uint - { - has_reactions_limit = 0x1, - has_paid_enabled = 0x2, - } - } - - [TLDef(0x18DEA0AC)] - public sealed partial class Messages_GetAvailableReactions : IMethod - { - public int hash; - } - - [TLDef(0x4F47A016)] - public sealed partial class Messages_SetDefaultReaction : IMethod - { - public Reaction reaction; - } - - [TLDef(0x63183030)] - public sealed partial class Messages_TranslateText : IMethod - { - public Flags flags; - [IfFlag(0)] public InputPeer peer; - [IfFlag(0)] public int[] id; - [IfFlag(1)] public TextWithEntities[] text; - public string to_lang; - - [Flags] public enum Flags : uint - { - has_peer = 0x1, - has_text = 0x2, - } - } - - [TLDef(0xBD7F90AC)] - public sealed partial class Messages_GetUnreadReactions : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(0)] public int top_msg_id; - [IfFlag(1)] public InputPeer saved_peer_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, - has_saved_peer_id = 0x2, - } - } - - [TLDef(0x9EC44F93)] - public sealed partial class Messages_ReadReactions : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(0)] public int top_msg_id; - [IfFlag(1)] public InputPeer saved_peer_id; - - [Flags] public enum Flags : uint - { - has_top_msg_id = 0x1, - has_saved_peer_id = 0x2, - } - } - - [TLDef(0x107E31A0)] - public sealed partial class Messages_SearchSentMedia : IMethod - { - public string q; - public MessagesFilter filter; - public int limit; - } - - [TLDef(0x16FCC2CB)] - public sealed partial class Messages_GetAttachMenuBots : IMethod - { - public long hash; - } - - [TLDef(0x77216192)] - public sealed partial class Messages_GetAttachMenuBot : IMethod - { - public InputUserBase bot; - } - - [TLDef(0x69F59D69)] - public sealed partial class Messages_ToggleBotInAttachMenu : IMethod - { - public Flags flags; - public InputUserBase bot; - public bool enabled; - - [Flags] public enum Flags : uint - { - write_allowed = 0x1, - } - } - - [TLDef(0x269DC2C1)] - public sealed partial class Messages_RequestWebView : IMethod - { - public Flags flags; - public InputPeer peer; - public InputUserBase bot; - [IfFlag(1)] public string url; - [IfFlag(3)] public string start_param; - [IfFlag(2)] public DataJSON theme_params; - public string platform; - [IfFlag(0)] public InputReplyTo reply_to; - [IfFlag(13)] public InputPeer send_as; - - [Flags] public enum Flags : uint - { - has_reply_to = 0x1, - has_url = 0x2, - has_theme_params = 0x4, - has_start_param = 0x8, - from_bot_menu = 0x10, - silent = 0x20, - compact = 0x80, - fullscreen = 0x100, - has_send_as = 0x2000, - } - } - - [TLDef(0xB0D81A83)] - public sealed partial class Messages_ProlongWebView : IMethod - { - public Flags flags; - public InputPeer peer; - public InputUserBase bot; - public long query_id; - [IfFlag(0)] public InputReplyTo reply_to; - [IfFlag(13)] public InputPeer send_as; - - [Flags] public enum Flags : uint - { - has_reply_to = 0x1, - silent = 0x20, - has_send_as = 0x2000, - } - } - - [TLDef(0x413A3E73)] - public sealed partial class Messages_RequestSimpleWebView : IMethod - { - public Flags flags; - public InputUserBase bot; - [IfFlag(3)] public string url; - [IfFlag(4)] public string start_param; - [IfFlag(0)] public DataJSON theme_params; - public string platform; - - [Flags] public enum Flags : uint - { - has_theme_params = 0x1, - from_switch_webview = 0x2, - from_side_menu = 0x4, - has_url = 0x8, - has_start_param = 0x10, - compact = 0x80, - fullscreen = 0x100, - } - } - - [TLDef(0x0A4314F5)] - public sealed partial class Messages_SendWebViewResultMessage : IMethod - { - public string bot_query_id; - public InputBotInlineResultBase result; - } - - [TLDef(0xDC0242C8)] - public sealed partial class Messages_SendWebViewData : IMethod - { - public InputUserBase bot; - public long random_id; - public string button_text; - public string data; - } - - [TLDef(0x269E9A49)] - public sealed partial class Messages_TranscribeAudio : IMethod - { - public InputPeer peer; - public int msg_id; - } - - [TLDef(0x7F1D072F)] - public sealed partial class Messages_RateTranscribedAudio : IMethod - { - public InputPeer peer; - public int msg_id; - public long transcription_id; - public bool good; - } - - [TLDef(0xD9AB0F54)] - public sealed partial class Messages_GetCustomEmojiDocuments : IMethod - { - public long[] document_id; - } - - [TLDef(0xFBFCA18F)] - public sealed partial class Messages_GetEmojiStickers : IMethod - { - public long hash; - } - - [TLDef(0x0ECF6736)] - public sealed partial class Messages_GetFeaturedEmojiStickers : IMethod - { - public long hash; - } - - [TLDef(0x3F64C076)] - public sealed partial class Messages_ReportReaction : IMethod - { - public InputPeer peer; - public int id; - public InputPeer reaction_peer; - } - - [TLDef(0xBB8125BA)] - public sealed partial class Messages_GetTopReactions : IMethod - { - public int limit; - public long hash; - } - - [TLDef(0x39461DB2)] - public sealed partial class Messages_GetRecentReactions : IMethod - { - public int limit; - public long hash; - } - - [TLDef(0x9DFEEFB4)] - public sealed partial class Messages_ClearRecentReactions : IMethod { } - - [TLDef(0x84F80814)] - public sealed partial class Messages_GetExtendedMedia : IMethod - { - public InputPeer peer; - public int[] id; - } - - [TLDef(0x9EB51445)] - public sealed partial class Messages_SetDefaultHistoryTTL : IMethod - { - public int period; - } - - [TLDef(0x658B7188)] - public sealed partial class Messages_GetDefaultHistoryTTL : IMethod { } - - [TLDef(0x91B2D060)] - public sealed partial class Messages_SendBotRequestedPeer : IMethod - { - public InputPeer peer; - public int msg_id; - public int button_id; - public InputPeer[] requested_peers; - } - - [TLDef(0x7488CE5B)] - public sealed partial class Messages_GetEmojiGroups : IMethod - { - public int hash; - } - - [TLDef(0x2ECD56CD)] - public sealed partial class Messages_GetEmojiStatusGroups : IMethod - { - public int hash; - } - - [TLDef(0x21A548F3)] - public sealed partial class Messages_GetEmojiProfilePhotoGroups : IMethod - { - public int hash; - } - - [TLDef(0x2C11C0D7)] - public sealed partial class Messages_SearchCustomEmoji : IMethod - { - public string emoticon; - public long hash; - } - - [TLDef(0xE47CB579)] - public sealed partial class Messages_TogglePeerTranslations : IMethod - { - public Flags flags; - public InputPeer peer; - - [Flags] public enum Flags : uint - { - disabled = 0x1, - } - } - - [TLDef(0x34FDC5C3)] - public sealed partial class Messages_GetBotApp : IMethod - { - public InputBotApp app; - public long hash; - } - - [TLDef(0x53618BCE)] - public sealed partial class Messages_RequestAppWebView : IMethod - { - public Flags flags; - public InputPeer peer; - public InputBotApp app; - [IfFlag(1)] public string start_param; - [IfFlag(2)] public DataJSON theme_params; - public string platform; - - [Flags] public enum Flags : uint - { - write_allowed = 0x1, - has_start_param = 0x2, - has_theme_params = 0x4, - compact = 0x80, - fullscreen = 0x100, - } - } - - [TLDef(0x8FFACAE1)] - public sealed partial class Messages_SetChatWallPaper : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(0)] public InputWallPaperBase wallpaper; - [IfFlag(2)] public WallPaperSettings settings; - [IfFlag(1)] public int id; - - [Flags] public enum Flags : uint - { - has_wallpaper = 0x1, - has_id = 0x2, - has_settings = 0x4, - for_both = 0x8, - revert = 0x10, - } - } - - [TLDef(0x92B4494C)] - public sealed partial class Messages_SearchEmojiStickerSets : IMethod - { - public Flags flags; - public string q; - public long hash; - - [Flags] public enum Flags : uint - { - exclude_featured = 0x1, - } - } - - [TLDef(0x1E91FC99)] - public sealed partial class Messages_GetSavedDialogs : IMethod - { - public Flags flags; - [IfFlag(1)] public InputPeer parent_peer; - public DateTime offset_date; - public int offset_id; - public InputPeer offset_peer; - public int limit; - public long hash; - - [Flags] public enum Flags : uint - { - exclude_pinned = 0x1, - has_parent_peer = 0x2, - } - } - - [TLDef(0x998AB009)] - public sealed partial class Messages_GetSavedHistory : IMethod - { - public Flags flags; - [IfFlag(0)] public InputPeer parent_peer; - public InputPeer peer; - public int offset_id; - public DateTime offset_date; - public int add_offset; - public int limit; - public int max_id; - public int min_id; - public long hash; - - [Flags] public enum Flags : uint - { - has_parent_peer = 0x1, - } - } - - [TLDef(0x4DC5085F)] - public sealed partial class Messages_DeleteSavedHistory : IMethod - { - public Flags flags; - [IfFlag(0)] public InputPeer parent_peer; - public InputPeer peer; - public int max_id; - [IfFlag(2)] public DateTime min_date; - [IfFlag(3)] public DateTime max_date; - - [Flags] public enum Flags : uint - { - has_parent_peer = 0x1, - has_min_date = 0x4, - has_max_date = 0x8, - } - } - - [TLDef(0xD63D94E0)] - public sealed partial class Messages_GetPinnedSavedDialogs : IMethod { } - - [TLDef(0xAC81BBDE)] - public sealed partial class Messages_ToggleSavedDialogPin : IMethod - { - public Flags flags; - public InputDialogPeerBase peer; - - [Flags] public enum Flags : uint - { - pinned = 0x1, - } - } - - [TLDef(0x8B716587)] - public sealed partial class Messages_ReorderPinnedSavedDialogs : IMethod - { - public Flags flags; - public InputDialogPeerBase[] order; - - [Flags] public enum Flags : uint - { - force = 0x1, - } - } - - [TLDef(0x3637E05B)] - public sealed partial class Messages_GetSavedReactionTags : IMethod - { - public Flags flags; - [IfFlag(0)] public InputPeer peer; - public long hash; - - [Flags] public enum Flags : uint - { - has_peer = 0x1, - } - } - - [TLDef(0x60297DEC)] - public sealed partial class Messages_UpdateSavedReactionTag : IMethod - { - public Flags flags; - public Reaction reaction; - [IfFlag(0)] public string title; - - [Flags] public enum Flags : uint - { - has_title = 0x1, - } - } - - [TLDef(0xBDF93428)] - public sealed partial class Messages_GetDefaultTagReactions : IMethod - { - public long hash; - } - - [TLDef(0x8C4BFE5D)] - public sealed partial class Messages_GetOutboxReadDate : IMethod - { - public InputPeer peer; - public int msg_id; - } - - [TLDef(0xD483F2A8)] - public sealed partial class Messages_GetQuickReplies : IMethod - { - public long hash; - } - - [TLDef(0x60331907)] - public sealed partial class Messages_ReorderQuickReplies : IMethod - { - public int[] order; - } - - [TLDef(0xF1D0FBD3)] - public sealed partial class Messages_CheckQuickReplyShortcut : IMethod - { - public string shortcut; - } - - [TLDef(0x5C003CEF)] - public sealed partial class Messages_EditQuickReplyShortcut : IMethod - { - public int shortcut_id; - public string shortcut; - } - - [TLDef(0x3CC04740)] - public sealed partial class Messages_DeleteQuickReplyShortcut : IMethod - { - public int shortcut_id; - } - - [TLDef(0x94A495C3)] - public sealed partial class Messages_GetQuickReplyMessages : IMethod - { - public Flags flags; - public int shortcut_id; - [IfFlag(0)] public int[] id; - public long hash; - - [Flags] public enum Flags : uint - { - has_id = 0x1, - } - } - - [TLDef(0x6C750DE1)] - public sealed partial class Messages_SendQuickReplyMessages : IMethod - { - public InputPeer peer; - public int shortcut_id; - public int[] id; - public long[] random_id; - } - - [TLDef(0xE105E910)] - public sealed partial class Messages_DeleteQuickReplyMessages : IMethod - { - public int shortcut_id; - public int[] id; - } - - [TLDef(0xFD2DDA49)] - public sealed partial class Messages_ToggleDialogFilterTags : IMethod - { - public bool enabled; - } - - [TLDef(0xD0B5E1FC)] - public sealed partial class Messages_GetMyStickers : IMethod - { - public long offset_id; - public int limit; - } - - [TLDef(0x1DD840F5)] - public sealed partial class Messages_GetEmojiStickerGroups : IMethod - { - public int hash; - } - - [TLDef(0xDEA20A39)] - public sealed partial class Messages_GetAvailableEffects : IMethod - { - public int hash; - } - - [TLDef(0x0589EE75)] - public sealed partial class Messages_EditFactCheck : IMethod - { - public InputPeer peer; - public int msg_id; - public TextWithEntities text; - } - - [TLDef(0xD1DA940C)] - public sealed partial class Messages_DeleteFactCheck : IMethod - { - public InputPeer peer; - public int msg_id; - } - - [TLDef(0xB9CDC5EE)] - public sealed partial class Messages_GetFactCheck : IMethod - { - public InputPeer peer; - public int[] msg_id; - } - - [TLDef(0xC9E01E7B)] - public sealed partial class Messages_RequestMainWebView : IMethod - { - public Flags flags; - public InputPeer peer; - public InputUserBase bot; - [IfFlag(1)] public string start_param; - [IfFlag(0)] public DataJSON theme_params; - public string platform; - - [Flags] public enum Flags : uint - { - has_theme_params = 0x1, - has_start_param = 0x2, - compact = 0x80, - fullscreen = 0x100, - } - } - - [TLDef(0x58BBCB50)] - public sealed partial class Messages_SendPaidReaction : IMethod - { - public Flags flags; - public InputPeer peer; - public int msg_id; - public int count; - public long random_id; - [IfFlag(0)] public PaidReactionPrivacy private_; - - [Flags] public enum Flags : uint - { - has_private = 0x1, - } - } - - [TLDef(0x435885B5)] - public sealed partial class Messages_TogglePaidReactionPrivacy : IMethod - { - public InputPeer peer; - public int msg_id; - public PaidReactionPrivacy private_; - } - - [TLDef(0x472455AA)] - public sealed partial class Messages_GetPaidReactionPrivacy : IMethod { } - - [TLDef(0x269E3643)] - public sealed partial class Messages_ViewSponsoredMessage : IMethod - { - public byte[] random_id; - } - - [TLDef(0x8235057E)] - public sealed partial class Messages_ClickSponsoredMessage : IMethod - { - public Flags flags; - public byte[] random_id; - - [Flags] public enum Flags : uint - { - media = 0x1, - fullscreen = 0x2, - } - } - - [TLDef(0x12CBF0C4)] - public sealed partial class Messages_ReportSponsoredMessage : IMethod - { - public byte[] random_id; - public byte[] option; - } - - [TLDef(0x3D6CE850)] - public sealed partial class Messages_GetSponsoredMessages : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(0)] public int msg_id; - - [Flags] public enum Flags : uint - { - has_msg_id = 0x1, - } - } - - [TLDef(0xF21F7F2F)] - public sealed partial class Messages_SavePreparedInlineMessage : IMethod - { - public Flags flags; - public InputBotInlineResultBase result; - public InputUserBase user_id; - [IfFlag(0)] public InlineQueryPeerType[] peer_types; - - [Flags] public enum Flags : uint - { - has_peer_types = 0x1, - } - } - - [TLDef(0x857EBDB8)] - public sealed partial class Messages_GetPreparedInlineMessage : IMethod - { - public InputUserBase bot; - public string id; - } - - [TLDef(0x29B1C66A)] - public sealed partial class Messages_SearchStickers : IMethod - { - public Flags flags; - public string q; - public string emoticon; - public string[] lang_code; - public int offset; - public int limit; - public long hash; - - [Flags] public enum Flags : uint - { - emojis = 0x1, - } - } - - [TLDef(0x5A6D7395)] - public sealed partial class Messages_ReportMessagesDelivery : IMethod - { - public Flags flags; - public InputPeer peer; - public int[] id; - - [Flags] public enum Flags : uint - { - push = 0x1, - } - } - - [TLDef(0x6F6F9C96)] - public sealed partial class Messages_GetSavedDialogsByID : IMethod - { - public Flags flags; - [IfFlag(1)] public InputPeer parent_peer; - public InputPeer[] ids; - - [Flags] public enum Flags : uint - { - has_parent_peer = 0x2, - } - } - - [TLDef(0xBA4A3B5B)] - public sealed partial class Messages_ReadSavedHistory : IMethod - { - public InputPeer parent_peer; - public InputPeer peer; - public int max_id; - } - - [TLDef(0xD3E03124)] - public sealed partial class Messages_ToggleTodoCompleted : IMethod - { - public InputPeer peer; - public int msg_id; - public int[] completed; - public int[] incompleted; - } - - [TLDef(0x21A61057)] - public sealed partial class Messages_AppendTodoList : IMethod - { - public InputPeer peer; - public int msg_id; - public TodoItem[] list; - } - - [TLDef(0x8107455C)] - public sealed partial class Messages_ToggleSuggestedPostApproval : IMethod - { - public Flags flags; - public InputPeer peer; - public int msg_id; - [IfFlag(0)] public DateTime schedule_date; - [IfFlag(2)] public string reject_comment; - - [Flags] public enum Flags : uint - { - has_schedule_date = 0x1, - reject = 0x2, - has_reject_comment = 0x4, - } - } - - [TLDef(0x3BA47BFF)] - public sealed partial class Messages_GetForumTopics : IMethod - { - public Flags flags; - public InputPeer peer; - [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(0xAF0A4A08)] - public sealed partial class Messages_GetForumTopicsByID : IMethod - { - public InputPeer peer; - public int[] topics; - } - - [TLDef(0xCECC1134)] - public sealed partial class Messages_EditForumTopic : IMethod - { - public Flags flags; - public InputPeer peer; - public int topic_id; - [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, - } - } - - [TLDef(0x175DF251)] - public sealed partial class Messages_UpdatePinnedForumTopic : IMethod - { - public InputPeer peer; - public int topic_id; - public bool pinned; - } - - [TLDef(0x0E7841F0)] - public sealed partial class Messages_ReorderPinnedForumTopics : IMethod - { - public Flags flags; - public InputPeer peer; - public int[] order; - - [Flags] public enum Flags : uint - { - force = 0x1, - } - } - - [TLDef(0x2F98C3D5)] - public sealed partial class Messages_CreateForumTopic : IMethod - { - public Flags flags; - public InputPeer peer; - 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, - title_missing = 0x10, - } - } - - [TLDef(0xD2816F10)] - public sealed partial class Messages_DeleteTopicHistory : IMethod - { - public InputPeer peer; - public int top_msg_id; - } - - [TLDef(0xFB7E8CA7)] - public sealed partial class Messages_GetEmojiGameInfo : IMethod { } - - [TLDef(0x9D4104E2)] - public sealed partial class Messages_SummarizeText : IMethod - { - public Flags flags; - public InputPeer peer; - public int id; - [IfFlag(0)] public string to_lang; - - [Flags] public enum Flags : uint - { - has_to_lang = 0x1, - } - } - - [TLDef(0xF743B857)] - public sealed partial class Messages_EditChatCreator : IMethod - { - public InputPeer peer; - public InputUserBase user_id; - public InputCheckPasswordSRP password; - } - - [TLDef(0x3B7D0EA6)] - public sealed partial class Messages_GetFutureChatCreatorAfterLeave : IMethod - { - public InputPeer peer; - } - - [TLDef(0xA00F32B0)] - public sealed partial class Messages_EditChatParticipantRank : IMethod - { - public InputPeer peer; - public InputPeer participant; - public string rank; - } - - [TLDef(0x35436BBC)] - public sealed partial class Messages_DeclineUrlAuth : IMethod - { - public string url; - } - - [TLDef(0xC9A47B0B)] - public sealed partial class Messages_CheckUrlAuthMatchCode : IMethod - { - public string url; - public string match_code; - } - - [TLDef(0xEDD4882A)] - public sealed partial class Updates_GetState : IMethod { } - - [TLDef(0x19C2F763)] - public sealed partial class Updates_GetDifference : IMethod - { - public Flags flags; - public int pts; - [IfFlag(1)] public int pts_limit; - [IfFlag(0)] public int pts_total_limit; - public DateTime date; - public int qts; - [IfFlag(2)] public int qts_limit; - - [Flags] public enum Flags : uint - { - has_pts_total_limit = 0x1, - has_pts_limit = 0x2, - has_qts_limit = 0x4, - } - } - - [TLDef(0x03173D78)] - public sealed partial class Updates_GetChannelDifference : IMethod - { - public Flags flags; - public InputChannelBase channel; - public ChannelMessagesFilter filter; - public int pts; - public int limit; - - [Flags] public enum Flags : uint - { - force = 0x1, - } - } - - [TLDef(0x09E82039)] - public sealed partial class Photos_UpdateProfilePhoto : IMethod - { - public Flags flags; - [IfFlag(1)] public InputUserBase bot; - public InputPhoto id; - - [Flags] public enum Flags : uint - { - fallback = 0x1, - has_bot = 0x2, - } - } - - [TLDef(0x0388A3B5)] - public sealed partial class Photos_UploadProfilePhoto : IMethod - { - public Flags flags; - [IfFlag(5)] public InputUserBase bot; - [IfFlag(0)] public InputFileBase file; - [IfFlag(1)] public InputFileBase video; - [IfFlag(2)] public double video_start_ts; - [IfFlag(4)] public VideoSizeBase video_emoji_markup; - - [Flags] public enum Flags : uint - { - has_file = 0x1, - has_video = 0x2, - has_video_start_ts = 0x4, - fallback = 0x8, - has_video_emoji_markup = 0x10, - has_bot = 0x20, - } - } - - [TLDef(0x87CF7F2F)] - public sealed partial class Photos_DeletePhotos : IMethod - { - public InputPhoto[] id; - } - - [TLDef(0x91CD32A8)] - public sealed partial class Photos_GetUserPhotos : IMethod - { - public InputUserBase user_id; - public int offset; - public long max_id; - public int limit; - } - - [TLDef(0xE14C4A71)] - public sealed partial 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; - [IfFlag(5)] public VideoSizeBase video_emoji_markup; - - [Flags] public enum Flags : uint - { - has_file = 0x1, - has_video = 0x2, - has_video_start_ts = 0x4, - suggest = 0x8, - save = 0x10, - has_video_emoji_markup = 0x20, - } - } - - [TLDef(0xB304A621)] - public sealed partial class Upload_SaveFilePart : IMethod - { - public long file_id; - public int file_part; - public byte[] bytes; - } - - [TLDef(0xBE5335BE)] - public sealed partial class Upload_GetFile : IMethod - { - public Flags flags; - public InputFileLocationBase location; - public long offset; - public int limit; - - [Flags] public enum Flags : uint - { - precise = 0x1, - cdn_supported = 0x2, - } - } - - [TLDef(0xDE7B673D)] - public sealed partial class Upload_SaveBigFilePart : IMethod - { - public long file_id; - public int file_part; - public int file_total_parts; - public byte[] bytes; - } - - [TLDef(0x24E6818D)] - public sealed partial class Upload_GetWebFile : IMethod - { - public InputWebFileLocationBase location; - public int offset; - public int limit; - } - - [TLDef(0x395F69DA)] - public sealed partial class Upload_GetCdnFile : IMethod - { - public byte[] file_token; - public long offset; - public int limit; - } - - [TLDef(0x9B2754A8)] - public sealed partial class Upload_ReuploadCdnFile : IMethod - { - public byte[] file_token; - public byte[] request_token; - } - - [TLDef(0x91DC3F31)] - public sealed partial class Upload_GetCdnFileHashes : IMethod - { - public byte[] file_token; - public long offset; - } - - [TLDef(0x9156982A)] - public sealed partial class Upload_GetFileHashes : IMethod - { - public InputFileLocationBase location; - public long offset; - } - - [TLDef(0xC4F9186B)] - public sealed partial class Help_GetConfig : IMethod { } - - [TLDef(0x1FB33026)] - public sealed partial class Help_GetNearestDc : IMethod { } - - [TLDef(0x522D5A7D)] - public sealed partial class Help_GetAppUpdate : IMethod - { - public string source; - } - - [TLDef(0x4D392343)] - public sealed partial class Help_GetInviteText : IMethod { } - - [TLDef(0x9CDF08CD)] - public sealed partial class Help_GetSupport : IMethod { } - - [TLDef(0xEC22CFCD)] - public sealed partial class Help_SetBotUpdatesStatus : IMethod - { - public int pending_updates_count; - public string message; - } - - [TLDef(0x52029342)] - public sealed partial class Help_GetCdnConfig : IMethod { } - - [TLDef(0x3DC0F114)] - public sealed partial class Help_GetRecentMeUrls : IMethod - { - public string referer; - } - - [TLDef(0x2CA51FD1)] - public sealed partial class Help_GetTermsOfServiceUpdate : IMethod { } - - [TLDef(0xEE72F79A)] - public sealed partial class Help_AcceptTermsOfService : IMethod - { - public DataJSON id; - } - - [TLDef(0x3FEDC75F)] - public sealed partial class Help_GetDeepLinkInfo : IMethod - { - public string path; - } - - [TLDef(0x61E3F854)] - public sealed partial class Help_GetAppConfig : IMethod - { - public int hash; - } - - [TLDef(0x6F02F748)] - public sealed partial class Help_SaveAppLog : IMethod - { - public InputAppEvent[] events; - } - - [TLDef(0xC661AD08)] - public sealed partial class Help_GetPassportConfig : IMethod - { - public int hash; - } - - [TLDef(0xD360E72C)] - public sealed partial class Help_GetSupportName : IMethod { } - - [TLDef(0x038A08D3)] - public sealed partial class Help_GetUserInfo : IMethod - { - public InputUserBase user_id; - } - - [TLDef(0x66B91B70)] - public sealed partial class Help_EditUserInfo : IMethod - { - public InputUserBase user_id; - public string message; - public MessageEntity[] entities; - } - - [TLDef(0xC0977421)] - public sealed partial class Help_GetPromoData : IMethod { } - - [TLDef(0x1E251C95)] - public sealed partial class Help_HidePromoData : IMethod - { - public InputPeer peer; - } - - [TLDef(0xF50DBAA1)] - public sealed partial class Help_DismissSuggestion : IMethod - { - public InputPeer peer; - public string suggestion; - } - - [TLDef(0x735787A8)] - public sealed partial class Help_GetCountriesList : IMethod - { - public string lang_code; - public int hash; - } - - [TLDef(0xB81B93D4)] - public sealed partial class Help_GetPremiumPromo : IMethod { } - - [TLDef(0xDA80F42F)] - public sealed partial class Help_GetPeerColors : IMethod - { - public int hash; - } - - [TLDef(0xABCFA9FD)] - public sealed partial class Help_GetPeerProfileColors : IMethod - { - public int hash; - } - - [TLDef(0x49B30240)] - public sealed partial class Help_GetTimezonesList : IMethod - { - public int hash; - } - - [TLDef(0xCC104937)] - public sealed partial class Channels_ReadHistory : IMethod - { - public InputChannelBase channel; - public int max_id; - } - - [TLDef(0x84C1FD4E)] - public sealed partial class Channels_DeleteMessages : IMethod - { - public InputChannelBase channel; - public int[] id; - } - - [TLDef(0xF44A8315)] - public sealed partial class Channels_ReportSpam : IMethod - { - public InputChannelBase channel; - public InputPeer participant; - public int[] id; - } - - [TLDef(0xAD8C9A23)] - public sealed partial class Channels_GetMessages : IMethod - { - public InputChannelBase channel; - public InputMessage[] id; - } - - [TLDef(0x77CED9D0)] - public sealed partial class Channels_GetParticipants : IMethod - { - public InputChannelBase channel; - public ChannelParticipantsFilter filter; - public int offset; - public int limit; - public long hash; - } - - [TLDef(0xA0AB6CC6)] - public sealed partial class Channels_GetParticipant : IMethod - { - public InputChannelBase channel; - public InputPeer participant; - } - - [TLDef(0x0A7F6BBB)] - public sealed partial class Channels_GetChannels : IMethod - { - public InputChannelBase[] id; - } - - [TLDef(0x08736A09)] - public sealed partial class Channels_GetFullChannel : IMethod - { - public InputChannelBase channel; - } - - [TLDef(0x91006707)] - public sealed partial class Channels_CreateChannel : IMethod - { - public Flags flags; - public string title; - 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 - { - broadcast = 0x1, - megagroup = 0x2, - has_geo_point = 0x4, - for_import = 0x8, - has_ttl_period = 0x10, - forum = 0x20, - } - } - - [TLDef(0x9A98AD68)] - public sealed partial class Channels_EditAdmin : IMethod - { - public Flags flags; - public InputChannelBase channel; - public InputUserBase user_id; - public ChatAdminRights admin_rights; - [IfFlag(0)] public string rank; - - [Flags] public enum Flags : uint - { - has_rank = 0x1, - } - } - - [TLDef(0x566DECD0)] - public sealed partial class Channels_EditTitle : IMethod - { - public InputChannelBase channel; - public string title; - } - - [TLDef(0xF12E57C9)] - public sealed partial class Channels_EditPhoto : IMethod - { - public InputChannelBase channel; - public InputChatPhotoBase photo; - } - - [TLDef(0x10E6BD2C)] - public sealed partial class Channels_CheckUsername : IMethod - { - public InputChannelBase channel; - public string username; - } - - [TLDef(0x3514B3DE)] - public sealed partial class Channels_UpdateUsername : IMethod - { - public InputChannelBase channel; - public string username; - } - - [TLDef(0x24B524C5)] - public sealed partial class Channels_JoinChannel : IMethod - { - public InputChannelBase channel; - } - - [TLDef(0xF836AA95)] - public sealed partial class Channels_LeaveChannel : IMethod - { - public InputChannelBase channel; - } - - [TLDef(0xC9E33D54)] - public sealed partial class Channels_InviteToChannel : IMethod - { - public InputChannelBase channel; - public InputUserBase[] users; - } - - [TLDef(0xC0111FE3)] - public sealed partial class Channels_DeleteChannel : IMethod - { - public InputChannelBase channel; - } - - [TLDef(0xE63FADEB)] - public sealed partial class Channels_ExportMessageLink : IMethod - { - public Flags flags; - public InputChannelBase channel; - public int id; - - [Flags] public enum Flags : uint - { - grouped = 0x1, - thread = 0x2, - } - } - - [TLDef(0x418D549C)] - public sealed partial class Channels_ToggleSignatures : IMethod - { - public Flags flags; - public InputChannelBase channel; - - [Flags] public enum Flags : uint - { - signatures_enabled = 0x1, - profiles_enabled = 0x2, - } - } - - [TLDef(0xF8B036AF)] - public sealed partial class Channels_GetAdminedPublicChannels : IMethod - { - public Flags flags; - - [Flags] public enum Flags : uint - { - by_location = 0x1, - check_limit = 0x2, - for_personal = 0x4, - } - } - - [TLDef(0x96E6CD81)] - public sealed partial class Channels_EditBanned : IMethod - { - public InputChannelBase channel; - public InputPeer participant; - public ChatBannedRights banned_rights; - } - - [TLDef(0x33DDF480)] - public sealed partial class Channels_GetAdminLog : IMethod - { - public Flags flags; - public InputChannelBase channel; - public string q; - [IfFlag(0)] public ChannelAdminLogEventsFilter events_filter; - [IfFlag(1)] public InputUserBase[] admins; - public long max_id; - public long min_id; - public int limit; - - [Flags] public enum Flags : uint - { - has_events_filter = 0x1, - has_admins = 0x2, - } - } - - [TLDef(0xEA8CA4F9)] - public sealed partial class Channels_SetStickers : IMethod - { - public InputChannelBase channel; - public InputStickerSet stickerset; - } - - [TLDef(0xEAB5DC38)] - public sealed partial class Channels_ReadMessageContents : IMethod - { - public InputChannelBase channel; - public int[] id; - } - - [TLDef(0x9BAA9647)] - public sealed partial class Channels_DeleteHistory : IMethod - { - public Flags flags; - public InputChannelBase channel; - public int max_id; - - [Flags] public enum Flags : uint - { - for_everyone = 0x1, - } - } - - [TLDef(0xEABBB94C)] - public sealed partial class Channels_TogglePreHistoryHidden : IMethod - { - public InputChannelBase channel; - public bool enabled; - } - - [TLDef(0x8341ECC0)] - public sealed partial class Channels_GetLeftChannels : IMethod - { - public int offset; - } - - [TLDef(0xF5DAD378)] - public sealed partial class Channels_GetGroupsForDiscussion : IMethod { } - - [TLDef(0x40582BB2)] - public sealed partial class Channels_SetDiscussionGroup : IMethod - { - public InputChannelBase broadcast; - public InputChannelBase group; - } - - [TLDef(0x58E63F6D)] - public sealed partial class Channels_EditLocation : IMethod - { - public InputChannelBase channel; - public InputGeoPoint geo_point; - public string address; - } - - [TLDef(0xEDD49EF0)] - public sealed partial class Channels_ToggleSlowMode : IMethod - { - public InputChannelBase channel; - public int seconds; - } - - [TLDef(0x11E831EE)] - public sealed partial class Channels_GetInactiveChannels : IMethod { } - - [TLDef(0x0B290C69)] - public sealed partial class Channels_ConvertToGigagroup : IMethod - { - public InputChannelBase channel; - } - - [TLDef(0xE785A43F)] - public sealed partial class Channels_GetSendAs : IMethod - { - public Flags flags; - public InputPeer peer; - - [Flags] public enum Flags : uint - { - for_paid_reactions = 0x1, - for_live_stories = 0x2, - } - } - - [TLDef(0x367544DB)] - public sealed partial class Channels_DeleteParticipantHistory : IMethod - { - public InputChannelBase channel; - public InputPeer participant; - } - - [TLDef(0xE4CB9580)] - public sealed partial class Channels_ToggleJoinToSend : IMethod - { - public InputChannelBase channel; - public bool enabled; - } - - [TLDef(0x4C2985B6)] - public sealed partial class Channels_ToggleJoinRequest : IMethod - { - public InputChannelBase channel; - public bool enabled; - } - - [TLDef(0xB45CED1D)] - public sealed partial class Channels_ReorderUsernames : IMethod - { - public InputChannelBase channel; - public string[] order; - } - - [TLDef(0x50F24105)] - public sealed partial class Channels_ToggleUsername : IMethod - { - public InputChannelBase channel; - public string username; - public bool active; - } - - [TLDef(0x0A245DD3)] - public sealed partial class Channels_DeactivateAllUsernames : IMethod - { - public InputChannelBase channel; - } - - [TLDef(0x3FF75734)] - public sealed partial class Channels_ToggleForum : IMethod - { - public InputChannelBase channel; - public bool enabled; - public bool tabs; - } - - [TLDef(0x68F3E4EB)] - public sealed partial class Channels_ToggleAntiSpam : IMethod - { - public InputChannelBase channel; - public bool enabled; - } - - [TLDef(0xA850A693)] - public sealed partial class Channels_ReportAntiSpamFalsePositive : IMethod - { - public InputChannelBase channel; - public int msg_id; - } - - [TLDef(0x6A6E7854)] - public sealed partial class Channels_ToggleParticipantsHidden : IMethod - { - public InputChannelBase channel; - public bool enabled; - } - - [TLDef(0xD8AA3671)] - public sealed partial class Channels_UpdateColor : IMethod - { - public Flags flags; - public InputChannelBase channel; - [IfFlag(2)] public int color; - [IfFlag(0)] public long background_emoji_id; - - [Flags] public enum Flags : uint - { - has_background_emoji_id = 0x1, - for_profile = 0x2, - has_color = 0x4, - } - } - - [TLDef(0x9738BB15)] - public sealed partial class Channels_ToggleViewForumAsMessages : IMethod - { - public InputChannelBase channel; - public bool enabled; - } - - [TLDef(0x25A71742)] - public sealed partial class Channels_GetChannelRecommendations : IMethod - { - public Flags flags; - [IfFlag(0)] public InputChannelBase channel; - - [Flags] public enum Flags : uint - { - has_channel = 0x1, - } - } - - [TLDef(0xF0D3E6A8)] - public sealed partial class Channels_UpdateEmojiStatus : IMethod - { - public InputChannelBase channel; - public EmojiStatusBase emoji_status; - } - - [TLDef(0xAD399CEE)] - public sealed partial class Channels_SetBoostsToUnblockRestrictions : IMethod - { - public InputChannelBase channel; - public int boosts; - } - - [TLDef(0x3CD930B7)] - public sealed partial class Channels_SetEmojiStickers : IMethod - { - public InputChannelBase channel; - public InputStickerSet stickerset; - } - - [TLDef(0x9AE91519)] - public sealed partial class Channels_RestrictSponsoredMessages : IMethod - { - public InputChannelBase channel; - public bool restricted; - } - - [TLDef(0xF2C4F24D)] - public sealed partial class Channels_SearchPosts : IMethod - { - public Flags flags; - [IfFlag(0)] public string hashtag; - [IfFlag(1)] public string query; - public int offset_rate; - public InputPeer offset_peer; - public int offset_id; - public int limit; - [IfFlag(2)] public long allow_paid_stars; - - [Flags] public enum Flags : uint - { - has_hashtag = 0x1, - has_query = 0x2, - has_allow_paid_stars = 0x4, - } - } - - [TLDef(0x4B12327B)] - public sealed partial class Channels_UpdatePaidMessagesPrice : IMethod - { - public Flags flags; - public InputChannelBase channel; - public long send_paid_messages_stars; - - [Flags] public enum Flags : uint - { - broadcast_messages_allowed = 0x1, - } - } - - [TLDef(0x167FC0A1)] - public sealed partial class Channels_ToggleAutotranslation : IMethod - { - public InputChannelBase channel; - public bool enabled; - } - - [TLDef(0xECE2A0E6)] - public sealed partial class Channels_GetMessageAuthor : IMethod - { - public InputChannelBase channel; - public int id; - } - - [TLDef(0x22567115)] - public sealed partial class Channels_CheckSearchPostsFlood : IMethod - { - public Flags flags; - [IfFlag(0)] public string query; - - [Flags] public enum Flags : uint - { - has_query = 0x1, - } - } - - [TLDef(0x3583FCB1)] - public sealed partial class Channels_SetMainProfileTab : IMethod - { - public InputChannelBase channel; - public ProfileTab tab; - } - - [TLDef(0xAA2769ED)] - public sealed partial class Bots_SendCustomRequest : IMethod - { - public string custom_method; - public DataJSON params_; - } - - [TLDef(0xE6213F4D)] - public sealed partial class Bots_AnswerWebhookJSONQuery : IMethod - { - public long query_id; - public DataJSON data; - } - - [TLDef(0x0517165A)] - public sealed partial class Bots_SetBotCommands : IMethod - { - public BotCommandScope scope; - public string lang_code; - public BotCommand[] commands; - } - - [TLDef(0x3D8DE0F9)] - public sealed partial class Bots_ResetBotCommands : IMethod - { - public BotCommandScope scope; - public string lang_code; - } - - [TLDef(0xE34C0DD6)] - public sealed partial class Bots_GetBotCommands : IMethod - { - public BotCommandScope scope; - public string lang_code; - } - - [TLDef(0x4504D54F)] - public sealed partial class Bots_SetBotMenuButton : IMethod - { - public InputUserBase user_id; - public BotMenuButtonBase button; - } - - [TLDef(0x9C60EB28)] - public sealed partial class Bots_GetBotMenuButton : IMethod - { - public InputUserBase user_id; - } - - [TLDef(0x788464E1)] - public sealed partial class Bots_SetBotBroadcastDefaultAdminRights : IMethod - { - public ChatAdminRights admin_rights; - } - - [TLDef(0x925EC9EA)] - public sealed partial class Bots_SetBotGroupDefaultAdminRights : IMethod - { - public ChatAdminRights admin_rights; - } - - [TLDef(0x10CF3123)] - public sealed partial class Bots_SetBotInfo : IMethod - { - public Flags flags; - [IfFlag(2)] public InputUserBase bot; - public string lang_code; - [IfFlag(3)] public string name; - [IfFlag(0)] public string about; - [IfFlag(1)] public string description; - - [Flags] public enum Flags : uint - { - has_about = 0x1, - has_description = 0x2, - has_bot = 0x4, - has_name = 0x8, - } - } - - [TLDef(0xDCD914FD)] - public sealed partial class Bots_GetBotInfo : IMethod - { - public Flags flags; - [IfFlag(0)] public InputUserBase bot; - public string lang_code; - - [Flags] public enum Flags : uint - { - has_bot = 0x1, - } - } - - [TLDef(0x9709B1C2)] - public sealed partial class Bots_ReorderUsernames : IMethod - { - public InputUserBase bot; - public string[] order; - } - - [TLDef(0x053CA973)] - public sealed partial class Bots_ToggleUsername : IMethod - { - public InputUserBase bot; - public string username; - public bool active; - } - - [TLDef(0x1359F4E6)] - public sealed partial class Bots_CanSendMessage : IMethod - { - public InputUserBase bot; - } - - [TLDef(0xF132E3EF)] - public sealed partial class Bots_AllowSendMessage : IMethod - { - public InputUserBase bot; - } - - [TLDef(0x087FC5E7)] - public sealed partial class Bots_InvokeWebViewCustomMethod : IMethod - { - public InputUserBase bot; - public string custom_method; - public DataJSON params_; - } - - [TLDef(0xC2510192)] - public sealed partial class Bots_GetPopularAppBots : IMethod - { - public string offset; - public int limit; - } - - [TLDef(0x17AEB75A)] - public sealed partial class Bots_AddPreviewMedia : IMethod - { - public InputUserBase bot; - public string lang_code; - public InputMedia media; - } - - [TLDef(0x8525606F)] - public sealed partial class Bots_EditPreviewMedia : IMethod - { - public InputUserBase bot; - public string lang_code; - public InputMedia media; - public InputMedia new_media; - } - - [TLDef(0x2D0135B3)] - public sealed partial class Bots_DeletePreviewMedia : IMethod - { - public InputUserBase bot; - public string lang_code; - public InputMedia[] media; - } - - [TLDef(0xB627F3AA)] - public sealed partial class Bots_ReorderPreviewMedias : IMethod - { - public InputUserBase bot; - public string lang_code; - public InputMedia[] order; - } - - [TLDef(0x423AB3AD)] - public sealed partial class Bots_GetPreviewInfo : IMethod - { - public InputUserBase bot; - public string lang_code; - } - - [TLDef(0xA2A5594D)] - public sealed partial class Bots_GetPreviewMedias : IMethod - { - public InputUserBase bot; - } - - [TLDef(0xED9F30C5)] - public sealed partial class Bots_UpdateUserEmojiStatus : IMethod - { - public InputUserBase user_id; - public EmojiStatusBase emoji_status; - } - - [TLDef(0x06DE6392)] - public sealed partial class Bots_ToggleUserEmojiStatusPermission : IMethod - { - public InputUserBase bot; - public bool enabled; - } - - [TLDef(0x50077589)] - public sealed partial class Bots_CheckDownloadFileParams : IMethod - { - public InputUserBase bot; - public string file_name; - public string url; - } - - [TLDef(0xB0711D83)] - public sealed partial class Bots_GetAdminedBots : IMethod { } - - [TLDef(0x778B5AB3)] - public sealed partial class Bots_UpdateStarRefProgram : IMethod - { - public Flags flags; - public InputUserBase bot; - public int commission_permille; - [IfFlag(0)] public int duration_months; - - [Flags] public enum Flags : uint - { - has_duration_months = 0x1, - } - } - - [TLDef(0x8B89DFBD)] - public sealed partial class Bots_SetCustomVerification : IMethod - { - public Flags flags; - [IfFlag(0)] public InputUserBase bot; - public InputPeer peer; - [IfFlag(2)] public string custom_description; - - [Flags] public enum Flags : uint - { - has_bot = 0x1, - enabled = 0x2, - has_custom_description = 0x4, - } - } - - [TLDef(0xA1B70815)] - public sealed partial class Bots_GetBotRecommendations : IMethod - { - public InputUserBase bot; - } - - [TLDef(0x37148DBB)] - public sealed partial class Payments_GetPaymentForm : IMethod - { - public Flags flags; - public InputInvoice invoice; - [IfFlag(0)] public DataJSON theme_params; - - [Flags] public enum Flags : uint - { - has_theme_params = 0x1, - } - } - - [TLDef(0x2478D1CC)] - public sealed partial class Payments_GetPaymentReceipt : IMethod - { - public InputPeer peer; - public int msg_id; - } - - [TLDef(0xB6C8F12B)] - public sealed partial class Payments_ValidateRequestedInfo : IMethod - { - public Flags flags; - public InputInvoice invoice; - public PaymentRequestedInfo info; - - [Flags] public enum Flags : uint - { - save = 0x1, - } - } - - [TLDef(0x2D03522F)] - public sealed partial class Payments_SendPaymentForm : IMethod - { - public Flags flags; - public long form_id; - public InputInvoice invoice; - [IfFlag(0)] public string requested_info_id; - [IfFlag(1)] public string shipping_option_id; - public InputPaymentCredentialsBase credentials; - [IfFlag(2)] public long tip_amount; - - [Flags] public enum Flags : uint - { - has_requested_info_id = 0x1, - has_shipping_option_id = 0x2, - has_tip_amount = 0x4, - } - } - - [TLDef(0x227D824B)] - public sealed partial class Payments_GetSavedInfo : IMethod { } - - [TLDef(0xD83D70C1)] - public sealed partial class Payments_ClearSavedInfo : IMethod - { - public Flags flags; - - [Flags] public enum Flags : uint - { - credentials = 0x1, - info = 0x2, - } - } - - [TLDef(0x2E79D779)] - public sealed partial class Payments_GetBankCardData : IMethod - { - public string number; - } - - [TLDef(0x0F91B065)] - public sealed partial class Payments_ExportInvoice : IMethod - { - public InputMedia invoice_media; - } - - [TLDef(0x80ED747D)] - public sealed partial class Payments_AssignAppStoreTransaction : IMethod - { - public byte[] receipt; - public InputStorePaymentPurpose purpose; - } - - [TLDef(0xDFFD50D3)] - public sealed partial class Payments_AssignPlayMarketTransaction : IMethod - { - public DataJSON receipt; - public InputStorePaymentPurpose purpose; - } - - [TLDef(0x2757BA54)] - public sealed partial class Payments_GetPremiumGiftCodeOptions : IMethod - { - public Flags flags; - [IfFlag(0)] public InputPeer boost_peer; - - [Flags] public enum Flags : uint - { - has_boost_peer = 0x1, - } - } - - [TLDef(0x8E51B4C1)] - public sealed partial class Payments_CheckGiftCode : IMethod - { - public string slug; - } - - [TLDef(0xF6E26854)] - public sealed partial class Payments_ApplyGiftCode : IMethod - { - public string slug; - } - - [TLDef(0xF4239425)] - public sealed partial class Payments_GetGiveawayInfo : IMethod - { - public InputPeer peer; - public int msg_id; - } - - [TLDef(0x5FF58F20)] - public sealed partial class Payments_LaunchPrepaidGiveaway : IMethod - { - public InputPeer peer; - public long giveaway_id; - public InputStorePaymentPurpose purpose; - } - - [TLDef(0xC00EC7D3)] - public sealed partial class Payments_GetStarsTopupOptions : IMethod { } - - [TLDef(0x4EA9B3BF)] - public sealed partial class Payments_GetStarsStatus : IMethod - { - public Flags flags; - public InputPeer peer; - - [Flags] public enum Flags : uint - { - ton = 0x1, - } - } - - [TLDef(0x69DA4557)] - public sealed partial class Payments_GetStarsTransactions : IMethod - { - public Flags flags; - [IfFlag(3)] public string subscription_id; - public InputPeer peer; - public string offset; - public int limit; - - [Flags] public enum Flags : uint - { - inbound = 0x1, - outbound = 0x2, - ascending = 0x4, - has_subscription_id = 0x8, - ton = 0x10, - } - } - - [TLDef(0x7998C914)] - public sealed partial class Payments_SendStarsForm : IMethod - { - public long form_id; - public InputInvoice invoice; - } - - [TLDef(0x25AE8F4A)] - public sealed partial class Payments_RefundStarsCharge : IMethod - { - public InputUserBase user_id; - public string charge_id; - } - - [TLDef(0xD91FFAD6)] - public sealed partial class Payments_GetStarsRevenueStats : IMethod - { - public Flags flags; - public InputPeer peer; - - [Flags] public enum Flags : uint - { - dark = 0x1, - ton = 0x2, - } - } - - [TLDef(0x2433DC92)] - public sealed partial class Payments_GetStarsRevenueWithdrawalUrl : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(1)] public long amount; - public InputCheckPasswordSRP password; - - [Flags] public enum Flags : uint - { - ton = 0x1, - has_amount = 0x2, - } - } - - [TLDef(0xD1D7EFC5)] - public sealed partial class Payments_GetStarsRevenueAdsAccountUrl : IMethod - { - public InputPeer peer; - } - - [TLDef(0x2DCA16B8)] - public sealed partial class Payments_GetStarsTransactionsByID : IMethod - { - public Flags flags; - public InputPeer peer; - public InputStarsTransaction[] id; - - [Flags] public enum Flags : uint - { - ton = 0x1, - } - } - - [TLDef(0xD3C96BC8)] - public sealed partial class Payments_GetStarsGiftOptions : IMethod - { - public Flags flags; - [IfFlag(0)] public InputUserBase user_id; - - [Flags] public enum Flags : uint - { - has_user_id = 0x1, - } - } - - [TLDef(0x032512C5)] - public sealed partial class Payments_GetStarsSubscriptions : IMethod - { - public Flags flags; - public InputPeer peer; - public string offset; - - [Flags] public enum Flags : uint - { - missing_balance = 0x1, - } - } - - [TLDef(0xC7770878)] - public sealed partial class Payments_ChangeStarsSubscription : IMethod - { - public Flags flags; - public InputPeer peer; - public string subscription_id; - [IfFlag(0)] public bool canceled; - - [Flags] public enum Flags : uint - { - has_canceled = 0x1, - } - } - - [TLDef(0xCC5BEBB3)] - public sealed partial class Payments_FulfillStarsSubscription : IMethod - { - public InputPeer peer; - public string subscription_id; - } - - [TLDef(0xBD1EFD3E)] - public sealed partial class Payments_GetStarsGiveawayOptions : IMethod { } - - [TLDef(0xC4563590)] - public sealed partial class Payments_GetStarGifts : IMethod - { - public int hash; - } - - [TLDef(0x2A2A697C)] - public sealed partial class Payments_SaveStarGift : IMethod - { - public Flags flags; - public InputSavedStarGift stargift; - - [Flags] public enum Flags : uint - { - unsave = 0x1, - } - } - - [TLDef(0x74BF076B)] - public sealed partial class Payments_ConvertStarGift : IMethod - { - public InputSavedStarGift stargift; - } - - [TLDef(0x6DFA0622)] - public sealed partial class Payments_BotCancelStarsSubscription : IMethod - { - public Flags flags; - public InputUserBase user_id; - public string charge_id; - - [Flags] public enum Flags : uint - { - restore = 0x1, - } - } - - [TLDef(0x5869A553)] - public sealed partial class Payments_GetConnectedStarRefBots : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(2)] public DateTime offset_date; - [IfFlag(2)] public string offset_link; - public int limit; - - [Flags] public enum Flags : uint - { - has_offset_date = 0x4, - } - } - - [TLDef(0xB7D998F0)] - public sealed partial class Payments_GetConnectedStarRefBot : IMethod - { - public InputPeer peer; - public InputUserBase bot; - } - - [TLDef(0x0D6B48F7)] - public sealed partial class Payments_GetSuggestedStarRefBots : IMethod - { - public Flags flags; - public InputPeer peer; - public string offset; - public int limit; - - [Flags] public enum Flags : uint - { - order_by_revenue = 0x1, - order_by_date = 0x2, - } - } - - [TLDef(0x7ED5348A)] - public sealed partial class Payments_ConnectStarRefBot : IMethod - { - public InputPeer peer; - public InputUserBase bot; - } - - [TLDef(0xE4FCA4A3)] - public sealed partial class Payments_EditConnectedStarRefBot : IMethod - { - public Flags flags; - public InputPeer peer; - public string link; - - [Flags] public enum Flags : uint - { - revoked = 0x1, - } - } - - [TLDef(0x9C9ABCB1)] - public sealed partial class Payments_GetStarGiftUpgradePreview : IMethod - { - public long gift_id; - } - - [TLDef(0xAED6E4F5)] - public sealed partial class Payments_UpgradeStarGift : IMethod - { - public Flags flags; - public InputSavedStarGift stargift; - - [Flags] public enum Flags : uint - { - keep_original_details = 0x1, - } - } - - [TLDef(0x7F18176A)] - public sealed partial class Payments_TransferStarGift : IMethod - { - public InputSavedStarGift stargift; - public InputPeer to_id; - } - - [TLDef(0xA1974D72)] - public sealed partial class Payments_GetUniqueStarGift : IMethod - { - public string slug; - } - - [TLDef(0xA319E569)] - public sealed partial class Payments_GetSavedStarGifts : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(6)] public int collection_id; - public string offset; - public int limit; - - [Flags] public enum Flags : uint - { - exclude_unsaved = 0x1, - exclude_saved = 0x2, - exclude_unlimited = 0x4, - exclude_unique = 0x10, - sort_by_value = 0x20, - has_collection_id = 0x40, - exclude_upgradable = 0x80, - exclude_unupgradable = 0x100, - peer_color_available = 0x200, - exclude_hosted = 0x400, - } - } - - [TLDef(0xB455A106)] - public sealed partial class Payments_GetSavedStarGift : IMethod - { - public InputSavedStarGift[] stargift; - } - - [TLDef(0xD06E93A8)] - public sealed partial class Payments_GetStarGiftWithdrawalUrl : IMethod - { - public InputSavedStarGift stargift; - public InputCheckPasswordSRP password; - } - - [TLDef(0x60EAEFA1)] - public sealed partial class Payments_ToggleChatStarGiftNotifications : IMethod - { - public Flags flags; - public InputPeer peer; - - [Flags] public enum Flags : uint - { - enabled = 0x1, - } - } - - [TLDef(0x1513E7B0)] - public sealed partial class Payments_ToggleStarGiftsPinnedToTop : IMethod - { - public InputPeer peer; - public InputSavedStarGift[] stargift; - } - - [TLDef(0x4FDC5EA7)] - public sealed partial class Payments_CanPurchaseStore : IMethod - { - public InputStorePaymentPurpose purpose; - } - - [TLDef(0x7A5FA236)] - public sealed partial class Payments_GetResaleStarGifts : IMethod - { - public Flags flags; - [IfFlag(0)] public long attributes_hash; - public long gift_id; - [IfFlag(3)] public StarGiftAttributeId[] attributes; - public string offset; - public int limit; - - [Flags] public enum Flags : uint - { - has_attributes_hash = 0x1, - sort_by_price = 0x2, - sort_by_num = 0x4, - has_attributes = 0x8, - for_craft = 0x10, - } - } - - [TLDef(0xEDBE6CCB)] - public sealed partial class Payments_UpdateStarGiftPrice : IMethod - { - public InputSavedStarGift stargift; - public StarsAmountBase resell_amount; - } - - [TLDef(0x1F4A0E87)] - public sealed partial class Payments_CreateStarGiftCollection : IMethod - { - public InputPeer peer; - public string title; - public InputSavedStarGift[] stargift; - } - - [TLDef(0x4FDDBEE7)] - public sealed partial class Payments_UpdateStarGiftCollection : IMethod - { - public Flags flags; - public InputPeer peer; - public int collection_id; - [IfFlag(0)] public string title; - [IfFlag(1)] public InputSavedStarGift[] delete_stargift; - [IfFlag(2)] public InputSavedStarGift[] add_stargift; - [IfFlag(3)] public InputSavedStarGift[] order; - - [Flags] public enum Flags : uint - { - has_title = 0x1, - has_delete_stargift = 0x2, - has_add_stargift = 0x4, - has_order = 0x8, - } - } - - [TLDef(0xC32AF4CC)] - public sealed partial class Payments_ReorderStarGiftCollections : IMethod - { - public InputPeer peer; - public int[] order; - } - - [TLDef(0xAD5648E8)] - public sealed partial class Payments_DeleteStarGiftCollection : IMethod - { - public InputPeer peer; - public int collection_id; - } - - [TLDef(0x981B91DD)] - public sealed partial class Payments_GetStarGiftCollections : IMethod - { - public InputPeer peer; - public long hash; - } - - [TLDef(0x4365AF6B)] - public sealed partial class Payments_GetUniqueStarGiftValueInfo : IMethod - { - public string slug; - } - - [TLDef(0xC0C4EDC9)] - public sealed partial class Payments_CheckCanSendGift : IMethod - { - public long gift_id; - } - - [TLDef(0x5C9FF4D6)] - public sealed partial class Payments_GetStarGiftAuctionState : IMethod - { - public InputStarGiftAuctionBase auction; - public int version; - } - - [TLDef(0x6BA2CBEC)] - public sealed partial class Payments_GetStarGiftAuctionAcquiredGifts : IMethod - { - public long gift_id; - } - - [TLDef(0xA5D0514D)] - public sealed partial class Payments_GetStarGiftActiveAuctions : IMethod - { - public long hash; - } - - [TLDef(0xE9CE781C)] - public sealed partial class Payments_ResolveStarGiftOffer : IMethod - { - public Flags flags; - public int offer_msg_id; - - [Flags] public enum Flags : uint - { - decline = 0x1, - } - } - - [TLDef(0x8FB86B41)] - public sealed partial class Payments_SendStarGiftOffer : IMethod - { - public Flags flags; - public InputPeer peer; - public string slug; - public StarsAmountBase price; - public int duration; - public long random_id; - [IfFlag(0)] public long allow_paid_stars; - - [Flags] public enum Flags : uint - { - has_allow_paid_stars = 0x1, - } - } - - [TLDef(0x6D038B58)] - public sealed partial class Payments_GetStarGiftUpgradeAttributes : IMethod - { - public long gift_id; - } - - [TLDef(0xFD05DD00)] - public sealed partial class Payments_GetCraftStarGifts : IMethod - { - public long gift_id; - public string offset; - public int limit; - } - - [TLDef(0xB0F9684F)] - public sealed partial class Payments_CraftStarGift : IMethod - { - public InputSavedStarGift[] stargift; - } - - [TLDef(0x9021AB67)] - public sealed partial class Stickers_CreateStickerSet : IMethod - { - public Flags flags; - public InputUserBase user_id; - public string title; - public string short_name; - [IfFlag(2)] public InputDocument thumb; - public InputStickerSetItem[] stickers; - [IfFlag(3)] public string software; - - [Flags] public enum Flags : uint - { - masks = 0x1, - has_thumb = 0x4, - has_software = 0x8, - emojis = 0x20, - text_color = 0x40, - } - } - - [TLDef(0xF7760F51)] - public sealed partial class Stickers_RemoveStickerFromSet : IMethod - { - public InputDocument sticker; - } - - [TLDef(0xFFB6D4CA)] - public sealed partial class Stickers_ChangeStickerPosition : IMethod - { - public InputDocument sticker; - public int position; - } - - [TLDef(0x8653FEBE)] - public sealed partial class Stickers_AddStickerToSet : IMethod - { - public InputStickerSet stickerset; - public InputStickerSetItem sticker; - } - - [TLDef(0xA76A5392)] - public sealed partial class Stickers_SetStickerSetThumb : IMethod - { - public Flags flags; - public InputStickerSet stickerset; - [IfFlag(0)] public InputDocument thumb; - [IfFlag(1)] public long thumb_document_id; - - [Flags] public enum Flags : uint - { - has_thumb = 0x1, - has_thumb_document_id = 0x2, - } - } - - [TLDef(0x284B3639)] - public sealed partial class Stickers_CheckShortName : IMethod - { - public string short_name; - } - - [TLDef(0x4DAFC503)] - public sealed partial class Stickers_SuggestShortName : IMethod - { - public string title; - } - - [TLDef(0xF5537EBC)] - public sealed partial class Stickers_ChangeSticker : IMethod - { - public Flags flags; - public InputDocument sticker; - [IfFlag(0)] public string emoji; - [IfFlag(1)] public MaskCoords mask_coords; - [IfFlag(2)] public string keywords; - - [Flags] public enum Flags : uint - { - has_emoji = 0x1, - has_mask_coords = 0x2, - has_keywords = 0x4, - } - } - - [TLDef(0x124B1C00)] - public sealed partial class Stickers_RenameStickerSet : IMethod - { - public InputStickerSet stickerset; - public string title; - } - - [TLDef(0x87704394)] - public sealed partial class Stickers_DeleteStickerSet : IMethod - { - public InputStickerSet stickerset; - } - - [TLDef(0x4696459A)] - public sealed partial class Stickers_ReplaceSticker : IMethod - { - public InputDocument sticker; - public InputStickerSetItem new_sticker; - } - - [TLDef(0x55451FA9)] - public sealed partial class Phone_GetCallConfig : IMethod { } - - [TLDef(0x42FF96ED)] - public sealed partial class Phone_RequestCall : IMethod - { - public Flags flags; - public InputUserBase user_id; - public int random_id; - public byte[] g_a_hash; - public PhoneCallProtocol protocol; - - [Flags] public enum Flags : uint - { - video = 0x1, - } - } - - [TLDef(0x3BD2B4A0)] - public sealed partial class Phone_AcceptCall : IMethod - { - public InputPhoneCall peer; - public byte[] g_b; - public PhoneCallProtocol protocol; - } - - [TLDef(0x2EFE1722)] - public sealed partial class Phone_ConfirmCall : IMethod - { - public InputPhoneCall peer; - public byte[] g_a; - public long key_fingerprint; - public PhoneCallProtocol protocol; - } - - [TLDef(0x17D54F61)] - public sealed partial class Phone_ReceivedCall : IMethod - { - public InputPhoneCall peer; - } - - [TLDef(0xB2CBC1C0)] - public sealed partial class Phone_DiscardCall : IMethod - { - public Flags flags; - public InputPhoneCall peer; - public int duration; - public PhoneCallDiscardReason reason; - public long connection_id; - - [Flags] public enum Flags : uint - { - video = 0x1, - } - } - - [TLDef(0x59EAD627)] - public sealed partial class Phone_SetCallRating : IMethod - { - public Flags flags; - public InputPhoneCall peer; - public int rating; - public string comment; - - [Flags] public enum Flags : uint - { - user_initiative = 0x1, - } - } - - [TLDef(0x277ADD7E)] - public sealed partial class Phone_SaveCallDebug : IMethod - { - public InputPhoneCall peer; - public DataJSON debug; - } - - [TLDef(0xFF7A9383)] - public sealed partial class Phone_SendSignalingData : IMethod - { - public InputPhoneCall peer; - public byte[] data; - } - - [TLDef(0x48CDC6D8)] - public sealed partial class Phone_CreateGroupCall : IMethod - { - public Flags flags; - public InputPeer peer; - public int random_id; - [IfFlag(0)] public string title; - [IfFlag(1)] public DateTime schedule_date; - - [Flags] public enum Flags : uint - { - has_title = 0x1, - has_schedule_date = 0x2, - rtmp_stream = 0x4, - } - } - - [TLDef(0x8FB53057)] - public sealed partial class Phone_JoinGroupCall : IMethod - { - public Flags flags; - public InputGroupCallBase call; - public InputPeer join_as; - [IfFlag(1)] public string invite_hash; - [IfFlag(3)] public Int256 public_key; - [IfFlag(3)] public byte[] block; - public DataJSON params_; - - [Flags] public enum Flags : uint - { - muted = 0x1, - has_invite_hash = 0x2, - video_stopped = 0x4, - has_public_key = 0x8, - } - } - - [TLDef(0x500377F9)] - public sealed partial class Phone_LeaveGroupCall : IMethod - { - public InputGroupCallBase call; - public int source; - } - - [TLDef(0x7B393160)] - public sealed partial class Phone_InviteToGroupCall : IMethod - { - public InputGroupCallBase call; - public InputUserBase[] users; - } - - [TLDef(0x7A777135)] - public sealed partial class Phone_DiscardGroupCall : IMethod - { - public InputGroupCallBase call; - } - - [TLDef(0x974392F2)] - public sealed partial class Phone_ToggleGroupCallSettings : IMethod - { - public Flags flags; - public InputGroupCallBase call; - [IfFlag(0)] public bool join_muted; - [IfFlag(2)] public bool messages_enabled; - [IfFlag(3)] public long send_paid_messages_stars; - - [Flags] public enum Flags : uint - { - has_join_muted = 0x1, - reset_invite_hash = 0x2, - has_messages_enabled = 0x4, - has_send_paid_messages_stars = 0x8, - } - } - - [TLDef(0x041845DB)] - public sealed partial class Phone_GetGroupCall : IMethod - { - public InputGroupCallBase call; - public int limit; - } - - [TLDef(0xC558D8AB)] - public sealed partial class Phone_GetGroupParticipants : IMethod - { - public InputGroupCallBase call; - public InputPeer[] ids; - public int[] sources; - public string offset; - public int limit; - } - - [TLDef(0xB59CF977)] - public sealed partial class Phone_CheckGroupCall : IMethod - { - public InputGroupCallBase call; - public int[] sources; - } - - [TLDef(0xF128C708)] - public sealed partial class Phone_ToggleGroupCallRecord : IMethod - { - public Flags flags; - public InputGroupCallBase call; - [IfFlag(1)] public string title; - [IfFlag(2)] public bool video_portrait; - - [Flags] public enum Flags : uint - { - start = 0x1, - has_title = 0x2, - video = 0x4, - } - } - - [TLDef(0xA5273ABF)] - public sealed partial class Phone_EditGroupCallParticipant : IMethod - { - public Flags flags; - public InputGroupCallBase call; - public InputPeer participant; - [IfFlag(0)] public bool muted; - [IfFlag(1)] public int volume; - [IfFlag(2)] public bool raise_hand; - [IfFlag(3)] public bool video_stopped; - [IfFlag(4)] public bool video_paused; - [IfFlag(5)] public bool presentation_paused; - - [Flags] public enum Flags : uint - { - has_muted = 0x1, - has_volume = 0x2, - has_raise_hand = 0x4, - has_video_stopped = 0x8, - has_video_paused = 0x10, - has_presentation_paused = 0x20, - } - } - - [TLDef(0x1CA6AC0A)] - public sealed partial class Phone_EditGroupCallTitle : IMethod - { - public InputGroupCallBase call; - public string title; - } - - [TLDef(0xEF7C213A)] - public sealed partial class Phone_GetGroupCallJoinAs : IMethod - { - public InputPeer peer; - } - - [TLDef(0xE6AA647F)] - public sealed partial class Phone_ExportGroupCallInvite : IMethod - { - public Flags flags; - public InputGroupCallBase call; - - [Flags] public enum Flags : uint - { - can_self_unmute = 0x1, - } - } - - [TLDef(0x219C34E6)] - public sealed partial class Phone_ToggleGroupCallStartSubscription : IMethod - { - public InputGroupCallBase call; - public bool subscribed; - } - - [TLDef(0x5680E342)] - public sealed partial class Phone_StartScheduledGroupCall : IMethod - { - public InputGroupCallBase call; - } - - [TLDef(0x575E1F8C)] - public sealed partial class Phone_SaveDefaultGroupCallJoinAs : IMethod - { - public InputPeer peer; - public InputPeer join_as; - } - - [TLDef(0xCBEA6BC4)] - public sealed partial class Phone_JoinGroupCallPresentation : IMethod - { - public InputGroupCallBase call; - public DataJSON params_; - } - - [TLDef(0x1C50D144)] - public sealed partial class Phone_LeaveGroupCallPresentation : IMethod - { - public InputGroupCallBase call; - } - - [TLDef(0x1AB21940)] - public sealed partial class Phone_GetGroupCallStreamChannels : IMethod - { - public InputGroupCallBase call; - } - - [TLDef(0x5AF4C73A)] - public sealed partial class Phone_GetGroupCallStreamRtmpUrl : IMethod - { - public Flags flags; - public InputPeer peer; - public bool revoke; - - [Flags] public enum Flags : uint - { - live_story = 0x1, - } - } - - [TLDef(0x41248786)] - public sealed partial class Phone_SaveCallLog : IMethod - { - public InputPhoneCall peer; - public InputFileBase file; - } - - [TLDef(0x7D0444BB)] - public sealed partial class Phone_CreateConferenceCall : IMethod - { - public Flags flags; - public int random_id; - [IfFlag(3)] public Int256 public_key; - [IfFlag(3)] public byte[] block; - [IfFlag(3)] public DataJSON params_; - - [Flags] public enum Flags : uint - { - muted = 0x1, - video_stopped = 0x4, - join = 0x8, - } - } - - [TLDef(0x8CA60525)] - public sealed partial class Phone_DeleteConferenceCallParticipants : IMethod - { - public Flags flags; - public InputGroupCallBase call; - public long[] ids; - public byte[] block; - - [Flags] public enum Flags : uint - { - only_left = 0x1, - kick = 0x2, - } - } - - [TLDef(0xC6701900)] - public sealed partial class Phone_SendConferenceCallBroadcast : IMethod - { - public InputGroupCallBase call; - public byte[] block; - } - - [TLDef(0xBCF22685)] - public sealed partial class Phone_InviteConferenceCallParticipant : IMethod - { - public Flags flags; - public InputGroupCallBase call; - public InputUserBase user_id; - - [Flags] public enum Flags : uint - { - video = 0x1, - } - } - - [TLDef(0x3C479971)] - public sealed partial class Phone_DeclineConferenceCallInvite : IMethod - { - public int msg_id; - } - - [TLDef(0xEE9F88A6)] - public sealed partial class Phone_GetGroupCallChainBlocks : IMethod - { - public InputGroupCallBase call; - public int sub_chain_id; - public int offset; - public int limit; - } - - [TLDef(0xB1D11410)] - public sealed partial class Phone_SendGroupCallMessage : IMethod - { - public Flags flags; - public InputGroupCallBase call; - public long random_id; - public TextWithEntities message; - [IfFlag(0)] public long allow_paid_stars; - [IfFlag(1)] public InputPeer send_as; - - [Flags] public enum Flags : uint - { - has_allow_paid_stars = 0x1, - has_send_as = 0x2, - } - } - - [TLDef(0xE5AFA56D)] - public sealed partial class Phone_SendGroupCallEncryptedMessage : IMethod - { - public InputGroupCallBase call; - public byte[] encrypted_message; - } - - [TLDef(0xF64F54F7)] - public sealed partial class Phone_DeleteGroupCallMessages : IMethod - { - public Flags flags; - public InputGroupCallBase call; - public int[] messages; - - [Flags] public enum Flags : uint - { - report_spam = 0x1, - } - } - - [TLDef(0x1DBFECA0)] - public sealed partial class Phone_DeleteGroupCallParticipantMessages : IMethod - { - public Flags flags; - public InputGroupCallBase call; - public InputPeer participant; - - [Flags] public enum Flags : uint - { - report_spam = 0x1, - } - } - - [TLDef(0x6F636302)] - public sealed partial class Phone_GetGroupCallStars : IMethod - { - public InputGroupCallBase call; - } - - [TLDef(0x4167ADD1)] - public sealed partial class Phone_SaveDefaultSendAs : IMethod - { - public InputGroupCallBase call; - public InputPeer send_as; - } - - [TLDef(0xF2F2330A)] - public sealed partial class Langpack_GetLangPack : IMethod - { - public string lang_pack; - public string lang_code; - } - - [TLDef(0xEFEA3803)] - public sealed partial class Langpack_GetStrings : IMethod - { - public string lang_pack; - public string lang_code; - public string[] keys; - } - - [TLDef(0xCD984AA5)] - public sealed partial class Langpack_GetDifference : IMethod - { - public string lang_pack; - public string lang_code; - public int from_version; - } - - [TLDef(0x42C6978F)] - public sealed partial class Langpack_GetLanguages : IMethod - { - public string lang_pack; - } - - [TLDef(0x6A596502)] - public sealed partial class Langpack_GetLanguage : IMethod - { - public string lang_pack; - public string lang_code; - } - - [TLDef(0x6847D0AB)] - public sealed partial class Folders_EditPeerFolders : IMethod - { - public InputFolderPeer[] folder_peers; - } - - [TLDef(0xAB42441A)] - public sealed partial class Stats_GetBroadcastStats : IMethod - { - public Flags flags; - public InputChannelBase channel; - - [Flags] public enum Flags : uint - { - dark = 0x1, - } - } - - [TLDef(0x621D5FA0)] - public sealed partial class Stats_LoadAsyncGraph : IMethod - { - public Flags flags; - public string token; - [IfFlag(0)] public long x; - - [Flags] public enum Flags : uint - { - has_x = 0x1, - } - } - - [TLDef(0xDCDF8607)] - public sealed partial class Stats_GetMegagroupStats : IMethod - { - public Flags flags; - public InputChannelBase channel; - - [Flags] public enum Flags : uint - { - dark = 0x1, - } - } - - [TLDef(0x5F150144)] - public sealed partial class Stats_GetMessagePublicForwards : IMethod - { - public InputChannelBase channel; - public int msg_id; - public string offset; - public int limit; - } - - [TLDef(0xB6E0A3F5)] - public sealed partial class Stats_GetMessageStats : IMethod - { - public Flags flags; - public InputChannelBase channel; - public int msg_id; - - [Flags] public enum Flags : uint - { - dark = 0x1, - } - } - - [TLDef(0x374FEF40)] - public sealed partial class Stats_GetStoryStats : IMethod - { - public Flags flags; - public InputPeer peer; - public int id; - - [Flags] public enum Flags : uint - { - dark = 0x1, - } - } - - [TLDef(0xA6437EF6)] - public sealed partial class Stats_GetStoryPublicForwards : IMethod - { - public InputPeer peer; - public int id; - public string offset; - public int limit; - } - - [TLDef(0x8472478E)] - public sealed partial class Chatlists_ExportChatlistInvite : IMethod - { - public InputChatlist chatlist; - public string title; - public InputPeer[] peers; - } - - [TLDef(0x719C5C5E)] - public sealed partial class Chatlists_DeleteExportedInvite : IMethod - { - public InputChatlist chatlist; - public string slug; - } - - [TLDef(0x653DB63D)] - public sealed partial class Chatlists_EditExportedInvite : IMethod - { - public Flags flags; - public InputChatlist chatlist; - public string slug; - [IfFlag(1)] public string title; - [IfFlag(2)] public InputPeer[] peers; - - [Flags] public enum Flags : uint - { - has_title = 0x2, - has_peers = 0x4, - } - } - - [TLDef(0xCE03DA83)] - public sealed partial class Chatlists_GetExportedInvites : IMethod - { - public InputChatlist chatlist; - } - - [TLDef(0x41C10FFF)] - public sealed partial class Chatlists_CheckChatlistInvite : IMethod - { - public string slug; - } - - [TLDef(0xA6B1E39A)] - public sealed partial class Chatlists_JoinChatlistInvite : IMethod - { - public string slug; - public InputPeer[] peers; - } - - [TLDef(0x89419521)] - public sealed partial class Chatlists_GetChatlistUpdates : IMethod - { - public InputChatlist chatlist; - } - - [TLDef(0xE089F8F5)] - public sealed partial class Chatlists_JoinChatlistUpdates : IMethod - { - public InputChatlist chatlist; - public InputPeer[] peers; - } - - [TLDef(0x66E486FB)] - public sealed partial class Chatlists_HideChatlistUpdates : IMethod - { - public InputChatlist chatlist; - } - - [TLDef(0xFDBCD714)] - public sealed partial class Chatlists_GetLeaveChatlistSuggestions : IMethod - { - public InputChatlist chatlist; - } - - [TLDef(0x74FAE13A)] - public sealed partial class Chatlists_LeaveChatlist : IMethod - { - public InputChatlist chatlist; - public InputPeer[] peers; - } - - [TLDef(0x30EB63F0)] - public sealed partial class Stories_CanSendStory : IMethod - { - public InputPeer peer; - } - - [TLDef(0x737FC2EC)] - public sealed partial class Stories_SendStory : IMethod - { - public Flags flags; - public InputPeer peer; - public InputMedia media; - [IfFlag(5)] public MediaArea[] media_areas; - [IfFlag(0)] public string caption; - [IfFlag(1)] public MessageEntity[] entities; - public InputPrivacyRule[] privacy_rules; - public long random_id; - [IfFlag(3)] public int period; - [IfFlag(6)] public InputPeer fwd_from_id; - [IfFlag(6)] public int fwd_from_story; - [IfFlag(8)] public int[] albums; - - [Flags] public enum Flags : uint - { - has_caption = 0x1, - has_entities = 0x2, - pinned = 0x4, - has_period = 0x8, - noforwards = 0x10, - has_media_areas = 0x20, - has_fwd_from_id = 0x40, - fwd_modified = 0x80, - has_albums = 0x100, - } - } - - [TLDef(0xB583BA46)] - public sealed partial class Stories_EditStory : IMethod - { - public Flags flags; - public InputPeer peer; - public int id; - [IfFlag(0)] public InputMedia media; - [IfFlag(3)] public MediaArea[] media_areas; - [IfFlag(1)] public string caption; - [IfFlag(1)] public MessageEntity[] entities; - [IfFlag(2)] public InputPrivacyRule[] privacy_rules; - - [Flags] public enum Flags : uint - { - has_media = 0x1, - has_caption = 0x2, - has_privacy_rules = 0x4, - has_media_areas = 0x8, - } - } - - [TLDef(0xAE59DB5F)] - public sealed partial class Stories_DeleteStories : IMethod - { - public InputPeer peer; - public int[] id; - } - - [TLDef(0x9A75A1EF)] - public sealed partial class Stories_TogglePinned : IMethod - { - public InputPeer peer; - public int[] id; - public bool pinned; - } - - [TLDef(0xEEB0D625)] - public sealed partial class Stories_GetAllStories : IMethod - { - public Flags flags; - [IfFlag(0)] public string state; - - [Flags] public enum Flags : uint - { - has_state = 0x1, - next = 0x2, - hidden = 0x4, - } - } - - [TLDef(0x5821A5DC)] - public sealed partial class Stories_GetPinnedStories : IMethod - { - public InputPeer peer; - public int offset_id; - public int limit; - } - - [TLDef(0xB4352016)] - public sealed partial class Stories_GetStoriesArchive : IMethod - { - public InputPeer peer; - public int offset_id; - public int limit; - } - - [TLDef(0x5774CA74)] - public sealed partial class Stories_GetStoriesByID : IMethod - { - public InputPeer peer; - public int[] id; - } - - [TLDef(0x7C2557C4)] - public sealed partial class Stories_ToggleAllStoriesHidden : IMethod - { - public bool hidden; - } - - [TLDef(0xA556DAC8)] - public sealed partial class Stories_ReadStories : IMethod - { - public InputPeer peer; - public int max_id; - } - - [TLDef(0xB2028AFB)] - public sealed partial class Stories_IncrementStoryViews : IMethod - { - public InputPeer peer; - public int[] id; - } - - [TLDef(0x7ED23C57)] - public sealed partial class Stories_GetStoryViewsList : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(1)] public string q; - public int id; - public string offset; - public int limit; - - [Flags] public enum Flags : uint - { - just_contacts = 0x1, - has_q = 0x2, - reactions_first = 0x4, - forwards_first = 0x8, - } - } - - [TLDef(0x28E16CC8)] - public sealed partial class Stories_GetStoriesViews : IMethod - { - public InputPeer peer; - public int[] id; - } - - [TLDef(0x7B8DEF20)] - public sealed partial class Stories_ExportStoryLink : IMethod - { - public InputPeer peer; - public int id; - } - - [TLDef(0x19D8EB45)] - public sealed partial class Stories_Report : IMethod - { - public InputPeer peer; - public int[] id; - public byte[] option; - public string message; - } - - [TLDef(0x57BBD166)] - public sealed partial class Stories_ActivateStealthMode : IMethod - { - public Flags flags; - - [Flags] public enum Flags : uint - { - past = 0x1, - future = 0x2, - } - } - - [TLDef(0x7FD736B2)] - public sealed partial class Stories_SendReaction : IMethod - { - public Flags flags; - public InputPeer peer; - public int story_id; - public Reaction reaction; - - [Flags] public enum Flags : uint - { - add_to_recent = 0x1, - } - } - - [TLDef(0x2C4ADA50)] - public sealed partial class Stories_GetPeerStories : IMethod - { - public InputPeer peer; - } - - [TLDef(0x9B5AE7F9)] - public sealed partial class Stories_GetAllReadPeerStories : IMethod { } - - [TLDef(0x78499170)] - public sealed partial class Stories_GetPeerMaxIDs : IMethod - { - public InputPeer[] id; - } - - [TLDef(0xA56A8B60)] - public sealed partial class Stories_GetChatsToSend : IMethod { } - - [TLDef(0xBD0415C4)] - public sealed partial class Stories_TogglePeerStoriesHidden : IMethod - { - public InputPeer peer; - public bool hidden; - } - - [TLDef(0xB9B2881F)] - public sealed partial class Stories_GetStoryReactionsList : IMethod - { - public Flags flags; - public InputPeer peer; - public int id; - [IfFlag(0)] public Reaction reaction; - [IfFlag(1)] public string offset; - public int limit; - - [Flags] public enum Flags : uint - { - has_reaction = 0x1, - has_offset = 0x2, - forwards_first = 0x4, - } - } - - [TLDef(0x0B297E9B)] - public sealed partial class Stories_TogglePinnedToTop : IMethod - { - public InputPeer peer; - public int[] id; - } - - [TLDef(0xD1810907)] - public sealed partial class Stories_SearchPosts : IMethod - { - public Flags flags; - [IfFlag(0)] public string hashtag; - [IfFlag(1)] public MediaArea area; - [IfFlag(2)] public InputPeer peer; - public string offset; - public int limit; - - [Flags] public enum Flags : uint - { - has_hashtag = 0x1, - has_area = 0x2, - has_peer = 0x4, - } - } - - [TLDef(0xA36396E5)] - public sealed partial class Stories_CreateAlbum : IMethod - { - public InputPeer peer; - public string title; - public int[] stories; - } - - [TLDef(0x5E5259B6)] - public sealed partial class Stories_UpdateAlbum : IMethod - { - public Flags flags; - public InputPeer peer; - public int album_id; - [IfFlag(0)] public string title; - [IfFlag(1)] public int[] delete_stories; - [IfFlag(2)] public int[] add_stories; - [IfFlag(3)] public int[] order; - - [Flags] public enum Flags : uint - { - has_title = 0x1, - has_delete_stories = 0x2, - has_add_stories = 0x4, - has_order = 0x8, - } - } - - [TLDef(0x8535FBD9)] - public sealed partial class Stories_ReorderAlbums : IMethod - { - public InputPeer peer; - public int[] order; - } - - [TLDef(0x8D3456D0)] - public sealed partial class Stories_DeleteAlbum : IMethod - { - public InputPeer peer; - public int album_id; - } - - [TLDef(0x25B3EAC7)] - public sealed partial class Stories_GetAlbums : IMethod - { - public InputPeer peer; - public long hash; - } - - [TLDef(0xAC806D61)] - public sealed partial class Stories_GetAlbumStories : IMethod - { - public InputPeer peer; - public int album_id; - public int offset; - public int limit; - } - - [TLDef(0xD069CCDE)] - public sealed partial class Stories_StartLive : IMethod - { - public Flags flags; - public InputPeer peer; - [IfFlag(0)] public string caption; - [IfFlag(1)] public MessageEntity[] entities; - public InputPrivacyRule[] privacy_rules; - public long random_id; - [IfFlag(6)] public bool messages_enabled; - [IfFlag(7)] public long send_paid_messages_stars; - - [Flags] public enum Flags : uint - { - has_caption = 0x1, - has_entities = 0x2, - pinned = 0x4, - noforwards = 0x10, - rtmp_stream = 0x20, - has_messages_enabled = 0x40, - has_send_paid_messages_stars = 0x80, - } - } - - [TLDef(0x60F67660)] - public sealed partial class Premium_GetBoostsList : IMethod - { - public Flags flags; - public InputPeer peer; - public string offset; - public int limit; - - [Flags] public enum Flags : uint - { - gifts = 0x1, - } - } - - [TLDef(0x0BE77B4A)] - public sealed partial class Premium_GetMyBoosts : IMethod { } - - [TLDef(0x6B7DA746)] - public sealed partial class Premium_ApplyBoost : IMethod - { - public Flags flags; - [IfFlag(0)] public int[] slots; - public InputPeer peer; - - [Flags] public enum Flags : uint - { - has_slots = 0x1, - } - } - - [TLDef(0x042F1F61)] - public sealed partial class Premium_GetBoostsStatus : IMethod - { - public InputPeer peer; - } - - [TLDef(0x39854D1F)] - public sealed partial class Premium_GetUserBoosts : IMethod - { - public InputPeer peer; - public InputUserBase user_id; - } - - [TLDef(0x0EDC39D0)] - public sealed partial class Smsjobs_IsEligibleToJoin : IMethod { } - - [TLDef(0xA74ECE2D)] - public sealed partial class Smsjobs_Join : IMethod { } - - [TLDef(0x9898AD73)] - public sealed partial class Smsjobs_Leave : IMethod { } - - [TLDef(0x093FA0BF)] - public sealed partial class Smsjobs_UpdateSettings : IMethod - { - public Flags flags; - - [Flags] public enum Flags : uint - { - allow_international = 0x1, - } - } - - [TLDef(0x10A698E8)] - public sealed partial class Smsjobs_GetStatus : IMethod { } - - [TLDef(0x778D902F)] - public sealed partial class Smsjobs_GetSmsJob : IMethod - { - public string job_id; - } - - [TLDef(0x4F1EBF24)] - public sealed partial class Smsjobs_FinishJob : IMethod - { - public Flags flags; - public string job_id; - [IfFlag(0)] public string error; - - [Flags] public enum Flags : uint - { - has_error = 0x1, - } - } - - [TLDef(0xBE1E85BA)] - public sealed partial class Fragment_GetCollectibleInfo : IMethod - { - public InputCollectible collectible; - } -} diff --git a/src/TL.Secret.cs b/src/TL.Secret.cs index 4988782..4edf334 100644 --- a/src/TL.Secret.cs +++ b/src/TL.Secret.cs @@ -1,873 +1,434 @@ -using System; +// This file is generated automatically using the Generator class +using System; namespace TL { - #pragma warning disable IDE1006, CS1574 - /// Object describes the contents of an encrypted message. See Derived classes: , - public abstract partial class DecryptedMessageBase : IObject - { - /// Flags, see TL conditional fields (added in layer 45) - public virtual uint FFlags => default; - /// Random message ID, assigned by the author of message.
Must be equal to the ID passed to sending method.
- public virtual long RandomId => default; - /// Message lifetime. Has higher priority than .
Parameter added in Layer 17.
- public virtual int Ttl => default; - /// Message text - public virtual string Message => default; - /// Media content - public virtual DecryptedMessageMedia Media => default; - /// Message entities for styled text (parameter added in layer 45) - public virtual MessageEntity[] Entities => default; - /// Specifies the ID of the inline bot that generated the message (parameter added in layer 45) - public virtual string ViaBotName => default; - /// Random message ID of the message this message replies to (parameter added in layer 45) - public virtual long ReplyToRandom => default; - /// Random group ID, assigned by the author of message.
Multiple encrypted messages with a photo attached and with the same group ID indicate an album or grouped media (parameter added in layer 45)
- public virtual long Grouped => default; - /// Random bytes, removed in layer 17. - public virtual byte[] RandomBytes => default; - public virtual DecryptedMessageAction Action => default; - } + using BinaryWriter = System.IO.BinaryWriter; + using Client = WTelegram.Client; - /// Object describes media contents of an encrypted message. See Derived classes: , , , , , , , , - /// a value means decryptedMessageMediaEmpty - public abstract partial class DecryptedMessageMedia : IObject - { - public virtual string MimeType => default; - internal virtual (long size, byte[] key, byte[] iv) SizeKeyIV { get => default; set => throw new WTelegram.WTException("Incompatible DecryptedMessageMedia"); } - } + ///See + public abstract partial class DecryptedMessageBase : ITLObject { } - /// Object describes the action to which a service message is linked. See Derived classes: , , , , , , , , , , , , - public abstract partial class DecryptedMessageAction : IObject { } + ///See + ///a null value means decryptedMessageMediaEmpty + public abstract partial class DecryptedMessageMedia : ITLObject { } - /// Indicates the location of a photo, will be deprecated soon See Derived classes: , - public abstract partial class FileLocationBase : IObject - { - /// Volume ID - public virtual long VolumeId => default; - /// Local ID - public virtual int LocalId => default; - /// Secret - public virtual long Secret => default; - } + ///See + public abstract partial class DecryptedMessageAction : ITLObject { } + + ///See + public abstract partial class FileLocationBase : ITLObject { } namespace Layer8 { - /// Contents of an encrypted message. See + ///See [TLDef(0x1F814F1F)] - public sealed partial class DecryptedMessage : DecryptedMessageBase + public partial class DecryptedMessage : DecryptedMessageBase { - /// Random message ID, assigned by the author of message.
Must be equal to the ID passed to sending method.
public long random_id; - /// Random bytes, removed in layer 17. public byte[] random_bytes; - /// Message text public string message; - /// Media content public DecryptedMessageMedia media; - - /// Random message ID, assigned by the author of message.
Must be equal to the ID passed to sending method.
- public override long RandomId => random_id; - /// Message text - public override string Message => message; - /// Media content - public override DecryptedMessageMedia Media => media; - /// Random bytes, removed in layer 17. - public override byte[] RandomBytes => random_bytes; } - ///
Contents of an encrypted service message. See + ///See [TLDef(0xAA48327D)] - public sealed partial class DecryptedMessageService : DecryptedMessageBase + public partial class DecryptedMessageService : DecryptedMessageBase { - /// Random message ID, assigned by the message author.
Must be equal to the ID passed to the sending method.
public long random_id; - /// Random bytes, removed in Layer 17. public byte[] random_bytes; - /// Action relevant to the service message public DecryptedMessageAction action; - - /// Random message ID, assigned by the message author.
Must be equal to the ID passed to the sending method.
- public override long RandomId => random_id; - /// Random bytes, removed in Layer 17. - public override byte[] RandomBytes => random_bytes; - /// Action relevant to the service message - public override DecryptedMessageAction Action => action; } - ///
Photo attached to an encrypted message. See + ///See [TLDef(0x32798A8C)] - public sealed partial class DecryptedMessageMediaPhoto : DecryptedMessageMedia + public partial class DecryptedMessageMediaPhoto : DecryptedMessageMedia { - /// Content of thumbnail file (JPEGfile, quality 55, set in a square 90x90) public byte[] thumb; - /// Thumbnail width public int thumb_w; - /// Thumbnail height public int thumb_h; - /// Photo width public int w; - /// Photo height public int h; - /// Size of the photo in bytes public int size; - /// Key to decrypt an attached file with a full version public byte[] key; - /// Initialization vector public byte[] iv; - - public override string MimeType => "image/jpeg"; - 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 + ///See [TLDef(0x4CEE6EF3)] - public sealed partial class DecryptedMessageMediaVideo : DecryptedMessageMedia + public partial class DecryptedMessageMediaVideo : DecryptedMessageMedia { - /// Content of thumbnail file (JPEG file, quality 55, set in a square 90x90) public byte[] thumb; - /// Thumbnail width public int thumb_w; - /// Thumbnail height public int thumb_h; - /// Duration of video in seconds public int duration; - /// Image width public int w; - /// Image height public int h; - /// File size public int size; - /// Key to decrypt the attached video file public byte[] key; - /// Initialization vector public byte[] iv; - - 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 + ///See [TLDef(0x35480A59)] - public sealed partial class DecryptedMessageMediaGeoPoint : DecryptedMessageMedia + public partial class DecryptedMessageMediaGeoPoint : DecryptedMessageMedia { - /// Latitude of point public double lat; - /// Longitude of point - public double lon; + public double long_; } - /// Contact attached to an encrypted message. See + ///See [TLDef(0x588A0A97)] - public sealed partial class DecryptedMessageMediaContact : DecryptedMessageMedia + public partial class DecryptedMessageMediaContact : DecryptedMessageMedia { - /// Phone number public string phone_number; - /// Contact's first name public string first_name; - /// Contact's last name public string last_name; - /// Telegram User ID of signed-up contact public int user_id; } - /// Document attached to a message in a secret chat. See + ///See [TLDef(0xB095434B)] - public sealed partial class DecryptedMessageMediaDocument : DecryptedMessageMedia + public partial class DecryptedMessageMediaDocument : DecryptedMessageMedia { - /// 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 name, moved to attributes in Layer 45. public string file_name; - /// File MIME-type public string mime_type; - /// Document size ( on layer <143, on layer >=143) public int size; - /// Key to decrypt the attached document file public byte[] key; - /// Initialization public byte[] iv; - - /// File MIME-type - public override string MimeType => mime_type; - - 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 + ///See [TLDef(0x6080758F)] - public sealed partial class DecryptedMessageMediaAudio : DecryptedMessageMedia + public partial class DecryptedMessageMediaAudio : DecryptedMessageMedia { - /// Audio duration in seconds public int duration; - /// File size public int size; - /// Key to decrypt the attached media file public byte[] key; - /// Initialization vector public byte[] iv; - - 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 + ///See [TLDef(0xA1733AEC)] - public sealed partial class DecryptedMessageActionSetMessageTTL : DecryptedMessageAction - { - /// Lifetime in seconds - public int ttl_seconds; - } - /// Messages marked as read. See + public partial class DecryptedMessageActionSetMessageTTL : DecryptedMessageAction { public int ttl_seconds; } + ///See [TLDef(0x0C4F40BE)] - public sealed partial class DecryptedMessageActionReadMessages : DecryptedMessageAction - { - /// List of message IDs - public long[] random_ids; - } - /// Deleted messages. See + public partial class DecryptedMessageActionReadMessages : DecryptedMessageAction { public long[] random_ids; } + ///See [TLDef(0x65614304)] - public sealed partial class DecryptedMessageActionDeleteMessages : DecryptedMessageAction - { - /// List of deleted message IDs - public long[] random_ids; - } - /// A screenshot was taken. See + public partial class DecryptedMessageActionDeleteMessages : DecryptedMessageAction { public long[] random_ids; } + ///See [TLDef(0x8AC1F475)] - public sealed partial class DecryptedMessageActionScreenshotMessages : DecryptedMessageAction - { - /// List of affected message ids (that appeared on the screenshot) - public long[] random_ids; - } - /// The entire message history has been deleted. See + public partial class DecryptedMessageActionScreenshotMessages : DecryptedMessageAction { public long[] random_ids; } + ///See [TLDef(0x6719E45C)] - public sealed partial class DecryptedMessageActionFlushHistory : DecryptedMessageAction { } + public partial class DecryptedMessageActionFlushHistory : DecryptedMessageAction { } } - namespace Layer23 + namespace Layer17 { - /// Image description. See - [TLDef(0x77BFB61B)] - public sealed 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 sealed 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 + ///See [TLDef(0x92042FF7)] - public sealed partial class SendMessageUploadVideoAction : SendMessageAction { } - /// User is uploading a voice message. See + public partial class SendMessageUploadVideoAction : SendMessageAction { } + ///See [TLDef(0xE6AC8A6F)] - public sealed partial class SendMessageUploadAudioAction : SendMessageAction { } - /// User is uploading a photo. See + public partial class SendMessageUploadAudioAction : SendMessageAction { } + ///See [TLDef(0x990A3C1A)] - public sealed partial class SendMessageUploadPhotoAction : SendMessageAction { } - /// User is uploading a file. See + public partial class SendMessageUploadPhotoAction : SendMessageAction { } + ///See [TLDef(0x8FAEE98E)] - public sealed partial class SendMessageUploadDocumentAction : SendMessageAction { } + public partial class SendMessageUploadDocumentAction : SendMessageAction { } - /// Defines a sticker See - [TLDef(0xFB0A5727)] - public sealed partial class DocumentAttributeSticker : DocumentAttribute { } - /// Defines a video See - [TLDef(0x5910CCCB)] - public sealed partial 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 sealed partial class DocumentAttributeAudio : DocumentAttribute - { - /// Duration in seconds - public int duration; - } - - /// Contents of an encrypted message. See + ///See [TLDef(0x204D3878)] - public sealed partial class DecryptedMessage : DecryptedMessageBase + public partial class DecryptedMessage : DecryptedMessageBase { - /// Random message ID, assigned by the author of message.
Must be equal to the ID passed to sending method.
public long random_id; - /// Message lifetime. Has higher priority than .
Parameter added in Layer 17.
public int ttl; - /// Message text public string message; - /// Media content public DecryptedMessageMedia media; - - /// Random message ID, assigned by the author of message.
Must be equal to the ID passed to sending method.
- public override long RandomId => random_id; - /// Message lifetime. Has higher priority than .
Parameter added in Layer 17.
- public override int Ttl => ttl; - /// Message text - public override string Message => message; - /// Media content - public override DecryptedMessageMedia Media => media; } - ///
Contents of an encrypted service message. See + ///See [TLDef(0x73164160)] - public sealed partial class DecryptedMessageService : DecryptedMessageBase + public partial class DecryptedMessageService : DecryptedMessageBase { - /// Random message ID, assigned by the message author.
Must be equal to the ID passed to the sending method.
public long random_id; - /// Action relevant to the service message public DecryptedMessageAction action; - - /// Random message ID, assigned by the message author.
Must be equal to the ID passed to the sending method.
- public override long RandomId => random_id; - /// Action relevant to the service message - public override DecryptedMessageAction Action => action; } - ///
Video attached to an encrypted message. See + ///See [TLDef(0x524A415D)] - public sealed partial class DecryptedMessageMediaVideo : DecryptedMessageMedia + public partial class DecryptedMessageMediaVideo : DecryptedMessageMedia { - /// Content of thumbnail file (JPEG file, quality 55, set in a square 90x90) public byte[] thumb; - /// Thumbnail width public int thumb_w; - /// Thumbnail height public int thumb_h; - /// Duration of video in seconds public int duration; - /// MIME-type of the video file
Parameter added in Layer 17.
public string mime_type; - /// Image width public int w; - /// Image height public int h; - /// File size public int size; - /// Key to decrypt the attached video file public byte[] key; - /// Initialization vector public byte[] iv; - - /// MIME-type of the video file
Parameter added in Layer 17.
- public override string MimeType => mime_type; - - 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 + ///See [TLDef(0x57E0A9CB)] - public sealed partial class DecryptedMessageMediaAudio : DecryptedMessageMedia + public partial class DecryptedMessageMediaAudio : DecryptedMessageMedia { - /// Audio duration in seconds public int duration; - /// MIME-type of the audio file
Parameter added in Layer 13.
public string mime_type; - /// File size public int size; - /// Key to decrypt the attached media file public byte[] key; - /// Initialization vector public byte[] iv; - - /// MIME-type of the audio file
Parameter added in Layer 13.
- public override string MimeType => mime_type; - - 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 sealed partial 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 + ///See [TLDef(0x511110B0)] - public sealed partial class DecryptedMessageActionResend : DecryptedMessageAction + public partial class DecryptedMessageActionResend : DecryptedMessageAction { - /// out_seq_no of the first message to be resent, with correct parity public int start_seq_no; - /// out_seq_no of the last message to be resent, with same parity. public int end_seq_no; } - /// A notification stating the API layer that is used by the client. You should use your current layer and take notice of the layer used on the other side of a conversation when sending messages. See + ///See [TLDef(0xF3048883)] - public sealed partial class DecryptedMessageActionNotifyLayer : DecryptedMessageAction - { - /// Layer number, must be 17 or higher (this constructor was introduced in Layer 17. - public int layer; - } - /// User is preparing a message: typing, recording, uploading, etc. See + public partial class DecryptedMessageActionNotifyLayer : DecryptedMessageAction { public int layer; } + ///See [TLDef(0xCCB27641)] - public sealed partial class DecryptedMessageActionTyping : DecryptedMessageAction - { - /// Type of action - public SendMessageAction action; - } - /// Request rekeying, see rekeying process See - [TLDef(0xF3C9611B)] - public sealed partial 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 sealed partial 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 sealed partial class DecryptedMessageActionAbortKey : DecryptedMessageAction - { - /// Exchange ID - public long exchange_id; - } - /// Commit new key, see rekeying process See - [TLDef(0xEC2E0B9B)] - public sealed partial 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 sealed partial class DecryptedMessageActionNoop : DecryptedMessageAction { } + public partial class DecryptedMessageActionTyping : DecryptedMessageAction { public SendMessageAction action; } - /// Sets the layer number for the contents of an encrypted message. See + ///See [TLDef(0x1BE31789)] - public sealed partial class DecryptedMessageLayer : IObject + public partial class DecryptedMessageLayer : ITLObject { - /// Set of random bytes to prevent content recognition in short encrypted messages.
Clients are required to check that there are at least 15 random bytes included in each message. Messages with less than 15 random bytes must be ignored.
Parameter moved here from in Layer 17.
public byte[] random_bytes; - /// Layer number. Mimimal value - 17 (the layer in which the constructor was added). public int layer; - /// 2x the number of messages in the sender's inbox (including deleted and service messages), incremented by 1 if current user was not the chat creator
Parameter added in Layer 17.
public int in_seq_no; - /// 2x the number of messages in the recipient's inbox (including deleted and service messages), incremented by 1 if current user was the chat creator
Parameter added in Layer 17.
public int out_seq_no; - /// The content of message itself public DecryptedMessageBase message; } - - ///
File is currently unavailable. See - [TLDef(0x7C596B46)] - public sealed partial class FileLocationUnavailable : FileLocationBase - { - /// Volume ID - public long volume_id; - /// Local ID - public int local_id; - /// Secret - public long secret; - - /// Volume ID - public override long VolumeId => volume_id; - /// Local ID - public override int LocalId => local_id; - /// Secret - public override long Secret => secret; - } - /// File location. See - [TLDef(0x53D69076)] - public sealed partial class FileLocation : FileLocationBase - { - /// DC ID - public int dc_id; - /// Volume ID - public long volume_id; - /// Local ID - public int local_id; - /// Secret - public long secret; - - /// Volume ID - public override long VolumeId => volume_id; - /// Local ID - public override int LocalId => local_id; - /// Secret - public override long Secret => secret; - } } namespace Layer45 { - /// Represents an audio file See - [TLDef(0xDED218E0)] - public sealed partial class DocumentAttributeAudio : DocumentAttribute + ///See + [TLDef(0x3A556302)] + public partial class DocumentAttributeSticker : DocumentAttribute + { + public string alt; + public InputStickerSet stickerset; + } + ///See + [TLDef(0xDED218E0)] + public partial class DocumentAttributeAudio : DocumentAttribute { - /// Duration in seconds public int duration; - /// Name of song public string title; - /// Performer public string performer; } + + ///See + [TLDef(0x36B091DE)] + public partial class DecryptedMessage : DecryptedMessageBase + { + [Flags] public enum Flags { has_reply_to_random_id = 0x8, has_entities = 0x80, has_media = 0x200, has_via_bot_name = 0x800 } + public Flags flags; + public long random_id; + public int ttl; + public string message; + [IfFlag(9)] public DecryptedMessageMedia media; + [IfFlag(7)] public MessageEntity[] entities; + [IfFlag(11)] public string via_bot_name; + [IfFlag(3)] public long reply_to_random_id; + } + + ///See + [TLDef(0xF1FA8D78)] + public partial class DecryptedMessageMediaPhoto : DecryptedMessageMedia + { + public byte[] thumb; + public int thumb_w; + public int thumb_h; + public int w; + public int h; + public int size; + public byte[] key; + public byte[] iv; + public string caption; + } + ///See + [TLDef(0x970C8C0E)] + public partial class DecryptedMessageMediaVideo : DecryptedMessageMedia + { + public byte[] thumb; + public int thumb_w; + public int thumb_h; + public int duration; + public string mime_type; + public int w; + public int h; + public int size; + public byte[] key; + public byte[] iv; + public string caption; + } + ///See + [TLDef(0x7AFE8AE2)] + public partial class DecryptedMessageMediaDocument : DecryptedMessageMedia + { + public byte[] thumb; + public int thumb_w; + public int thumb_h; + public string mime_type; + public int size; + public byte[] key; + public byte[] iv; + public DocumentAttribute[] attributes; + public string caption; + } + ///See + [TLDef(0x8A0DF56F)] + public partial class DecryptedMessageMediaVenue : DecryptedMessageMedia + { + public double lat; + public double long_; + public string title; + public string address; + public string provider; + public string venue_id; + } + ///See + [TLDef(0xE50511D8)] + public partial class DecryptedMessageMediaWebPage : DecryptedMessageMedia { public string url; } + } + + namespace Layer73 + { + ///See + [TLDef(0x91CC4674)] + public partial class DecryptedMessage : DecryptedMessageBase + { + [Flags] public enum Flags { has_reply_to_random_id = 0x8, has_entities = 0x80, has_media = 0x200, has_via_bot_name = 0x800, + has_grouped_id = 0x20000 } + public Flags flags; + public long random_id; + public int ttl; + public string message; + [IfFlag(9)] public DecryptedMessageMedia media; + [IfFlag(7)] public MessageEntity[] entities; + [IfFlag(11)] public string via_bot_name; + [IfFlag(3)] public long reply_to_random_id; + [IfFlag(17)] public long grouped_id; + } } - namespace Layer46 + namespace Layer20 { - /// Defines a sticker See - [TLDef(0x3A556302)] - public sealed partial class DocumentAttributeSticker : DocumentAttribute + ///See + [TLDef(0xF3C9611B)] + public partial class DecryptedMessageActionRequestKey : DecryptedMessageAction { - /// Alternative emoji representation of sticker - public string alt; - /// Associated stickerset - public InputStickerSet stickerset; + public long exchange_id; + public byte[] g_a; } - - /// Message entity representing a user mention: for creating a mention use . See - [TLDef(0x352DCA58, inheritAt = 0)] - public sealed partial class MessageEntityMentionName : MessageEntity + ///See + [TLDef(0x6FE1735B)] + public partial class DecryptedMessageActionAcceptKey : DecryptedMessageAction { - /// Identifier of the user that was mentioned - public int user_id; + public long exchange_id; + public byte[] g_b; + public long key_fingerprint; } - - /// Contents of an encrypted message. See - [TLDef(0x36B091DE)] - public sealed partial class DecryptedMessage : DecryptedMessageBase + ///See + [TLDef(0xDD05EC6B)] + public partial class DecryptedMessageActionAbortKey : DecryptedMessageAction { public long exchange_id; } + ///See + [TLDef(0xEC2E0B9B)] + public partial class DecryptedMessageActionCommitKey : DecryptedMessageAction { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Random message ID, assigned by the author of message.
Must be equal to the ID passed to sending method.
- public long random_id; - /// Message lifetime. Has higher priority than .
Parameter added in Layer 17.
- public int ttl; - /// Message text - public string message; - /// Media content - [IfFlag(9)] public DecryptedMessageMedia media; - ///
Message entities for styled text (parameter added in layer 45) - [IfFlag(7)] public MessageEntity[] entities; - /// Specifies the ID of the inline bot that generated the message (parameter added in layer 45) - [IfFlag(11)] public string via_bot_name; - /// Random message ID of the message this message replies to (parameter added in layer 45) - [IfFlag(3)] public long reply_to_random_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_reply_to_random_id = 0x8, - /// Field has a value - has_entities = 0x80, - /// Field has a value - has_media = 0x200, - /// Field has a value - has_via_bot_name = 0x800, - } - - /// Flags, see TL conditional fields (added in layer 45) - public override uint FFlags => (uint)flags; - /// Random message ID, assigned by the author of message.
Must be equal to the ID passed to sending method.
- public override long RandomId => random_id; - /// Message lifetime. Has higher priority than .
Parameter added in Layer 17.
- public override int Ttl => ttl; - /// Message text - public override string Message => message; - /// Media content - public override DecryptedMessageMedia Media => media; - /// Message entities for styled text (parameter added in layer 45) - public override MessageEntity[] Entities => entities; - /// Specifies the ID of the inline bot that generated the message (parameter added in layer 45) - public override string ViaBotName => via_bot_name; - /// Random message ID of the message this message replies to (parameter added in layer 45) - public override long ReplyToRandom => reply_to_random_id; + public long exchange_id; + public long key_fingerprint; } + ///See + [TLDef(0xA82FDD63)] + public partial class DecryptedMessageActionNoop : DecryptedMessageAction { } + } - /// Photo attached to an encrypted message. See - [TLDef(0xF1FA8D78)] - public sealed partial class DecryptedMessageMediaPhoto : DecryptedMessageMedia + namespace Layer23 + { + ///See + [TLDef(0x77BFB61B)] + public partial class PhotoSize : PhotoSizeBase { - /// Content of thumbnail file (JPEGfile, quality 55, set in a square 90x90) - public byte[] thumb; - /// Thumbnail width - public int thumb_w; - /// Thumbnail height - public int thumb_h; - /// Photo width + public string type; + public FileLocationBase location; public int w; - /// Photo height public int h; - /// Size of the photo in bytes public int size; - /// Key to decrypt an attached file with a full version - public byte[] key; - /// Initialization vector - public byte[] iv; - /// Caption - public string caption; - - public override string MimeType => "image/jpeg"; - 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)] - public sealed partial class DecryptedMessageMediaVideo : DecryptedMessageMedia + ///See + [TLDef(0xE9A734FA)] + public partial class PhotoCachedSize : PhotoSizeBase + { + public string type; + public FileLocationBase location; + public int w; + public int h; + public byte[] bytes; + } + + ///See + [TLDef(0xFB0A5727)] + public partial class DocumentAttributeSticker : DocumentAttribute { } + ///See + [TLDef(0x5910CCCB)] + public partial class DocumentAttributeVideo : DocumentAttribute { - /// Content of thumbnail file (JPEG file, quality 55, set in a square 90x90) - public byte[] thumb; - /// Thumbnail width - public int thumb_w; - /// Thumbnail height - public int thumb_h; - /// Duration of video in seconds public int duration; - /// MIME-type of the video file
Parameter added in Layer 17.
- public string mime_type; - /// Image width public int w; - /// Image height public int h; - /// File size - public int size; - /// Key to decrypt the attached video file - public byte[] key; - /// Initialization vector - public byte[] iv; - /// Caption - public string caption; - - /// MIME-type of the video file
Parameter added in Layer 17.
- public override string MimeType => mime_type; - - 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)] - public sealed partial class DecryptedMessageMediaDocument : DecryptedMessageMedia + ///See + [TLDef(0x051448E5)] + public partial class DocumentAttributeAudio : DocumentAttribute { public int duration; } + + ///See + [TLDef(0xFA95B0DD)] + public partial class DecryptedMessageMediaExternalDocument : DecryptedMessageMedia { - /// 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 long id; + public long access_hash; + public DateTime date; public string mime_type; - /// Document size ( on layer <143, on layer >=143) public int size; - /// Key to decrypt the attached document file - public byte[] key; - /// Initialization - public byte[] iv; - /// Document attributes for media types + public PhotoSizeBase thumb; + public int dc_id; public DocumentAttribute[] attributes; - /// Caption - public string caption; - - /// File MIME-type - public override string MimeType => mime_type; - - 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)] - public sealed partial class DecryptedMessageMediaVenue : DecryptedMessageMedia + + ///See + [TLDef(0x7C596B46)] + public partial class FileLocationUnavailable : FileLocationBase { - /// Latitude of venue - public double lat; - /// Longitude of venue - public double lon; - /// Venue name - public string title; - /// Address - public string address; - /// Venue provider: currently only "foursquare" and "gplaces" (Google Places) need to be supported - public string provider; - /// Venue ID in the provider's database - public string venue_id; + public long volume_id; + public int local_id; + public long secret; } - /// Webpage preview See - [TLDef(0xE50511D8)] - public sealed partial class DecryptedMessageMediaWebPage : DecryptedMessageMedia + ///See + [TLDef(0x53D69076)] + public partial class FileLocation : FileLocationBase { - /// URL of webpage - public string url; + public int dc_id; + public long volume_id; + public int local_id; + public long secret; } } namespace Layer66 { - /// User is uploading a round video See + ///See [TLDef(0xBB718624)] - public sealed partial class SendMessageUploadRoundAction : SendMessageAction { } - - /// Defines a video See - [TLDef(0x0EF02CE6)] - public sealed partial class DocumentAttributeVideo : DocumentAttribute - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Duration in seconds - public int duration; - /// Video width - public int w; - /// Video height - public int h; - - [Flags] public enum Flags : uint - { - /// Whether this is a round video - round_message = 0x1, - } - } + public partial class SendMessageUploadRoundAction : SendMessageAction { } } - namespace Layer73 - { - /// Contents of an encrypted message. See - [TLDef(0x91CC4674)] - public sealed partial class DecryptedMessage : DecryptedMessageBase - { - /// Extra bits of information, use flags.HasFlag(...) to test for those - public Flags flags; - /// Random message ID, assigned by the author of message.
Must be equal to the ID passed to sending method.
- public long random_id; - /// Message lifetime. Has higher priority than .
Parameter added in Layer 17.
- public int ttl; - /// Message text - public string message; - /// Media content - [IfFlag(9)] public DecryptedMessageMedia media; - ///
Message entities for styled text (parameter added in layer 45) - [IfFlag(7)] public MessageEntity[] entities; - /// Specifies the ID of the inline bot that generated the message (parameter added in layer 45) - [IfFlag(11)] public string via_bot_name; - /// Random message ID of the message this message replies to (parameter added in layer 45) - [IfFlag(3)] public long reply_to_random_id; - /// Random group ID, assigned by the author of message.
Multiple encrypted messages with a photo attached and with the same group ID indicate an album or grouped media (parameter added in layer 45)
- [IfFlag(17)] public long grouped_id; - - [Flags] public enum Flags : uint - { - /// Field has a value - has_reply_to_random_id = 0x8, - silent = 0x20, - /// Field has a value - has_entities = 0x80, - /// Field has a value - has_media = 0x200, - /// Field has a value - has_via_bot_name = 0x800, - /// Field has a value - has_grouped_id = 0x20000, - } - - /// Flags, see TL conditional fields (added in layer 45) - public override uint FFlags => (uint)flags; - /// Random message ID, assigned by the author of message.
Must be equal to the ID passed to sending method.
- public override long RandomId => random_id; - /// Message lifetime. Has higher priority than .
Parameter added in Layer 17.
- public override int Ttl => ttl; - /// Message text - public override string Message => message; - /// Media content - public override DecryptedMessageMedia Media => media; - /// Message entities for styled text (parameter added in layer 45) - public override MessageEntity[] Entities => entities; - /// Specifies the ID of the inline bot that generated the message (parameter added in layer 45) - public override string ViaBotName => via_bot_name; - /// Random message ID of the message this message replies to (parameter added in layer 45) - public override long ReplyToRandom => reply_to_random_id; - /// Random group ID, assigned by the author of message.
Multiple encrypted messages with a photo attached and with the same group ID indicate an album or grouped media (parameter added in layer 45)
- public override long Grouped => grouped_id; - } - } - - namespace Layer101 - { - /// Message entity representing a block quote. See - [TLDef(0x020DF5D0)] - public sealed partial class MessageEntityBlockquote : MessageEntity { } - } - - namespace Layer143 - { - /// Document attached to a message in a secret chat. See - [TLDef(0x6ABD9782)] - public sealed partial class DecryptedMessageMediaDocument : DecryptedMessageMedia - { - /// 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; - /// 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; - - /// File MIME-type - public override string MimeType => mime_type; - - internal override (long size, byte[] key, byte[] iv) SizeKeyIV { get => (size, key, iv); set => (size, key, iv) = value; } - } - } - - namespace Layer144 + namespace Layer46 { } } diff --git a/src/TL.Table.cs b/src/TL.Table.cs index a26fd62..f278660 100644 --- a/src/TL.Table.cs +++ b/src/TL.Table.cs @@ -1,32 +1,24 @@ -using System; +// This file is generated automatically using the Generator class +using System; using System.Collections.Generic; -using System.ComponentModel; namespace TL { - public static partial class Layer + public static class Layer { - public const int Version = 223; // fetched 03/02/2026 11:38:17 - internal const int SecretChats = 144; - internal const int MTProto2 = 73; + public const int Version = 133; // fetched 17/09/2021 02:47:02 internal const uint VectorCtor = 0x1CB5C415; internal const uint NullCtor = 0x56730BCC; internal const uint RpcResultCtor = 0xF35C6D01; - internal const uint RpcErrorCtor = 0x2144CA19; internal const uint MsgContainerCtor = 0x73F1F8DC; - internal const uint BadMsgCtor = 0xA7EFF811; - internal const uint GZipedCtor = 0x3072CFA1; -#if !MTPG - [EditorBrowsable(EditorBrowsableState.Never)] - public readonly static Dictionary Table = new() + internal readonly static Dictionary Table = new() { [0xF35C6D01] = typeof(RpcResult), [0x5BB8E511] = typeof(_Message), [0x73F1F8DC] = typeof(MsgContainer), [0xE06046B2] = typeof(MsgCopy), [0x3072CFA1] = typeof(GzipPacked), - [0xFEFEFEFE] = typeof(WTelegram.SecretChat), // from TL.MTProto: [0x05162463] = typeof(ResPQ), [0x83C95AEC] = typeof(PQInnerData), @@ -41,9 +33,7 @@ namespace TL [0x3BCBF734] = typeof(DhGenOk), [0x46DC1FB9] = typeof(DhGenRetry), [0xA69DAE02] = typeof(DhGenFail), - [0xF660E1D4] = typeof(DestroyAuthKeyOk), - [0x0A9F2259] = typeof(DestroyAuthKeyNone), - [0xEA109B13] = typeof(DestroyAuthKeyFail), + [0x7ABE77EC] = typeof(Ping), [0x62D6B459] = typeof(MsgsAck), [0xA7EFF811] = typeof(BadMsgNotification), [0xEDAB447B] = typeof(BadServerSalt), @@ -68,8 +58,7 @@ namespace TL [0x37982646] = typeof(IpPortSecret), [0x4679B65F] = typeof(AccessPointRule), [0x5A592A6C] = typeof(Help_ConfigSimple), - [0x7ABE77EC] = typeof(Methods.Ping), - // from TL.SchemaExtensions: + // from TL.Schema: [0x3FEDD339] = typeof(True), [0xC4B9F9BB] = typeof(Error), [0x56730BCC] = null,//Null @@ -84,32 +73,26 @@ namespace TL [0xF7C1B13F] = typeof(InputUserSelf), [0xF21158C6] = typeof(InputUser), [0x1DA448E2] = typeof(InputUserFromMessage), - [0x6A1DC4BE] = typeof(InputPhoneContact), + [0xF392B7F4] = typeof(InputPhoneContact), [0xF52FF27F] = typeof(InputFile), [0xFA4F0BB5] = typeof(InputFileBig), - [0x62DC8B48] = typeof(InputFileStoryDocument), [0x9664F57F] = null,//InputMediaEmpty [0x1E287D04] = typeof(InputMediaUploadedPhoto), [0xB3BA0635] = typeof(InputMediaPhoto), [0xF9C44144] = typeof(InputMediaGeoPoint), [0xF8AB7DFB] = typeof(InputMediaContact), - [0x037C9330] = typeof(InputMediaUploadedDocument), - [0xA8763AB5] = typeof(InputMediaDocument), + [0x5B38C6C1] = typeof(InputMediaUploadedDocument), + [0x33473058] = typeof(InputMediaDocument), [0xC13D1C11] = typeof(InputMediaVenue), [0xE5BBFE1A] = typeof(InputMediaPhotoExternal), - [0x779600F9] = typeof(InputMediaDocumentExternal), + [0xFB52DC99] = typeof(InputMediaDocumentExternal), [0xD33F43F3] = typeof(InputMediaGame), - [0x405FEF0D] = typeof(InputMediaInvoice), + [0xD9799874] = typeof(InputMediaInvoice), [0x971FA843] = typeof(InputMediaGeoLive), [0x0F94E5F1] = typeof(InputMediaPoll), [0xE66FBF7B] = typeof(InputMediaDice), - [0x89FDD778] = typeof(InputMediaStory), - [0xC21B8849] = typeof(InputMediaWebPage), - [0xC4103386] = typeof(InputMediaPaidMedia), - [0x9FC55FDE] = typeof(InputMediaTodo), - [0xF3A9244A] = typeof(InputMediaStakeDice), [0x1CA48F57] = null,//InputChatPhotoEmpty - [0xBDCDAEC0] = typeof(InputChatUploadedPhoto), + [0xC642724E] = typeof(InputChatUploadedPhoto), [0x8953AD37] = typeof(InputChatPhoto), [0xE4C123D6] = null,//InputGeoPointEmpty [0x48222FAF] = typeof(InputGeoPoint), @@ -129,51 +112,45 @@ namespace TL [0x36C6019A] = typeof(PeerChat), [0xA2A5371E] = typeof(PeerChannel), [0xD3BC4B7A] = typeof(UserEmpty), - [0x31774388] = typeof(User), + [0x3FF6ECB0] = typeof(User), [0x4F11BAE1] = null,//UserProfilePhotoEmpty [0x82D1F706] = typeof(UserProfilePhoto), [0x09D05049] = null,//UserStatusEmpty [0xEDB93949] = typeof(UserStatusOnline), [0x008C703F] = typeof(UserStatusOffline), - [0x7B197DC8] = typeof(UserStatusRecently), - [0x541A1D1A] = typeof(UserStatusLastWeek), - [0x65899777] = typeof(UserStatusLastMonth), + [0xE26F42F1] = typeof(UserStatusRecently), + [0x07BF09FC] = typeof(UserStatusLastWeek), + [0x77EBC742] = typeof(UserStatusLastMonth), [0x29562865] = typeof(ChatEmpty), [0x41CBF256] = typeof(Chat), [0x6592A1A7] = typeof(ChatForbidden), - [0x1C32B11C] = typeof(Channel), + [0x8261AC61] = typeof(Channel), [0x17D493D5] = typeof(ChannelForbidden), - [0x2633421B] = typeof(ChatFull), - [0xE4E0B29D] = typeof(ChannelFull), - [0x38E79FDE] = typeof(ChatParticipant), - [0xE1F867B8] = typeof(ChatParticipantCreator), - [0x0360D5D2] = typeof(ChatParticipantAdmin), + [0x4DBDC099] = typeof(ChatFull), + [0xE9B27A17] = typeof(ChannelFull), + [0xC02D4007] = typeof(ChatParticipant), + [0xE46BCEE4] = typeof(ChatParticipantCreator), + [0xA0933F5B] = typeof(ChatParticipantAdmin), [0x8763D3E1] = typeof(ChatParticipantsForbidden), [0x3CBC93F8] = typeof(ChatParticipants), [0x37C1011C] = null,//ChatPhotoEmpty [0x1C6E1C11] = typeof(ChatPhoto), [0x90A6CA84] = typeof(MessageEmpty), - [0x3AE56482] = typeof(Message), - [0x7A800E0A] = typeof(MessageService), + [0x85D6CBE2] = typeof(Message), + [0x2B085862] = typeof(MessageService), [0x3DED6320] = null,//MessageMediaEmpty [0x695150D7] = typeof(MessageMediaPhoto), [0x56E0D474] = typeof(MessageMediaGeo), [0x70322949] = typeof(MessageMediaContact), [0x9F84F49E] = typeof(MessageMediaUnsupported), - [0x52D8CCD9] = typeof(MessageMediaDocument), - [0xDDF10C3B] = typeof(MessageMediaWebPage), + [0x9CB070D7] = typeof(MessageMediaDocument), + [0xA32DD600] = typeof(MessageMediaWebPage), [0x2EC0533F] = typeof(MessageMediaVenue), [0xFDB19008] = typeof(MessageMediaGame), - [0xF6A548D3] = typeof(MessageMediaInvoice), + [0x84551347] = typeof(MessageMediaInvoice), [0xB940C666] = typeof(MessageMediaGeoLive), [0x4BD6E798] = typeof(MessageMediaPoll), - [0x08CBEC07] = typeof(MessageMediaDice), - [0x68CB6283] = typeof(MessageMediaStory), - [0xAA073BEB] = typeof(MessageMediaGiveaway), - [0xCEAA3EA1] = typeof(MessageMediaGiveawayResults), - [0xA8852491] = typeof(MessageMediaPaidMedia), - [0x8A53B014] = typeof(MessageMediaToDo), - [0xCA5CAB89] = typeof(MessageMediaVideoStream), + [0x3F7EE58B] = typeof(MessageMediaDice), [0xB6AEF7B0] = null,//MessageActionEmpty [0xBD47CBAD] = typeof(MessageActionChatCreate), [0xB5A1CE5A] = typeof(MessageActionChatEditTitle), @@ -188,57 +165,22 @@ namespace TL [0x94BD38ED] = typeof(MessageActionPinMessage), [0x9FBAB604] = typeof(MessageActionHistoryClear), [0x92A72876] = typeof(MessageActionGameScore), - [0xFFA00CCC] = typeof(MessageActionPaymentSentMe), - [0xC624B16E] = typeof(MessageActionPaymentSent), + [0x8F31B327] = typeof(MessageActionPaymentSentMe), + [0x40699CD0] = typeof(MessageActionPaymentSent), [0x80E11A7F] = typeof(MessageActionPhoneCall), [0x4792929B] = typeof(MessageActionScreenshotTaken), [0xFAE69F56] = typeof(MessageActionCustomAction), - [0xC516D679] = typeof(MessageActionBotAllowed), + [0xABE9AFFE] = typeof(MessageActionBotAllowed), [0x1B287353] = typeof(MessageActionSecureValuesSentMe), [0xD95C6154] = typeof(MessageActionSecureValuesSent), [0xF3F25F76] = typeof(MessageActionContactSignUp), [0x98E0D697] = typeof(MessageActionGeoProximityReached), [0x7A0D7F42] = typeof(MessageActionGroupCall), [0x502F92F7] = typeof(MessageActionInviteToGroupCall), - [0x3C134D7B] = typeof(MessageActionSetMessagesTTL), + [0xAA1AFBFD] = typeof(MessageActionSetMessagesTTL), [0xB3A07661] = typeof(MessageActionGroupCallScheduled), - [0xB91BBD3A] = typeof(MessageActionSetChatTheme), - [0xEBBCA3CB] = typeof(MessageActionChatJoinedByRequest), - [0x47DD8079] = typeof(MessageActionWebViewDataSentMe), - [0xB4C38CB5] = typeof(MessageActionWebViewDataSent), - [0x48E91302] = typeof(MessageActionGiftPremium), - [0x0D999256] = typeof(MessageActionTopicCreate), - [0xC0944820] = typeof(MessageActionTopicEdit), - [0x57DE635E] = typeof(MessageActionSuggestProfilePhoto), - [0x31518E9B] = typeof(MessageActionRequestedPeer), - [0x5060A3F4] = typeof(MessageActionSetChatWallPaper), - [0x31C48347] = typeof(MessageActionGiftCode), - [0xA80F51E4] = typeof(MessageActionGiveawayLaunch), - [0x87E2F155] = typeof(MessageActionGiveawayResults), - [0xCC02AA6D] = typeof(MessageActionBoostApply), - [0x93B31848] = typeof(MessageActionRequestedPeerSentMe), - [0x41B3E202] = typeof(MessageActionPaymentRefunded), - [0x45D5B021] = typeof(MessageActionGiftStars), - [0xB00C47A2] = typeof(MessageActionPrizeStars), - [0xEA2C31D3] = typeof(MessageActionStarGift), - [0xE6C31522] = typeof(MessageActionStarGiftUnique), - [0xAC1F1FCD] = typeof(MessageActionPaidMessagesRefunded), - [0x84B88578] = typeof(MessageActionPaidMessagesPrice), - [0x2FFE2F7A] = typeof(MessageActionConferenceCall), - [0xCC7C5C89] = typeof(MessageActionTodoCompletions), - [0xC7EDBC83] = typeof(MessageActionTodoAppendTasks), - [0xEE7A1596] = typeof(MessageActionSuggestedPostApproval), - [0x95DDCF69] = typeof(MessageActionSuggestedPostSuccess), - [0x69F916F8] = typeof(MessageActionSuggestedPostRefund), - [0xA8A3C699] = typeof(MessageActionGiftTon), - [0x2C8F2A25] = typeof(MessageActionSuggestBirthday), - [0x774278D4] = typeof(MessageActionStarGiftPurchaseOffer), - [0x73ADA76B] = typeof(MessageActionStarGiftPurchaseOfferDeclined), - [0xB07ED085] = typeof(MessageActionNewCreatorPending), - [0xE188503B] = typeof(MessageActionChangeCreator), - [0xBF7D6572] = typeof(MessageActionNoForwardsToggle), - [0x3E2793BA] = typeof(MessageActionNoForwardsRequest), - [0xD58A08C6] = typeof(Dialog), + [0xAA786345] = typeof(MessageActionSetChatTheme), + [0x2C171F72] = typeof(Dialog), [0x71BD134C] = typeof(DialogFolder), [0x2331B22D] = typeof(PhotoEmpty), [0xFB197A65] = typeof(Photo), @@ -251,22 +193,19 @@ namespace TL [0x1117DD5F] = null,//GeoPointEmpty [0xB2A2F663] = typeof(GeoPoint), [0x5E002502] = typeof(Auth_SentCode), - [0x2390FE44] = typeof(Auth_SentCodeSuccess), - [0xE0955A3C] = typeof(Auth_SentCodePaymentRequired), - [0x2EA2C0D4] = typeof(Auth_Authorization), + [0xCD050916] = typeof(Auth_Authorization), [0x44747E9A] = typeof(Auth_AuthorizationSignUpRequired), [0xB434E2B8] = typeof(Auth_ExportedAuthorization), [0xB8BC5B0C] = typeof(InputNotifyPeer), [0x193B4417] = typeof(InputNotifyUsers), [0x4A95E84E] = typeof(InputNotifyChats), [0xB1DB7C7E] = typeof(InputNotifyBroadcasts), - [0x5C467992] = typeof(InputNotifyForumTopic), - [0xCACB6AE2] = typeof(InputPeerNotifySettings), - [0x99622C0C] = typeof(PeerNotifySettings), - [0xF47741F7] = typeof(PeerSettings), + [0x9C3D198E] = typeof(InputPeerNotifySettings), + [0xAF509D20] = typeof(PeerNotifySettings), + [0x733F2961] = typeof(PeerSettings), [0xA437C3ED] = typeof(WallPaper), [0xE0804116] = typeof(WallPaperNoFile), - [0xA02BC13E] = typeof(UserFull), + [0xD697FF05] = typeof(UserFull), [0x145ADE0B] = typeof(Contact), [0xC13E3C50] = typeof(ImportedContact), [0x16D9703B] = typeof(ContactStatus), @@ -278,9 +217,9 @@ namespace TL [0x15BA6C40] = typeof(Messages_Dialogs), [0x71E094F3] = typeof(Messages_DialogsSlice), [0xF0E3E596] = typeof(Messages_DialogsNotModified), - [0x1D73E7EA] = typeof(Messages_Messages), - [0x5F206716] = typeof(Messages_MessagesSlice), - [0xC776BA4E] = typeof(Messages_ChannelMessages), + [0x8C718E87] = typeof(Messages_Messages), + [0x3A54685E] = typeof(Messages_MessagesSlice), + [0x64479808] = typeof(Messages_ChannelMessages), [0x74535F21] = typeof(Messages_MessagesNotModified), [0x64FF9FD5] = typeof(Messages_Chats), [0x9CD81144] = typeof(Messages_ChatsSlice), @@ -306,12 +245,12 @@ namespace TL [0x1F2B0AFD] = typeof(UpdateNewMessage), [0x4E90BFD6] = typeof(UpdateMessageID), [0xA20DB0E5] = typeof(UpdateDeleteMessages), - [0x2A17BF5C] = typeof(UpdateUserTyping), + [0xC01E857F] = typeof(UpdateUserTyping), [0x83487AF0] = typeof(UpdateChatUserTyping), [0x07761198] = typeof(UpdateChatParticipants), [0xE5BDF8DE] = typeof(UpdateUserStatus), - [0xA7848924] = typeof(UpdateUserName), - [0x8951ABEF] = typeof(UpdateNewAuthorization), + [0xC3F202E0] = typeof(UpdateUserName), + [0xF227868C] = typeof(UpdateUserPhoto), [0x12BCBD9A] = typeof(UpdateNewEncryptedMessage), [0x1710F156] = typeof(UpdateEncryptedChatTyping), [0xB4A2E88D] = typeof(UpdateEncryption), @@ -323,10 +262,10 @@ namespace TL [0xEBE46819] = typeof(UpdateServiceNotification), [0xEE3B272A] = typeof(UpdatePrivacy), [0x05492A13] = typeof(UpdateUserPhone), - [0x9E84BC99] = typeof(UpdateReadHistoryInbox), + [0x9C974FDF] = typeof(UpdateReadHistoryInbox), [0x2F2F21BF] = typeof(UpdateReadHistoryOutbox), [0x7F891213] = typeof(UpdateWebPage), - [0xF8227181] = typeof(UpdateReadMessagesContents), + [0x68C13933] = typeof(UpdateReadMessagesContents), [0x108D941F] = typeof(UpdateChannelTooLong), [0x635B4C09] = typeof(UpdateChannel), [0x62BA04D9] = typeof(UpdateNewChannelMessage), @@ -336,7 +275,7 @@ namespace TL [0xD7CA61A2] = typeof(UpdateChatParticipantAdmin), [0x688A30AA] = typeof(UpdateNewStickerSet), [0x0BB2D201] = typeof(UpdateStickerSetsOrder), - [0x31C24808] = typeof(UpdateStickerSets), + [0x43AE3DEC] = typeof(UpdateStickerSets), [0x9375341E] = typeof(UpdateSavedGifs), [0x496F379C] = typeof(UpdateBotInlineQuery), [0x12F12A07] = typeof(UpdateBotInlineSend), @@ -345,7 +284,7 @@ namespace TL [0xE40370A3] = typeof(UpdateEditMessage), [0x691E9052] = typeof(UpdateInlineBotCallbackQuery), [0xB75F99A9] = typeof(UpdateReadChannelOutbox), - [0xEDFC111E] = typeof(UpdateDraftMessage), + [0xEE2BB969] = typeof(UpdateDraftMessage), [0x571D2742] = typeof(UpdateReadFeaturedStickers), [0x9A422C20] = typeof(UpdateRecentStickers), [0xA229DD06] = typeof(UpdateConfig), @@ -361,21 +300,21 @@ namespace TL [0x46560264] = typeof(UpdateLangPackTooLong), [0x56022F4D] = typeof(UpdateLangPack), [0xE511996D] = typeof(UpdateFavedStickers), - [0x25F324F7] = typeof(UpdateChannelReadMessagesContents), + [0x44BDD535] = typeof(UpdateChannelReadMessagesContents), [0x7084A7BE] = typeof(UpdateContactsReset), [0xB23FC698] = typeof(UpdateChannelAvailableMessages), - [0xB658F23E] = typeof(UpdateDialogUnreadMark), + [0xE16459C3] = typeof(UpdateDialogUnreadMark), [0xACA1657B] = typeof(UpdateMessagePoll), [0x54C01850] = typeof(UpdateChatDefaultBannedRights), [0x19360DC0] = typeof(UpdateFolderPeers), [0x6A7E7366] = typeof(UpdatePeerSettings), [0xB4AFCFB0] = typeof(UpdatePeerLocated), [0x39A51DFB] = typeof(UpdateNewScheduledMessage), - [0xF2A71983] = typeof(UpdateDeleteScheduledMessages), + [0x90866CEE] = typeof(UpdateDeleteScheduledMessages), [0x8216FBA3] = typeof(UpdateTheme), [0x871FB939] = typeof(UpdateGeoLiveViewed), [0x564FE691] = typeof(UpdateLoginToken), - [0x24F40E77] = typeof(UpdateMessagePollVote), + [0x106395C9] = typeof(UpdateMessagePollVote), [0x26FFDE7D] = typeof(UpdateDialogFilter), [0xA5D72105] = typeof(UpdateDialogFilterOrder), [0x3504914F] = typeof(UpdateDialogFilters), @@ -383,79 +322,19 @@ namespace TL [0xD29A27F4] = typeof(UpdateChannelMessageForwards), [0xD6B19546] = typeof(UpdateReadChannelDiscussionInbox), [0x695C9E7C] = typeof(UpdateReadChannelDiscussionOutbox), - [0xEBE07752] = typeof(UpdatePeerBlocked), + [0x246A4B22] = typeof(UpdatePeerBlocked), [0x8C88C923] = typeof(UpdateChannelUserTyping), [0xED85EAB5] = typeof(UpdatePinnedMessages), [0x5BB98608] = typeof(UpdatePinnedChannelMessages), [0xF89A6A4E] = typeof(UpdateChat), [0xF2EBDB4E] = typeof(UpdateGroupCallParticipants), - [0x9D2216E0] = typeof(UpdateGroupCall), + [0x14B24500] = typeof(UpdateGroupCall), [0xBB9BB9A5] = typeof(UpdatePeerHistoryTTL), [0xD087663A] = typeof(UpdateChatParticipant), [0x985D3ABB] = typeof(UpdateChannelParticipant), [0xC4870A49] = typeof(UpdateBotStopped), [0x0B783982] = typeof(UpdateGroupCallConnection), [0x4D712F2E] = typeof(UpdateBotCommands), - [0x7063C3DB] = typeof(UpdatePendingJoinRequests), - [0x11DFA986] = typeof(UpdateBotChatInviteRequester), - [0x1E297BFA] = typeof(UpdateMessageReactions), - [0x17B7A20B] = typeof(UpdateAttachMenuBots), - [0x1592B79D] = typeof(UpdateWebViewResultSent), - [0x14B85813] = typeof(UpdateBotMenuButton), - [0x74D8BE99] = typeof(UpdateSavedRingtones), - [0x0084CD5A] = typeof(UpdateTranscribedAudio), - [0xFB4C496C] = typeof(UpdateReadFeaturedEmojiStickers), - [0x28373599] = typeof(UpdateUserEmojiStatus), - [0x30F443DB] = typeof(UpdateRecentEmojiStatuses), - [0x6F7863F4] = typeof(UpdateRecentReactions), - [0x86FCCF85] = typeof(UpdateMoveStickerSetToTop), - [0xD5A41724] = typeof(UpdateMessageExtendedMedia), - [0x20529438] = typeof(UpdateUser), - [0xEC05B097] = typeof(UpdateAutoSaveSettings), - [0x75B3B798] = typeof(UpdateStory), - [0xF74E932B] = typeof(UpdateReadStories), - [0x1BF335B9] = typeof(UpdateStoryID), - [0x2C084DC1] = typeof(UpdateStoriesStealthMode), - [0x7D627683] = typeof(UpdateSentStoryReaction), - [0x904DD49C] = typeof(UpdateBotChatBoost), - [0x07B68920] = typeof(UpdateChannelViewForumAsMessages), - [0xAE3F101D] = typeof(UpdatePeerWallpaper), - [0xAC21D3CE] = typeof(UpdateBotMessageReaction), - [0x09CB7759] = typeof(UpdateBotMessageReactions), - [0xAEAF9E74] = typeof(UpdateSavedDialogPinned), - [0x686C85A6] = typeof(UpdatePinnedSavedDialogs), - [0x39C67432] = typeof(UpdateSavedReactionTags), - [0xF16269D4] = typeof(UpdateSmsJob), - [0xF9470AB2] = typeof(UpdateQuickReplies), - [0xF53DA717] = typeof(UpdateNewQuickReply), - [0x53E6F1EC] = typeof(UpdateDeleteQuickReply), - [0x3E050D0F] = typeof(UpdateQuickReplyMessage), - [0x566FE7CD] = typeof(UpdateDeleteQuickReplyMessages), - [0x8AE5C97A] = typeof(UpdateBotBusinessConnect), - [0x9DDB347C] = typeof(UpdateBotNewBusinessMessage), - [0x07DF587C] = typeof(UpdateBotEditBusinessMessage), - [0xA02A982E] = typeof(UpdateBotDeleteBusinessMessage), - [0x1824E40B] = typeof(UpdateNewStoryReaction), - [0x4E80A379] = typeof(UpdateStarsBalance), - [0x1EA2FDA7] = typeof(UpdateBusinessBotCallbackQuery), - [0xA584B019] = typeof(UpdateStarsRevenueStatus), - [0x283BD312] = typeof(UpdateBotPurchasedPaidMedia), - [0x8B725FCE] = typeof(UpdatePaidReactionPrivacy), - [0x504AA18F] = typeof(UpdateSentPhoneCode), - [0xA477288F] = typeof(UpdateGroupCallChainBlocks), - [0x77B0E372] = typeof(UpdateReadMonoForumInbox), - [0xA4A79376] = typeof(UpdateReadMonoForumOutbox), - [0x9F812B08] = typeof(UpdateMonoForumNoPaidException), - [0xD8326F0D] = typeof(UpdateGroupCallMessage), - [0xC957A766] = typeof(UpdateGroupCallEncryptedMessage), - [0x683B2C52] = typeof(UpdatePinnedForumTopic), - [0xDEF143D0] = typeof(UpdatePinnedForumTopics), - [0x3E85E92C] = typeof(UpdateDeleteGroupCallMessages), - [0x48E246C2] = typeof(UpdateStarGiftAuctionState), - [0xDC58F31E] = typeof(UpdateStarGiftAuctionUserState), - [0xFB9C547A] = typeof(UpdateEmojiGameInfo), - [0xAC072444] = typeof(UpdateStarGiftCraftFail), - [0xBD8367B9] = typeof(UpdateChatParticipantRank), [0xA56C2A3E] = typeof(Updates_State), [0x5D75A138] = typeof(Updates_DifferenceEmpty), [0x00F49CA0] = typeof(Updates_Difference), @@ -474,7 +353,7 @@ namespace TL [0x096A18D5] = typeof(Upload_File), [0xF18CDA44] = typeof(Upload_FileCdnRedirect), [0x18B7A10D] = typeof(DcOption), - [0xCC1A241E] = typeof(Config), + [0x330B4067] = typeof(Config), [0x8E1A1775] = typeof(NearestDc), [0xCCBBCE30] = typeof(Help_AppUpdate), [0xC45A6536] = null,//Help_NoAppUpdate @@ -486,7 +365,7 @@ namespace TL [0x1E1C7C45] = typeof(EncryptedChatDiscarded), [0xF141B5E1] = typeof(InputEncryptedChat), [0xC21F497E] = null,//EncryptedFileEmpty - [0xA8008CD8] = typeof(EncryptedFile), + [0x4A70994C] = typeof(EncryptedFile), [0x1837C364] = null,//InputEncryptedFileEmpty [0x64BD0306] = typeof(InputEncryptedFileUploaded), [0x5A17B5E5] = typeof(InputEncryptedFile), @@ -500,13 +379,12 @@ namespace TL [0x72F0EAAE] = null,//InputDocumentEmpty [0x1ABFB575] = typeof(InputDocument), [0x36F8C871] = typeof(DocumentEmpty), - [0x8FD4C4D8] = typeof(Document), + [0x1E87342B] = typeof(Document), [0x17C6B5F6] = typeof(Help_Support), [0x9FD40BD8] = typeof(NotifyPeer), [0xB4C83B4C] = typeof(NotifyUsers), [0xC007CEC3] = typeof(NotifyChats), [0xD612E8EF] = typeof(NotifyBroadcasts), - [0x226E6308] = typeof(NotifyForumTopic), [0x16BF744E] = typeof(SendMessageTypingAction), [0xFD5EC8F5] = typeof(SendMessageCancelAction), [0xA187D66F] = typeof(SendMessageRecordVideoAction), @@ -523,9 +401,8 @@ namespace TL [0xD92C2285] = typeof(SpeakingInGroupCallAction), [0xDBDA9246] = typeof(SendMessageHistoryImportAction), [0xB05AC6B1] = typeof(SendMessageChooseStickerAction), - [0x25972BCB] = typeof(SendMessageEmojiInteraction), + [0x6A3233B6] = typeof(SendMessageEmojiInteraction), [0xB665902E] = typeof(SendMessageEmojiInteractionSeen), - [0x376D975C] = typeof(SendMessageTextDraftAction), [0xB3134D9D] = typeof(Contacts_Found), [0x0D09E07B] = typeof(InputPrivacyValueAllowContacts), [0x184B35CE] = typeof(InputPrivacyValueAllowAll), @@ -535,10 +412,6 @@ namespace TL [0x90110467] = typeof(InputPrivacyValueDisallowUsers), [0x840649CF] = typeof(InputPrivacyValueAllowChatParticipants), [0xE94F0F86] = typeof(InputPrivacyValueDisallowChatParticipants), - [0x2F453E49] = typeof(InputPrivacyValueAllowCloseFriends), - [0x77CDC9F1] = typeof(InputPrivacyValueAllowPremium), - [0x5A4FCCE5] = typeof(InputPrivacyValueAllowBots), - [0xC4E57915] = typeof(InputPrivacyValueDisallowBots), [0xFFFE1BAC] = typeof(PrivacyValueAllowContacts), [0x65427B82] = typeof(PrivacyValueAllowAll), [0xB8905FB2] = typeof(PrivacyValueAllowUsers), @@ -547,77 +420,56 @@ namespace TL [0xE4621141] = typeof(PrivacyValueDisallowUsers), [0x6B134E8E] = typeof(PrivacyValueAllowChatParticipants), [0x41C87565] = typeof(PrivacyValueDisallowChatParticipants), - [0xF7E8D89B] = typeof(PrivacyValueAllowCloseFriends), - [0xECE9814B] = typeof(PrivacyValueAllowPremium), - [0x21461B5D] = typeof(PrivacyValueAllowBots), - [0xF6A5F82F] = typeof(PrivacyValueDisallowBots), [0x50A04E45] = typeof(Account_PrivacyRules), [0xB8D0AFDF] = typeof(AccountDaysTTL), [0x6C37C15C] = typeof(DocumentAttributeImageSize), [0x11B58939] = typeof(DocumentAttributeAnimated), [0x6319D612] = typeof(DocumentAttributeSticker), - [0x43C57C48] = typeof(DocumentAttributeVideo), + [0x0EF02CE6] = typeof(DocumentAttributeVideo), [0x9852F9C6] = typeof(DocumentAttributeAudio), [0x15590068] = typeof(DocumentAttributeFilename), [0x9801D2F7] = typeof(DocumentAttributeHasStickers), - [0xFD149899] = typeof(DocumentAttributeCustomEmoji), [0xF1749A22] = null,//Messages_StickersNotModified [0x30A6EC7E] = typeof(Messages_Stickers), [0x12B299D4] = typeof(StickerPack), [0xE86602C3] = null,//Messages_AllStickersNotModified [0xCDBBCEBB] = typeof(Messages_AllStickers), [0x84D19185] = typeof(Messages_AffectedMessages), - [0x211A1788] = typeof(WebPageEmpty), - [0xB0D13E47] = typeof(WebPagePending), + [0xEB1477E8] = typeof(WebPageEmpty), + [0xC586DA1C] = typeof(WebPagePending), [0xE89C45B2] = typeof(WebPage), [0x7311CA11] = typeof(WebPageNotModified), [0xAD01D61D] = typeof(Authorization), - [0x4BFF8EA0] = typeof(Account_Authorizations), - [0x957B50FB] = typeof(Account_Password), + [0x1250ABDE] = typeof(Account_Authorizations), + [0x185B184F] = typeof(Account_Password), [0x9A5C33E5] = typeof(Account_PasswordSettings), [0xC23727C9] = typeof(Account_PasswordInputSettings), [0x137948A5] = typeof(Auth_PasswordRecovery), [0xA384B779] = typeof(ReceivedNotifyMessage), - [0xA22CBD96] = typeof(ChatInviteExported), - [0xED107AB7] = typeof(ChatInvitePublicJoinRequests), + [0xB18105E8] = typeof(ChatInviteExported), [0x5A686D7C] = typeof(ChatInviteAlready), - [0x5C9D3702] = typeof(ChatInvite), + [0xDFC2F58E] = typeof(ChatInvite), [0x61695CB0] = typeof(ChatInvitePeek), [0xFFB62B95] = null,//InputStickerSetEmpty [0x9DE7A269] = typeof(InputStickerSetID), [0x861CC8A0] = typeof(InputStickerSetShortName), [0x028703C8] = typeof(InputStickerSetAnimatedEmoji), [0xE67F520E] = typeof(InputStickerSetDice), - [0x0CDE3739] = typeof(InputStickerSetAnimatedEmojiAnimations), - [0xC88B3B02] = typeof(InputStickerSetPremiumGifts), - [0x04C4D4CE] = typeof(InputStickerSetEmojiGenericAnimations), - [0x29D0F5EE] = typeof(InputStickerSetEmojiDefaultStatuses), - [0x44C1F8E9] = typeof(InputStickerSetEmojiDefaultTopicIcons), - [0x49748553] = typeof(InputStickerSetEmojiChannelDefaultStatuses), - [0x1CF671A0] = typeof(InputStickerSetTonGifts), - [0x2DD14EDC] = typeof(StickerSet), - [0x6E153F16] = typeof(Messages_StickerSet), - [0xD3F924EB] = null,//Messages_StickerSetNotModified + [0xD7DF217A] = typeof(StickerSet), + [0xB60A24A6] = typeof(Messages_StickerSet), [0xC27AC8C7] = typeof(BotCommand), - [0x4D8A0299] = typeof(BotInfo), - [0x7D170CFF] = typeof(KeyboardButton), - [0xD80C25EC] = typeof(KeyboardButtonUrl), - [0xE62BC960] = typeof(KeyboardButtonCallback), - [0x417EFD8F] = typeof(KeyboardButtonRequestPhone), - [0xAA40F94D] = typeof(KeyboardButtonRequestGeoLocation), - [0x991399FC] = typeof(KeyboardButtonSwitchInline), - [0x89C590F9] = typeof(KeyboardButtonGame), - [0x3FA53905] = typeof(KeyboardButtonBuy), - [0xF51006F9] = typeof(KeyboardButtonUrlAuth), - [0x68013E72] = typeof(InputKeyboardButtonUrlAuth), - [0x7A11D782] = typeof(KeyboardButtonRequestPoll), - [0x7D5E07C7] = typeof(InputKeyboardButtonUserProfile), - [0xC0FD5D09] = typeof(KeyboardButtonUserProfile), - [0xE846B1A0] = typeof(KeyboardButtonWebView), - [0xE15C4370] = typeof(KeyboardButtonSimpleWebView), - [0x5B0F15F5] = typeof(KeyboardButtonRequestPeer), - [0x02B78156] = typeof(InputKeyboardButtonRequestPeer), - [0xBCC4AF10] = typeof(KeyboardButtonCopy), + [0x1B74B335] = typeof(BotInfo), + [0xA2FA4880] = typeof(KeyboardButton), + [0x258AFF05] = typeof(KeyboardButtonUrl), + [0x35BBDB6B] = typeof(KeyboardButtonCallback), + [0xB16A6C29] = typeof(KeyboardButtonRequestPhone), + [0xFC796B3F] = typeof(KeyboardButtonRequestGeoLocation), + [0x0568A748] = typeof(KeyboardButtonSwitchInline), + [0x50F41CCF] = typeof(KeyboardButtonGame), + [0xAFD93FBB] = typeof(KeyboardButtonBuy), + [0x10B78D29] = typeof(KeyboardButtonUrlAuth), + [0xD02E7FD4] = typeof(InputKeyboardButtonUrlAuth), + [0xBBC7515D] = typeof(KeyboardButtonRequestPoll), [0x77608B83] = typeof(KeyboardButtonRow), [0xA03E5B85] = typeof(ReplyKeyboardHide), [0x86B40B08] = typeof(ReplyKeyboardForceReply), @@ -640,11 +492,8 @@ namespace TL [0x4C4E743F] = typeof(MessageEntityCashtag), [0x9C4E7E8B] = typeof(MessageEntityUnderline), [0xBF0693D4] = typeof(MessageEntityStrike), + [0x020DF5D0] = typeof(MessageEntityBlockquote), [0x761E6AF4] = typeof(MessageEntityBankCard), - [0x32CA960F] = typeof(MessageEntitySpoiler), - [0xC8CF05F8] = typeof(MessageEntityCustomEmoji), - [0xF1CCAAAC] = typeof(MessageEntityBlockquote), - [0x904AC7C7] = typeof(MessageEntityFormattedDate), [0xEE8C1E86] = null,//InputChannelEmpty [0xF35AEC28] = typeof(InputChannel), [0x5B934F9D] = typeof(InputChannelFromMessage), @@ -655,11 +504,11 @@ namespace TL [0x2064674E] = typeof(Updates_ChannelDifference), [0x94D42EE7] = null,//ChannelMessagesFilterEmpty [0xCD77D957] = typeof(ChannelMessagesFilter), - [0x1BD54456] = typeof(ChannelParticipant), - [0xA9478A1A] = typeof(ChannelParticipantSelf), + [0xC00C07C0] = typeof(ChannelParticipant), + [0x28A8BC67] = typeof(ChannelParticipantSelf), [0x2FE601D3] = typeof(ChannelParticipantCreator), [0x34C3BB53] = typeof(ChannelParticipantAdmin), - [0xD5F0AD91] = typeof(ChannelParticipantBanned), + [0x6DF8014E] = typeof(ChannelParticipantBanned), [0x1B03F006] = typeof(ChannelParticipantLeft), [0xDE3F3C79] = typeof(ChannelParticipantsRecent), [0xB4608969] = typeof(ChannelParticipantsAdmins), @@ -682,7 +531,6 @@ namespace TL [0xA6EDBFFD] = typeof(InputBotInlineMessageMediaContact), [0x4B425864] = typeof(InputBotInlineMessageGame), [0xD7E78225] = typeof(InputBotInlineMessageMediaInvoice), - [0xBDDCC510] = typeof(InputBotInlineMessageMediaWebPage), [0x88BF9319] = typeof(InputBotInlineResult), [0xA8D864A7] = typeof(InputBotInlineResultPhoto), [0xFFF8FDC4] = typeof(InputBotInlineResultDocument), @@ -693,23 +541,15 @@ namespace TL [0x8A86659C] = typeof(BotInlineMessageMediaVenue), [0x18D1CDC2] = typeof(BotInlineMessageMediaContact), [0x354A9B09] = typeof(BotInlineMessageMediaInvoice), - [0x809AD9A6] = typeof(BotInlineMessageMediaWebPage), [0x11965F3A] = typeof(BotInlineResult), [0x17DB940B] = typeof(BotInlineMediaResult), - [0xE021F2F6] = typeof(Messages_BotResults), + [0x947CA848] = typeof(Messages_BotResults), [0x5DAB1AF4] = typeof(ExportedMessageLink), - [0x4E4DF4BB] = typeof(MessageFwdHeader), + [0x5F777DCE] = typeof(MessageFwdHeader), [0x3DBB5986] = typeof(Auth_SentCodeTypeApp), [0xC000BBA2] = typeof(Auth_SentCodeTypeSms), [0x5353E5A7] = typeof(Auth_SentCodeTypeCall), [0xAB03C6D9] = typeof(Auth_SentCodeTypeFlashCall), - [0x82006484] = typeof(Auth_SentCodeTypeMissedCall), - [0xF450F59B] = typeof(Auth_SentCodeTypeEmailCode), - [0xA5491DEA] = typeof(Auth_SentCodeTypeSetUpEmailRequired), - [0xD9565C39] = typeof(Auth_SentCodeTypeFragmentSms), - [0x009FD736] = typeof(Auth_SentCodeTypeFirebaseSms), - [0xA416AC81] = typeof(Auth_SentCodeTypeSmsWord), - [0xB37794AF] = typeof(Auth_SentCodeTypeSmsPhrase), [0x36585EA4] = typeof(Messages_BotCallbackAnswer), [0x26B5DDE6] = typeof(Messages_MessageEditData), [0x890C3D89] = typeof(InputBotInlineMessageID), @@ -722,9 +562,9 @@ namespace TL [0x70B772A8] = typeof(Contacts_TopPeers), [0xB52C939D] = typeof(Contacts_TopPeersDisabled), [0x1B0C841A] = typeof(DraftMessageEmpty), - [0x96EAA5EB] = typeof(DraftMessage), + [0xFD8E711F] = typeof(DraftMessage), [0xC6DC0C66] = typeof(Messages_FeaturedStickersNotModified), - [0xBE382906] = typeof(Messages_FeaturedStickers), + [0x84C02310] = typeof(Messages_FeaturedStickers), [0x0B17F890] = null,//Messages_RecentStickersNotModified [0x88D37C56] = typeof(Messages_RecentStickers), [0x4FCBA9C8] = typeof(Messages_ArchivedStickers), @@ -732,8 +572,6 @@ namespace TL [0x35E410A8] = typeof(Messages_StickerSetInstallResultArchive), [0x6410A5D2] = typeof(StickerSetCovered), [0x3407E51B] = typeof(StickerSetMultiCovered), - [0x40D13C0E] = typeof(StickerSetFullCovered), - [0x77B15D1C] = typeof(StickerSetNoCovered), [0xAED6DBB2] = typeof(MaskCoords), [0x4A992157] = typeof(InputStickeredMediaPhoto), [0x0438865B] = typeof(InputStickeredMediaDocument), @@ -787,14 +625,9 @@ namespace TL [0x76768BED] = typeof(PageBlockDetails), [0x16115A96] = typeof(PageBlockRelatedArticles), [0xA44F3EF6] = typeof(PageBlockMap), - [0x85E42301] = typeof(PhoneCallDiscardReasonMissed), - [0xE095C1A0] = typeof(PhoneCallDiscardReasonDisconnect), - [0x57ADC690] = typeof(PhoneCallDiscardReasonHangup), - [0xFAF7E8C9] = typeof(PhoneCallDiscardReasonBusy), - [0x9FBBF1F7] = typeof(PhoneCallDiscardReasonMigrateConferenceCall), [0x7D748D04] = typeof(DataJSON), [0xCB296BF8] = typeof(LabeledPrice), - [0x049EE584] = typeof(Invoice), + [0x0CD886E0] = typeof(Invoice), [0xEA02C27E] = typeof(PaymentCharge), [0x1E8CAAEB] = typeof(PostAddress), [0x909C3F94] = typeof(PaymentRequestedInfo), @@ -804,16 +637,12 @@ namespace TL [0x9BED434D] = typeof(InputWebDocument), [0xC239D686] = typeof(InputWebFileLocation), [0x9F2221C9] = typeof(InputWebFileGeoPointLocation), - [0xF46FE924] = typeof(InputWebFileAudioAlbumThumbLocation), [0x21E753BC] = typeof(Upload_WebFile), - [0xA0058751] = typeof(Payments_PaymentForm), - [0x7BF6B15C] = typeof(Payments_PaymentFormStars), - [0xB425CFE1] = typeof(Payments_PaymentFormStarGift), + [0x1694761B] = typeof(Payments_PaymentForm), [0xD1451883] = typeof(Payments_ValidatedRequestedInfo), [0x4E5F810D] = typeof(Payments_PaymentResult), [0xD8411139] = typeof(Payments_PaymentVerificationNeeded), [0x70C4FE03] = typeof(Payments_PaymentReceipt), - [0xDABBF83A] = typeof(Payments_PaymentReceiptStars), [0xFB8FE43C] = typeof(Payments_SavedInfo), [0xC10EB2CF] = typeof(InputPaymentCredentialsSaved), [0x3417D728] = typeof(InputPaymentCredentials), @@ -821,15 +650,15 @@ namespace TL [0x8AC32801] = typeof(InputPaymentCredentialsGooglePay), [0xDB64FD34] = typeof(Account_TmpPassword), [0xB6213CDF] = typeof(ShippingOption), - [0x32DA9E9C] = typeof(InputStickerSetItem), + [0xFFA0A496] = typeof(InputStickerSetItem), [0x1E36FDED] = typeof(InputPhoneCall), [0x5366C915] = typeof(PhoneCallEmpty), [0xC5226F17] = typeof(PhoneCallWaiting), [0x14B0ED0C] = typeof(PhoneCallRequested), [0x3660C311] = typeof(PhoneCallAccepted), - [0x30535AF5] = typeof(PhoneCall), + [0x967F7C67] = typeof(PhoneCall), [0x50CA4DE1] = typeof(PhoneCallDiscarded), - [0x9CC123C7] = typeof(PhoneConnection), + [0x9D4C17C0] = typeof(PhoneConnection), [0x635FE375] = typeof(PhoneConnectionWebrtc), [0xFC878FC8] = typeof(PhoneCallProtocol), [0xEC82E140] = typeof(Phone_PhoneCall), @@ -868,32 +697,13 @@ namespace TL [0xF92424D2] = typeof(ChannelAdminLogEventActionParticipantMute), [0xE64429C0] = typeof(ChannelAdminLogEventActionParticipantUnmute), [0x56D6A247] = typeof(ChannelAdminLogEventActionToggleGroupCallSetting), - [0xFE9FC158] = typeof(ChannelAdminLogEventActionParticipantJoinByInvite), + [0x5CDADA77] = typeof(ChannelAdminLogEventActionParticipantJoinByInvite), [0x5A50FCA4] = typeof(ChannelAdminLogEventActionExportedInviteDelete), [0x410A134E] = typeof(ChannelAdminLogEventActionExportedInviteRevoke), [0xE90EBB59] = typeof(ChannelAdminLogEventActionExportedInviteEdit), [0x3E7F6847] = typeof(ChannelAdminLogEventActionParticipantVolume), [0x6E941A38] = typeof(ChannelAdminLogEventActionChangeHistoryTTL), - [0xAFB6144A] = typeof(ChannelAdminLogEventActionParticipantJoinByRequest), - [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), - [0x64F36DFC] = typeof(ChannelAdminLogEventActionToggleAntiSpam), - [0x5796E780] = typeof(ChannelAdminLogEventActionChangePeerColor), - [0x5E477B25] = typeof(ChannelAdminLogEventActionChangeProfilePeerColor), - [0x31BB5D52] = typeof(ChannelAdminLogEventActionChangeWallpaper), - [0x3EA9FEB1] = typeof(ChannelAdminLogEventActionChangeEmojiStatus), - [0x46D840AB] = typeof(ChannelAdminLogEventActionChangeEmojiStickerSet), - [0x60A79C79] = typeof(ChannelAdminLogEventActionToggleSignatureProfiles), - [0x64642DB3] = typeof(ChannelAdminLogEventActionParticipantSubExtend), - [0xC517F77E] = typeof(ChannelAdminLogEventActionToggleAutotranslation), - [0x5806B4EC] = typeof(ChannelAdminLogEventActionParticipantEditRank), + [0xFE69018D] = typeof(ChannelAdminLogEventActionChangeTheme), [0x1FAD68CD] = typeof(ChannelAdminLogEvent), [0xED8AF74D] = typeof(Channels_AdminLogResults), [0xEA107AE4] = typeof(ChannelAdminLogEventsFilter), @@ -919,14 +729,14 @@ namespace TL [0x514519E2] = typeof(DialogPeerFolder), [0x0D54B65D] = null,//Messages_FoundStickerSetsNotModified [0x8AF09DD2] = typeof(Messages_FoundStickerSets), - [0xF39B035C] = typeof(FileHash), + [0x6242C773] = typeof(FileHash), [0x75588B3F] = typeof(InputClientProxy), [0xE3309F7F] = typeof(Help_TermsOfServiceUpdateEmpty), [0x28ECF961] = typeof(Help_TermsOfServiceUpdate), [0x3334B0F0] = typeof(InputSecureFileUploaded), [0x5367E5BE] = typeof(InputSecureFile), [0x64199744] = null,//SecureFileEmpty - [0x7D09C27E] = typeof(SecureFile), + [0xE0277A62] = typeof(SecureFile), [0x8AEABEC3] = typeof(SecureData), [0x7D6099DD] = typeof(SecurePlainPhone), [0x21EC5A5F] = typeof(SecurePlainEmail), @@ -981,10 +791,10 @@ namespace TL [0x8C05F1C9] = typeof(Help_SupportName), [0xF3AE2EED] = null,//Help_UserInfoEmpty [0x01EB3758] = typeof(Help_UserInfo), - [0xFF16E2CA] = typeof(PollAnswer), - [0x58747131] = typeof(Poll), + [0x6CA9C2E9] = typeof(PollAnswer), + [0x86E18161] = typeof(Poll), [0x3B6DDAD2] = typeof(PollAnswerVoters), - [0x7ADF2420] = typeof(PollResults), + [0xDCB82EA3] = typeof(PollResults), [0xF041E250] = typeof(ChatOnlines), [0x47A971E0] = typeof(StatsURL), [0x5FB224D5] = typeof(ChatAdminRights), @@ -994,9 +804,9 @@ namespace TL [0x967A462E] = typeof(InputWallPaperNoFile), [0x1C199183] = null,//Account_WallPapersNotModified [0xCDC3858C] = typeof(Account_WallPapers), - [0xAD253D78] = typeof(CodeSettings), - [0x372EFCD0] = typeof(WallPaperSettings), - [0xBAA57628] = typeof(AutoDownloadSettings), + [0xDEBEBE83] = typeof(CodeSettings), + [0x1DC1BCA4] = typeof(WallPaperSettings), + [0xE04232F3] = typeof(AutoDownloadSettings), [0x63CACF26] = typeof(Account_AutoDownloadSettings), [0xD5B3B9F9] = typeof(EmojiKeyword), [0x236DF622] = typeof(EmojiKeywordDeleted), @@ -1007,9 +817,9 @@ namespace TL [0xFBD2C296] = typeof(InputFolderPeer), [0xE9BAA668] = typeof(FolderPeer), [0xE844EBFF] = typeof(Messages_SearchCounter), - [0xF8F8EB1E] = typeof(UrlAuthResultRequest), - [0x623A8FA0] = typeof(UrlAuthResultAccepted), - [0xA9D6DB1F] = null,//UrlAuthResultDefault + [0x92D33A0E] = typeof(UrlAuthResultRequest), + [0x8F8C0E4E] = typeof(UrlAuthResultAccepted), + [0xA9D6DB1F] = typeof(UrlAuthResultDefault), [0xBFB5AD8B] = null,//ChannelLocationEmpty [0x209B82DB] = typeof(ChannelLocation), [0xCA461B5D] = typeof(PeerLocated), @@ -1017,7 +827,7 @@ namespace TL [0xD072ACB4] = typeof(RestrictionReason), [0x3C5693E9] = typeof(InputTheme), [0xF5890DF1] = typeof(InputThemeSlug), - [0xA00E67D6] = typeof(Theme), + [0xE802B8DC] = typeof(Theme), [0xF41EB622] = null,//Account_ThemesNotModified [0x9A3D8C6D] = typeof(Account_Themes), [0x629F1980] = typeof(Auth_LoginToken), @@ -1028,17 +838,13 @@ namespace TL [0x8FDE504F] = typeof(InputThemeSettings), [0xFA58B6D4] = typeof(ThemeSettings), [0x54B56617] = typeof(WebPageAttributeTheme), - [0x2E94C3E7] = typeof(WebPageAttributeStory), - [0x50CC03D3] = typeof(WebPageAttributeStickerSet), - [0xCF6F6DB8] = typeof(WebPageAttributeUniqueStarGift), - [0x31CAD303] = typeof(WebPageAttributeStarGiftCollection), - [0x01C641C2] = typeof(WebPageAttributeStarGiftAuction), - [0x4899484E] = typeof(Messages_VotesList), + [0x34D247B4] = typeof(MessageUserVote), + [0x3CA5B0EC] = typeof(MessageUserVoteInputOption), + [0x8A65E557] = typeof(MessageUserVoteMultiple), + [0x0823F649] = typeof(Messages_VotesList), [0xF568028A] = typeof(BankCardOpenUrl), [0x3E24E573] = typeof(Payments_BankCardData), - [0xAA472651] = typeof(DialogFilter), - [0x363293AE] = null,//DialogFilterDefault - [0x96537BD7] = typeof(DialogFilterChatlist), + [0x7438F7E8] = typeof(DialogFilter), [0x77744D4A] = typeof(DialogFilterSuggested), [0xB637EDAF] = typeof(StatsDateRangeDays), [0xCB43ACDE] = typeof(StatsAbsValueAndPrev), @@ -1046,17 +852,16 @@ namespace TL [0x4A27EB2D] = typeof(StatsGraphAsync), [0xBEDC9822] = typeof(StatsGraphError), [0x8EA464B6] = typeof(StatsGraph), - [0x396CA5FC] = typeof(Stats_BroadcastStats), + [0xAD4FC9BD] = typeof(MessageInteractionCounters), + [0xBDF78394] = typeof(Stats_BroadcastStats), [0x98F6AC75] = typeof(Help_PromoDataEmpty), - [0x08A4D87A] = typeof(Help_PromoData), + [0x8C39793F] = typeof(Help_PromoData), [0xDE33B094] = typeof(VideoSize), - [0xF85C413C] = typeof(VideoSizeEmojiMarkup), - [0x0DA082FE] = typeof(VideoSizeStickerMarkup), [0x9D04AF9B] = typeof(StatsGroupTopPoster), [0xD7584C87] = typeof(StatsGroupTopAdmin), [0x535F779D] = typeof(StatsGroupTopInviter), [0xEF7FF916] = typeof(Stats_MegagroupStats), - [0xFE41B34F] = typeof(GlobalPrivacySettings), + [0xBEA2F424] = typeof(GlobalPrivacySettings), [0x4203C5EF] = typeof(Help_CountryCode), [0xC3878E23] = typeof(Help_Country), [0x93CC1F32] = null,//Help_CountriesListNotModified @@ -1064,23 +869,20 @@ namespace TL [0x455B853D] = typeof(MessageViews), [0xB6C4F543] = typeof(Messages_MessageViews), [0xA6341782] = typeof(Messages_DiscussionMessage), - [0x6917560B] = typeof(MessageReplyHeader), - [0x0E5AF939] = typeof(MessageReplyStoryHeader), + [0xA6D57763] = typeof(MessageReplyHeader), [0x83D60FC2] = typeof(MessageReplies), [0xE8FD8014] = typeof(PeerBlocked), - [0x7FE91C14] = typeof(Stats_MessageStats), + [0x8999F295] = typeof(Stats_MessageStats), [0x7780BCB4] = typeof(GroupCallDiscarded), - [0xEFB2B617] = typeof(GroupCall), + [0xD597650C] = typeof(GroupCall), [0xD8AA840F] = typeof(InputGroupCall), - [0xFE06823F] = typeof(InputGroupCallSlug), - [0x8C10603F] = typeof(InputGroupCallInviteMessage), - [0x2A3DC7AC] = typeof(GroupCallParticipant), + [0xEBA636FE] = typeof(GroupCallParticipant), [0x9E727AAD] = typeof(Phone_GroupCall), [0xF47751B6] = typeof(Phone_GroupParticipants), [0x1662AF0B] = typeof(Messages_HistoryImport), [0x5E0FB7B9] = typeof(Messages_HistoryImportParsed), [0xEF8D3E6C] = typeof(Messages_AffectedFoundMessages), - [0x8C5ADFD9] = typeof(ChatInviteImporter), + [0x0B5CD5F4] = typeof(ChatInviteImporter), [0xBDC62DCC] = typeof(Messages_ExportedChatInvites), [0x1871BE50] = typeof(Messages_ExportedChatInvite), [0x222600EF] = typeof(Messages_ExportedChatInviteReplaced), @@ -1093,7 +895,7 @@ namespace TL [0xDCB118B7] = typeof(GroupCallParticipantVideoSourceGroup), [0x67753AC8] = typeof(GroupCallParticipantVideo), [0x85FEA03F] = typeof(Stickers_SuggestedShortName), - [0x2F6CB2AB] = null,//BotCommandScopeDefault + [0x2F6CB2AB] = typeof(BotCommandScopeDefault), [0x3C4F04D8] = typeof(BotCommandScopeUsers), [0x6FE1A881] = typeof(BotCommandScopeChats), [0xB9AA606A] = typeof(BotCommandScopeChatAdmins), @@ -1103,471 +905,63 @@ namespace TL [0xE3779861] = typeof(Account_ResetPasswordFailedWait), [0xE9EFFC7D] = typeof(Account_ResetPasswordRequestedWait), [0xE926D63E] = typeof(Account_ResetPasswordOk), - [0xC3DFFC04] = typeof(ChatTheme), - [0x3458F9C8] = typeof(ChatThemeUniqueGift), + [0xED0B5C33] = typeof(ChatTheme), [0xE011E1C4] = null,//Account_ChatThemesNotModified - [0xBE098173] = typeof(Account_ChatThemes), - [0x7DBF8673] = typeof(SponsoredMessage), - [0xFFDA656D] = typeof(Messages_SponsoredMessages), - [0x1839490F] = null,//Messages_SponsoredMessagesEmpty - [0xC9B0539F] = typeof(SearchResultsCalendarPeriod), - [0x147EE23C] = typeof(Messages_SearchResultsCalendar), - [0x7F648B67] = typeof(SearchResultPosition), - [0x53B22BAF] = typeof(Messages_SearchResultsPositions), - [0xF496B0C6] = typeof(Channels_SendAsPeers), - [0x3B6D152E] = typeof(Users_UserFull), - [0x6880B94D] = typeof(Messages_PeerSettings), - [0xC3A2835F] = typeof(Auth_LoggedOut), - [0xA3D1CB80] = typeof(ReactionCount), - [0x0A339F0B] = typeof(MessageReactions), - [0x31BD492D] = typeof(Messages_MessageReactionsList), - [0xC077EC01] = typeof(AvailableReaction), - [0x9F071957] = null,//Messages_AvailableReactionsNotModified - [0x768E3AAD] = typeof(Messages_AvailableReactions), - [0x8C79B63C] = typeof(MessagePeerReaction), - [0x80EB48AF] = typeof(GroupCallStreamChannel), - [0xD0E482B2] = typeof(Phone_GroupCallStreamChannels), - [0x2DBF3432] = typeof(Phone_GroupCallStreamRtmpUrl), - [0x4576F3F0] = typeof(AttachMenuBotIconColor), - [0xB2A7386B] = typeof(AttachMenuBotIcon), - [0xD90D8DFE] = typeof(AttachMenuBot), - [0xF1D88A5C] = null,//AttachMenuBotsNotModified - [0x3C4301C0] = typeof(AttachMenuBots), - [0x93BF667F] = typeof(AttachMenuBotsBot), - [0x4D22FF98] = typeof(WebViewResultUrl), - [0x0C94511C] = typeof(WebViewMessageSent), - [0x7533A588] = null,//BotMenuButtonDefault - [0x4258C205] = typeof(BotMenuButtonCommands), - [0xC7B57CE6] = typeof(BotMenuButton), - [0xFBF6E8B1] = null,//Account_SavedRingtonesNotModified - [0xC1E92CC5] = typeof(Account_SavedRingtones), - [0x97E8BEBE] = null,//NotificationSoundDefault - [0x6F0C34DF] = typeof(NotificationSoundNone), - [0x830B9AE4] = typeof(NotificationSoundLocal), - [0xFF6C8049] = typeof(NotificationSoundRingtone), - [0xB7263F6D] = typeof(Account_SavedRingtone), - [0x1F307EB7] = typeof(Account_SavedRingtoneConverted), - [0xC5B56859] = typeof(InputInvoiceMessage), - [0xC326CAEF] = typeof(InputInvoiceSlug), - [0x98986C0D] = typeof(InputInvoicePremiumGiftCode), - [0x65F00CE3] = typeof(InputInvoiceStars), - [0x34E793F1] = typeof(InputInvoiceChatInviteSubscription), - [0xE8625E92] = typeof(InputInvoiceStarGift), - [0x4D818D5D] = typeof(InputInvoiceStarGiftUpgrade), - [0x4A5F5BD9] = typeof(InputInvoiceStarGiftTransfer), - [0xDABAB2EF] = typeof(InputInvoicePremiumGiftStars), - [0xF4997E42] = typeof(InputInvoiceBusinessBotTransferStars), - [0xC39F5324] = typeof(InputInvoiceStarGiftResale), - [0x9A0B48B8] = typeof(InputInvoiceStarGiftPrepaidUpgrade), - [0x3E77F614] = typeof(InputInvoicePremiumAuthCode), - [0x0923D8D1] = typeof(InputInvoiceStarGiftDropOriginalDetails), - [0x1ECAFA10] = typeof(InputInvoiceStarGiftAuctionBid), - [0xAED0CBD9] = typeof(Payments_ExportedInvoice), - [0xCFB9D957] = typeof(Messages_TranscribedAudio), - [0x5334759C] = typeof(Help_PremiumPromo), - [0xA6751E66] = typeof(InputStorePaymentPremiumSubscription), - [0x616F7FE8] = typeof(InputStorePaymentGiftPremium), - [0xFB790393] = typeof(InputStorePaymentPremiumGiftCode), - [0x160544CA] = typeof(InputStorePaymentPremiumGiveaway), - [0xF9A2A6CB] = typeof(InputStorePaymentStarsTopup), - [0x1D741EF7] = typeof(InputStorePaymentStarsGift), - [0x751F08FA] = typeof(InputStorePaymentStarsGiveaway), - [0x9BB2636D] = typeof(InputStorePaymentAuthCode), - [0x88F8F21B] = typeof(PaymentFormMethod), - [0x2DE11AAE] = null,//EmojiStatusEmpty - [0xE7FF068A] = typeof(EmojiStatus), - [0x7184603B] = typeof(EmojiStatusCollectible), - [0x07141DBF] = typeof(InputEmojiStatusCollectible), - [0xD08CE645] = null,//Account_EmojiStatusesNotModified - [0x90C467D1] = typeof(Account_EmojiStatuses), - [0x79F5D419] = null,//ReactionEmpty - [0x1B2286B8] = typeof(ReactionEmoji), - [0x8935FC73] = typeof(ReactionCustomEmoji), - [0x523DA4EB] = typeof(ReactionPaid), - [0xEAFC32BC] = null,//ChatReactionsNone - [0x52928BCA] = typeof(ChatReactionsAll), - [0x661D4037] = typeof(ChatReactionsSome), - [0xB06FDBDF] = null,//Messages_ReactionsNotModified - [0xEAFDF716] = typeof(Messages_Reactions), - [0x4345BE73] = typeof(EmailVerifyPurposeLoginSetup), - [0x527D22EB] = typeof(EmailVerifyPurposeLoginChange), - [0xBBF51685] = typeof(EmailVerifyPurposePassport), - [0x922E55A9] = typeof(EmailVerificationCode), - [0xDB909EC2] = typeof(EmailVerificationGoogle), - [0x96D074FD] = typeof(EmailVerificationApple), - [0x2B96CD1B] = typeof(Account_EmailVerified), - [0xE1BB0D61] = typeof(Account_EmailVerifiedLogin), - [0x5F2D1DF2] = typeof(PremiumSubscriptionOption), - [0xB81C7034] = typeof(SendAsPeer), - [0xAD628CC8] = typeof(MessageExtendedMediaPreview), - [0xEE479C64] = typeof(MessageExtendedMedia), - [0xFCFEB29C] = typeof(StickerKeyword), - [0xB4073647] = typeof(Username), - [0x023F109B] = typeof(ForumTopicDeleted), - [0xCDFF0ECA] = typeof(ForumTopic), - [0x367617D3] = typeof(Messages_ForumTopics), - [0x43B46B20] = typeof(DefaultHistoryTTL), - [0x41BF109B] = typeof(ExportedContactToken), - [0x5F3B8A00] = typeof(RequestPeerTypeUser), - [0xC9F06E1B] = typeof(RequestPeerTypeChat), - [0x339BEF6C] = typeof(RequestPeerTypeBroadcast), - [0x481EADFA] = null,//EmojiListNotModified - [0x7A1E11D1] = typeof(EmojiList), - [0x7A9ABDA9] = typeof(EmojiGroup), - [0x80D26CC7] = typeof(EmojiGroupGreeting), - [0x093BCF34] = typeof(EmojiGroupPremium), - [0x6FB4AD87] = null,//Messages_EmojiGroupsNotModified - [0x881FB94B] = typeof(Messages_EmojiGroups), - [0x751F3146] = typeof(TextWithEntities), - [0x33DB32F8] = typeof(Messages_TranslateResult), - [0xC84834CE] = typeof(AutoSaveSettings), - [0x81602D47] = typeof(AutoSaveException), - [0x4C3E069D] = typeof(Account_AutoSaveSettings), - [0x7CDE641D] = null,//Help_AppConfigNotModified - [0xDD18782E] = typeof(Help_AppConfig), - [0xA920BD7A] = typeof(InputBotAppID), - [0x908C0407] = typeof(InputBotAppShortName), - [0x5DA674B7] = null,//BotAppNotModified - [0x95FCD1D6] = typeof(BotApp), - [0xEB50ADF5] = typeof(Messages_BotApp), - [0xB57295D5] = typeof(InlineBotWebView), - [0x4A4FF172] = typeof(ReadParticipantDate), - [0xF3E0DA33] = typeof(InputChatlistDialogFilter), - [0x0C5181AC] = typeof(ExportedChatlistInvite), - [0x10E6E3A6] = typeof(Chatlists_ExportedChatlistInvite), - [0x10AB6DC7] = typeof(Chatlists_ExportedInvites), - [0xFA87F659] = typeof(Chatlists_ChatlistInviteAlready), - [0xF10ECE2F] = typeof(Chatlists_ChatlistInvite), - [0x93BD878D] = typeof(Chatlists_ChatlistUpdates), - [0xE8A775B0] = typeof(Bots_BotInfo), - [0xB6CC2D5C] = typeof(MessagePeerVote), - [0x74CDA504] = typeof(MessagePeerVoteInputOption), - [0x4628F6E6] = typeof(MessagePeerVoteMultiple), - [0x8D595CD6] = typeof(StoryViews), - [0x51E6EE4F] = typeof(StoryItemDeleted), - [0xFFADC913] = typeof(StoryItemSkipped), - [0xEDF164F1] = typeof(StoryItem), - [0x1158FE3E] = typeof(Stories_AllStoriesNotModified), - [0x6EFC5E81] = typeof(Stories_AllStories), - [0x63C3DD0A] = typeof(Stories_Stories), - [0xB0BDEAC5] = typeof(StoryView), - [0x9083670B] = typeof(StoryViewPublicForward), - [0xBD74CF49] = typeof(StoryViewPublicRepost), - [0x59D78FC5] = typeof(Stories_StoryViewsList), - [0xDE9EED1D] = typeof(Stories_StoryViews), - [0x869FBE10] = typeof(InputReplyToMessage), - [0x5881323A] = typeof(InputReplyToStory), - [0x69D66C45] = typeof(InputReplyToMonoForum), - [0x3FC9053B] = typeof(ExportedStoryLink), - [0x712E27FD] = typeof(StoriesStealthMode), - [0xCFC9E002] = typeof(MediaAreaCoordinates), - [0xBE82DB9C] = typeof(MediaAreaVenue), - [0xB282217F] = typeof(InputMediaAreaVenue), - [0xCAD5452D] = typeof(MediaAreaGeoPoint), - [0x14455871] = typeof(MediaAreaSuggestedReaction), - [0x770416AF] = typeof(MediaAreaChannelPost), - [0x2271F2BF] = typeof(InputMediaAreaChannelPost), - [0x37381085] = typeof(MediaAreaUrl), - [0x49A6549C] = typeof(MediaAreaWeather), - [0x5787686D] = typeof(MediaAreaStarGift), - [0x9A35E999] = typeof(PeerStories), - [0xCAE68768] = typeof(Stories_PeerStories), - [0xFD5E12BD] = typeof(Messages_WebPage), - [0x257E962B] = typeof(PremiumGiftCodeOption), - [0xEB983F8F] = typeof(Payments_CheckedGiftCode), - [0x4367DAA0] = typeof(Payments_GiveawayInfo), - [0xE175E66F] = typeof(Payments_GiveawayInfoResults), - [0xB2539D54] = typeof(PrepaidGiveaway), - [0x9A9D77E0] = typeof(PrepaidStarsGiveaway), - [0x4B3E14D6] = typeof(Boost), - [0x86F8613C] = typeof(Premium_BoostsList), - [0xC448415C] = typeof(MyBoost), - [0x9AE228E2] = typeof(Premium_MyBoosts), - [0x4959427A] = typeof(Premium_BoostsStatus), - [0xB826E150] = typeof(StoryFwdHeader), - [0xE7058E7F] = typeof(PostInteractionCountersMessage), - [0x8A480E27] = typeof(PostInteractionCountersStory), - [0x50CD067C] = typeof(Stats_StoryStats), - [0x01F2BF4A] = typeof(PublicForwardMessage), - [0xEDF3ADD0] = typeof(PublicForwardStory), - [0x93037E20] = typeof(Stats_PublicForwards), - [0xB54B5ACF] = typeof(PeerColor), - [0xB9C0639A] = typeof(PeerColorCollectible), - [0xB8EA86A9] = typeof(InputPeerColorCollectible), - [0x26219A58] = typeof(Help_PeerColorSet), - [0x767D61EB] = typeof(Help_PeerColorProfileSet), - [0xADEC6EBE] = typeof(Help_PeerColorOption), - [0x2BA1F5CE] = null,//Help_PeerColorsNotModified - [0x00F8ED08] = typeof(Help_PeerColors), - [0x6090D6D5] = typeof(StoryReaction), - [0xBBAB2643] = typeof(StoryReactionPublicForward), - [0xCFCD0F13] = typeof(StoryReactionPublicRepost), - [0xAA5F789C] = typeof(Stories_StoryReactionsList), - [0xBD87CB6C] = typeof(SavedDialog), - [0x64407EA7] = typeof(MonoForumDialog), - [0xF83AE221] = typeof(Messages_SavedDialogs), - [0x44BA9DD9] = typeof(Messages_SavedDialogsSlice), - [0xC01F6FE8] = typeof(Messages_SavedDialogsNotModified), - [0xCB6FF828] = typeof(SavedReactionTag), - [0x889B59EF] = null,//Messages_SavedReactionTagsNotModified - [0x3259950A] = typeof(Messages_SavedReactionTags), - [0x3BB842AC] = typeof(OutboxReadDate), - [0xDC8B44CF] = typeof(Smsjobs_EligibleToJoin), - [0x2AEE9191] = typeof(Smsjobs_Status), - [0xE6A1EEB8] = typeof(SmsJob), - [0x120B1AB9] = typeof(BusinessWeeklyOpen), - [0x8C92B098] = typeof(BusinessWorkHours), - [0xAC5C1AF7] = typeof(BusinessLocation), - [0x6F8B32AA] = typeof(InputBusinessRecipients), - [0x21108FF7] = typeof(BusinessRecipients), - [0xC9B9E2B9] = typeof(BusinessAwayMessageScheduleAlways), - [0xC3F2F501] = typeof(BusinessAwayMessageScheduleOutsideWorkHours), - [0xCC4D9ECC] = typeof(BusinessAwayMessageScheduleCustom), - [0x0194CB3B] = typeof(InputBusinessGreetingMessage), - [0xE519ABAB] = typeof(BusinessGreetingMessage), - [0x832175E0] = typeof(InputBusinessAwayMessage), - [0xEF156A5C] = typeof(BusinessAwayMessage), - [0xFF9289F5] = typeof(Timezone), - [0x970708CC] = null,//Help_TimezonesListNotModified - [0x7B74ED71] = typeof(Help_TimezonesList), - [0x0697102B] = typeof(QuickReply), - [0x24596D41] = typeof(InputQuickReplyShortcut), - [0x01190CF1] = typeof(InputQuickReplyShortcutId), - [0xC68D6695] = typeof(Messages_QuickReplies), - [0x5F91EB5B] = null,//Messages_QuickRepliesNotModified - [0xCD64636C] = typeof(ConnectedBot), - [0x17D7F87B] = typeof(Account_ConnectedBots), - [0x2AD93719] = typeof(Messages_DialogFilters), - [0x6C8E1E06] = typeof(Birthday), - [0x8F34B2F5] = typeof(BotBusinessConnection), - [0x09C469CD] = typeof(InputBusinessIntro), - [0x5A0A066D] = typeof(BusinessIntro), - [0xFAFF629D] = typeof(Messages_MyStickers), - [0xE39460A9] = typeof(InputCollectibleUsername), - [0xA2E214A4] = typeof(InputCollectiblePhone), - [0x6EBDFF91] = typeof(Fragment_CollectibleInfo), - [0xC4E5921E] = typeof(InputBusinessBotRecipients), - [0xB88CF373] = typeof(BusinessBotRecipients), - [0x1D998733] = typeof(ContactBirthday), - [0x114FF30D] = typeof(Contacts_ContactBirthdays), - [0x628C9224] = typeof(MissingInvitee), - [0x7F5DEFA6] = typeof(Messages_InvitedUsers), - [0x11679FA7] = typeof(InputBusinessChatLink), - [0xB4AE666F] = typeof(BusinessChatLink), - [0xEC43A2D1] = typeof(Account_BusinessChatLinks), - [0x9A23AF21] = typeof(Account_ResolvedBusinessChatLinks), - [0xD62FF46A] = typeof(RequestedPeerUser), - [0x7307544F] = typeof(RequestedPeerChat), - [0x8BA403E4] = typeof(RequestedPeerChannel), - [0x430D3150] = typeof(SponsoredMessageReportOption), - [0x846F9E42] = typeof(Channels_SponsoredMessageReportResultChooseOption), - [0x3E3BCF2F] = typeof(Channels_SponsoredMessageReportResultAdsHidden), - [0xAD798849] = typeof(Channels_SponsoredMessageReportResultReported), - [0x56E34970] = typeof(ReactionsNotifySettings), - [0x93C3E27E] = typeof(AvailableEffect), - [0xD1ED9A5B] = null,//Messages_AvailableEffectsNotModified - [0xBDDB616E] = typeof(Messages_AvailableEffects), - [0xB89BFCCF] = typeof(FactCheck), - [0x95F2BFE4] = typeof(StarsTransactionPeerUnsupported), - [0xB457B375] = typeof(StarsTransactionPeerAppStore), - [0x7B560A0B] = typeof(StarsTransactionPeerPlayMarket), - [0x250DBAF8] = typeof(StarsTransactionPeerPremiumBot), - [0xE92FD902] = typeof(StarsTransactionPeerFragment), - [0xD80DA15D] = typeof(StarsTransactionPeer), - [0x60682812] = typeof(StarsTransactionPeerAds), - [0xF9677AAD] = typeof(StarsTransactionPeerAPI), - [0x0BD915C0] = typeof(StarsTopupOption), - [0x13659EB0] = typeof(StarsTransaction), - [0x6C9CE8ED] = typeof(Payments_StarsStatus), - [0xE87ACBC0] = typeof(FoundStory), - [0xE2DE7737] = typeof(Stories_FoundStories), - [0xDE4C5D93] = typeof(GeoPointAddress), - [0xFEBE5491] = typeof(StarsRevenueStatus), - [0x6C207376] = typeof(Payments_StarsRevenueStats), - [0x1DAB80B7] = typeof(Payments_StarsRevenueWithdrawalUrl), - [0x394E7F21] = typeof(Payments_StarsRevenueAdsAccountUrl), - [0x206AE6D1] = typeof(InputStarsTransaction), - [0x5E0589F1] = typeof(StarsGiftOption), - [0x1991B13B] = typeof(Bots_PopularAppBots), - [0x23E91BA3] = typeof(BotPreviewMedia), - [0x0CA71D64] = typeof(Bots_PreviewInfo), - [0x05416D58] = typeof(StarsSubscriptionPricing), - [0x2E6EAB1A] = typeof(StarsSubscription), - [0x4BA3A95A] = typeof(MessageReactor), - [0x94CE852A] = typeof(StarsGiveawayOption), - [0x54236209] = typeof(StarsGiveawayWinnersOption), - [0x313A9547] = typeof(StarGift), - [0x85F0A9CD] = typeof(StarGiftUnique), - [0xA388A368] = null,//Payments_StarGiftsNotModified - [0x2ED82995] = typeof(Payments_StarGifts), - [0x7903E3D9] = typeof(MessageReportOption), - [0xF0E4E0B6] = typeof(ReportResultChooseOption), - [0x6F09AC31] = typeof(ReportResultAddComment), - [0x8DB33C4B] = typeof(ReportResultReported), - [0x8ECF0511] = typeof(Messages_BotPreparedInlineMessage), - [0xFF57708D] = typeof(Messages_PreparedInlineMessage), - [0xC99B1950] = typeof(BotAppSettings), - [0xDD0C66F2] = typeof(StarRefProgram), - [0x19A13F71] = typeof(ConnectedBotStarRef), - [0x98D5EA1D] = typeof(Payments_ConnectedStarRefBots), - [0xB4D5D859] = typeof(Payments_SuggestedStarRefBots), - [0xBBB6B4A3] = typeof(StarsAmount), - [0x74AEE3E0] = typeof(StarsTonAmount), - [0x6010C534] = typeof(Messages_FoundStickersNotModified), - [0x82C9E290] = typeof(Messages_FoundStickers), - [0xB0CD6617] = typeof(BotVerifierSettings), - [0xF93CD45C] = typeof(BotVerification), - [0x565251E2] = typeof(StarGiftAttributeModel), - [0x4E7085EA] = typeof(StarGiftAttributePattern), - [0x9F2504E4] = typeof(StarGiftAttributeBackdrop), - [0xE0BFF26C] = typeof(StarGiftAttributeOriginalDetails), - [0x3DE1DFED] = typeof(Payments_StarGiftUpgradePreview), - [0x62D706B8] = typeof(Users_Users), - [0x315A4974] = typeof(Users_UsersSlice), - [0x416C56E8] = typeof(Payments_UniqueStarGift), - [0x8C9A88AC] = typeof(Messages_WebPagePreview), - [0x41DF43FC] = typeof(SavedStarGift), - [0x95F389B1] = typeof(Payments_SavedStarGifts), - [0x69279795] = typeof(InputSavedStarGiftUser), - [0xF101AA7F] = typeof(InputSavedStarGiftChat), - [0x2085C238] = typeof(InputSavedStarGiftSlug), - [0x84AA3A9C] = typeof(Payments_StarGiftWithdrawalUrl), - [0x206AD49E] = null,//PaidReactionPrivacyDefault - [0x1F0C1AD9] = typeof(PaidReactionPrivacyAnonymous), - [0xDC6CFCF0] = typeof(PaidReactionPrivacyPeer), - [0x1E109708] = typeof(Account_PaidMessagesRevenue), - [0x050A9839] = null,//RequirementToContactEmpty - [0xE581E4E9] = typeof(RequirementToContactPremium), - [0xB4F67E93] = typeof(RequirementToContactPaidMessages), - [0xA0624CF7] = typeof(BusinessBotRights), - [0x71F276C4] = typeof(DisallowedGiftsSettings), - [0xC69708D3] = typeof(SponsoredPeer), - [0xEA32B4B1] = null,//Contacts_SponsoredPeersEmpty - [0xEB032884] = typeof(Contacts_SponsoredPeers), - [0x48AAAE3C] = typeof(StarGiftAttributeIdModel), - [0x4A162433] = typeof(StarGiftAttributeIdPattern), - [0x1F01C757] = typeof(StarGiftAttributeIdBackdrop), - [0x2EB1B658] = typeof(StarGiftAttributeCounter), - [0x947A12DF] = typeof(Payments_ResaleStarGifts), - [0xC387C04E] = typeof(Stories_CanSendStoryCount), - [0xE7E82E12] = typeof(PendingSuggestion), - [0xCBA9A52F] = typeof(TodoItem), - [0x49B92A26] = typeof(TodoList), - [0x221BB5E4] = typeof(TodoCompletion), - [0x0E8E37E5] = typeof(SuggestedPost), - [0x1B0E4F07] = typeof(StarsRating), - [0x9D6B13B0] = typeof(StarGiftCollection), - [0xA0BA4F17] = null,//Payments_StarGiftCollectionsNotModified - [0x8A2932F3] = typeof(Payments_StarGiftCollections), - [0x9325705A] = typeof(StoryAlbum), - [0x564EDAEB] = null,//Stories_AlbumsNotModified - [0xC3987A3A] = typeof(Stories_Albums), - [0x3E0B5B6A] = typeof(SearchPostsFlood), - [0x512FE446] = typeof(Payments_UniqueStarGiftValueInfo), - [0xE3878AA4] = typeof(Users_SavedMusicNotModified), - [0x34A2F297] = typeof(Users_SavedMusic), - [0x4FC81D6E] = null,//Account_SavedMusicIdsNotModified - [0x998D6636] = typeof(Account_SavedMusicIds), - [0x374FA7AD] = typeof(Payments_CheckCanSendGiftResultOk), - [0xD5E58274] = typeof(Payments_CheckCanSendGiftResultFail), - [0x83268483] = null,//InputChatThemeEmpty - [0xC93DE95C] = typeof(InputChatTheme), - [0x87E5DFE4] = typeof(InputChatThemeUniqueGift), - [0x99EA331D] = typeof(StarGiftUpgradePrice), - [0x1A8AFC7E] = typeof(GroupCallMessage), - [0xEE430C85] = typeof(GroupCallDonor), - [0x9D1DBD26] = typeof(Phone_GroupCallStars), - [0x711D692D] = typeof(RecentStory), - [0x310240CC] = typeof(AuctionBidLevel), - [0xFE333952] = null,//StarGiftAuctionStateNotModified - [0x771A4E66] = typeof(StarGiftAuctionState), - [0x972DABBF] = typeof(StarGiftAuctionStateFinished), - [0x2EEED1C4] = typeof(StarGiftAuctionUserState), - [0x6B39F4EC] = typeof(Payments_StarGiftAuctionState), - [0x42B00348] = typeof(StarGiftAuctionAcquiredGift), - [0x7D5BD1F0] = typeof(Payments_StarGiftAuctionAcquiredGifts), - [0xD31BC45D] = typeof(StarGiftActiveAuctionState), - [0xDB33DAD0] = null,//Payments_StarGiftActiveAuctionsNotModified - [0xAEF6ABBC] = typeof(Payments_StarGiftActiveAuctions), - [0x02E16C98] = typeof(InputStarGiftAuction), - [0x7AB58308] = typeof(InputStarGiftAuctionSlug), - [0x98613EBF] = typeof(Passkey), - [0xF8E0AA1C] = typeof(Account_Passkeys), - [0xE16B5CE1] = typeof(Account_PasskeyRegistrationOptions), - [0xE2037789] = typeof(Auth_PasskeyLoginOptions), - [0x3E63935C] = typeof(InputPasskeyResponseRegister), - [0xC31FC14A] = typeof(InputPasskeyResponseLogin), - [0x3C27B78F] = typeof(InputPasskeyCredentialPublicKey), - [0x5B1CCB28] = typeof(InputPasskeyCredentialFirebasePNV), - [0xAFF56398] = typeof(StarGiftBackground), - [0x3AAE0528] = typeof(StarGiftAuctionRound), - [0x0AA021E5] = typeof(StarGiftAuctionRoundExtendable), - [0x46C6E36F] = typeof(Payments_StarGiftUpgradeAttributes), - [0xDA2AD647] = typeof(Messages_EmojiGameOutcome), - [0x59E65335] = typeof(Messages_EmojiGameUnavailable), - [0x44E56023] = typeof(Messages_EmojiGameDiceInfo), - [0x36437737] = typeof(StarGiftAttributeRarity), - [0xDBCE6389] = typeof(StarGiftAttributeRarityUncommon), - [0xF08D516B] = typeof(StarGiftAttributeRarityRare), - [0x78FBF3A8] = typeof(StarGiftAttributeRarityEpic), - [0xCEF7E7A8] = typeof(StarGiftAttributeRarityLegendary), - [0x4FDD3430] = typeof(KeyboardButtonStyle), + [0xFE4CBEBD] = typeof(Account_ChatThemes), + [0x2A3C381F] = typeof(SponsoredMessage), + [0x65A4C7D5] = typeof(Messages_SponsoredMessages), // from TL.Secret: - [0x6ABD9782] = typeof(Layer143.DecryptedMessageMediaDocument), - [0x020DF5D0] = typeof(Layer101.MessageEntityBlockquote), - [0x91CC4674] = typeof(Layer73.DecryptedMessage), - [0x0EF02CE6] = typeof(Layer66.DocumentAttributeVideo), [0xBB718624] = typeof(Layer66.SendMessageUploadRoundAction), - [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), + [0xE50511D8] = typeof(Layer45.DecryptedMessageMediaWebPage), + [0x8A0DF56F] = typeof(Layer45.DecryptedMessageMediaVenue), [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(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), + [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), [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), + // The End }; -#endif internal readonly static Dictionary Nullables = new() { @@ -1595,7 +989,6 @@ namespace TL [typeof(Messages_Stickers)] = 0xF1749A22, //messages.stickersNotModified [typeof(Messages_AllStickers)] = 0xE86602C3, //messages.allStickersNotModified [typeof(InputStickerSet)] = 0xFFB62B95, //inputStickerSetEmpty - [typeof(Messages_StickerSet)] = 0xD3F924EB, //messages.stickerSetNotModified [typeof(InputChannelBase)] = 0xEE8C1E86, //inputChannelEmpty [typeof(ChannelMessagesFilter)] = 0x94D42EE7, //channelMessagesFilterEmpty [typeof(Channels_ChannelParticipants)] = 0xF0173FE9, //channels.channelParticipantsNotModified @@ -1613,46 +1006,13 @@ 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(DialogFilterBase)] = 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 - [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(Account_ChatThemes)] = 0xE011E1C4, //account.chatThemesNotModified - [typeof(EmojiStatusBase)] = 0x2DE11AAE, //emojiStatusEmpty - [typeof(EmojiList)] = 0x481EADFA, //emojiListNotModified - [typeof(Messages_EmojiGroups)] = 0x6FB4AD87, //messages.emojiGroupsNotModified - [typeof(Help_AppConfig)] = 0x7CDE641D, //help.appConfigNotModified - [typeof(BotApp)] = 0x5DA674B7, //botAppNotModified - [typeof(Help_PeerColors)] = 0x2BA1F5CE, //help.peerColorsNotModified - [typeof(Messages_SavedReactionTags)] = 0x889B59EF, //messages.savedReactionTagsNotModified - [typeof(Help_TimezonesList)] = 0x970708CC, //help.timezonesListNotModified - [typeof(Messages_QuickReplies)] = 0x5F91EB5B, //messages.quickRepliesNotModified - [typeof(Messages_AvailableEffects)] = 0xD1ED9A5B, //messages.availableEffectsNotModified - [typeof(Payments_StarGifts)] = 0xA388A368, //payments.starGiftsNotModified - [typeof(PaidReactionPrivacy)] = 0x206AD49E, //paidReactionPrivacyDefault - [typeof(RequirementToContact)] = 0x050A9839, //requirementToContactEmpty - [typeof(Contacts_SponsoredPeers)] = 0xEA32B4B1, //contacts.sponsoredPeersEmpty - [typeof(Payments_StarGiftCollections)] = 0xA0BA4F17, //payments.starGiftCollectionsNotModified - [typeof(Stories_Albums)] = 0x564EDAEB, //stories.albumsNotModified - [typeof(Account_SavedMusicIds)] = 0x4FC81D6E, //account.savedMusicIdsNotModified - [typeof(InputChatThemeBase)] = 0x83268483, //inputChatThemeEmpty - [typeof(StarGiftAuctionStateBase)] = 0xFE333952, //starGiftAuctionStateNotModified - [typeof(Payments_StarGiftActiveAuctions)]= 0xDB33DAD0, //payments.starGiftActiveAuctionsNotModified + // from TL.Secret: [typeof(DecryptedMessageMedia)] = 0x089F5C4A, //decryptedMessageMediaEmpty + // The End }; } } diff --git a/src/TL.Xtended.cs b/src/TL.Xtended.cs deleted file mode 100644 index e4ba9ad..0000000 --- a/src/TL.Xtended.cs +++ /dev/null @@ -1,776 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; -using System.Web; - -namespace TL -{ - public interface IPeerInfo - { - long ID { get; } - bool IsActive { get; } - string MainUsername { get; } - InputPeer ToInputPeer(); - } - - 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 - { - /// This type is only for basic Chat. See Terminology in the README to understand what this means
Chat groups of type Channel must use .
- /// 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 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 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; } } - partial class InputUserSelf { public override long? UserId => null; } - partial class InputUserFromMessage { public override long? UserId => user_id; } - partial class InputUser - { - 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 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); - } - - partial class InputFileBase - { - 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, 10 seconds max, larger than 160x160 - 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 }; - } - /// Random file identifier created by the client - public abstract long ID { get; set; } - /// Number of parts saved - public abstract int Parts { get; set; } - /// Full name of the file - public abstract string Name { get; set; } - } - partial class InputFile - { - public override InputEncryptedFileBase ToInputEncryptedFile(int key_fingerprint) => new InputEncryptedFileUploaded { id = id, parts = parts, md5_checksum = md5_checksum, key_fingerprint = key_fingerprint }; - public override InputSecureFileBase ToInputSecureFile(byte[] file_hash, byte[] secret) => new InputSecureFileUploaded { id = id, parts = parts, md5_checksum = md5_checksum, file_hash = file_hash, secret = secret }; - public override long ID { get => id; set => id = value; } - public override int Parts { get => parts; set => parts = value; } - public override string Name { get => name; set => name = value; } - } - partial class InputFileBig - { - public override InputEncryptedFileBase ToInputEncryptedFile(int key_fingerprint) => new InputEncryptedFileBigUploaded { id = id, parts = parts, key_fingerprint = key_fingerprint }; - public override InputSecureFileBase ToInputSecureFile(byte[] file_hash, byte[] secret) => new InputSecureFileUploaded { id = id, parts = parts, file_hash = file_hash, secret = secret }; - public override long ID { get => id; set => id = value; } - public override int Parts { get => parts; set => parts = value; } - public override string Name { get => name; set => name = value; } - } - partial class InputFileStoryDocument // apparently this is used only in InputMediaUploadedDocument.file - { - public override InputEncryptedFileBase ToInputEncryptedFile(int key_fingerprint) => throw new NotSupportedException(); - public override InputSecureFileBase ToInputSecureFile(byte[] file_hash, byte[] secret) => throw new NotSupportedException(); - public override long ID { get => 0; set => throw new NotSupportedException(); } - public override int Parts { get => 0; set => throw new NotSupportedException(); } - public override string Name { get => null; set => throw new NotSupportedException(); } - } - - partial class InputMediaUploadedDocument - { - public InputMediaUploadedDocument() { } - public InputMediaUploadedDocument(InputFileBase inputFile, string mimeType) - { - file = inputFile; - mime_type = mimeType; - if (inputFile.Name is string filename) attributes = [new DocumentAttributeFilename { file_name = filename }]; - } - public InputMediaUploadedDocument(InputFileBase inputFile, string mimeType, params DocumentAttribute[] attribs) - { - file = inputFile; - mime_type = mimeType; - if (inputFile.Name is string filename && !attribs.Any(a => a is DocumentAttributeFilename)) - attributes = [.. attribs, new DocumentAttributeFilename { file_name = filename }]; - else - attributes = attribs; - } - } - - partial class InputPhoto - { - 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 - partial class Peer - { - public abstract long ID { get; } - 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; - 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; - 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; - protected internal override IPeerInfo UserOrChat(Dictionary users, Dictionary chats) => chats.TryGetValue(channel_id, out var chat) ? chat : null; - } - - partial class UserBase : IPeerInfo - { - public abstract long ID { get; } - public abstract bool IsActive { get; } - public abstract string MainUsername { get; } - public abstract InputPeer ToInputPeer(); - protected abstract InputUser ToInputUser(); - public static implicit operator InputPeer(UserBase user) => user?.ToInputPeer(); - public static implicit operator InputUser(UserBase user) => user?.ToInputUser(); - } - partial class UserEmpty - { - public override long ID => id; - public override bool IsActive => false; - public override string MainUsername => null; - public override string ToString() => null; - public override InputPeer ToInputPeer() => null; - protected override InputUser ToInputUser() => null; - } - partial class User - { - public override long ID => id; - public override bool IsActive => (flags & Flags.deleted) == 0; - public override string MainUsername => username ?? usernames?.FirstOrDefault(u => u.flags.HasFlag(Username.Flags.active))?.username; - public override string ToString() => MainUsername is string uname ? '@' + uname : last_name == null ? first_name : $"{first_name} {last_name}"; - public override InputPeer ToInputPeer() => new InputPeerUser(id, access_hash); - protected override InputUser ToInputUser() => new(id, access_hash); - /// An estimation of the number of days ago the user was last seen (Online=0, Recently=1, LastWeek=5, LastMonth=20, LongTimeAgo=150) - public TimeSpan LastSeenAgo => status?.LastSeenAgo ?? TimeSpan.FromDays(150); - public bool IsBot => (flags & Flags.bot) != 0; - public IEnumerable ActiveUsernames - { - get - { - if (username != null) - yield return username; - if (usernames != null) - foreach (var un in usernames) - if (un.flags.HasFlag(Username.Flags.active)) - yield return un.username; - } - } - } - - /// 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 - was_online; } - /// covers anything between 1 second and 2-3 days - partial class UserStatusRecently { internal override TimeSpan LastSeenAgo => TimeSpan.FromDays(1); } - /// between 2-3 and seven days - partial class UserStatusLastWeek { internal override TimeSpan LastSeenAgo => TimeSpan.FromDays(5); } - /// between 6-7 days and a month - partial class UserStatusLastMonth { internal override TimeSpan LastSeenAgo => TimeSpan.FromDays(20); } - - partial class ChatBase : IPeerInfo - { - /// Is this chat among current user active chats? - public abstract bool IsActive { get; } - /// Is this chat a broadcast channel? - public virtual bool IsChannel => false; - public bool IsGroup => !IsChannel; - public virtual string MainUsername => null; - public abstract ChatPhoto Photo { get; } - /// returns true if you're banned of any of these rights - public abstract bool IsBanned(ChatBannedRights.Flags flags = 0); - public abstract InputPeer ToInputPeer(); - public static implicit operator InputPeer(ChatBase chat) => chat?.ToInputPeer(); - } - partial class ChatEmpty - { - public override bool IsActive => false; - public override ChatPhoto Photo => null; - public override bool IsBanned(ChatBannedRights.Flags flags = 0) => true; - public override InputPeer ToInputPeer() => null; - public override string ToString() => $"ChatEmpty {id}"; - } - partial class Chat - { - public override bool IsActive => (flags & (Flags.left | Flags.deactivated)) == 0; - public override ChatPhoto Photo => photo; - public override bool IsBanned(ChatBannedRights.Flags flags = 0) => ((default_banned_rights?.flags ?? 0) & flags) != 0; - public override InputPeer ToInputPeer() => new InputPeerChat(id); - public override string ToString() => $"Chat \"{title}\"" + (flags.HasFlag(Flags.deactivated) ? " [deactivated]" : null); - } - partial class ChatForbidden - { - public override bool IsActive => false; - public override ChatPhoto Photo => null; - public override bool IsBanned(ChatBannedRights.Flags flags = 0) => true; - public override InputPeer ToInputPeer() => new InputPeerChat(id); - public override string ToString() => $"ChatForbidden {id} \"{title}\""; - } - partial class Channel - { - public override bool IsActive => (flags & Flags.left) == 0; - public override bool IsChannel => (flags & Flags.broadcast) != 0; - public override string MainUsername => username ?? usernames?.FirstOrDefault(un => un.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); - public static implicit operator InputChannel(Channel channel) => new(channel.id, channel.access_hash); - public override string ToString() => (flags.HasFlag(Flags.broadcast) ? "Channel " : "Group ") + (MainUsername is string uname ? '@' + uname : $"\"{title}\""); - public IEnumerable ActiveUsernames - { - get - { - if (username != null) - yield return username; - if (usernames != null) - foreach (var un in usernames) - if (un.flags.HasFlag(Username.Flags.active)) - yield return un.username; - } - } - } - partial class ChannelForbidden - { - public override bool IsActive => false; - public override bool IsChannel => (flags & Flags.broadcast) != 0; - public override ChatPhoto Photo => null; - public override bool IsBanned(ChatBannedRights.Flags flags = 0) => true; - public override InputPeer ToInputPeer() => new InputPeerChannel(id, access_hash); - public override string ToString() => $"ChannelForbidden {id} \"{title}\""; - } - - partial class ChatFullBase { public abstract int ParticipantsCount { get; } } - partial class ChatFull { public override int ParticipantsCount => participants.Participants.Length; } - partial class ChannelFull { public override int ParticipantsCount => participants_count; } - - partial class ChatParticipantBase { public abstract bool IsAdmin { get; } } - partial class ChatParticipant { public override bool IsAdmin => false; } - partial class ChatParticipantCreator { public override bool IsAdmin => true; } - partial class ChatParticipantAdmin { public override bool IsAdmin => true; } - - partial class ChatParticipantsBase { public abstract ChatParticipantBase[] Participants { get; }} - partial class ChatParticipantsForbidden { public override ChatParticipantBase[] Participants => []; } - partial class ChatParticipants { public override ChatParticipantBase[] Participants => participants; } - - partial class MessageBase { public MessageReplyHeader ReplyHeader => ReplyTo as MessageReplyHeader; } - 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; } - partial class MessageMediaPhoto { public override InputMedia ToInputMedia() => new InputMediaPhoto { id = photo }; } - partial class MessageMediaGeo { public override InputMedia ToInputMedia() => new InputMediaGeoPoint { geo_point = geo }; } - partial class MessageMediaContact { public override InputMedia ToInputMedia() => new InputMediaContact { phone_number = phone_number, first_name = first_name, last_name = last_name, vcard = vcard }; } - partial class MessageMediaDocument { public override InputMedia ToInputMedia() => new InputMediaDocument { id = document }; } - partial class MessageMediaVenue { public override InputMedia ToInputMedia() => new InputMediaVenue { geo_point = geo, title = title, address = address, provider = provider, venue_id = venue_id, venue_type = venue_type }; } - partial class MessageMediaGame { public override InputMedia ToInputMedia() => new InputMediaGame { id = game }; } - partial class MessageMediaGeoLive { public override InputMedia ToInputMedia() => new InputMediaGeoLive { geo_point = geo, heading = heading, period = period, proximity_notification_radius = proximity_notification_radius, - flags = (period != 0 ? InputMediaGeoLive.Flags.has_period : 0) | (flags.HasFlag(Flags.has_heading) ? InputMediaGeoLive.Flags.has_heading : 0) | (flags.HasFlag(Flags.has_proximity_notification_radius) ? InputMediaGeoLive.Flags.has_proximity_notification_radius : 0) }; } - partial class MessageMediaPoll { public override InputMedia ToInputMedia() => new InputMediaPoll { poll = poll, solution = results.solution, solution_entities = results.solution_entities, - correct_answers = results.results?.Where(pav => pav.flags.HasFlag(PollAnswerVoters.Flags.correct)).Select(pav => pav.option).ToArray(), - flags = (results.results != null ? InputMediaPoll.Flags.has_correct_answers : 0) | (results.solution != null ? InputMediaPoll.Flags.has_solution : 0) }; } - partial class MessageMediaDice { public override InputMedia ToInputMedia() => new InputMediaDice { emoticon = emoticon }; } - partial class MessageMediaWebPage { public override InputMedia ToInputMedia() => new InputMediaWebPage { flags = (InputMediaWebPage.Flags)((int)flags & 3), url = webpage.Url }; } - - partial class PhotoBase - { - public abstract long ID { get; } - protected abstract InputPhoto ToInputPhoto(); - public static implicit operator InputPhoto(PhotoBase photo) => photo.ToInputPhoto(); - public static implicit operator InputMediaPhoto(PhotoBase photo) => photo.ToInputPhoto(); - } - partial class PhotoEmpty - { - public override long ID => id; - protected override InputPhoto ToInputPhoto() => null; - } - partial class Photo - { - public override long ID => id; - protected override InputPhoto ToInputPhoto() => new() { id = id, access_hash = access_hash, file_reference = file_reference }; - public InputPhotoFileLocation ToFileLocation() => ToFileLocation(LargestPhotoSize); - public InputPhotoFileLocation ToFileLocation(PhotoSizeBase photoSize) => new() { id = id, access_hash = access_hash, file_reference = file_reference, thumb_size = photoSize.Type }; - public InputPhotoFileLocation ToFileLocation(VideoSize videoSize) => new() { id = id, access_hash = access_hash, file_reference = file_reference, thumb_size = videoSize.type }; - public PhotoSizeBase LargestPhotoSize => sizes.Aggregate((agg, next) => (long)next.Width * next.Height > (long)agg.Width * agg.Height ? next : agg); - public VideoSize LargestVideoSize => video_sizes?.OfType().DefaultIfEmpty().Aggregate((agg, next) => (long)next.w * next.h > (long)agg.w * agg.h ? next : agg); - } - - partial class PhotoSizeBase - { - public abstract int Width { get; } - public abstract int Height { get; } - public abstract int FileSize { get; } - } - partial class PhotoSizeEmpty - { - public override int Width => 0; - public override int Height => 0; - public override int FileSize => 0; - } - partial class PhotoSize - { - public override int Width => w; - public override int Height => h; - public override int FileSize => size; - } - partial class PhotoCachedSize - { - public override int Width => w; - public override int Height => h; - public override int FileSize => bytes.Length; - } - partial class PhotoStrippedSize - { - public override int Width => bytes[2]; - public override int Height => bytes[1]; - public override int FileSize => bytes.Length; - } - partial class PhotoSizeProgressive - { - public override int Width => w; - public override int Height => h; - public override int FileSize => sizes.Last(); - } - partial class PhotoPathSize - { - public override int Width => -1; - public override int Height => -1; - public override int FileSize => bytes.Length; - } - namespace Layer23 - { - partial class PhotoSize - { - public override int Width => w; - public override int Height => h; - public override int FileSize => size; - } - partial class PhotoCachedSize - { - public override int Width => w; - public override int Height => h; - public override int FileSize => bytes.Length; - } - } - - partial class GeoPoint - { - 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 InputNotifyPeerBase - { - public static implicit operator InputNotifyPeerBase(InputPeer peer) => new InputNotifyPeer { peer = peer }; - public static implicit operator InputNotifyPeerBase(ChatBase chat) => new InputNotifyPeer { peer = chat }; - public static implicit operator InputNotifyPeerBase(UserBase user) => new InputNotifyPeer { peer = user }; - } - - 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; } } - partial class Messages_Dialogs { public override int TotalCount => dialogs.Length; } - partial class Messages_DialogsSlice { public override int TotalCount => count; } - partial class Messages_DialogsNotModified { public override int TotalCount => count; } - - partial class Messages_MessagesBase { public abstract int Count { get; } public abstract int Offset { get; } } - partial class Messages_Messages { public override int Count => messages.Length; public override int Offset => 0; } - partial class Messages_MessagesSlice { public override int Count => count; public override int Offset => offset_id_offset; } - partial class Messages_ChannelMessages { public override int Count => count; public override int Offset => offset_id_offset; } - partial class Messages_MessagesNotModified { public override int Count => count; public override int Offset => 0; } - - partial class Updates_DifferenceBase { public abstract Updates_State State { get; } } - partial class Updates_DifferenceEmpty { public override Updates_State State => null; } - partial class Updates_Difference { public override Updates_State State => state; } - partial class Updates_DifferenceSlice { public override Updates_State State => intermediate_state; } - partial class Updates_DifferenceTooLong { public override Updates_State State => null; } - - partial class UpdatesBase - { - public abstract Update[] UpdateList { get; } - public virtual Dictionary Users => NoUsers; - public virtual Dictionary Chats => NoChats; - private static readonly Dictionary NoUsers = []; - private static readonly Dictionary NoChats = []; - public virtual (long mbox_id, int pts, int pts_count) GetMBox() => default; - } - partial class UpdatesCombined - { - public override Update[] UpdateList => updates; - public override Dictionary Users => users; - public override Dictionary Chats => chats; - public override (long mbox_id, int pts, int pts_count) GetMBox() => (-2, seq, seq - seq_start + 1); - } - partial class Updates - { - public override Update[] UpdateList => updates; - public override Dictionary Users => users; - public override Dictionary Chats => chats; - public override (long mbox_id, int pts, int pts_count) GetMBox() => (-2, seq, 1); - } - partial class UpdatesTooLong { public override Update[] UpdateList => []; } - partial class UpdateShort { public override Update[] UpdateList => [update]; } - partial class UpdateShortSentMessage { public override Update[] UpdateList => []; } - partial class UpdateShortMessage { public override Update[] UpdateList => [ new UpdateNewMessage - { - message = new Message - { - flags = (Message.Flags)flags | (flags.HasFlag(Flags.out_) ? 0 : Message.Flags.has_from_id), id = id, date = date, - message = message, entities = entities, reply_to = reply_to, - from_id = flags.HasFlag(Flags.out_) ? null : new PeerUser { user_id = user_id }, - peer_id = new PeerUser { user_id = user_id }, - fwd_from = fwd_from, via_bot_id = via_bot_id, ttl_period = ttl_period - }, pts = pts, pts_count = pts_count - } ]; } - partial class UpdateShortChatMessage { public override Update[] UpdateList => [ new UpdateNewMessage - { - message = new Message - { - flags = (Message.Flags)flags | Message.Flags.has_from_id, id = id, date = date, - message = message, entities = entities, reply_to = reply_to, - from_id = new PeerUser { user_id = from_id }, - peer_id = new PeerChat { chat_id = chat_id }, - fwd_from = fwd_from, via_bot_id = via_bot_id, ttl_period = ttl_period - }, 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 EncryptedFile - { - public static implicit operator InputEncryptedFile(EncryptedFile file) => file == null ? null : new InputEncryptedFile { id = file.id, access_hash = file.access_hash }; - public static implicit operator InputEncryptedFileLocation(EncryptedFile file) => file == null ? null : new InputEncryptedFileLocation { id = file.id, access_hash = file.access_hash }; - public InputEncryptedFileLocation ToFileLocation() => new() { id = id, access_hash = access_hash }; - } - - partial class InputDocument - { - public static implicit operator InputMediaDocument(InputDocument document) => new() { id = document }; - } - - partial class DocumentBase - { - public abstract long ID { get; } - protected abstract InputDocument ToInputDocument(); - public static implicit operator InputDocument(DocumentBase document) => document.ToInputDocument(); - public static implicit operator InputMediaDocument(DocumentBase document) => document.ToInputDocument(); - } - partial class DocumentEmpty - { - public override long ID => id; - protected override InputDocument ToInputDocument() => null; - } - partial class Document - { - public override long ID => id; - public override string ToString() => $"{Filename ?? $"Document {mime_type}"} {size:N0} bytes"; - public string Filename => GetAttribute()?.file_name; - protected override InputDocument ToInputDocument() => new() { id = id, access_hash = access_hash, file_reference = file_reference }; - public InputDocumentFileLocation ToFileLocation(PhotoSizeBase thumbSize = null) => new() { id = id, access_hash = access_hash, file_reference = file_reference, thumb_size = thumbSize?.Type }; - public InputDocumentFileLocation ToFileLocation(VideoSize videoSize) => new() { id = id, access_hash = access_hash, file_reference = file_reference, thumb_size = videoSize.type }; - public PhotoSizeBase LargestThumbSize => thumbs?.Aggregate((agg, next) => (long)next.Width * next.Height > (long)agg.Width * agg.Height ? next : agg); - public T GetAttribute() where T : DocumentAttribute => attributes.OfType().FirstOrDefault(); - } - - partial class SendMessageAction - { - public override string ToString() - { - var type = GetType().Name[11..^6]; - for (int i = 1; i < type.Length; i++) - if (char.IsUpper(type[i])) - return type.ToLowerInvariant().Insert(i, "ing ").Remove(i - 1, type[i - 1] == 'e' ? 1 : 0); - return type.ToLowerInvariant(); - } - } - partial class SpeakingInGroupCallAction { public override string ToString() => "speaking in group call"; } - partial class SendMessageTypingAction { public override string ToString() => "typing"; } - partial class SendMessageCancelAction { public override string ToString() => "stopping"; } - partial class SendMessageGeoLocationAction { public override string ToString() => "selecting a location"; } - partial class SendMessageGamePlayAction { public override string ToString() => "playing a game"; } - partial class SendMessageHistoryImportAction { public override string ToString() => "importing history"; } - partial class SendMessageEmojiInteraction { public override string ToString() => "clicking on emoji"; } - partial class SendMessageEmojiInteractionSeen { public override string ToString() => "watching emoji reaction"; } - - partial class InputStickerSet - { - public static implicit operator InputStickerSet(string shortName) => new InputStickerSetShortName { short_name = shortName }; - } - - partial class StickerSet - { - public static implicit operator InputStickerSetID(StickerSet stickerSet) => new() { id = stickerSet.id, access_hash = stickerSet.access_hash }; - [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060")] - public InputStickerSetThumb ToFileLocation(PhotoSizeBase thumbSize) => new() { stickerset = this, thumb_version = thumb_version }; - public PhotoSizeBase LargestThumbSize => thumbs?.Aggregate((agg, next) => (long)next.Width * next.Height > (long)agg.Width * agg.Height ? next : agg); - } - - partial class MessageEntity - { - public string Type { - get { var name = GetType().Name; return name[(name.IndexOf("MessageEntity") + 13)..]; } - set { if (value != Type) throw new NotSupportedException("Can't change Type. You need to create a new instance of the right TL.MessageEntity* subclass"); } - } - public int Offset { get => offset; set => offset = value; } - public int Length { get => length; set => length = value; } - } - - partial class InputChannel - { - /// Channel identifier - /// 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); - } - - partial class Contacts_ResolvedPeer - { - public static implicit operator InputPeer(Contacts_ResolvedPeer resolved) => resolved?.UserOrChat.ToInputPeer(); - /// A , or if the username was for a channel - public User User => peer is PeerUser pu ? users[pu.user_id] : null; - /// A or , or if the username was for a user - public ChatBase Chat => peer is PeerChannel or PeerChat ? chats[peer.ID] : null; - /// A , or if the username was for a user or for a forbidden channel - public Channel Channel => peer is PeerChannel pc ? chats[pc.channel_id] as Channel : null; - } - - partial class Updates_ChannelDifferenceBase - { - public abstract MessageBase[] NewMessages { get; } - public abstract Update[] OtherUpdates { get; } - public abstract bool Final { get; } - public abstract int Timeout { get; } - public abstract int Pts { get; } - } - partial class Updates_ChannelDifferenceEmpty - { - public override MessageBase[] NewMessages => []; - public override Update[] OtherUpdates => []; - public override bool Final => flags.HasFlag(Flags.final); - public override int Timeout => timeout; - public override int Pts => pts; - } - partial class Updates_ChannelDifference - { - public override MessageBase[] NewMessages => new_messages; - public override Update[] OtherUpdates => other_updates; - public override bool Final => flags.HasFlag(Flags.final); - public override int Timeout => timeout; - public override int Pts => pts; - } - partial class Updates_ChannelDifferenceTooLong - { - public override MessageBase[] NewMessages => messages; - public override Update[] OtherUpdates => null; - public override bool Final => flags.HasFlag(Flags.final); - public override int Timeout => timeout; - public override int Pts => dialog is Dialog d ? d.pts : 0; - } - - partial class ChannelParticipantBase - { - public virtual bool IsAdmin => false; - public abstract long UserId { get; } - } - partial class ChannelParticipantCreator - { - public override bool IsAdmin => true; - public override long UserId => user_id; - } - partial class ChannelParticipantAdmin - { - public override bool IsAdmin => true; - public override long UserId => user_id; - } - partial class ChannelParticipant { public override long UserId => user_id; } - partial class ChannelParticipantSelf { public override long UserId => user_id; } - partial class ChannelParticipantBanned { public override long UserId => peer is PeerUser pu ? pu.user_id : 0; } - partial class ChannelParticipantLeft { public override long UserId => peer is PeerUser pu ? pu.user_id : 0; } - - partial class Messages_PeerDialogs { public IPeerInfo UserOrChat(DialogBase dialog) => dialog.Peer?.UserOrChat(users, chats); } - - partial class Game { public static implicit operator InputGameID(Game game) => new() { id = game.id, access_hash = game.access_hash }; } - - partial class WebDocumentBase { public T GetAttribute() where T : DocumentAttribute => Attributes.OfType().FirstOrDefault(); } - 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 ChannelAdminLogEventsFilter - { - public static implicit operator ChannelAdminLogEventsFilter(Flags flags) => flags == 0 ? null : new() { flags = flags }; - } - - partial class InputMessage - { - 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(ChatBase chat) => new InputDialogPeer { peer = chat }; - public static implicit operator InputDialogPeerBase(UserBase user) => new InputDialogPeer { peer = user }; - } - - partial class SecureFile - { - public static implicit operator InputSecureFile(SecureFile file) => new() { id = file.id, access_hash = file.access_hash }; - public InputSecureFileLocation ToFileLocation() => new() { id = id, access_hash = access_hash }; - } - - partial class JsonObjectValue { public override string ToString() => $"{HttpUtility.JavaScriptStringEncode(key, true)}:{value}"; } - partial class JSONValue { public abstract object ToNative(); - private static JsonObjectValue FromJsonProperty(System.Text.Json.JsonProperty p) => new() { key = p.Name, value = FromJsonElement(p.Value) }; - public static JSONValue FromJsonElement(System.Text.Json.JsonElement elem) => elem.ValueKind switch - { - System.Text.Json.JsonValueKind.True or - System.Text.Json.JsonValueKind.False => new JsonBool { value = elem.GetBoolean() }, - System.Text.Json.JsonValueKind.Object => new JsonObject { value = [.. elem.EnumerateObject().Select(FromJsonProperty)] }, - System.Text.Json.JsonValueKind.Array => new JsonArray { value = [.. elem.EnumerateArray().Select(FromJsonElement)] }, - System.Text.Json.JsonValueKind.String => new JsonString { value = elem.GetString() }, - System.Text.Json.JsonValueKind.Number => new JsonNumber { value = elem.GetDouble() }, - _ => new JsonNull(), - }; - } - 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() - { - var sb = new StringBuilder().Append('['); - for (int i = 0; i < value.Length; i++) - sb.Append(i == 0 ? "" : ",").Append(value[i]); - return sb.Append(']').ToString(); - } - public object[] ToNativeArray() => [.. value.Select(v => v.ToNative())]; - public override object ToNative() - { - if (value.Length == 0) return Array.Empty(); - var first = value[0].ToNative(); - var T = first.GetType(); - var array = Array.CreateInstance(T, value.Length); // create an array T[] of the native type - array.SetValue(first, 0); - for (int i = 1; i < value.Length; i++) - { - var elem = value[i].ToNative(); - if (elem.GetType() != T) return ToNativeArray(); // incompatible => return an object[] instead - array.SetValue(elem, i); - } - return array; - } - } - partial class JsonObject - { - /// Returns a JSON serialization string for this object - public override string ToString() - { - var sb = new StringBuilder().Append('{'); - for (int i = 0; i < value.Length; i++) - sb.Append(i == 0 ? "" : ",").Append(value[i]); - return sb.Append('}').ToString(); - } - /// Returns the given entry in native form (, , , Dictionary or ), or if the key is not found - public object this[string key] => value.FirstOrDefault(v => v.key == key)?.value.ToNative(); - /// Converts the entries to a Dictionary with keys and values in native form (, , , Dictionary or ) - public Dictionary ToDictionary() => value.ToDictionary(v => v.key, v => v.value.ToNative()); - public override object ToNative() - { - if (value.Length == 0) return new Dictionary(); - var first = value[0].value.ToNative(); - var T = first.GetType(); // create a Dictionary of the native type T: - var dic = Activator.CreateInstance(typeof(Dictionary<,>).MakeGenericType(typeof(string), T)) as System.Collections.IDictionary; - dic.Add(value[0].key, first); - for (int i = 1; i < value.Length; i++) - { - var elem = value[i].value.ToNative(); - if (elem.GetType() != T) return ToDictionary(); // incompatible => return a Dictionary instead - dic.Add(value[i].key, elem); - } - return dic; - } - } - - partial class Theme { public static implicit operator InputTheme(Theme theme) => new() { id = theme.id, access_hash = theme.access_hash }; } - partial class MessageReplyHeader { public int TopicID => flags.HasFlag(Flags.forum_topic) ? flags.HasFlag(Flags.has_reply_to_top_id) ? reply_to_top_id : reply_to_msg_id : 0; } - partial class GroupCallBase { public static implicit operator InputGroupCall(GroupCallBase call) => new() { id = call.ID, access_hash = call.AccessHash }; } - - partial class EmojiStatusBase { public virtual long DocumentId => 0; } - partial class EmojiStatus { public override long DocumentId => document_id; } - partial class EmojiStatusCollectible{ public override long DocumentId => document_id; } - - partial class ForumTopicBase { public virtual string Title => null; } - partial class ForumTopic { public override string Title => title; } - - partial class RequestedPeer { public abstract long ID { get; } } - partial class RequestedPeerUser { public override long ID => user_id; } - partial class RequestedPeerChat { public override long ID => chat_id; } - partial class RequestedPeerChannel { public override long ID => channel_id; } - -} diff --git a/src/TL.cs b/src/TL.cs index 2f12b19..0cb701c 100644 --- a/src/TL.cs +++ b/src/TL.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.IO; using System.IO.Compression; using System.Linq; @@ -8,133 +7,71 @@ using System.Reflection; using System.Security.Cryptography; using System.Text; -#pragma warning disable IDE1006 // Naming Styles - namespace TL { -#if MTPG - public interface IObject { void WriteTL(BinaryWriter writer); } -#else - public interface IObject { } -#endif - public interface IMethod : IObject { } - public interface IPeerResolver { IPeerInfo UserOrChat(Peer peer); } - - [AttributeUsage(AttributeTargets.Class)] - public sealed class TLDefAttribute(uint ctorNb) : Attribute - { - public readonly uint CtorNb = ctorNb; - public int inheritAt = -1; - } - - [AttributeUsage(AttributeTargets.Field)] - public sealed class IfFlagAttribute(int bit) : Attribute - { - public readonly int Bit = bit; - } - - public sealed class RpcException(int code, string message, int x = -1) : WTelegram.WTException(message) - { - public readonly int Code = code; - /// The value of X in the message, -1 if no variable X was found - public readonly int X = x; - public override string ToString() { var str = base.ToString(); return str.Insert(str.IndexOf(':') + 1, " " + Code); } - } - - public sealed partial class ReactorError : IObject - { - public Exception Exception; - public void WriteTL(BinaryWriter writer) => throw new NotSupportedException(); - } + public interface ITLObject { } + public delegate string ITLFunction(BinaryWriter writer); public static class Serialization { - [EditorBrowsable(EditorBrowsableState.Never)] - public static byte[] ToBytes(this T obj) where T : IObject + internal static byte[] Serialize(this ITLObject msg) { - using var ms = new MemoryStream(384); - using var writer = new BinaryWriter(ms); - writer.WriteTLObject(obj); - return ms.ToArray(); + using var memStream = new MemoryStream(1024); + using (var writer = new BinaryWriter(memStream)) + WriteTLObject(writer, msg); + return memStream.ToArray(); } - public static void WriteTLObject(this BinaryWriter writer, T obj) where T : IObject + internal static T Deserialize(byte[] bytes) where T : ITLObject + { + using var memStream = new MemoryStream(bytes); + using var reader = new BinaryReader(memStream, null); + return (T)reader.ReadTLObject(); + } + + internal static void WriteTLObject(this BinaryWriter writer, T obj) where T : ITLObject { if (obj == null) { writer.WriteTLNull(typeof(T)); return; } -#if MTPG - obj.WriteTL(writer); -#else var type = obj.GetType(); var tlDef = type.GetCustomAttribute(); var ctorNb = tlDef.CtorNb; writer.Write(ctorNb); - var fields = GetTLFields(type, tlDef); - ulong flags = 0; + IEnumerable fields = type.GetFields(); + if (!tlDef.inheritAfter) fields = fields.GroupBy(f => f.DeclaringType).Reverse().SelectMany(g => g); + int flags = 0; IfFlagAttribute ifFlag; foreach (var field in fields) { - if (((ifFlag = field.GetCustomAttribute()) != null) && (flags & (1UL << ifFlag.Bit)) == 0) continue; + if (((ifFlag = field.GetCustomAttribute()) != null) && (flags & (1 << ifFlag.Bit)) == 0) continue; object value = field.GetValue(obj); writer.WriteTLValue(value, field.FieldType); - if (field.FieldType.IsEnum) - if (field.Name == "flags") flags = (uint)value; - else if (field.Name == "flags2") flags |= (ulong)(uint)value << 32; + if (field.Name.Equals("Flags", StringComparison.OrdinalIgnoreCase)) flags = (int)value; } -#endif } - public static IObject ReadTLObject(this BinaryReader reader, uint ctorNb = 0) + internal static ITLObject ReadTLObject(this BinaryReader reader, uint ctorNb = 0) { if (ctorNb == 0) ctorNb = reader.ReadUInt32(); -#if MTPG - if (!Layer.Table.TryGetValue(ctorNb, out var ctor)) - throw new WTelegram.WTException($"Cannot find type for ctor #{ctorNb:x}"); - return ctor?.Invoke(reader); -#else - if (ctorNb == Layer.GZipedCtor) return (IObject)reader.ReadTLGzipped(typeof(IObject)); if (!Layer.Table.TryGetValue(ctorNb, out var type)) - throw new WTelegram.WTException($"Cannot find type for ctor #{ctorNb:x}"); + throw new ApplicationException($"Cannot find type for ctor #{ctorNb:x}"); if (type == null) return null; // nullable ctor (class meaning is associated with null) var tlDef = type.GetCustomAttribute(); - var obj = Activator.CreateInstance(type, true); - var fields = GetTLFields(type, tlDef); - ulong flags = 0; + var obj = Activator.CreateInstance(type); + IEnumerable fields = type.GetFields(); + if (!tlDef.inheritAfter) fields = fields.GroupBy(f => f.DeclaringType).Reverse().SelectMany(g => g); + int flags = 0; IfFlagAttribute ifFlag; foreach (var field in fields) { - if (((ifFlag = field.GetCustomAttribute()) != null) && (flags & (1UL << ifFlag.Bit)) == 0) continue; + if (((ifFlag = field.GetCustomAttribute()) != null) && (flags & (1 << ifFlag.Bit)) == 0) continue; object value = reader.ReadTLValue(field.FieldType); field.SetValue(obj, value); - if (field.FieldType.IsEnum) - if (field.Name == "flags") flags = (uint)value; - else if (field.Name == "flags2") flags |= (ulong)(uint)value << 32; + if (field.Name == "flags") flags = (int)value; + else if (field.Name == "access_hash") reader.Client?.UpdateAccessHash(obj, type, value); } - return (IObject)obj; -#endif + return type == typeof(GzipPacked) ? UnzipPacket((GzipPacked)obj, reader.Client) : (ITLObject)obj; } -#if !MTPG - static IEnumerable GetTLFields(Type type, TLDefAttribute tlDef) - { - if (!(tlDef?.inheritAt >= 0)) return type.GetFields(BindingFlags.Instance | BindingFlags.Public); - var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); - if (type.IsAbstract || type.BaseType == typeof(IObject)) return fields; - var subfields = GetTLFields(type.BaseType, type.BaseType.GetCustomAttribute()); - return fields.Take(tlDef.inheritAt).Concat(subfields).Concat(fields.Skip(tlDef.inheritAt)); - } -#else - public static IMethod ReadTLMethod(this BinaryReader reader) - { - uint ctorNb = reader.ReadUInt32(); - if (!Layer.Methods.TryGetValue(ctorNb, out var ctor)) - throw new WTelegram.WTException($"Cannot find method for ctor #{ctorNb:x}"); - var method = ctor?.Invoke(reader); - if (method is IMethod && typeof(X) == typeof(object)) - method = new BoolMethod { query = method }; - return (IMethod)method; - } -#endif - internal static void WriteTLValue(this BinaryWriter writer, object value, Type valueType) { if (value == null) @@ -146,29 +83,25 @@ namespace TL switch (Type.GetTypeCode(type)) { case TypeCode.Int32: writer.Write((int)value); break; - case TypeCode.Int64: writer.Write((long)value); break; case TypeCode.UInt32: writer.Write((uint)value); break; + case TypeCode.Int64: writer.Write((long)value); break; case TypeCode.UInt64: writer.Write((ulong)value); break; case TypeCode.Double: writer.Write((double)value); break; case TypeCode.String: writer.WriteTLString((string)value); break; - case TypeCode.Boolean: writer.Write((bool)value ? 0x997275B5 : 0xBC799737); break; case TypeCode.DateTime: writer.WriteTLStamp((DateTime)value); break; + case TypeCode.Boolean: writer.Write((bool)value ? 0x997275B5 : 0xBC799737); break; case TypeCode.Object: if (type.IsArray) if (value is byte[] bytes) writer.WriteTLBytes(bytes); else writer.WriteTLVector((Array)value); - else if (value is IObject tlObject) - WriteTLObject(writer, tlObject); - else if (value is List<_Message> messages) - writer.WriteTLMessages(messages); else if (value is Int128 int128) writer.Write(int128); else if (value is Int256 int256) writer.Write(int256); - else if (type.IsEnum) // needed for Mono (enums in generic types are seen as TypeCode.Object) - writer.Write((uint)value); + else if (value is ITLObject tlObject) + WriteTLObject(writer, tlObject); else ShouldntBeHere(); break; @@ -183,8 +116,8 @@ namespace TL switch (Type.GetTypeCode(type)) { case TypeCode.Int32: return reader.ReadInt32(); - case TypeCode.Int64: return reader.ReadInt64(); case TypeCode.UInt32: return reader.ReadUInt32(); + case TypeCode.Int64: return reader.ReadInt64(); case TypeCode.UInt64: return reader.ReadUInt64(); case TypeCode.Double: return reader.ReadDouble(); case TypeCode.String: return reader.ReadTLString(); @@ -194,8 +127,7 @@ namespace TL { 0x997275b5 => true, 0xbc799737 => false, - Layer.RpcErrorCtor => reader.ReadTLObject(Layer.RpcErrorCtor), - var value => throw new WTelegram.WTException($"Invalid boolean value #{value:x}") + var value => throw new ApplicationException($"Invalid boolean value #{value:x}") }; case TypeCode.Object: if (type.IsArray) @@ -209,10 +141,6 @@ namespace TL return new Int128(reader); else if (type == typeof(Int256)) return new Int256(reader); - else if (type == typeof(Dictionary)) - return reader.ReadTLDictionary(); - else if (type == typeof(Dictionary)) - return reader.ReadTLDictionary(); else return reader.ReadTLObject(); default: @@ -221,26 +149,6 @@ namespace TL } } - internal static void WriteTLMessages(this BinaryWriter writer, List<_Message> messages) - { - writer.Write(messages.Count); - foreach (var msg in messages) - { - writer.Write(msg.msg_id); - writer.Write(msg.seqno); - var patchPos = writer.BaseStream.Position; - writer.Write(0); // patched below - if ((msg.seqno & 1) != 0) - WTelegram.Helpers.Log(1, $" → {msg.body.GetType().Name.TrimEnd('_'),-38} #{(short)msg.msg_id.GetHashCode():X4}"); - else - WTelegram.Helpers.Log(1, $" → {msg.body.GetType().Name.TrimEnd('_'),-38}"); - writer.WriteTLObject(msg.body); - writer.BaseStream.Position = patchPos; - writer.Write((int)(writer.BaseStream.Length - patchPos - 4)); // patch bytes field - writer.Seek(0, SeekOrigin.End); - } - } - internal static void WriteTLVector(this BinaryWriter writer, Array array) { writer.Write(Layer.VectorCtor); @@ -252,42 +160,6 @@ namespace TL writer.WriteTLValue(array.GetValue(i), elementType); } - internal static void WriteTLRawVector(this BinaryWriter writer, Array array, int elementSize) - { - var startPos = writer.BaseStream.Position; - int count = array.Length; - var elementType = array.GetType().GetElementType(); - for (int i = count - 1; i >= 0; i--) - { - writer.BaseStream.Position = startPos + i * elementSize; - writer.WriteTLValue(array.GetValue(i), elementType); - } - writer.BaseStream.Position = startPos; - writer.Write(count); - writer.BaseStream.Position = startPos + count * elementSize + 4; - } - - internal static List ReadTLRawVector(this BinaryReader reader, uint ctorNb) - { - int count = reader.ReadInt32(); - var list = new List(count); - for (int i = 0; i < count; i++) - list.Add((T)reader.ReadTLObject(ctorNb)); - return list; - } - - internal static T[] ReadTLVector(this BinaryReader reader) - { - var elementType = typeof(T); - if (reader.ReadUInt32() is not Layer.VectorCtor and uint ctorNb) - throw new WTelegram.WTException($"Cannot deserialize {elementType.Name}[] with ctor #{ctorNb:x}"); - int count = reader.ReadInt32(); - var array = new T[count]; - for (int i = 0; i < count; i++) - array[i] = (T)reader.ReadTLValue(elementType); - return array; - } - internal static Array ReadTLVector(this BinaryReader reader, Type type) { var elementType = type.GetElementType(); @@ -296,12 +168,8 @@ namespace TL { int count = reader.ReadInt32(); Array array = (Array)Activator.CreateInstance(type, count); - if (elementType.IsEnum) - for (int i = 0; i < count; i++) - array.SetValue(Enum.ToObject(elementType, reader.ReadTLValue(elementType)), i); - else - for (int i = 0; i < count; i++) - array.SetValue(reader.ReadTLValue(elementType), i); + for (int i = 0; i < count; i++) + array.SetValue(reader.ReadTLValue(elementType), i); return array; } else if (ctorNb < 1024 && !elementType.IsAbstract && elementType.GetCustomAttribute() is TLDefAttribute attr) @@ -313,35 +181,14 @@ namespace TL return array; } else - throw new WTelegram.WTException($"Cannot deserialize {type.Name} with ctor #{ctorNb:x}"); - } - - internal static Dictionary ReadTLDictionary(this BinaryReader reader) where T : class, IPeerInfo - { - uint ctorNb = reader.ReadUInt32(); - if (ctorNb != Layer.VectorCtor) - throw new WTelegram.WTException($"Cannot deserialize Vector<{typeof(T).Name}> with ctor #{ctorNb:x}"); - int count = reader.ReadInt32(); - var dict = new Dictionary(count); - for (int i = 0; i < count; i++) - { - var obj = reader.ReadTLObject(); - if (obj is T value) dict[value.ID] = value; - else if (obj is UserEmpty ue) dict[ue.id] = null; - else throw new InvalidCastException($"ReadTLDictionary got '{obj?.GetType().Name}' instead of '{typeof(T).Name}'"); - } - return dict; + throw new ApplicationException($"Cannot deserialize {type.Name} with ctor #{ctorNb:x}"); } internal static void WriteTLStamp(this BinaryWriter writer, DateTime datetime) - => writer.Write((int)Math.Min(Math.Max(datetime.ToUniversalTime().Ticks / 10000000 - 62135596800L, 0), int.MaxValue)); + => writer.Write((uint)(datetime.ToUniversalTime().Ticks / 10000000 - 62135596800L)); - internal static DateTime ReadTLStamp(this BinaryReader reader) => reader.ReadInt32() switch - { - <= 0 => default, - int.MaxValue => DateTime.MaxValue, - int unixstamp => new((unixstamp + 62135596800L) * 10000000, DateTimeKind.Utc) - }; + internal static DateTime ReadTLStamp(this BinaryReader reader) + => new((reader.ReadUInt32() + 62135596800L) * 10000000, DateTimeKind.Utc); internal static void WriteTLString(this BinaryWriter writer, string str) { @@ -398,19 +245,13 @@ namespace TL writer.Write(0); // null arrays/strings are serialized as empty } - internal static object ReadTLGzipped(this BinaryReader reader, Type type) + internal static ITLObject UnzipPacket(GzipPacked obj, WTelegram.Client client) { - using var gzipReader = new BinaryReader(new GZipStream(new MemoryStream(reader.ReadTLBytes()), CompressionMode.Decompress)); - return gzipReader.ReadTLValue(type); + using var reader = new BinaryReader(new GZipStream(new MemoryStream(obj.packed_data), CompressionMode.Decompress), client); + var result = reader.ReadTLObject(); + return result; } - internal static bool ReadTLBool(this BinaryReader reader) => reader.ReadUInt32() switch - { - 0x997275b5 => true, - 0xbc799737 => false, - var value => throw new WTelegram.WTException($"Invalid boolean value #{value:x}") - }; - #if DEBUG private static void ShouldntBeHere() => System.Diagnostics.Debugger.Break(); #else @@ -418,17 +259,37 @@ namespace TL #endif } + public class BinaryReader : System.IO.BinaryReader + { + public readonly WTelegram.Client Client; + public BinaryReader(Stream stream, WTelegram.Client client) : base(stream) => Client = client; + } + + [AttributeUsage(AttributeTargets.Class)] + public class TLDefAttribute : Attribute + { + public readonly uint CtorNb; + public TLDefAttribute(uint ctorNb) => CtorNb = ctorNb; + public bool inheritAfter; + } + + [AttributeUsage(AttributeTargets.Field)] + public class IfFlagAttribute : Attribute + { + public readonly int Bit; + public IfFlagAttribute(int bit) => Bit = bit; + } + public struct Int128 { public byte[] raw; public Int128(BinaryReader reader) => raw = reader.ReadBytes(16); - public Int128(RandomNumberGenerator rng) => rng.GetBytes(raw = new byte[16]); + public Int128(RNGCryptoServiceProvider rng) => rng.GetBytes(raw = new byte[16]); public static bool operator ==(Int128 left, Int128 right) { for (int i = 0; i < 16; i++) if (left.raw[i] != right.raw[i]) return false; return true; } public static bool operator !=(Int128 left, Int128 right) { for (int i = 0; i < 16; i++) if (left.raw[i] != right.raw[i]) return true; return false; } - public override readonly bool Equals(object obj) => obj is Int128 other && this == other; - public override readonly int GetHashCode() => BitConverter.ToInt32(raw, 0); - public override readonly string ToString() => Convert.ToHexString(raw); + public override bool Equals(object obj) => obj is Int128 other && this == other; + public override int GetHashCode() => HashCode.Combine(raw[0], raw[1]); public static implicit operator byte[](Int128 int128) => int128.raw; } @@ -437,72 +298,49 @@ namespace TL public byte[] raw; public Int256(BinaryReader reader) => raw = reader.ReadBytes(32); - public Int256(RandomNumberGenerator rng) => rng.GetBytes(raw = new byte[32]); + public Int256(RNGCryptoServiceProvider rng) => rng.GetBytes(raw = new byte[32]); public static bool operator ==(Int256 left, Int256 right) { for (int i = 0; i < 32; i++) if (left.raw[i] != right.raw[i]) return false; return true; } public static bool operator !=(Int256 left, Int256 right) { for (int i = 0; i < 32; i++) if (left.raw[i] != right.raw[i]) return true; return false; } - public override readonly bool Equals(object obj) => obj is Int256 other && this == other; - public override readonly int GetHashCode() => BitConverter.ToInt32(raw, 0); - public override readonly string ToString() => Convert.ToHexString(raw); + public override bool Equals(object obj) => obj is Int256 other && this == other; + public override int GetHashCode() => HashCode.Combine(raw[0], raw[1]); public static implicit operator byte[](Int256 int256) => int256.raw; } - public sealed partial class UpdateAffectedMessages : Update // auto-generated for OnOwnUpdates in case of such API call result + public class RpcException : Exception { - public long mbox_id; - public int pts; - public int pts_count; - public override (long, int, int) GetMBox() => (mbox_id, pts, pts_count); -#if MTPG - public override void WriteTL(BinaryWriter writer) => throw new NotSupportedException(); -#endif + public readonly int Code; + public RpcException(int code, string message) : base(message) => Code = code; + } + + public class ReactorError : ITLObject + { + public Exception Exception; } // Below TL types are commented "parsed manually" from https://github.com/telegramdesktop/tdesktop/blob/dev/Telegram/Resources/tl/mtproto.tl - [TLDef(0x7A19CB76)] //RSA_public_key#7a19cb76 n:bytes e:bytes = RSAPublicKey - public sealed partial class RSAPublicKey : IObject - { - public byte[] n; - public byte[] e; - } - [TLDef(0xF35C6D01)] //rpc_result#f35c6d01 req_msg_id:long result:Object = RpcResult - public sealed partial class RpcResult : IObject + public partial class RpcResult : ITLObject { public long req_msg_id; public object result; } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006")] [TLDef(0x5BB8E511)] //message#5bb8e511 msg_id:long seqno:int bytes:int body:Object = Message - public sealed partial class _Message(long msgId, int seqno, IObject obj) : IObject + public partial class _Message { - public long msg_id = msgId; - public int seqno = seqno; + public long msg_id; + public int seqno; public int bytes; - public IObject body = obj; + public ITLObject body; } [TLDef(0x73F1F8DC)] //msg_container#73f1f8dc messages:vector<%Message> = MessageContainer - public sealed partial class MsgContainer : IObject { public List<_Message> messages; } + public partial class MsgContainer : ITLObject { public _Message[] messages; } [TLDef(0xE06046B2)] //msg_copy#e06046b2 orig_message:Message = MessageCopy - public sealed partial class MsgCopy : IObject { public _Message orig_message; } + public partial class MsgCopy : ITLObject { public _Message orig_message; } [TLDef(0x3072CFA1)] //gzip_packed#3072cfa1 packed_data:bytes = Object - public sealed partial class GzipPacked : IObject { public byte[] packed_data; } - - public sealed class Null : IObject - { - public readonly static Null Instance = new(); - public void WriteTL(BinaryWriter writer) => writer.WriteTLNull(typeof(X)); - } - - public sealed class BoolMethod : IMethod - { - public IObject query; -#if MTPG - public void WriteTL(BinaryWriter writer) => query.WriteTL(writer); -#else - public void WriteTL(BinaryWriter writer) => writer.WriteTLObject(query); -#endif - } + public partial class GzipPacked : ITLObject { public byte[] packed_data; } } diff --git a/src/TlsStream.cs b/src/TlsStream.cs deleted file mode 100644 index 4e6ff30..0000000 --- a/src/TlsStream.cs +++ /dev/null @@ -1,201 +0,0 @@ -using System; -using System.Buffers.Binary; -using System.IO; -using System.Linq; -using System.Security.Cryptography; -using System.Threading; -using System.Threading.Tasks; - -// necessary for .NET Standard 2.0 compilation: -#pragma warning disable CA1835 // Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync' - -namespace WTelegram -{ - internal sealed class TlsStream(Stream innerStream) : Helpers.IndirectStream(innerStream) - { - private int _tlsFrameleft; - private readonly byte[] _tlsSendHeader = [0x17, 0x03, 0x03, 0, 0]; - private readonly byte[] _tlsReadHeader = new byte[5]; - static readonly byte[] TlsServerHello3 = [0x14, 0x03, 0x03, 0x00, 0x01, 0x01, 0x17, 0x03, 0x03]; - static readonly byte[] TlsClientPrefix = [0x14, 0x03, 0x03, 0x00, 0x01, 0x01]; - - public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken ct) - { - if (_tlsFrameleft == 0) - { - if (await _innerStream.FullReadAsync(_tlsReadHeader, 5, ct) != 5) - return 0; - if (_tlsReadHeader[0] != 0x17 || _tlsReadHeader[1] != 0x03 || _tlsReadHeader[2] != 0x03) - throw new WTException("Could not read frame data : Invalid TLS header"); - _tlsFrameleft = (_tlsReadHeader[3] << 8) + _tlsReadHeader[4]; - } - var read = await _innerStream.ReadAsync(buffer, offset, Math.Min(count, _tlsFrameleft), ct); - _tlsFrameleft -= read; - return read; - } - - public override async Task WriteAsync(byte[] buffer, int start, int count, CancellationToken ct) - { - for (int offset = 0; offset < count;) - { - int len = Math.Min(count - offset, 2878); - _tlsSendHeader[3] = (byte)(len >> 8); - _tlsSendHeader[4] = (byte)len; - await _innerStream.WriteAsync(_tlsSendHeader, 0, _tlsSendHeader.Length, ct); - await _innerStream.WriteAsync(buffer, start + offset, len, ct); - offset += len; - } - } - - public static async Task HandshakeAsync(Stream stream, byte[] key, byte[] domain, CancellationToken ct) - { - var clientHello = TlsClientHello(key, domain); - await stream.WriteAsync(clientHello, 0, clientHello.Length, ct); - - var part1 = new byte[5]; - if (await stream.FullReadAsync(part1, 5, ct) == 5) - if (part1[0] == 0x16 && part1[1] == 0x03 && part1[2] == 0x03) - { - var part2size = BinaryPrimitives.ReadUInt16BigEndian(part1.AsSpan(3)); - var part23 = new byte[part2size + TlsServerHello3.Length + 2]; - if (await stream.FullReadAsync(part23, part23.Length, ct) == part23.Length) - if (TlsServerHello3.SequenceEqual(part23.Skip(part2size).Take(TlsServerHello3.Length))) - { - var part4size = BinaryPrimitives.ReadUInt16BigEndian(part23.AsSpan(part23.Length - 2)); - var part4 = new byte[part4size]; - if (await stream.FullReadAsync(part4, part4size, ct) == part4size) - { - var serverDigest = part23[6..38]; - Array.Clear(part23, 6, 32); // clear server digest from received parts - var hmc = new HMACSHA256(key); // hash the client digest + all received parts - hmc.TransformBlock(clientHello, 11, 32, null, 0); - hmc.TransformBlock(part1, 0, part1.Length, null, 0); - hmc.TransformBlock(part23, 0, part23.Length, null, 0); - hmc.TransformFinalBlock(part4, 0, part4.Length); - if (serverDigest.SequenceEqual(hmc.Hash)) - { - Helpers.Log(2, "TLS Handshake succeeded"); - await stream.WriteAsync(TlsClientPrefix, 0, TlsClientPrefix.Length, ct); - return new TlsStream(stream); - } - } - } - } - throw new WTException("TLS Handshake failed"); - } - - static readonly byte[] TlsClientHello1 = [ // https://tls13.xargs.org/#client-hello/annotated - 0x16, 0x03, 0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0xfc, 0x03, 0x03 ]; - // digest[32] - // 0x20 - // random[32] - // 0x00, 0x20 - // grease(0) GREASE are two identical bytes ending with nibble 'A' - static readonly byte[] TlsClientHello2 = [ - 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xcc, 0xa9, - 0xcc, 0xa8, 0xc0, 0x13, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, - 0x01, 0x00, 0x01, 0x93 ]; - // grease(2) - // 0x00, 0x00 - static readonly byte[] TlsClientHello3 = [ - // 0x00, 0x00, len { len { 0x00 len { domain } } } len is 16-bit big-endian length of the following block of data - 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x4A, 0x4A/*=grease(4)*/, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, - 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, - 0x00, 0x0d, 0x00, 0x12, 0x00, 0x10, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, - 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0c, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, - 0x00, 0x12, 0x00, 0x00, - 0x00, 0x17, 0x00, 0x00, - 0x00, 0x1b, 0x00, 0x03, 0x02, 0x00, 0x02, - 0x00, 0x23, 0x00, 0x00, - 0x00, 0x2b, 0x00, 0x07, 0x06, 0x6A, 0x6A/*=grease(6)*/, 0x03, 0x04, 0x03, 0x03, - 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, - 0x00, 0x33, 0x00, 0x2b, 0x00, 0x29, 0x4A, 0x4A/*=grease(4)*/, 0x00, 0x01, 0x00, 0x00, 0x1d, 0x00, 0x20, /* random[32] */ - 0x44, 0x69, 0x00, 0x05, 0x00, 0x03, 0x02, 0x68, 0x32, - 0xff, 0x01, 0x00, 0x01, 0x00, - ]; - // grease(3) - static readonly byte[] TlsClientHello4 = [ - 0x00, 0x01, 0x00, 0x00, 0x15 ]; - // len { padding } padding with NUL bytes to reach 517 bytes - - static byte[] TlsClientHello(byte[] key, byte[] domain) - { - var greases = new byte[7]; - Encryption.RNG.GetBytes(greases); - for (int i = 0; i < 7; i++) greases[i] = (byte)((greases[i] & 0xF0) + 0x0A); - if (greases[3] == greases[2]) greases[3] ^= 0x10; - - var buffer = new byte[517]; - TlsClientHello1.CopyTo(buffer, 0); - Encryption.RNG.GetBytes(buffer, 44, 32); - buffer[43] = buffer[77] = 0x20; - buffer[78] = buffer[79] = greases[0]; - TlsClientHello2.CopyTo(buffer, 80); - buffer[114] = buffer[115] = greases[2]; - - int dlen = domain.Length; - var server_name = new byte[dlen + 9]; - server_name[3] = (byte)(dlen + 5); - server_name[5] = (byte)(dlen + 3); - server_name[8] = (byte)dlen; - domain.CopyTo(server_name, 9); - - var key_share = new byte[47]; - Array.Copy(TlsClientHello3, 105, key_share, 0, 15); - key_share[6] = key_share[7] = greases[4]; - Encryption.RNG.GetBytes(key_share, 15, 32); // public key - key_share[46] &= 0x7F; // must be positive - - var random = new Random(); - var permutations = new ArraySegment[15]; - for (var i = 0; i < permutations.Length; i++) - { - var j = random.Next(0, i + 1); - if (i != j) permutations[i] = permutations[j]; - permutations[j] = i switch - { - 0 => new(server_name), - 1 => new(TlsClientHello3, 0, 9), - 2 => PatchGrease(TlsClientHello3[9..23], 6, greases[4]), - 3 => new(TlsClientHello3, 23, 6), - 4 => new(TlsClientHello3, 29, 22), - 5 => new(TlsClientHello3, 51, 18), - 6 => new(TlsClientHello3, 69, 4), - 7 => new(TlsClientHello3, 73, 4), - 8 => new(TlsClientHello3, 77, 7), - 9 => new(TlsClientHello3, 84, 4), - 10 => PatchGrease(TlsClientHello3[88..99], 5, greases[6]), - 11 => new(TlsClientHello3, 99, 6), - 12 => new(key_share), - 13 => new(TlsClientHello3, 120, 9), - _ => new(TlsClientHello3, 129, 5), - }; - } - int offset = 118; - foreach (var perm in permutations) - { - Array.Copy(perm.Array, perm.Offset, buffer, offset, perm.Count); - offset += perm.Count; - } - buffer[offset++] = buffer[offset++] = greases[3]; - TlsClientHello4.CopyTo(buffer, offset); - buffer[offset + 6] = (byte)(510 - offset); - - // patch-in digest with timestamp - using var hmac = new HMACSHA256(key); - var digest = hmac.ComputeHash(buffer); - var stamp = BinaryPrimitives.ReadInt32LittleEndian(digest.AsSpan(28)); - stamp ^= (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); - BinaryPrimitives.WriteInt32LittleEndian(digest.AsSpan(28), stamp); - digest.CopyTo(buffer, 11); - return buffer; - - static ArraySegment PatchGrease(byte[] buffer, int offset, byte grease) - { - buffer[offset] = buffer[offset + 1] = grease; - return new(buffer); - } - } - } -} diff --git a/src/UpdateManager.cs b/src/UpdateManager.cs deleted file mode 100644 index 9446054..0000000 --- a/src/UpdateManager.cs +++ /dev/null @@ -1,610 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.ComponentModel; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using TL; - -namespace WTelegram -{ - public class UpdateManager - { - /// Collected info about Users (only if using the default collector) - public readonly Dictionary Users; - /// Collected info about Chats (only if using the default collector) - public readonly Dictionary Chats; - /// Timout to detect lack of updates and force refetch them - public TimeSpan InactivityThreshold { get; set; } = TimeSpan.FromMinutes(15); - /// Logging callback (defaults to WTelegram.Helpers.Log ; can be null for performance) - public Action Log { get; set; } = Helpers.Log; - /// Current set of update states (for saving and later resume) - public ImmutableDictionary State - { - get - { - _sem.Wait(); - try { return _local.ToImmutableDictionary(); } - finally { _sem.Release(); } - } - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006")] - public sealed class MBoxState { public int pts { get; set; } public long access_hash { get; set; } } - - private readonly Client _client; - private readonly Func _onUpdate; - private readonly IPeerCollector _collector; - private readonly bool _reentrant; - private readonly TaskScheduler _scheduler; - private readonly SemaphoreSlim _sem = new(1); - private readonly List<(Update update, UpdatesBase updates, bool own, DateTime stamp)> _pending = []; - private readonly Dictionary _local; // -2 for seq/date, -1 for qts, 0 for common pts, >0 for channel pts - private const int L_SEQ = -2, L_QTS = -1, L_PTS = 0; - private const long UndefinedSeqDate = 3155378975999999999L; // DateTime.MaxValue.Ticks - private static readonly TimeSpan HalfSec = new(TimeSpan.TicksPerSecond / 2); - private Task _recoveringGaps; - private DateTime _lastUpdateStamp = DateTime.UtcNow; - - /// Manager ensuring that you receive Telegram updates in correct order, without missing any - /// the WTelegram Client to manage - /// Event to be called on sequential individual update - /// (optional) Resume session by recovering all updates that occured since this state - /// Custom users/chats collector. By default, those are collected in properties Users/Chats - /// if your method can be called again even when last async call didn't return yet - public UpdateManager(Client client, Func onUpdate, IDictionary state = null, IPeerCollector collector = null, bool reentrant = false) - { - _client = client; - _onUpdate = onUpdate; - _collector = collector ?? new Services.CollectorPeer(Users = [], Chats = []); - _scheduler = SynchronizationContext.Current == null ? TaskScheduler.Current : TaskScheduler.FromCurrentSynchronizationContext(); - - if (state == null || state.Count < 3) - _local = new() { [L_SEQ] = new() { access_hash = UndefinedSeqDate }, [L_QTS] = new(), [L_PTS] = new() }; - else - _local = state as Dictionary ?? new Dictionary(state); - _reentrant = reentrant; - client.OnOther += OnOther; - client.OnUpdates += u => OnUpdates(u, false); - client.OnOwnUpdates += u => OnUpdates(u, true); - } - - private async Task OnOther(IObject obj) - { - switch (obj) - { - case Pong when DateTime.UtcNow - _lastUpdateStamp > InactivityThreshold: - if (_local[L_PTS].pts != 0) await ResyncState(); - break; - case User user when user.flags.HasFlag(User.Flags.self): - _collector.Collect([user]); - goto newSession; - case NewSessionCreated when _client.User != null: - newSession: - await Task.Delay(HalfSec); // let the opportunity to call DropPendingUpdates/StopResync before a big resync - if (_local[L_PTS].pts != 0) await ResyncState(); - else await ResyncState(await _client.Updates_GetState()); - break; - case Updates_State state: - await ResyncState(state); - break; - } - } - - private async Task ResyncState(Updates_State state = null) - { - if (state != null) state.qts = 0; // for some reason Updates_GetState returns an invalid qts, so better consider we have no qts. - else state = new() { qts = int.MaxValue }; - await _sem.WaitAsync(); - try - { - var local = _local[L_PTS]; - Log?.Invoke(2, $"Got Updates_State {local.pts}->{state.pts}, date={new DateTime(_local[L_SEQ].access_hash, DateTimeKind.Utc)}->{state.date}, seq={_local[L_SEQ].pts}->{state.seq}"); - if (local.pts == 0 || local.pts >= state.pts && _local[L_SEQ].pts >= state.seq && _local[L_QTS].pts >= state.qts) - await HandleDifference(null, null, state, null); - else if (await GetDifference(L_PTS, state.pts, local)) - await ApplyFilledGaps(); - } - finally { _sem.Release(); } - } - - private async Task OnUpdates(UpdatesBase updates, bool own) - { - RaiseCollect(updates.Users, updates.Chats); - await _sem.WaitAsync(); - try - { - await HandleUpdates(updates, own); - } - finally { _sem.Release(); } - } - - private async Task HandleUpdates(UpdatesBase updates, bool own) - { - var now = _lastUpdateStamp = DateTime.UtcNow; - var updateList = updates.UpdateList; - if (updates is UpdateShortSentMessage sent) - updateList = [new UpdateNewMessage { pts = sent.pts, pts_count = sent.pts_count, message = new Message { - flags = (Message.Flags)sent.flags, - id = sent.id, date = sent.date, entities = sent.entities, media = sent.media, ttl_period = sent.ttl_period, - } }]; - else if (updates is UpdateShortMessage usm && !_collector.HasUser(usm.user_id)) - RaiseCollect(await _client.Updates_GetDifference(usm.pts - usm.pts_count, usm.date, 0)); - else if (updates is UpdateShortChatMessage uscm && (!_collector.HasUser(uscm.from_id) || !_collector.HasChat(uscm.chat_id))) - RaiseCollect(await _client.Updates_GetDifference(uscm.pts - uscm.pts_count, uscm.date, 0)); - - bool ptsChanged = false, gotUPts = false; - int seq = 0; - try - { - if (updates is UpdatesTooLong) - { - var local_pts = _local[L_PTS]; - ptsChanged = await GetDifference(L_PTS, local_pts.pts, local_pts); - return; - } - foreach (var update in updateList) - { - if (update == null) continue; - var (mbox_id, pts, pts_count) = update.GetMBox(); - if (pts == 0) (mbox_id, pts, pts_count) = updates.GetMBox(); - MBoxState local = null; - if (pts != 0) - { - local = _local.GetOrCreate(mbox_id); - if (mbox_id > 0 && local.access_hash == 0) - if (updates.Chats.TryGetValue(mbox_id, out var chat) && chat is Channel channel && !channel.flags.HasFlag(Channel.Flags.min)) - local.access_hash = channel.access_hash; - var diff = local.pts + pts_count - pts; - if (diff > 0 && pts_count != 0) // the update was already applied, and must be ignored. - { - Log?.Invoke(1, $"({mbox_id,10}, {local.pts,6}+{pts_count}->{pts,-6}) {update,-30} ignored {ExtendedLog(update)}"); - continue; - } - if (diff < 0) // there's an update gap that must be filled. - { - Log?.Invoke(1, $"({mbox_id,10}, {local.pts,6}+{pts_count}->{pts,-6}) {update,-30} pending {ExtendedLog(update)}"); - _pending.Add((update, updates, own, now + HalfSec)); - _recoveringGaps ??= Task.Delay(HalfSec).ContinueWith(RecoverGaps, _scheduler); - continue; - } - // the update can be applied. - } - Log?.Invoke(1, $"({mbox_id,10}, {local?.pts,6}+{pts_count}->{pts,-6}) {update,-30} applied {ExtendedLog(update)}"); - if (mbox_id == L_SEQ && update is UpdatePtsChanged) gotUPts = true; - if (pts_count > 0 && pts != 0) - { - ptsChanged = true; - if (mbox_id == L_SEQ) - seq = pts; - else if (pts_count != 0) - local.pts = pts; - } - if (!own) await RaiseUpdate(update); - } - } - finally - { - if (seq > 0) // update local_seq & date after the updates were applied - { - var local_seq = _local[L_SEQ]; - local_seq.pts = seq; - local_seq.access_hash = updates.Date.Ticks; - } - if (gotUPts) ptsChanged = await GetDifference(L_PTS, _local[L_PTS].pts = 1, _local[L_PTS]); - if (ptsChanged) await ApplyFilledGaps(); - } - } - - private async Task ApplyFilledGaps() - { - if (_pending.Count != 0) Log?.Invoke(2, $"Trying to apply {_pending.Count} pending updates after filled gaps"); - int removed = 0; - for (int i = 0; i < _pending.Count; ) - { - var (update, updates, own, _) = _pending[i]; - var (mbox_id, pts, pts_count) = update.GetMBox(); - if (pts == 0) (mbox_id, pts, pts_count) = updates.GetMBox(); - var local = _local[mbox_id]; - var diff = local.pts + pts_count - pts; - if (diff < 0) - ++i; // there's still a gap, skip it - else - { - _pending.RemoveAt(i); - ++removed; - if (diff > 0) // the update was already applied, remove & ignore - Log?.Invoke(1, $"({mbox_id,10}, {local.pts,6}+{pts_count}->{pts,-6}) {update,-30} obsolete {ExtendedLog(update)}"); - else - { - Log?.Invoke(1, $"({mbox_id,10}, {local.pts,6}+{pts_count}->{pts,-6}) {update,-30} applied now {ExtendedLog(update)}"); - // the update can be applied. - local.pts = pts; - if (mbox_id == L_SEQ) local.access_hash = updates.Date.Ticks; - if (!own) await RaiseUpdate(update); - i = 0; // rescan pending updates from start - } - } - } - return removed; - } - - private async Task RecoverGaps(Task _) // https://corefork.telegram.org/api/updates#recovering-gaps - { - await _sem.WaitAsync(); - try - { - _recoveringGaps = null; - if (_pending.Count == 0) return; - Log?.Invoke(2, $"Trying to recover gaps for {_pending.Count} pending updates"); - var now = DateTime.UtcNow; - while (_pending.Count != 0) - { - var (update, updates, own, stamp) = _pending[0]; - if (stamp > now) - { - _recoveringGaps = Task.Delay(stamp - now).ContinueWith(RecoverGaps, _scheduler); - return; - } - var (mbox_id, pts, pts_count) = update.GetMBox(); - if (pts == 0) (mbox_id, pts, pts_count) = updates.GetMBox(); - var local = _local[mbox_id]; - bool getDiffSuccess = false; - if (local.pts == 0) - Log?.Invoke(2, $"({mbox_id,10}, new +{pts_count}->{pts,-6}) {update,-30} First appearance of MBox {ExtendedLog(update)}"); - else if (local.access_hash == -1) // no valid access_hash for this channel, so just raise this update - Log?.Invoke(3, $"({mbox_id,10}, {local.pts,6}+{pts_count}->{pts,-6}) {update,-30} No access_hash to recover {ExtendedLog(update)}"); - else if (local.pts + pts_count - pts >= 0) - getDiffSuccess = true; - else - { - Log?.Invoke(1, $"({mbox_id,10}, {local.pts,6}+{pts_count}->{pts,-6}) {update,-30} Calling GetDifference {ExtendedLog(update)}"); - getDiffSuccess = await GetDifference(mbox_id, pts, local); - } - if (!getDiffSuccess) // no getDiff => just raise received pending updates in order - { - local.pts = pts - pts_count; - for (int i = 1; i < _pending.Count; i++) // find lowest pending pts-pts_count for this mbox - { - var pending = _pending[i]; - var mbox = pending.update.GetMBox(); - if (mbox.pts == 0) mbox = pending.updates.GetMBox(); - if (mbox.mbox_id == mbox_id) local.pts = Math.Min(local.pts, mbox.pts - mbox.pts_count); - } - } - - if (await ApplyFilledGaps() == 0) - { - Log?.Invoke(3, $"({mbox_id,10}, {local.pts,6}+{pts_count}->{pts,-6}) {update,-30} forcibly removed!"); - _pending.RemoveAt(0); - local.pts = pts; - if (!own) await RaiseUpdate(update); - } - } - } - finally { _sem.Release(); } - } - - public async Task StopResync() - { - await _sem.WaitAsync(); - try - { - foreach (var local in _local.Values) - local.pts = 0; - _pending.Clear(); - } - finally { _sem.Release(); } - } - - private async Task GetInputChannel(long channel_id, MBoxState local) - { - if (channel_id <= 0) return null; - if (local?.access_hash is not null and not 0) - return new InputChannel(channel_id, local.access_hash); - var inputChannel = new InputChannel(channel_id, 0); - try - { - var mc = await _client.Channels_GetChannels(inputChannel); - if (mc.chats.TryGetValue(channel_id, out var chat) && chat is Channel channel) - inputChannel.access_hash = channel.access_hash; - } - catch (Exception) - { - inputChannel.access_hash = -1; // no valid access_hash available - } - local ??= _local[channel_id] = new(); - local.access_hash = inputChannel.access_hash; - return inputChannel; - } - - private async Task GetDifference(long mbox_id, int expected_pts, MBoxState local) - { - try - { - moreDiffNeeded: - if (mbox_id <= 0) - { - Log?.Invoke(0, $"Local states {string.Join(" ", _local.Select(l => $"{l.Key}:{l.Value.pts}"))}"); - var local_seq = _local[L_SEQ]; - var diff = await _client.Updates_GetDifference(_local[L_PTS].pts, qts: _local[L_QTS].pts, - date: new DateTime(local_seq.access_hash, DateTimeKind.Utc)); - Log?.Invoke(1, $"{diff.GetType().Name[8..]}: {diff.NewMessages.Length} msg, {diff.OtherUpdates.Length} upd, pts={diff.State?.pts}, date={diff.State?.date}, seq={diff.State?.seq}, msgIDs={string.Join(" ", diff.NewMessages.Select(m => m.ID))}"); - switch (diff) - { - case Updates_Difference ud: - await HandleDifference(ud.new_messages, ud.new_encrypted_messages, ud.state, - new UpdatesCombined { updates = ud.other_updates, users = ud.users, chats = ud.chats, - date = ud.state.date, seq_start = local_seq.pts + 1, seq = ud.state.seq }); - break; - case Updates_DifferenceSlice uds: - await HandleDifference(uds.new_messages, uds.new_encrypted_messages, uds.intermediate_state, - new UpdatesCombined { updates = uds.other_updates, users = uds.users, chats = uds.chats, - date = uds.intermediate_state.date, seq_start = local_seq.pts + 1, seq = uds.intermediate_state.seq }); - goto moreDiffNeeded; - case Updates_DifferenceTooLong udtl: - _local[L_PTS].pts = udtl.pts; - goto moreDiffNeeded; - case Updates_DifferenceEmpty ude: - local_seq.pts = ude.seq; - local_seq.access_hash = ude.date.Ticks; - _lastUpdateStamp = DateTime.UtcNow; - break; - } - } - else - { - var channel = await GetInputChannel(mbox_id, local); - if (channel.access_hash == -1) return false; - try - { - var diff = await _client.Updates_GetChannelDifference(channel, null, local.pts); - Log?.Invoke(1, $"{diff.GetType().Name[8..]}({mbox_id}): {diff.NewMessages.Length} msg, {diff.OtherUpdates.Length} upd, pts={diff.Pts}, msgIDs={string.Join(" ", diff.NewMessages.Select(m => m.ID))}"); - switch (diff) - { - case Updates_ChannelDifference ucd: - local.pts = ucd.pts; - await HandleDifference(ucd.new_messages, null, null, - new UpdatesCombined { updates = ucd.other_updates, users = ucd.users, chats = ucd.chats }); - if (!ucd.flags.HasFlag(Updates_ChannelDifference.Flags.final)) goto moreDiffNeeded; - break; - case Updates_ChannelDifferenceTooLong ucdtl: - if (ucdtl.dialog is Dialog dialog) local.pts = dialog.pts; - await HandleDifference(ucdtl.messages, null, null, - new UpdatesCombined { updates = null, users = ucdtl.users, chats = ucdtl.chats }); - break; - case Updates_ChannelDifferenceEmpty ucde: - local.pts = ucde.pts; - break; - } - } - catch (RpcException ex) when (ex.Message is "CHANNEL_PRIVATE" or "CHANNEL_INVALID") - { - local.access_hash = -1; // access_hash is no longer valid - throw; - } - } - return true; - } - catch (Exception ex) - { - Log?.Invoke(4, $"GetDifference({mbox_id}, {local.pts}->{expected_pts}) raised {ex}"); - if (ex.Message == "PERSISTENT_TIMESTAMP_INVALID") // oh boy, we're lost! - if (mbox_id <= 0) - await HandleDifference(null, null, await _client.Updates_GetState(), null); - else if ((await _client.Channels_GetFullChannel(await GetInputChannel(mbox_id, local))).full_chat is ChannelFull full) - local.pts = full.pts; - } - finally - { - if (local.pts < expected_pts) local.pts = expected_pts; - } - return false; - } - - private async Task HandleDifference(MessageBase[] new_messages, EncryptedMessageBase[] enc_messages, Updates_State state, UpdatesCombined updates) - { - if (updates != null) - RaiseCollect(updates.users, updates.chats); - try - { - int updatesCount = updates?.updates.Length ?? 0; - if (updatesCount != 0) - for (int i = 0; i < updates.updates.Length; i++) - { - var update = updates.updates[i]; - if (update is UpdateMessageID or UpdateStoryID) - { - await RaiseUpdate(update); - updates.updates[i] = null; - --updatesCount; - } - } - if (new_messages?.Length > 0) - { - var update = state == null ? new UpdateNewChannelMessage() : new UpdateNewMessage() { pts = state.pts, pts_count = 1 }; - foreach (var msg in new_messages) - { - if (_pending.Any(p => p is { own: true, update: UpdateNewMessage { message: { Peer.ID: var peer_id, ID: var msg_id } } } - && peer_id == msg.Peer.ID && msg_id == msg.ID)) - continue; - update.message = msg; - await RaiseUpdate(update); - } - } - if (enc_messages?.Length > 0) - { - var update = new UpdateNewEncryptedMessage(); - if (state != null) update.qts = state.qts; - foreach (var msg in enc_messages) - { - if (_pending.Any(p => p is { own: true, update: UpdateNewEncryptedMessage { message: { ChatId: var chat_id, RandomId: var random_id } } } - && chat_id == msg.ChatId && random_id == msg.RandomId)) - continue; - update.message = msg; - await RaiseUpdate(update); - } - } - if (updatesCount != 0) - { - // try to remove matching pending OwnUpdates from this updates list (starting from most-recent) - for (int p = _pending.Count - 1, u = updates.updates.Length; p >= 0 && u > 0; p--) - { - if (_pending[p].own == false) continue; - var updateP = _pending[p].update; - var (mbox_idP, ptsP, pts_countP) = updateP.GetMBox(); - if (ptsP == 0) (mbox_idP, ptsP, pts_countP) = _pending[p].updates.GetMBox(); - Type updatePtype = null; - while (--u >= 0) - { - var update = updates.updates[u]; - if (update == null) continue; - var (mbox_id, pts, pts_count) = update.GetMBox(); - if (pts == 0) (mbox_id, pts, pts_count) = updates.GetMBox(); - if (mbox_idP == mbox_id && ptsP <= pts) - { - updatePtype ??= updateP.GetType(); - if (updatePtype == (update is UpdateDeleteMessages ? typeof(UpdateAffectedMessages) : update.GetType())) - { - updates.updates[u] = null; - --updatesCount; - break; - } - } - } - } - if (updatesCount != 0) - await HandleUpdates(updates, false); - } - } - finally - { - if (state != null) - { - _local[L_PTS].pts = state.pts; - _local[L_QTS].pts = state.qts; - var local_seq = _local[L_SEQ]; - local_seq.pts = state.seq; - local_seq.access_hash = state.date.Ticks; - } - } - } - - private void RaiseCollect(Updates_DifferenceBase diff) - { - if (diff is Updates_DifferenceSlice uds) - RaiseCollect(uds.users, uds.chats); - else if (diff is Updates_Difference ud) - RaiseCollect(ud.users, ud.chats); - } - - private void RaiseCollect(Dictionary users, Dictionary chats) - { - try - { - foreach (var chat in chats.Values) - if (chat is Channel channel && !channel.flags.HasFlag(Channel.Flags.min)) - if (_local.TryGetValue(channel.id, out var local)) - local.access_hash = channel.access_hash; - _collector.Collect(users.Values); - _collector.Collect(chats.Values); - } - catch (Exception ex) - { - Log?.Invoke(4, $"Collect({users?.Count},{chats?.Count}) raised {ex}"); - } - } - - private async Task RaiseUpdate(Update update) - { - try - { - var task = _onUpdate(update); - if (!_reentrant) await task; - } - catch (Exception ex) - { - Log?.Invoke(4, $"onUpdate({update?.GetType().Name}) raised {ex}"); - } - } - - private static string ExtendedLog(Update update) => update switch - { - UpdateNewMessage unm => $"| msgID={unm.message.ID}", - UpdateEditMessage uem => $"| msgID={uem.message.ID}", - UpdateDeleteMessages udm => $"| count={udm.messages.Length}", - _ => null - }; - - /// Load latest dialogs states, checking for missing updates - /// structure returned by Messages_Get*Dialogs calls - /// Dangerous! Load full history of unknown new channels as updates - public async Task LoadDialogs(Messages_Dialogs dialogs, bool fullLoadNewChans = false) - { - await _sem.WaitAsync(); - try - { - foreach (var dialog in dialogs.dialogs.OfType()) - { - if (dialog.peer is not PeerChannel pc) continue; - var local = _local.GetOrCreate(pc.channel_id); - if (dialogs.chats.TryGetValue(pc.channel_id, out var chat) && chat is Channel channel) - local.access_hash = channel.access_hash; - if (local.pts is 0) - if (fullLoadNewChans) local.pts = 1; - else local.pts = dialog.pts; - if (local.pts < dialog.pts) - { - Log?.Invoke(1, $"LoadDialogs {pc.channel_id} has {local.pts} < {dialog.pts} ({dialog.folder_id})"); - await GetDifference(pc.channel_id, dialog.pts, local); - } - } - } - finally { _sem.Release(); } - } - - /// Save the current state of the manager to JSON file - /// File path to write - /// Note: This does not save the content of collected Users/Chats dictionaries - public void SaveState(string statePath) - => System.IO.File.WriteAllText(statePath, System.Text.Json.JsonSerializer.Serialize(State, Helpers.JsonOptions)); - public static Dictionary LoadState(string statePath) => !System.IO.File.Exists(statePath) ? null - : System.Text.Json.JsonSerializer.Deserialize>(System.IO.File.ReadAllText(statePath), Helpers.JsonOptions); - /// returns a or for the given Peer (only if using the default collector) - public IPeerInfo UserOrChat(Peer peer) => peer?.UserOrChat(Users, Chats); - } - - public interface IPeerCollector - { - void Collect(IEnumerable users); - void Collect(IEnumerable chats); - bool HasUser(long id); - bool HasChat(long id); - } -} - -namespace TL -{ - using WTelegram; - - [EditorBrowsable(EditorBrowsableState.Never)] - public static class UpdateManagerExtensions - { - /// Manager ensuring that you receive Telegram updates in correct order, without missing any - /// Event to be called on sequential individual update - /// Resume session by recovering all updates that occured since the state saved in this file - /// Custom users/chats collector. By default, those are collected in properties Users/Chats - /// if your method can be called again even when last async call didn't return yet - public static UpdateManager WithUpdateManager(this Client client, Func onUpdate, string statePath, IPeerCollector collector = null, bool reentrant = false) - => new(client, onUpdate, UpdateManager.LoadState(statePath), collector, reentrant); - - /// Manager ensuring that you receive Telegram updates in correct order, without missing any - /// Event to be called on sequential individual update - /// (optional) Resume session by recovering all updates that occured since this state - /// Custom users/chats collector. By default, those are collected in properties Users/Chats - /// if your method can be called again even when last async call didn't return yet - public static UpdateManager WithUpdateManager(this Client client, Func onUpdate, IDictionary state = null, IPeerCollector collector = null, bool reentrant = false) - => new(client, onUpdate, state, collector, reentrant); - } -} \ No newline at end of file diff --git a/src/WTelegramClient.csproj b/src/WTelegramClient.csproj index bd1d6c3..b4b7057 100644 --- a/src/WTelegramClient.csproj +++ b/src/WTelegramClient.csproj @@ -2,63 +2,55 @@ Library - netstandard2.0;net5.0;net8.0 + netstandard2.0;net5.0 latest WTelegram true - true + True true snupkg + true true WTelegramClient + Telegram client library written 100% in C# and .NET Standard Wizou - 0.0.0 - layer.223 - Telegram Client API (MTProto) library written 100% in C# and .NET Standard | Latest API layer: 223 - -Release Notes: -$(ReleaseNotes) - Copyright © Olivier Marcoux 2021-2026 - MIT - https://wiz0u.github.io/WTelegramClient + Copyright © Olivier Marcoux 2021 logo.png - true + Telegram;Client;Api;UserBot;MTProto + MIT + https://github.com/wiz0u/WTelegramClient https://github.com/wiz0u/WTelegramClient.git git - Telegram;MTProto;Client;Api;UserBot - README.md - $(ReleaseNotes) - NETSDK1138;CS0419;CS1573;CS1591;CA1850 - TRACE;OBFUSCATION;MTPG - + + + + + IDE0079;0419;1573;1591 - - - - - - + + - - - - + + + + + + + + + - - - - - - - + + + + +