WTelegramClient 4.1.7-dev.1

This is a prerelease version of WTelegramClient.
There is a newer version of this package available.
See the version list below for details.
dotnet add package WTelegramClient --version 4.1.7-dev.1                
NuGet\Install-Package WTelegramClient -Version 4.1.7-dev.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="WTelegramClient" Version="4.1.7-dev.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add WTelegramClient --version 4.1.7-dev.1                
#r "nuget: WTelegramClient, 4.1.7-dev.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install WTelegramClient as a Cake Addin
#addin nuget:?package=WTelegramClient&version=4.1.7-dev.1&prerelease

// Install WTelegramClient as a Cake Tool
#tool nuget:?package=WTelegramClient&version=4.1.7-dev.1&prerelease                

API Layer NuGet version NuGet prerelease Donate

Telegram Client API library written 100% in C# and .NET

This library allows you to connect to Telegram and control a user programmatically (or a bot, but 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.

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, your first Console program will be as simple as:

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})");
}

When run, this will prompt you interactively for your App api_hash and api_id (that you obtain through Telegram's API development tools 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.

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).

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.

After login, you now have access to the full range of Telegram Client APIs. 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(...)

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.

This is because WTelegramClient saves (typically in the encrypted file bin\WTelegram.session) its state and the authentication keys that were negotiated with Telegram so that you needn't sign-in again every time.

That file path is configurable (session_pathname), and under various circumstances (changing user or server address, write permissions) 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.

To do this, you need to write a method that will provide the answers, and pass it on the constructor:

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
    }
}
...
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 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).

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.

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:

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 and ASP.NET example

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 )

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.

The Telegram API object classes are defined in the TL namespace, and the API functions are available as async methods of Client.

Below is an example of calling the 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:

using TL;
...
var chats = await client.Messages_GetAllChats();
Console.WriteLine("This user has joined the following:");
foreach (var (id, chat) in chats.chats)
    if (chat.IsActive)
        Console.WriteLine($"{id,10}: {chat}");
Console.Write("Type a chat ID to send a message: ");
long chatId = long.Parse(Console.ReadLine());
var target = chats.chats[chatId];
Console.WriteLine($"Sending a message in chat {chatId}: {target.Title}");
await client.SendMessageAsync(target, "Hello, World");

➡️ You can find lots of useful code snippets in EXAMPLES and more detailed programs in the Examples subdirectory.
➡️ Check the FAQ if example codes don't compile correctly on your machine, or other troubleshooting.

<a name="terminology"></a>

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), or a broadcast channel (the broadcast flag differentiate those)
  • Chat: A private basic chat group 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 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 to simplify the handling of such updates.
See Examples/Program_ListenUpdates.cs and Examples/Program_ReactorError.cs

An invalid API request can result in a RpcException being raised, reflecting the error code and status text of the problem.

To prevent getting banned during dev, you can connect to 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 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 or experiment).

I've added several useful converters, implicit cast or helper properties to various API objects so that they are more easy to manipulate.

Beyond the TL async methods, the Client class offers a few other methods to simplify the sending/receiving of files, medias or messages, as well as generic handling of chats/channels.

This library works best with .NET 5.0+ (faster, no dependencies) and is also available for .NET Standard 2.0 (.NET Framework 4.6.1+ & .NET Core 2.0+) and Xamarin/Mono.Android

Library uses and limitations

This library can be used for any Telegram scenario including:

  • Sequential or parallel automated steps based on API requests/responses
  • Real-time monitoring of incoming Updates/Messages
  • Download/upload of files/media
  • Exchange end-to-end encrypted messages/files in Secret Chats
  • Building a full-featured interactive client

It has been tested in a Console app, in Windows Forms, in ASP.NET webservice, and in Xamarin/Android.

Don't use this library for Spam or Scam. Respect Telegram Terms of Service as well as the API Terms of Service or you might get banned from Telegram servers.

If you read all this ReadMe, the Frequently Asked Questions, the Examples codes and still have questions, feedback is welcome in our Telegram group @WTelegramClient

If you like this library, you can buy me a coffee ❤ This will help the project keep going.

© 2024 Olivier Marcoux

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (7)

Showing the top 5 NuGet packages that depend on WTelegramClient:

Package Downloads
WTelegramClient.Extensions.Updates

Extensions over WtelegramClient For Dealing With Updates

WTelegramBot

Telegram Bot API (local server) library providing more extended features Release Notes: - Bot API 7.11 - renaming of methods without Async suffix

MTProto

A MTProto client library based on wiz0u/WTelegramClient

ProfitSniper.Profitview

Package Description

WTC.Abstractions.Types

Telegram Type Abstractions For WTelegramClient

GitHub repositories (2)

Showing the top 2 popular GitHub repositories that depend on WTelegramClient:

Repository Stars
yiyungent/KnifeHub
🧰 简单易用的效率工具平台
DamianMorozov/TgDownloader
Telegram Downloader
Version Downloads Last updated
4.2.3-dev.2 56 11/2/2024
4.2.3-dev.1 44 11/1/2024
4.2.2 484 10/31/2024
4.2.2-dev.7 44 10/29/2024
4.2.2-dev.5 107 10/24/2024
4.2.2-dev.4 30 10/24/2024
4.2.2-dev.3 96 10/17/2024
4.2.2-dev.2 48 10/15/2024
4.2.2-dev.1 34 10/15/2024
4.2.1 3,857 10/7/2024
4.1.11-dev.4 43 10/7/2024
4.1.11-dev.3 72 9/30/2024
4.1.11-dev.2 98 9/22/2024
4.1.11-dev.1 56 9/21/2024
4.1.10 2,811 9/19/2024
4.1.10-dev.3 119 9/8/2024
4.1.10-dev.2 62 9/7/2024
4.1.10-dev.1 44 9/7/2024
4.1.9 2,020 9/7/2024
4.1.9-dev.2 58 9/6/2024
4.1.9-dev.1 72 9/5/2024
4.1.8 4,272 8/14/2024
4.1.7 796 8/10/2024
4.1.7-dev.1 57 8/10/2024
4.1.6 1,062 7/31/2024
4.1.6-dev.1 37 7/29/2024
4.1.5 1,924 7/20/2024
4.1.5-dev.2 59 7/20/2024
4.1.5-dev.1 140 7/12/2024
4.1.4 1,488 7/7/2024
4.1.3 320 7/6/2024
4.1.2 517 7/2/2024
4.1.2-dev.8 61 7/1/2024
4.1.2-dev.7 165 6/15/2024
4.1.2-dev.6 53 6/15/2024
4.1.2-dev.5 142 6/4/2024
4.1.2-dev.4 82 5/28/2024
4.1.2-dev.3 55 5/27/2024
4.1.2-dev.2 186 5/7/2024
4.1.2-dev.1 76 5/1/2024
4.1.1 11,512 4/28/2024
4.1.1-dev.5 58 4/28/2024
4.1.1-dev.2 60 4/27/2024
4.1.1-dev.1 56 4/27/2024
4.0.1 1,681 4/24/2024
4.0.1-dev.6 79 4/22/2024
4.0.1-dev.5 70 4/18/2024
4.0.1-dev.4 57 4/17/2024
4.0.1-dev.3 72 4/16/2024
4.0.1-dev.2 69 4/14/2024
4.0.1-dev.1 68 4/13/2024
4.0.0 2,545 4/5/2024
4.0.0-dev.8 65 4/4/2024
4.0.0-dev.7 56 4/3/2024
4.0.0-dev.6 93 3/30/2024
4.0.0-dev.5 65 3/29/2024
4.0.0-dev.4 73 3/28/2024
4.0.0-dev.2 80 3/26/2024
4.0.0-dev.1 80 3/26/2024
3.7.2 1,835 3/24/2024
3.7.2-dev.3 71 3/23/2024
3.7.2-dev.2 81 3/19/2024
3.7.2-dev.1 78 3/13/2024
3.7.1 3,437 3/8/2024
3.6.7-dev.13 54 3/8/2024
3.6.7-dev.12 61 3/8/2024
3.6.7-dev.11 53 3/8/2024
3.6.7-dev.9 67 3/8/2024
3.6.7-dev.8 81 3/4/2024
3.6.7-dev.7 125 2/25/2024
3.6.7-dev.6 86 2/21/2024
3.6.7-dev.5 74 2/19/2024
3.6.7-dev.4 76 2/18/2024
3.6.7-dev.3 72 2/18/2024
3.6.7-dev.1 56 2/18/2024
3.6.6 2,682 2/1/2024
3.6.5 3,005 1/18/2024
3.6.4 583 1/16/2024
3.6.4-dev.2 69 1/16/2024
3.6.4-dev.1 65 1/15/2024
3.6.3 4,652 12/31/2023
3.6.3-dev.1 82 12/31/2023
3.6.2 1,410 12/23/2023
3.6.2-dev.2 77 12/23/2023
3.6.2-dev.1 105 12/17/2023
3.6.1 2,978 11/30/2023
3.6.1-dev.7 68 11/30/2023
3.6.1-dev.6 78 11/29/2023
3.6.1-dev.2 95 11/25/2023
3.6.1-dev.1 156 11/17/2023
3.5.10-dev.1 109 11/11/2023
3.5.9 2,794 11/6/2023
3.5.8 1,571 10/28/2023
3.5.8-dev.5 81 10/28/2023
3.5.8-dev.4 133 10/24/2023
3.5.8-dev.3 81 10/24/2023
3.5.8-dev.2 110 10/19/2023
3.5.8-dev.1 114 10/9/2023
3.5.7 2,482 10/4/2023
3.5.6 1,420 9/22/2023
3.5.5 1,083 9/18/2023
3.5.5-dev.1 68 9/18/2023
3.5.4 3,057 9/6/2023
3.5.4-dev.2 84 9/6/2023
3.5.3 7,967 7/21/2023
3.5.2-dev.21 88 7/21/2023
3.5.2-dev.20 177 7/7/2023
3.5.2-dev.19 102 7/6/2023
3.5.2-dev.16 88 7/5/2023
3.5.2-dev.15 136 6/27/2023
3.5.2-dev.3 901 5/18/2023
3.5.2-dev.1 82 5/17/2023
3.5.1 24,474 5/17/2023
3.5.1-dev.4 85 5/17/2023
3.5.1-dev.3 477 5/9/2023
3.5.1-dev.2 148 5/5/2023
3.5.1-dev.1 103 5/2/2023
3.4.3-dev.4 90 5/1/2023
3.4.3-dev.3 98 4/29/2023
3.4.3-dev.2 177 4/25/2023
3.4.3-dev.1 113 4/25/2023
3.4.2 4,698 4/24/2023
3.4.2-dev.2 85 4/24/2023
3.4.2-dev.1 100 4/23/2023
3.4.1 1,079 4/21/2023
3.4.1-dev.5 83 4/21/2023
3.4.1-dev.4 164 4/9/2023
3.4.1-dev.2 89 4/8/2023
3.4.1-dev.1 112 4/2/2023
3.3.4-dev.1 99 4/1/2023
3.3.3 2,313 3/26/2023
3.3.3-dev.2 109 3/26/2023
3.3.3-dev.1 155 3/16/2023
3.3.2 1,961 3/9/2023
3.3.2-dev.2 92 3/9/2023
3.3.2-dev.1 95 3/9/2023
3.3.1 936 3/8/2023
3.3.1-dev.1 95 3/8/2023
3.2.3-dev.5 199 2/26/2023
3.2.3-dev.4 141 2/17/2023
3.2.3-dev.3 98 2/15/2023
3.2.3-dev.2 102 2/14/2023
3.2.3-dev.1 95 2/13/2023
3.2.2 9,528 2/6/2023
3.2.2-dev.7 110 2/5/2023
3.2.2-dev.6 117 2/4/2023
3.2.2-dev.5 128 1/26/2023
3.2.2-dev.4 174 1/12/2023
3.2.2-dev.3 127 1/9/2023
3.2.2-dev.2 118 1/7/2023
3.2.2-dev.1 123 1/6/2023
3.2.1 3,615 12/29/2022
3.2.1-dev.2 113 12/29/2022
3.2.1-dev.1 108 12/29/2022
3.1.6-dev.2 138 12/19/2022
3.1.6-dev.1 108 12/15/2022
3.1.5 2,405 12/7/2022
3.1.4-dev.6 100 12/7/2022
3.1.4-dev.5 102 12/5/2022
3.1.4-dev.4 118 12/2/2022
3.1.4-dev.3 123 11/26/2022
3.1.4-dev.2 105 11/26/2022
3.1.4-dev.1 105 11/26/2022
3.1.3 2,085 11/23/2022
3.1.3-dev.5 102 11/23/2022
3.1.3-dev.3 109 11/20/2022
3.1.2 1,832 11/12/2022
3.0.3 1,891 11/1/2022
3.0.2 2,073 10/26/2022
3.0.1 1,297 10/21/2022
3.0.0 3,296 10/8/2022
2.6.4 4,361 9/14/2022
2.6.3 1,820 9/2/2022
2.6.2 4,257 8/6/2022
2.5.2 3,954 7/1/2022
2.5.1 19,123 6/15/2022
2.4.1 24,675 5/20/2022
2.3.3 1,690 5/14/2022
2.3.2 1,986 5/7/2022
2.3.1 3,824 4/13/2022
2.2.1 4,844 3/28/2022
2.1.4 1,329 3/23/2022
2.1.3 1,410 3/18/2022
2.1.2 31,297 2/27/2022
2.1.1 3,004 2/13/2022
2.0.3 1,695 2/7/2022
2.0.2 1,185 2/4/2022
2.0.1 1,586 1/30/2022
2.0.0 1,611 1/24/2022
1.9.4 1,391 1/19/2022
1.9.3 1,203 1/17/2022
1.9.2 3,319 1/11/2022
1.9.1 1,211 1/3/2022
1.8.3 1,017 12/30/2021
1.8.2 1,698 12/25/2021
1.8.1 1,101 12/21/2021
1.7.6 1,311 12/12/2021
1.7.5 1,265 12/6/2021
1.7.4 1,570 12/1/2021
1.7.3 2,170 11/27/2021
1.7.2 1,577 11/20/2021
1.7.1 1,016 11/10/2021
1.6.4 1,067 11/6/2021
1.6.3 977 11/3/2021
1.6.2 977 10/31/2021
1.6.1 1,001 10/31/2021
1.5.1 1,016 10/25/2021
1.4.1 963 10/20/2021
1.3.1 951 10/19/2021
1.3.0 1,023 10/17/2021
1.0.2 1,006 10/15/2021
1.0.1 932 10/11/2021
1.0.0 1,081 9/30/2021
0.9.5 1,046 9/1/2021
0.9.4 951 8/29/2021
0.9.3 937 8/24/2021
0.9.2 944 8/19/2021
0.9.1 993 8/16/2021
0.8.1 994 8/13/2021
0.7.4 984 8/10/2021
0.7.3 936 8/9/2021
0.7.1 1,054 8/8/2021

Fix infinite recursion on Dispose after downloads (fix #274)