2021-10-17 03:22:49 +02:00
## Example programs using WTelegramClient
The following codes can be saved into a Program.cs file with the only addition of some `using` on top of file, like
```csharp
using System;
using System.Linq;
using TL;
```
2021-12-01 15:50:35 +01:00
Those examples use environment variables for configuration so make sure to
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.
In real production code, you might want to properly test the success of each operation or handle exceptions.
2021-10-17 03:22:49 +02:00
2021-12-07 02:32:19 +01:00
< 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 >
2021-10-17 03:22:49 +02:00
### Send a message to someone by @username
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
2021-10-31 02:40:10 +01:00
var resolved = await client.Contacts_ResolveUsername("username"); // without the @
2021-10-22 19:33:17 +02:00
await client.SendMessageAsync(resolved, "Hello!");
2021-10-17 03:22:49 +02:00
```
2021-12-07 02:32:19 +01:00
*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.*
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
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
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 >
2021-10-31 02:40:10 +01:00
### Send a Markdown message to ourself (Saved Messages)
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
2021-10-31 18:28:25 +01:00
var user = await client.LoginUserIfNeeded();
var text = $"Hello __dear *{Markdown.Escape(user.first_name)}*__ \nEnjoy this `userbot` written with [WTelegramClient ](https://github.com/wiz0u/WTelegramClient )";
2021-10-31 02:40:10 +01:00
var entities = client.MarkdownToEntities(ref text);
await client.SendMessageAsync(InputPeer.Self, text, entities: entities);
```
2021-11-15 17:17:11 +01:00
See [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-07 02:32:19 +01:00
< a name = "dice" > < / a >
2021-11-14 15:35:41 +01:00
### Send a random dice (or other "game of chance" animated emoji)
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
var user = await client.LoginUserIfNeeded();
var appConfig = await client.Help_GetAppConfig();
if (appConfig["emojies_send_dice"] is string[] emojies_send_dice) // get list of animated "dice" emojies
{
var which = new Random().Next(emojies_send_dice.Length); // choose one of the available emojies
await client.SendMessageAsync(InputPeer.Self, null, new InputMediaDice { emoticon = emojies_send_dice[which] });
}
```
2021-12-07 02:32:19 +01:00
< a name = "list-chats" > < / a >
2021-10-20 00:24:50 +02:00
### List all chats (groups/channels) the user is in and send a message to one
2021-10-20 13:08:10 +02:00
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
var chats = await client.Messages_GetAllChats(null);
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-11-15 17:17:11 +01:00
*Note: the list returned by Messages_GetAllChats contains the `access_hash` for those chats.*
2021-10-20 13:08:10 +02:00
See a longer version of this example in [Examples/Program_GetAllChats.cs ](Examples/Program_GetAllChats.cs )
2021-10-17 03:22:49 +02:00
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
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
var chats = await client.Messages_GetAllChats(null);
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
const int TargetChatId = 1234567890; // the chat we want
const string Filepath = @"C:\...\photo.jpg";
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
var chats = await client.Messages_GetAllChats(null);
2021-10-20 19:12:50 +02:00
InputPeer peer = chats.chats[TargetChatId];
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
< a name = "list-dialog" > < / a >
2021-10-17 03:22:49 +02:00
### List all dialogs (chats/groups/channels/user chat) the user is in
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
2021-11-09 01:43:27 +01:00
var dialogs = await client.Messages_GetDialogs(default, 0, null, 0, 0);
while (dialogs.Dialogs.Length != 0)
{
foreach (var dialog in dialogs.Dialogs)
switch (dialogs.UserOrChat(dialog))
{
case UserBase user when user.IsActive: Console.WriteLine("User " + user); break;
case ChatBase chat when chat.IsActive: Console.WriteLine(chat); break;
}
var lastDialog = dialogs.Dialogs[^1];
var lastMsg = dialogs.Messages.LastOrDefault(m => m.Peer.ID == lastDialog.Peer.ID & & m.ID == lastDialog.TopMessage);
var offsetPeer = dialogs.UserOrChat(lastDialog).ToInputPeer();
dialogs = await client.Messages_GetDialogs(lastMsg?.Date ?? default, lastDialog.TopMessage, offsetPeer, 500, 0);
}
2021-10-17 03:22:49 +02:00
```
2021-11-15 17:17:11 +01:00
*Note: the lists returned by Messages_GetDialogs contains the `access_hash` for those chats and users.*
2021-10-17 03:22:49 +02:00
See also the `Main` method in [Examples/Program_ListenUpdates.cs ](Examples/Program_ListenUpdates.cs ).
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
2021-12-07 02:32:19 +01:00
For a simple Chat: (see Terminology in [ReadMe ](README.md#terminology ))
2021-10-17 03:22:49 +02:00
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
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
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
var chats = await client.Messages_GetAllChats(null);
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; ;)
{
var participants = await client.Channels_GetParticipants(channel, null, offset, 1000, 0);
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;
if (offset >= participants.count) break;
}
```
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.
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);
```
2021-12-22 04:46:34 +01:00
< a name = "add-members" > < / a >
### Add/Invite/Remove someone in a chat
```csharp
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
var chats = await client.Messages_GetAllChats(null);
const long chatId = 1234567890; // the target chat
var chat = chats.chats[chatId];
```
After the above code, once you have obtained an InputUser (or User), you can:
```csharp
// • Directly add the user to a simple Chat:
await client.Messages_AddChatUser(1234567890, inputUser, int.MaxValue);
// • Directly add the user to a Channel/group:
await client.Channels_InviteToChannel((Channel)chat, new[] { inputUser });
// 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
// • Obtain the main invite link for a simple Chat:
var mcf = await client.Messages_GetFullChat(1234567890);
// • Obtain the main invite link for a Channel/group:
var mcf = await client.Channels_GetFullChannel((Channel)chat);
// extract the invite link and send it to the user:
var invite = (ChatInviteExported)mcf.full_chat.ExportedInvite;
await client.SendMessageAsync(inputUser, "Join our group with this link: " + invite.link);
// • 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");
await client.SendMessageAsync(inputUser, "Join our group with this link: " + invite.link);
// • 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);
// • Remove the user from a simple Chat:
await client.Messages_DeleteChatUser(1234567890, inputUser);
// • Remove the user from a Channel/group:
await client.Channels_EditBanned((Channel)chat, inputUser, new ChatBannedRights { flags = ChatBannedRights.Flags.view_messages });
```
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
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
var chats = await client.Messages_GetAllChats(null);
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
for (int offset = 0; ;)
{
2021-11-09 01:43:27 +01:00
var messages = await client.Messages_GetHistory(peer, 0, default, offset, 1000, 0, 0, 0);
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);
2021-11-09 01:43:27 +01:00
offset += messages.Messages.Length;
if (offset >= messages.Count) break;
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
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
var contacts = await client.Contacts_GetContacts(0);
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
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
await client.LoginUserIfNeeded();
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
This is done through the `client.Update` callback event.
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 >
2021-10-17 03:22:49 +02:00
### Monitor new messages being posted in chats
2021-12-01 15:50:35 +01:00
You have to handle `client.Update` 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 >
2021-10-28 04:59:41 +02:00
### Download media files you forward to yourself (Saved Messages)
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)`
that simplify the download of a photo/document/file once you get a reference to its location.
2021-10-17 03:22:49 +02:00
See [Examples/Program_DownloadSavedMedia.cs ](Examples/Program_DownloadSavedMedia.cs ).
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
2021-12-01 15:50:35 +01:00
You can automate the collection of `access_hash` for the various resources obtained in response to API calls or Update events,
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
2021-10-28 04:59:41 +02:00
This can be done using 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);
};
var user = await client.LoginUserIfNeeded();
Console.WriteLine($"We are logged-in as {user.username ?? user.first_name + " " + user.last_name}");
```
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);
};
```
2021-11-02 01:47:14 +01:00
2021-12-07 02:32:19 +01:00
< a name = "logging" > < / a >
2021-11-06 05:22:33 +01:00
### Change logging settings
2021-11-02 01:47:14 +01:00
Log to VS Output debugging pane in addition to default Console screen logging:
```csharp
WTelegram.Helpers.Log += (lvl, str) => System.Diagnostics.Debug.WriteLine(str);
```
Log to file in replacement of default Console screen logging:
```csharp
WTelegram.Helpers.Log = (lvl, str) => File.AppendAllText("WTelegram.log", str + Environment.NewLine);
```
More efficient example with a static variable and detailed logging to file:
```csharp
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}");