2021-10-17 03:22:49 +02:00
## Example programs using WTelegramClient
2022-02-14 15:17:15 +01:00
For these examples to work as a fully-functional Program.cs, be sure to start with these lines:
2021-10-17 03:22:49 +02:00
```csharp
using System;
using System.Linq;
using TL;
2022-02-14 15:17:15 +01:00
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
var myself = await client.LoginUserIfNeeded();
2021-10-17 03:22:49 +02:00
```
2022-02-14 15:17:15 +01:00
In this case, environment variables are used for configuration so make sure to
2021-12-01 15:50:35 +01:00
go to your **Project Properties > Debug > Environment variables**
and add at least these variables with adequate value: **api_id, api_hash, phone_number**
2021-10-17 03:22:49 +02:00
2021-12-01 15:50:35 +01:00
Remember that these are just simple example codes that you should adjust to your needs.
2022-09-25 19:21:00 +02:00
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.
2021-10-17 03:22:49 +02:00
2022-04-01 21:48:28 +02:00
ℹ ️ WTelegramClient covers 100% of Telegram Client API, much more than the examples below: check the [full API methods list ](https://corefork.telegram.org/methods )!
2022-05-15 00:57:28 +02:00
More examples can also be found in the [Examples folder ](Examples ) and in answers to [StackOverflow questions ](https://stackoverflow.com/questions/tagged/wtelegramclient ).
2022-02-11 02:43:48 +01:00
2021-12-07 02:32:19 +01:00
< a name = "msg-by-name" > < / a >
2021-10-17 03:22:49 +02:00
### Send a message to someone by @username
```csharp
2022-04-13 15:53:06 +02:00
var resolved = await client.Contacts_ResolveUsername("MyEch0_Bot"); // username without the @
await client.SendMessageAsync(resolved, "/start");
2021-10-17 03:22:49 +02:00
```
2022-09-02 23:02:44 +02:00
*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.
2021-12-07 02:32:19 +01:00
If the username is invalid/unused, the API call raises an exception.*
2021-10-31 02:40:10 +01:00
2021-12-07 02:32:19 +01:00
< a name = "msg-by-phone" > < / a >
2021-10-17 03:22:49 +02:00
### Send a message to someone by phone number
```csharp
2021-10-22 15:26:46 +02:00
var contacts = await client.Contacts_ImportContacts(new[] { new InputPhoneContact { phone = "+PHONENUMBER" } });
2021-10-22 19:33:17 +02:00
if (contacts.imported.Length > 0)
await client.SendMessageAsync(contacts.users[contacts.imported[0].user_id], "Hello!");
2021-10-17 03:22:49 +02:00
```
2021-10-20 19:12:50 +02:00
*Note: To prevent spam, Telegram may restrict your ability to add new phone numbers.*
2021-12-07 02:32:19 +01:00
< a name = "markdown" > < / a >
2022-01-12 02:54:59 +01:00
< a name = "html" > < / a >
2022-07-29 02:19:25 +02:00
### Convert message to/from HTML or Markdown, and send it to ourself (Saved Messages)
2021-10-31 02:40:10 +01:00
```csharp
2022-01-12 02:54:59 +01:00
// HTML-formatted text:
2022-03-30 15:17:28 +02:00
var text = $"Hello < u > dear < b > {HtmlText.Escape(myself.first_name)}</ b ></ u > \n" +
2022-09-25 19:21:00 +02:00
"Enjoy this < code > userbot</ code > written with < a href = \"https://github.com/wiz0u/WTelegramClient \"> WTelegramClient</ a > ";
2022-03-30 15:17:28 +02:00
var entities = client.HtmlToEntities(ref text);
var sent = await client.SendMessageAsync(InputPeer.Self, text, entities: entities);
2022-07-29 02:19:25 +02:00
// if you need to convert a sent/received Message to HTML: (easier to store)
2022-03-30 15:17:28 +02:00
text = client.EntitiesToHtml(sent.message, sent.entities);
2022-08-11 19:39:18 +02:00
```
```csharp
2022-03-30 15:17:28 +02:00
// Markdown-style text:
var text2 = $"Hello __dear *{Markdown.Escape(myself.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);
2022-07-29 02:19:25 +02:00
// if you need to convert a sent/received Message to Markdown: (easier to store)
2022-03-30 15:17:28 +02:00
text2 = client.EntitiesToMarkdown(sent2.message, sent2.entities);
2021-10-31 02:40:10 +01:00
```
2022-08-12 21:19:10 +02:00
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.
2021-12-07 02:32:19 +01:00
*Note: For the `tg://user?id=` notation to work, that user's access hash must have been collected first ([see below](#collect-access-hash))*
2021-10-31 02:40:10 +01:00
2021-12-23 01:38:59 +01:00
< a name = "fun" > < / a >
2021-12-25 03:20:22 +01:00
### Fun with stickers, GIFs, dice, and animated emojies
2021-11-14 15:35:41 +01:00
```csharp
2021-12-23 01:38:59 +01:00
// • List all stickerSets the user has added to his account
2022-02-13 02:50:10 +01:00
var allStickers = await client.Messages_GetAllStickers();
2021-12-23 01:38:59 +01:00
foreach (var stickerSet in allStickers.sets)
Console.WriteLine($"Pack {stickerSet.short_name} contains {stickerSet.count} stickers");
2022-02-13 02:50:10 +01:00
//if you need details on each: var sticketSetDetails = await client.Messages_GetStickerSet(stickerSet);
2021-12-23 01:38:59 +01:00
// • Send a random sticker from the user's favorites stickers
2022-02-13 02:50:10 +01:00
var favedStickers = await client.Messages_GetFavedStickers();
2022-02-14 15:17:15 +01:00
var stickerDoc = favedStickers.stickers[new Random().Next(favedStickers.stickers.Length)];
2022-06-17 15:12:50 +02:00
await client.SendMessageAsync(InputPeer.Self, null, stickerDoc);
2021-12-23 01:38:59 +01:00
// • Send a specific sticker given the stickerset shortname and emoticon
2022-06-17 15:12:50 +02:00
var friendlyPanda = await client.Messages_GetStickerSet("Friendly_Panda");
2021-12-23 01:38:59 +01:00
var laughId = friendlyPanda.packs.First(p => p.emoticon == "😂").documents[0];
var laughDoc = friendlyPanda.documents.First(d => d.ID == laughId);
2022-06-17 15:12:50 +02:00
await client.SendMessageAsync(InputPeer.Self, null, laughDoc);
2021-12-23 01:38:59 +01:00
2021-12-25 03:20:22 +01:00
// • 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["emojies_send_dice"] as string[];
2022-02-14 15:17:15 +01:00
var dice_emoji = emojies_send_dice[new Random().Next(emojies_send_dice.Length)];
2021-12-25 03:20:22 +01:00
var diceMsg = await client.SendMessageAsync(InputPeer.Self, null, new InputMediaDice { emoticon = dice_emoji });
Console.WriteLine("Dice result:" + ((MessageMediaDice)diceMsg.media).value);
2021-12-23 01:38:59 +01:00
// • 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);
2021-11-14 15:35:41 +01:00
```
2021-12-07 02:32:19 +01:00
< a name = "list-chats" > < / a >
2022-08-12 21:19:10 +02:00
### List all chats (groups/channels NOT users) that we joined and send a message to one
2021-10-20 13:08:10 +02:00
```csharp
2022-02-13 02:50:10 +01:00
var chats = await client.Messages_GetAllChats();
2021-10-20 19:12:50 +02:00
foreach (var (id, chat) in chats.chats)
2021-10-22 15:26:46 +02:00
if (chat.IsActive)
Console.WriteLine($"{id} : {chat}");
2021-10-20 13:08:10 +02:00
Console.Write("Choose a chat ID to send a message to: ");
2021-10-20 19:12:50 +02:00
long chatId = long.Parse(Console.ReadLine());
await client.SendMessageAsync(chats.chats[chatId], "Hello, World");
2021-10-20 13:08:10 +02:00
```
2021-12-26 18:28:10 +01:00
Notes:
2022-02-27 22:06:13 +01:00
- This list does not include discussions with other users. For this, you need to use [Messages_GetAllDialogs ](#list-dialogs ).
2022-07-01 12:18:13 +02:00
- The list returned by Messages_GetAllChats contains the `access_hash` for those chats. Read [FAQ #4 ](FAQ.md#access-hash ) about this.
2022-05-21 02:32:15 +02:00
- 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,
2021-12-26 18:28:10 +01:00
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 ](Examples/Program_GetAllChats.cs )
2021-10-17 03:22:49 +02:00
2022-08-12 21:19:10 +02:00
< a name = "list-dialogs" > < / a >
### List all dialogs (chats/groups/channels/user chat) we are currently in
```csharp
var dialogs = await client.Messages_GetAllDialogs();
foreach (var 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;
}
```
*Note: 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 ](Examples/Program_ListenUpdates.cs ).
2021-12-07 02:32:19 +01:00
< a name = "schedule-msg" > < / a >
2021-10-17 03:22:49 +02:00
### Schedule a message to be sent to a chat
```csharp
2022-02-13 02:50:10 +01:00
var chats = await client.Messages_GetAllChats();
2021-10-20 19:12:50 +02:00
InputPeer peer = chats.chats[1234567890]; // the chat we want
2021-10-17 03:22:49 +02:00
DateTime when = DateTime.UtcNow.AddMinutes(3);
await client.SendMessageAsync(peer, "This will be posted in 3 minutes", schedule_date: when);
```
2021-12-07 02:32:19 +01:00
< a name = "upload" > < / a >
2021-10-17 03:22:49 +02:00
### Upload a media file and post it with caption to a chat
```csharp
2021-12-26 18:28:10 +01:00
const int ChatId = 1234567890; // the chat we want
2021-10-17 03:22:49 +02:00
const string Filepath = @"C:\...\photo.jpg";
2022-02-13 02:50:10 +01:00
var chats = await client.Messages_GetAllChats();
2021-12-26 18:28:10 +01:00
InputPeer peer = chats.chats[ChatId];
2021-10-17 03:22:49 +02:00
var inputFile = await client.UploadFileAsync(Filepath);
await client.SendMediaAsync(peer, "Here is the photo", inputFile);
```
2021-12-07 02:32:19 +01:00
2022-01-24 22:52:18 +01:00
< a name = "album" > < / a >
### 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
2022-02-13 02:50:10 +01:00
var history = await client.Messages_GetHistory(InputPeer.Self);
2022-01-24 22:52:18 +01:00
PhotoBase photoFromTelegram = history.Messages.OfType< Message > ().Select(m => m.media).OfType< MessageMediaPhoto > ().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 InputMedia[]
{
photoFromTelegram, // PhotoBase has implicit conversion to InputMediaPhoto
new InputMediaUploadedPhoto { file = uploadedFile },
new InputMediaPhotoExternal() { url = photoUrl },
};
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*
2021-12-07 02:32:19 +01:00
< a name = "list-members" > < / a >
2021-10-17 03:22:49 +02:00
### Get all members from a chat
2022-05-21 02:32:15 +02:00
For a basic Chat: *(see Terminology in [ReadMe](README.md#terminology))*
2021-10-17 03:22:49 +02:00
```csharp
var chatFull = await client.Messages_GetFullChat(1234567890); // the chat we want
2021-10-22 19:33:17 +02:00
foreach (var (id, user) in chatFull.users)
2021-10-17 03:22:49 +02:00
Console.WriteLine(user);
```
For a Channel/Group:
```csharp
2022-02-13 02:50:10 +01:00
var chats = await client.Messages_GetAllChats();
2021-10-20 19:12:50 +02:00
var channel = (Channel)chats.chats[1234567890]; // the channel we want
2021-10-17 03:22:49 +02:00
for (int offset = 0; ;)
{
2022-02-13 02:50:10 +01:00
var participants = await client.Channels_GetParticipants(channel, null, offset);
2021-10-22 19:33:17 +02:00
foreach (var (id, user) in participants.users)
2021-10-17 03:22:49 +02:00
Console.WriteLine(user);
offset += participants.participants.Length;
2022-09-29 11:53:41 +02:00
if (offset >= participants.count || participants.participants.Length == 0) break;
2021-10-17 03:22:49 +02:00
}
```
2021-12-07 02:32:19 +01:00
For big Channel/Group, Telegram servers might limit the number of members you can obtain with the normal above method.
2022-09-02 23:02:44 +02:00
In this case, you can use the following helper method, but it can take several minutes to complete:
2021-12-07 02:32:19 +01:00
```csharp
2022-02-13 02:50:10 +01:00
var chats = await client.Messages_GetAllChats();
2021-12-07 02:32:19 +01:00
var channel = (Channel)chats.chats[1234567890]; // the channel we want
var participants = await client.Channels_GetAllParticipants(channel);
```
2022-01-11 04:14:23 +01:00
< a name = "join-channel" > < / a >
2022-07-01 12:18:13 +02:00
### 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:
2022-01-11 04:14:23 +01:00
```csharp
var resolved = await client.Contacts_ResolveUsername("channelname"); // without the @
if (resolved.Chat is Channel channel)
await client.Channels_JoinChannel(channel);
```
2022-07-01 12:18:13 +02:00
* 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
2022-09-02 23:02:44 +02:00
// Note: This works also with hash invite links of public channel/group
2022-07-01 12:18:13 +02:00
```
2022-01-11 04:14:23 +01:00
2021-12-22 04:46:34 +01:00
< a name = "add-members" > < / a >
### Add/Invite/Remove someone in a chat
```csharp
2022-02-13 02:50:10 +01:00
var chats = await client.Messages_GetAllChats();
2022-01-07 23:10:18 +01:00
var chat = chats.chats[1234567890]; // the target chat
2021-12-22 04:46:34 +01:00
```
2021-12-24 07:21:02 +01:00
After the above code, once you [have obtained ](https://github.com/wiz0u/WTelegramClient/blob/master/FAQ.md#access-hash ) an `InputUser` or `User` , you can:
2021-12-22 04:46:34 +01:00
```csharp
2021-12-31 08:38:41 +01:00
// • Directly add the user to a Chat/Channel/group:
await client.AddChatUser(chat, user);
2021-12-22 04:46:34 +01:00
// You may get exception USER_PRIVACY_RESTRICTED if the user has denied the right to be added to a chat
// or exception USER_NOT_MUTUAL_CONTACT if the user left the chat previously and you want to add him again
2021-12-30 17:38:07 +01:00
// • Obtain the main invite link for the chat, and send it to the user:
var mcf = await client.GetFullChat(chat);
2021-12-22 04:46:34 +01:00
var invite = (ChatInviteExported)mcf.full_chat.ExportedInvite;
2021-12-24 07:21:02 +01:00
await client.SendMessageAsync(user, "Join our group with this link: " + invite.link);
2021-12-22 04:46:34 +01:00
// • 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");
2021-12-24 07:21:02 +01:00
await client.SendMessageAsync(user, "Join our group with this link: " + invite.link);
2021-12-22 04:46:34 +01:00
// • 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);
2021-12-31 08:38:41 +01:00
// • Remove the user from a Chat/Channel/Group:
2022-01-07 23:10:18 +01:00
await client.DeleteChatUser(chat, user);
2021-12-22 04:46:34 +01:00
```
2021-12-07 02:32:19 +01:00
< a name = "history" > < / a >
2021-10-17 03:22:49 +02:00
### Get all messages (history) from a chat
```csharp
2022-02-13 02:50:10 +01:00
var chats = await client.Messages_GetAllChats();
2021-10-20 19:12:50 +02:00
InputPeer peer = chats.chats[1234567890]; // the chat we want
2022-02-13 02:50:10 +01:00
for (int offset_id = 0; ;)
2021-10-17 03:22:49 +02:00
{
2022-02-13 02:50:10 +01:00
var messages = await client.Messages_GetHistory(peer, offset_id);
if (messages.Messages.Length == 0) break;
2021-11-09 01:43:27 +01:00
foreach (var msgBase in messages.Messages)
2021-10-17 03:22:49 +02:00
if (msgBase is Message msg)
2021-10-28 04:59:41 +02:00
Console.WriteLine(msg.message);
2022-02-13 02:50:10 +01:00
offset_id = messages.Messages[^1].ID;
2021-10-17 03:22:49 +02:00
}
```
2021-12-07 02:32:19 +01:00
2021-12-16 14:41:43 +01:00
< a name = "contacts" > < / a >
### Retrieve the current user's contacts list
There are two different methods. Here is the simpler one:
```csharp
2022-02-13 02:50:10 +01:00
var contacts = await client.Contacts_GetContacts();
2021-12-16 14:41:43 +01:00
foreach (User contact in contacts.users.Values)
Console.WriteLine($"{contact} {contact.phone}");
```
< a name = "takeout" > < / a >
The second method uses the more complex GDPR export, **takeout session** system.
Here is an example on how to implement it:
```csharp
2021-12-16 14:51:47 +01:00
using TL.Methods; // methods as structures, for Invoke* calls
2021-12-16 14:41:43 +01:00
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);
}
```
2021-12-07 02:32:19 +01:00
< a name = "updates" > < / a >
2021-10-17 03:22:49 +02:00
### Monitor all Telegram events happening for the user
2022-07-29 15:24:18 +02:00
This is done through the `client.OnUpdate` callback event.
Your event handler implementation can either return `Task.CompletedTask` or be an `async Task` method.
2021-12-01 15:50:35 +01:00
2021-10-17 03:22:49 +02:00
See [Examples/Program_ListenUpdates.cs ](Examples/Program_ListenUpdates.cs ).
2021-12-07 02:32:19 +01:00
< a name = "monitor-msg" > < / a >
2022-09-02 23:02:44 +02:00
### Monitor new messages being posted in chats in real-time
2021-10-17 03:22:49 +02:00
2022-07-29 15:24:18 +02:00
You have to handle `client.OnUpdate` events containing an `UpdateNewMessage` .
2021-10-17 03:22:49 +02:00
See the `DisplayMessage` method in [Examples/Program_ListenUpdates.cs ](Examples/Program_ListenUpdates.cs ).
You can filter specific chats the message are posted in, by looking at the `Message.peer_id` field.
2021-12-07 02:32:19 +01:00
< a name = "download" > < / a >
2022-02-14 15:17:15 +01:00
### Downloading photos, medias, files
2021-10-17 03:22:49 +02:00
2021-12-01 15:50:35 +01:00
This is done using the helper method `client.DownloadFileAsync(file, outputStream)`
2022-02-14 15:17:15 +01:00
that simplify the download of a photo/document/file once you get a reference to its location *(through updates or API calls)* .
2021-12-01 15:50:35 +01:00
2022-02-14 15:17:15 +01:00
See [Examples/Program_DownloadSavedMedia.cs ](Examples/Program_DownloadSavedMedia.cs ) that download all media files you forward to yourself (Saved Messages)
2021-10-17 03:22:49 +02:00
2021-12-07 02:32:19 +01:00
< a name = "collect-access-hash" > < / a >
2021-10-17 03:22:49 +02:00
### Collect Access Hash and save them for later use
2022-07-29 15:24:18 +02:00
You can automate the collection of `access_hash` for the various resources obtained in response to API calls or Updates,
2021-12-01 15:50:35 +01:00
so that you don't have to remember them by yourself or ask the API about them each time.
2021-10-17 03:22:49 +02:00
2021-12-01 15:50:35 +01:00
This is done by activating the experimental `client.CollectAccessHash` system.
2021-10-17 03:22:49 +02:00
See [Examples/Program_CollectAccessHash.cs ](Examples/Program_CollectAccessHash.cs ) for how to enable it, and save/restore them for later use.
2021-10-25 02:40:15 +02:00
2021-12-07 02:32:19 +01:00
< a name = "proxy" > < / a >
2021-10-25 02:40:15 +02:00
### Use a proxy to connect to Telegram
2022-08-01 19:06:31 +02:00
SOCKS/HTTPS proxies can be used through the `client.TcpHandler` delegate and a proxy library like [StarkSoftProxy ](https://www.nuget.org/packages/StarkSoftProxy/ ):
2021-10-25 02:40:15 +02:00
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
client.TcpHandler = async (address, port) =>
{
var proxy = new Socks5ProxyClient(ProxyHost, ProxyPort, ProxyUsername, ProxyPassword);
return proxy.CreateConnection(address, port);
};
2022-02-14 15:17:15 +01:00
var myself = await client.LoginUserIfNeeded();
2021-10-25 02:40:15 +02:00
```
2021-12-07 17:15:25 +01:00
or with [xNetStandard ](https://www.nuget.org/packages/xNetStandard/ ):
```csharp
client.TcpHandler = async (address, port) =>
{
var proxy = xNet.Socks5ProxyClient.Parse("host:port:username:password");
return proxy.CreateConnection(address, port);
};
```
2022-01-03 18:50:16 +01:00
< a name = "mtproxy" > < / a >
2022-04-18 22:07:04 +02:00
MTProxy (MTProto proxy) can be used to prevent ISP blocking Telegram servers, through the `client.MTProxyUrl` property:
2022-01-03 18:50:16 +01:00
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
client.MTProxyUrl = "http://t.me/proxy?server=...&port=...&secret=...";
2022-02-14 15:17:15 +01:00
var myself = await client.LoginUserIfNeeded();
2022-01-03 18:50:16 +01:00
```
2022-04-18 22:07:04 +02:00
You can find a list of working MTProxies in channels like [@ProxyMTProto ](https://t.me/ProxyMTProto ) or [@MTProxyT ](https://t.me/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  and then ** ⋮** > **Share**
2022-01-03 18:50:16 +01:00
*Note: WTelegramClient always uses transport obfuscation when connecting to Telegram servers, even without MTProxy*
2021-12-07 02:32:19 +01:00
< a name = "logging" > < / a >
2021-11-06 05:22:33 +01:00
### Change logging settings
2021-12-26 18:28:10 +01:00
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:
2021-11-02 01:47:14 +01:00
```csharp
2022-02-24 16:44:27 +01:00
// • Log to file in replacement of default Console screen logging, using this static variable:
2021-11-02 01:47:14 +01:00
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}");
2021-12-30 23:43:00 +01:00
2022-06-15 01:58:44 +02:00
// • 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:
2021-12-26 18:28:10 +01:00
WTelegram.Helpers.Log = (lvl, str) => _logger.Log((LogLevel)lvl, str);
2022-06-15 01:58:44 +02:00
// • Disable logging (THIS IS NOT RECOMMENDED as you won't be able to diagnose any upcoming problem):
WTelegram.Helpers.Log = (lvl, str) => { };
2021-12-26 18:28:10 +01:00
```
2021-12-30 17:38:07 +01:00
< a name = "2FA" > < / a >
### Change 2FA password
```csharp
2022-01-21 19:04:33 +01:00
const string old_password = "password"; // current password if any (unused otherwise)
2021-12-30 17:38:07 +01:00
const string new_password = "new_password"; // or null to disable 2FA
2022-09-25 19:21:00 +02:00
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);
2021-12-30 17:38:07 +01:00
await client.Account_UpdatePasswordSettings(password, new Account_PasswordInputSettings
{
flags = Account_PasswordInputSettings.Flags.has_new_algo,
new_password_hash = new_password_hash?.A,
2022-09-25 19:21:00 +02:00
new_algo = accountPwd.new_algo,
2022-02-14 15:17:15 +01:00
hint = "new password hint",
2022-01-21 19:04:33 +01:00
});
2021-12-30 17:38:07 +01:00
```
2022-09-25 19:21:00 +02:00
< a name = "database" > < / a > < a name = "sessionStore" > < / a > < a name = "customStore" > < / a >
### 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#L61 )
< a name = "reaction" > < / a > < a name = "pinned" > < / a > < a name = "custom_emoji" > < / a >
2022-09-24 15:34:31 +02:00
### Fun with custom emojies and reactions on pinned messages
2021-12-30 17:38:07 +01:00
```csharp
2022-10-08 15:35:10 +02:00
// • Sending a message with custom emojies in Markdown to ourself:
var text = "Vicksy says Hi! [👋 ](emoji?id=5190875290439525089 )";
var entities = client.MarkdownToEntities(ref text, premium: true);
await client.SendMessageAsync(InputPeer.Self, text, entities: entities);
// also available in HTML: "< tg-emoji id = \"5190875290439525089 \"> 👋</ tg-emoji > "
2022-09-24 15:34:31 +02:00
// • Fetch all available standard emoji reactions
var all_emoji = await client.Messages_GetAvailableReactions();
2022-02-13 02:50:10 +01:00
var chats = await client.Messages_GetAllChats();
2021-12-30 17:38:07 +01:00
var chat = chats.chats[1234567890]; // the chat we want
2022-09-24 15:34:31 +02:00
// • Check reactions available in this chat
2021-12-30 17:38:07 +01:00
var full = await client.GetFullChat(chat);
2022-09-24 15:34:31 +02:00
Reaction reaction = full.full_chat.AvailableReactions switch
{
2022-10-07 03:00:57 +02:00
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
2022-09-24 15:34:31 +02:00
};
if (reaction == null) return;
// • Send the selected reaction on the last 2 pinned messages
2022-02-13 02:50:10 +01:00
var messages = await client.Messages_Search< InputMessagesFilterPinned > (chat, limit: 2);
2021-12-30 17:38:07 +01:00
foreach (var msg in messages.Messages)
2022-10-07 03:00:57 +02:00
await client.Messages_SendReaction(chat, msg.ID, reaction: new[] { reaction });
2021-12-30 17:38:07 +01:00
```
2022-09-25 19:21:00 +02:00
*Note: you can find custom emoji document IDs via API methods like [Messages_GetFeaturedEmojiStickers ](https://corefork.telegram.org/method/messages.getFeaturedEmojiStickers ). Access hash is not required*
2022-03-28 13:24:37 +02:00
2022-09-25 19:21:00 +02:00
< a name = "forward" > < / a > < a name = "copy" > < / a >
### 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
2022-03-28 13:24:37 +02:00
2022-09-25 19:21:00 +02:00
// • Forward the message (only the source message id is necessary)
await client.Messages_ForwardMessages(from_chat, new[] { msg.ID }, new[] { WTelegram.Helpers.RandomLong() }, to_chat);
2022-03-28 13:24:37 +02:00
2022-10-04 00:52:44 +02:00
// • Copy the message without the "Forwarded" header (only the source message id is necessary)
await client.Messages_ForwardMessages(from_chat, new[] { msg.ID }, new[] { WTelegram.Helpers.RandomLong() }, to_chat, drop_author: true);
// • Alternative solution to copy the message (the full message is needed)
2022-09-25 19:21:00 +02:00
await client.SendMessageAsync(to_chat, msg.message, msg.media?.ToInputMedia(), entities: msg.entities);
2022-10-04 00:52:44 +02:00
```
2022-10-08 15:35:10 +02:00
< a name = "e2e" > < / a > < a name = "secrets" > < / a >
### Send/receive end-to-end encrypted messages in Secret Chats
This can be done easily using the helper class `WTelegram.SecretChats` offering methods to manage/encrypt/decrypt secret chats & encrypted messages.
You can view a full working example at [Examples/Program_SecretChats.cs ](Examples/Program_SecretChats.cs ).
Secret Chats have been tested successfully with Telegram Android & iOS official clients.