docs: more anchors

This commit is contained in:
Wizou 2021-12-07 02:32:19 +01:00
parent d0c783ec23
commit 4195876b8f
3 changed files with 50 additions and 14 deletions

View file

@ -14,6 +14,17 @@ and add at least these variables with adequate value: **api_id, api_hash, phone_
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.
<a name="join-channel"></a>
### Join a channel/group by @channelname
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
var resolved = await client.Contacts_ResolveUsername("channelname"); // without the @
if (resolved.UserOrChat is Channel channel)
await client.Channels_JoinChannel(channel);
```
<a name="msg-by-name"></a>
### Send a message to someone by @username
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
@ -21,9 +32,10 @@ await client.LoginUserIfNeeded();
var resolved = await client.Contacts_ResolveUsername("username"); // without the @
await client.SendMessageAsync(resolved, "Hello!");
```
*Note: This also works if the @username points to a chat, but you must join the chat before posting there.
You can check `resolved` properties to ensure it's a user or a chat. If the username is invalid/unused, the API call raises an exception.*
*Note: This also works if the @username points to a channel/group, but you must already have joined that channel before posting there.
If the username is invalid/unused, the API call raises an exception.*
<a name="msg-by-phone"></a>
### Send a message to someone by phone number
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
@ -34,6 +46,7 @@ if (contacts.imported.Length > 0)
```
*Note: To prevent spam, Telegram may restrict your ability to add new phone numbers.*
<a name="markdown"></a>
### Send a Markdown message to ourself (Saved Messages)
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
@ -43,8 +56,9 @@ var entities = client.MarkdownToEntities(ref text);
await client.SendMessageAsync(InputPeer.Self, text, entities: entities);
```
See [MarkdownV2 formatting style](https://core.telegram.org/bots/api/#markdownv2-style) for details.
*Note: For the `tg://user?id=` notation to work, that user's access hash must have been collected first ([see below](#Collect-Access-Hash-and-save-them-for-later-use))*
*Note: For the `tg://user?id=` notation to work, that user's access hash must have been collected first ([see below](#collect-access-hash))*
<a name="dice"></a>
### Send a random dice (or other "game of chance" animated emoji)
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
@ -57,6 +71,7 @@ if (appConfig["emojies_send_dice"] is string[] emojies_send_dice) // get list of
}
```
<a name="list-chats"></a>
### List all chats (groups/channels) the user is in and send a message to one
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
@ -72,6 +87,7 @@ await client.SendMessageAsync(chats.chats[chatId], "Hello, World");
*Note: the list returned by Messages_GetAllChats contains the `access_hash` for those chats.*
See a longer version of this example in [Examples/Program_GetAllChats.cs](Examples/Program_GetAllChats.cs)
<a name="schedule-msg"></a>
### Schedule a message to be sent to a chat
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
@ -81,6 +97,8 @@ 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);
```
<a name="upload"></a>
### Upload a media file and post it with caption to a chat
```csharp
const int TargetChatId = 1234567890; // the chat we want
@ -93,6 +111,8 @@ InputPeer peer = chats.chats[TargetChatId];
var inputFile = await client.UploadFileAsync(Filepath);
await client.SendMediaAsync(peer, "Here is the photo", inputFile);
```
<a name="list-dialog"></a>
### List all dialogs (chats/groups/channels/user chat) the user is in
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
@ -116,8 +136,9 @@ while (dialogs.Dialogs.Length != 0)
*Note: the lists returned by Messages_GetDialogs contains the `access_hash` for those chats and users.*
See also the `Main` method in [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
<a name="list-members"></a>
### Get all members from a chat
For a simple Chat: (see Terminology in [ReadMe](README.md#Terminology-in-Telegram-Client-API))
For a simple Chat: (see Terminology in [ReadMe](README.md#terminology))
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
@ -142,6 +163,17 @@ for (int offset = 0; ;)
}
```
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 this helper method, but it can take several minutes to complete:
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
var chats = await client.Messages_GetAllChats(null);
var channel = (Channel)chats.chats[1234567890]; // the channel we want
var participants = await client.Channels_GetAllParticipants(channel);
```
<a name="history"></a>
### Get all messages (history) from a chat
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
@ -158,12 +190,15 @@ for (int offset = 0; ;)
if (offset >= messages.Count) break;
}
```
<a name="updates"></a>
### Monitor all Telegram events happening for the user
This is done through the `client.Update` callback event.
See [Examples/Program_ListenUpdates.cs](Examples/Program_ListenUpdates.cs).
<a name="monitor-msg"></a>
### Monitor new messages being posted in chats
You have to handle `client.Update` events containing an `UpdateNewMessage`.
@ -172,6 +207,7 @@ See the `DisplayMessage` method in [Examples/Program_ListenUpdates.cs](Examples/
You can filter specific chats the message are posted in, by looking at the `Message.peer_id` field.
<a name="download"></a>
### Download media files you forward to yourself (Saved Messages)
This is done using the helper method `client.DownloadFileAsync(file, outputStream)`
@ -179,6 +215,7 @@ that simplify the download of a photo/document/file once you get a reference to
See [Examples/Program_DownloadSavedMedia.cs](Examples/Program_DownloadSavedMedia.cs).
<a name="collect-access-hash"></a>
### Collect Access Hash and save them for later use
You can automate the collection of `access_hash` for the various resources obtained in response to API calls or Update events,
@ -187,6 +224,7 @@ so that you don't have to remember them by yourself or ask the API about them ea
This is done by activating the experimental `client.CollectAccessHash` system.
See [Examples/Program_CollectAccessHash.cs](Examples/Program_CollectAccessHash.cs) for how to enable it, and save/restore them for later use.
<a name="proxy"></a>
### Use a proxy to connect to Telegram
This can be done using the `client.TcpHandler` delegate and a proxy library like [StarkSoftProxy](https://www.nuget.org/packages/StarkSoftProxy/):
```csharp
@ -200,6 +238,7 @@ var user = await client.LoginUserIfNeeded();
Console.WriteLine($"We are logged-in as {user.username ?? user.first_name + " " + user.last_name}");
```
<a name="logging"></a>
### Change logging settings
Log to VS Output debugging pane in addition to default Console screen logging:
```csharp

16
FAQ.md
View file

@ -7,7 +7,7 @@ Writing the library logs to the Console is the default behavior of the `WTelegra
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 analyze a problem after it happens.
Read the [example about logging settings](EXAMPLES.md#change-logging-settings) for how to write logs to a file.
Read the [example about logging settings](EXAMPLES.md#logging) for how to write logs to a file.
<a name="multiple-users"></a>
#### 2. How to handle multiple user accounts
@ -43,7 +43,7 @@ An `access_hash` is required by Telegram when dealing with a channel, user, phot
This serves as a proof that you are entitled to access it (otherwise, anybody with the ID could access it)
> A small private `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-in-Telegram-Client-API).
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...).
@ -54,7 +54,7 @@ Once you obtained the description structure, there are 3 methods for building yo
you will see that they have conversion implicit operators or methods that can create the `Input...` structure for you automatically.
So you can just pass that structure you already have, in place of the `Input...` argument, it will work!
* Alternatively, you can manually create the `Input...` structure yourself by extracting the `access_hash` from the **description structure**
* If you have enabled the [CollectAccessHash system](EXAMPLES.md#collect-access-hash-and-save-them-for-later-use) at the start of your session, it will have collected the `access_hash`.
* If you have enabled the [CollectAccessHash system](EXAMPLES.md#collect-access-hash) at the start of your session, it will have collected the `access_hash`.
You can then retrieve it with `client.GetAccessHashFor<User/Channel/Photo/Document>(id)`
<a name="dev-versions"></a>
@ -65,7 +65,7 @@ The developmental versions of the library are available through Azure DevOps as
You can access these versions for testing in your program by going to our [private nuget feed](https://dev.azure.com/wiz0u/WTelegramClient/_packaging?_a=package&feed=WTelegramClient&view=overview&package=WTelegramClient&protocolType=NuGet), then click on "Connect to feed" and follow the steps.
After that, you should be able to see/install the pre-release versions in your Nuget package manager and install them in your application. *(make sure you enable the **pre-release** checkbox)*
<a name="test-servers"></a>
<a name="wrong-server"></a>
#### 6. Telegram can't find any chats and 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.
@ -138,12 +138,8 @@ If you don't authenticate as a user (or bot), you have access to a very limited
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?
4) Is your program ending immediately instead of waiting for Updates?
Your program must be running/waiting continuously in order for the background Task to receive and process the Updates. So make sure your main program doesn't end immediately. For a console program, this is typical done by waiting for a key or some close event.
6) Is every Telegram API call rejected? (typically with an exception message like `AUTH_RESTART`)
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()`

View file

@ -103,6 +103,7 @@ await client.SendMessageAsync(target, "Hello, World");
➡️ You can find more useful code snippets in [EXAMPLES.md](https://github.com/wiz0u/WTelegramClient/blob/master/EXAMPLES.md) and in the [Examples subdirectory](https://github.com/wiz0u/WTelegramClient/tree/master/Examples).
<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: