WTelegramClient/README.md

201 lines
14 KiB
Markdown
Raw Normal View History

[![API Layer](https://img.shields.io/badge/API_Layer-165-blueviolet)](https://corefork.telegram.org/methods)
2022-11-15 16:20:00 +01:00
[![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)
2023-03-16 13:43:18 +01:00
[![Donate](https://img.shields.io/badge/Help_this_project:-Donate-ff4444)](https://www.buymeacoffee.com/wizou)
2021-08-08 14:58:49 +02:00
## _Telegram Client API library written 100% in C# and .NET_
2021-08-07 06:25:59 +02:00
2022-04-13 15:53:06 +02:00
This library allows you to connect to Telegram and control a user programmatically (or a bot, but [Telegram.Bot](https://github.com/TelegramBots/Telegram.Bot) is much easier for that).
2022-05-07 22:13:20 +02:00
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**...
2021-12-16 14:41:43 +01:00
>If you are a beginner in C#, starting a project based on this library might not be a great idea.
2021-08-07 06:25:59 +02:00
2022-02-26 05:22:41 +01:00
# How to use
2022-05-07 22:13:20 +02:00
After installing WTelegramClient through [Nuget](https://www.nuget.org/packages/WTelegramClient/), your first Console program will be as simple as:
2021-08-07 06:25:59 +02:00
```csharp
static async Task Main(string[] _)
2021-08-07 06:25:59 +02:00
{
using var client = new WTelegram.Client();
2022-10-07 03:00:57 +02:00
var myself = await client.LoginUserIfNeeded();
Console.WriteLine($"We are logged-in as {myself} (id {myself.id})");
2021-08-07 06:25:59 +02:00
}
```
2022-09-14 18:22:52 +02:00
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.
2022-02-11 02:43:48 +01:00
Those api hash/id represent your application and one can be used for handling many user accounts.
2021-08-07 06:25:59 +02:00
2022-09-14 18:22:52 +02:00
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).
2021-08-07 06:25:59 +02:00
2022-03-10 14:55:32 +01:00
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**.
2022-03-10 14:55:32 +01:00
All these login scenarios are handled automatically within the call to `LoginUserIfNeeded`.
2021-08-07 06:25:59 +02:00
2022-09-02 23:02:44 +02:00
After login, you now have access to the **[full range of Telegram Client APIs](https://corefork.telegram.org/methods)**.
2022-07-12 01:31:18 +02:00
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(...)`
2021-08-07 06:25:59 +02:00
# 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.
2021-08-07 06:25:59 +02:00
2022-09-14 18:22:52 +02:00
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.
2021-08-07 06:25:59 +02:00
2023-03-24 16:57:54 +01:00
That file path is configurable (**session_pathname**), and under various circumstances *(changing user or server address, write permissions)*
2022-09-14 18:22:52 +02:00
you may want to change it or simply delete the existing session file in order to restart the authentification process.
2021-08-07 06:25:59 +02:00
# Non-interactive configuration
2022-04-01 21:48:28 +02:00
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.
2021-08-07 06:25:59 +02:00
To do this, you need to write a method that will provide the answers, and pass it on the constructor:
2021-08-07 06:25:59 +02:00
```csharp
static string Config(string what)
{
2021-10-28 04:59:41 +02:00
switch (what)
{
case "api_id": return "YOUR_API_ID";
case "api_hash": return "YOUR_API_HASH";
case "phone_number": return "+12025550156";
2021-10-29 23:27:23 +02:00
case "verification_code": Console.Write("Code: "); return Console.ReadLine();
2021-10-28 04:59:41 +02:00
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
}
2021-08-07 06:25:59 +02:00
}
...
using var client = new WTelegram.Client(Config);
```
2021-10-29 23:27:23 +02:00
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.
2022-08-06 13:06:46 +02:00
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)*
2022-08-06 13:06:46 +02:00
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)*.
2021-08-07 06:25:59 +02:00
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).
2021-08-07 06:25:59 +02:00
2022-10-08 15:35:10 +02:00
# 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.
2022-10-08 15:35:10 +02:00
async Task DoLogin(string loginInfo) // (add this method to your code)
2022-10-08 15:35:10 +02:00
{
2022-11-12 19:40:34 +01:00
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})");
2022-10-08 15:35:10 +02:00
}
```
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)
2022-10-08 15:35:10 +02:00
2021-08-07 06:25:59 +02:00
# Example of API call
2022-09-14 18:22:52 +02:00
> 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` )
2021-08-07 06:25:59 +02:00
2022-09-14 18:22:52 +02:00
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.
2021-08-07 06:25:59 +02:00
2022-09-14 18:22:52 +02:00
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`.
2021-08-07 06:59:36 +02:00
2022-09-14 18:22:52 +02:00
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:
2021-08-07 06:25:59 +02:00
```csharp
2021-08-07 06:59:36 +02:00
using TL;
...
var chats = await client.Messages_GetAllChats();
2021-08-07 06:59:36 +02:00
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");
2021-08-07 06:25:59 +02:00
```
➡️ 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.
2021-11-15 17:17:11 +01:00
2021-12-07 02:32:19 +01:00
<a name="terminology"></a>
2021-10-20 00:24:50 +02:00
# Terminology in Telegram Client API
2021-10-20 00:24:50 +02:00
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))*,
2022-09-14 18:22:52 +02:00
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`)
2021-12-26 18:28:10 +01:00
**⚠️ 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.
2021-08-07 06:59:36 +02:00
# Other things to know
The Client class also offers `OnUpdate` and `OnOther` events that are triggered when Telegram servers sends Updates (like new messages or status) or other notifications, independently of your API requests.
See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L23) and [Examples/Program_ReactorError.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ReactorError.cs?ts=4#L32)
2021-10-01 05:46:51 +02:00
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.
2021-08-07 06:59:36 +02:00
The other configuration items that you can provide include: **session_pathname, email, email_verification_code, session_key, server_address, device_model, system_version, app_version, system_lang_code, lang_pack, lang_code, firebase, user_id, bot_token**
2021-08-07 06:59:36 +02:00
2022-09-14 18:22:52 +02:00
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).
2021-08-14 08:55:30 +02:00
2022-01-19 21:31:07 +01:00
I've added several useful converters, implicit cast or helper properties to various API objects so that they are more easy to manipulate.
2021-08-14 08:55:30 +02:00
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.
2021-08-14 08:55:30 +02:00
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**
2021-08-08 14:58:49 +02:00
2021-09-30 20:36:52 +02:00
# Library uses and limitations
This library can be used for any Telegram scenario including:
2021-09-30 20:36:52 +02:00
- Sequential or parallel automated steps based on API requests/responses
- Real-time [monitoring](https://wiz0u.github.io/WTelegramClient/EXAMPLES#updates) of incoming Updates/Messages
2021-09-30 20:36:52 +02:00
- Download/upload of files/media
- Exchange end-to-end encrypted messages/files in [Secret Chats](https://wiz0u.github.io/WTelegramClient/EXAMPLES#e2e)
2022-01-19 21:31:07 +01:00
- Building a full-featured interactive client
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.
2021-09-30 20:36:52 +02:00
Don't use this library for Spam or Scam. Respect Telegram [Terms of Service](https://telegram.org/tos)
2022-09-14 18:22:52 +02:00
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)
2021-10-28 04:59:41 +02:00
2023-03-16 13:43:18 +01:00
If you like this library, you can [buy me a coffee](https://www.buymeacoffee.com/wizou) ❤ This will help the project keep going.