updated README

This commit is contained in:
Wizou 2021-08-07 06:59:36 +02:00
parent 39ba5c3ff4
commit 95870c485d
8 changed files with 49 additions and 17 deletions

View file

@ -1,9 +1,9 @@
# WTelegramClient # WTelegramClient
## _Telegram client library written 100% in C# and .NET Core_ ### _Telegram client library written 100% in C# and .NET Core_
## How to use ## How to use
:warning: This library makes heavy use of asynchronous C# programming (`async/await`) so make sure you are familiar with this before attempting to use it. :warning: This library relies on asynchronous C# programming (`async/await`) so make sure you are familiar with this before proceeding.
After installing WTelegramClient through Nuget, your first Console program will be as simple as: After installing WTelegramClient through Nuget, your first Console program will be as simple as:
```csharp ```csharp
@ -21,12 +21,12 @@ Then it will attempt to sign-in as a user for which you must enter the **phone_n
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**. 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**.
And that's it, you have now access to the full range of Telegram services, mainly through calls to `await client.CallAsync(...)` And that's it, you now have access to the full range of Telegram services, mainly through calls to `await client.CallAsync(...)`
# Saved session # Saved session
If you run this program again, you will notice that the previous prompts are gone and you are automatically logged-on and ready to go. If you run this program again, you will notice that the previous 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 negociated with Telegram so that you needn't sign-in again every time before using the Telegram API. 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, 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. 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.
@ -50,24 +50,28 @@ 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. There are other configuration items that are queried to your method but returning `null` let WTelegramClient choose a default adequate value.
The configuration items shown above are the only one that have no default values and are required to be provided by your method. The configuration items shown above are the only ones that have no default values and are required to be provided by your method.
The constructor also takes another delegate parameter that will be called for any other Update and other information/status messages that Telegram sends unsollicited, independently of your API requests. The constructor also takes another optional delegate parameter that will be called for any other Update and other information/status/service messages that Telegram sends unsollicited, independently of your API requests.
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. 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.
The first `int` parameter is the log severity, compatible with the classic [LogLevel enum](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel) 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 # Example of API call
:information_source: The Telegram API makes extensive usage of base and derived classes, so be ready to use the various syntax C# offers to check/cast base classes into the more useful derived classes (`is`, `as`, `case DerivedType` ) :information_source: 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` )
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 appear in groups. 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.
Below is an example of calling the [messages.getAllChats](https://core.telegram.org/method/messages.getAllChats) API and enumerating the various groups/channels the users is into: The Telegram [API object classes](https://core.telegram.org/schema) are defined in the `TL` namespace, and the request classes ([API functions](https://core.telegram.org/methods)) usable with `client.CallAsync` are under the `TL.Fn` static class.
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:
```csharp ```csharp
using TL;
...
var chatsBase = await client.CallAsync(new Fn.Messages_GetAllChats { }); var chatsBase = await client.CallAsync(new Fn.Messages_GetAllChats { });
if (chatsBase is not Messages_Chats { chats: var chats }) return; if (chatsBase is not Messages_Chats { chats: var chats }) throw new Exception("hu?");
Console.WriteLine("This person has joined the following:"); Console.WriteLine("This user has joined the following:");
foreach (var chat in chats) foreach (var chat in chats)
switch (chat) switch (chat)
{ {
@ -83,4 +87,28 @@ foreach (var chat in chats)
} }
``` ```
# Other things to know
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.
Beyond CallAsync, the Client class offers a few other methods to simplify the sending of files, medias or messages.
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**
# Development status
The library is already well usable for many scenarios involving automated steps based on API requests/responses.
Here are the main expected developments:
- [x] Encrypt session file
- [x] Support SignUp of unregistered users
- [x] Improve code Generator (import of TL-schema JSONs)
- [ ] Improve Nuget deployment experience (debug symbols? XML documentation?)
- [ ] Convert API functions classes to real methods and serialize structures without using Reflection
- [ ] Separate task/thread for reading/handling update messages independently from CallAsync
- [ ] Support MTProto 2.0
- [ ] Support users with 2FA enabled
- [ ] Support secret chats end-to-end encryption & PFS
- [ ] Support all service messages
------------
[![Build Status](https://dev.azure.com/wiz0u/WTelegramClient/_apis/build/status/wiz0u.WTelegramClient?branchName=master)](https://dev.azure.com/wiz0u/WTelegramClient/_build/latest?definitionId=7&branchName=master) [![Build Status](https://dev.azure.com/wiz0u/WTelegramClient/_apis/build/status/wiz0u.WTelegramClient?branchName=master)](https://dev.azure.com/wiz0u/WTelegramClient/_build/latest?definitionId=7&branchName=master)

View file

@ -456,7 +456,6 @@ namespace WTelegram
} }
#region TL-Helpers #region TL-Helpers
/// <summary>Helper function to upload a file to Telegram</summary> /// <summary>Helper function to upload a file to Telegram</summary>
/// <returns>an <see cref="InputFile"/> or <see cref="InputFileBig"/> than can be used in various requests</returns> /// <returns>an <see cref="InputFile"/> or <see cref="InputFileBig"/> than can be used in various requests</returns>
public Task<InputFileBase> UploadFileAsync(string pathname) public Task<InputFileBase> UploadFileAsync(string pathname)

View file

@ -40,6 +40,7 @@ namespace WTelegram
Console.WriteLine("Parsing " + jsonPath); Console.WriteLine("Parsing " + jsonPath);
var schema = JsonSerializer.Deserialize<SchemaJson>(File.ReadAllText(jsonPath)); var schema = JsonSerializer.Deserialize<SchemaJson>(File.ReadAllText(jsonPath));
using var sw = File.CreateText(outputCs); using var sw = File.CreateText(outputCs);
sw.WriteLine("// This file is (mainly) generated automatically using the Generator class");
sw.WriteLine("using System;"); sw.WriteLine("using System;");
sw.WriteLine(); sw.WriteLine();
sw.WriteLine("namespace TL"); sw.WriteLine("namespace TL");

View file

@ -1,4 +1,5 @@
using System; // This file is (mainly) generated automatically using the Generator class
using System;
namespace TL namespace TL
{ {

View file

@ -1,3 +1,4 @@
// This file is (mainly) generated automatically using the Generator class
using System; using System;
namespace TL namespace TL

View file

@ -1,3 +1,4 @@
// This file is (mainly) generated automatically using the Generator class
using System; using System;
namespace TL namespace TL

View file

@ -1,4 +1,5 @@
using System; // This file is (mainly) generated automatically using the Generator class
using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace TL namespace TL

View file

@ -214,9 +214,9 @@ namespace TL
{ {
if (!type.IsArray) if (!type.IsArray)
writer.Write(NullCtor); writer.Write(NullCtor);
else if (type != typeof(byte[])) // null arrays are serialized as empty else if (type != typeof(byte[]))
writer.Write(VectorCtor); writer.Write(VectorCtor);
writer.Write(0); writer.Write(0); // null arrays are serialized as empty
} }
private static _Message[] DeserializeMessages(BinaryReader reader) private static _Message[] DeserializeMessages(BinaryReader reader)