mirror of
https://github.com/wiz0u/WTelegramClient.git
synced 2025-12-06 06:52:01 +01:00
Custom emoji Markdown/Html syntax updated for tdlib compatibility
- Markdown:  - Html: <tg-emoji emoji-id="..."> Previous syntaxes are still accepted Also, changed Github examples links with ts=4
This commit is contained in:
parent
42be950896
commit
231bf632e2
20
EXAMPLES.md
20
EXAMPLES.md
|
|
@ -95,7 +95,7 @@ foreach (Dialog dialog in dialogs.dialogs)
|
|||
|
||||
Notes:
|
||||
- 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](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs#L20).
|
||||
- See also the `Main` method in [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L20).
|
||||
- To retrieve the dialog information about a specific [peer](README.md#terminology), use `client.Messages_GetPeerDialogs(inputPeer)`
|
||||
|
||||
<a name="list-chats"></a>
|
||||
|
|
@ -114,7 +114,7 @@ Notes:
|
|||
- The list returned by Messages_GetAllChats contains the `access_hash` for those chats. Read [FAQ #4](FAQ.md#access-hash) about this.
|
||||
- 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,
|
||||
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](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_GetAllChats.cs#L32)
|
||||
- You can find a longer version of this method call in [Examples/Program_GetAllChats.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_GetAllChats.cs?ts=4#L32)
|
||||
|
||||
<a name="list-members"></a>
|
||||
## List the members from a chat
|
||||
|
|
@ -189,14 +189,14 @@ Notes:
|
|||
This is done through the `client.OnUpdate` callback event.
|
||||
Your event handler implementation can either return `Task.CompletedTask` or be an `async Task` method.
|
||||
|
||||
See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs#L23).
|
||||
See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L23).
|
||||
|
||||
<a name="monitor-msg"></a>
|
||||
## Monitor new messages being posted in chats in real-time
|
||||
|
||||
You have to handle `client.OnUpdate` events containing an `UpdateNewMessage`.
|
||||
|
||||
See the `DisplayMessage` method in [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs#L23).
|
||||
See the `DisplayMessage` method in [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L23).
|
||||
|
||||
You can filter specific chats the message are posted in, by looking at the `Message.peer_id` field.
|
||||
|
||||
|
|
@ -206,7 +206,7 @@ You can filter specific chats the message are posted in, by looking at the `Mess
|
|||
This is done using the helper method `client.DownloadFileAsync(file, outputStream)`
|
||||
that simplifies the download of a photo/document/file once you get a reference to its location *(through updates or API calls)*.
|
||||
|
||||
See [Examples/Program_DownloadSavedMedia.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_DownloadSavedMedia.cs#L31) that download all media files you forward to yourself (Saved Messages)
|
||||
See [Examples/Program_DownloadSavedMedia.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_DownloadSavedMedia.cs?ts=4#L31) that download all media files you forward to yourself (Saved Messages)
|
||||
|
||||
<a name="upload"></a>
|
||||
## Upload a media file and post it with caption to a chat
|
||||
|
|
@ -323,10 +323,10 @@ await Task.Delay(5000);
|
|||
## Fun with custom emojies and reactions on pinned messages
|
||||
```csharp
|
||||
// • Sending a message with custom emojies in Markdown to ourself:
|
||||
var text = "Vicksy says Hi! [👋](emoji?id=5190875290439525089)";
|
||||
var text = "Vicksy says Hi! ";
|
||||
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>
|
||||
// also available in HTML: <tg-emoji emoji-id="5190875290439525089">👋</tg-emoji>
|
||||
|
||||
// • Fetch all available standard emoji reactions
|
||||
var all_emoji = await client.Messages_GetAvailableReactions();
|
||||
|
|
@ -448,7 +448,7 @@ You can automate the collection of `access_hash` for the various resources obtai
|
|||
so that you don't have to remember them by yourself or ask the API about them each time.
|
||||
|
||||
This is done by activating the experimental `client.CollectAccessHash` system.
|
||||
See [Examples/Program_CollectAccessHash.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_CollectAccessHash.cs#L22) for how to enable it, and save/restore them for later use.
|
||||
See [Examples/Program_CollectAccessHash.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_CollectAccessHash.cs?ts=4#L22) for how to enable it, and save/restore them for later use.
|
||||
|
||||
<a name="proxy"></a>
|
||||
## Use a proxy or MTProxy to connect to Telegram
|
||||
|
|
@ -509,14 +509,14 @@ 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)
|
||||
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?ts=4#L61)
|
||||
|
||||
<a name="e2e"></a><a name="secrets"></a>
|
||||
## Send/receive end-to-end encrypted messages & files in Secret Chats
|
||||
|
||||
This can be done easily using the helper class `WTelegram.SecretChats` offering methods to manage/encrypt/decrypt secret chats & encrypted messages/files.
|
||||
|
||||
You can view a full working example at [Examples/Program_SecretChats.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_SecretChats.cs#L11).
|
||||
You can view a full working example at [Examples/Program_SecretChats.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_SecretChats.cs?ts=4#L11).
|
||||
|
||||
Secret Chats have been tested successfully with Telegram Android & iOS official clients.
|
||||
You can also check our [FAQ for more implementation details](FAQ.md#14-secret-chats-implementation-details).
|
||||
2
FAQ.md
2
FAQ.md
|
|
@ -243,7 +243,7 @@ and hosted online on any [VPS Hosting](https://www.google.com/search?q=vps+hosti
|
|||
Pure WebApp hosts might not be adequate as they will recycle (stop) your app if there is no incoming HTTP requests.
|
||||
|
||||
There are many cheap VPS Hosting offers available, for example Heroku:
|
||||
See [Examples/Program_Heroku.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_Heroku.cs#L9) for such an implementation and the steps to host/deploy it.
|
||||
See [Examples/Program_Heroku.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_Heroku.cs?ts=4#L9) for such an implementation and the steps to host/deploy it.
|
||||
|
||||
<a name="secrets"></a>
|
||||
## 14. Secret Chats implementation details
|
||||
|
|
|
|||
14
README.md
14
README.md
|
|
@ -156,23 +156,23 @@ and in the [Examples subdirectory](https://github.com/wiz0u/WTelegramClient/tree
|
|||
# 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:
|
||||
- `Channel` : A (large or public) chat group *(sometimes called [supergroup](https://corefork.telegram.org/api/channel#supergroups))*
|
||||
- `Channel`: A (large or public) chat group *(sometimes called [supergroup](https://corefork.telegram.org/api/channel#supergroups))*,
|
||||
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`)
|
||||
**⚠️ 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)*
|
||||
- **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.
|
||||
- **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.
|
||||
- **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.
|
||||
|
||||
# Other things to know
|
||||
|
||||
The Client class also offers an `OnUpdate` event that is triggered when Telegram servers sends Updates (like new messages or status), independently of your API requests.
|
||||
See [Examples/Program_ListenUpdates.cs](https://wiz0u.github.io/WTelegramClient/Examples/Program_ListenUpdates.cs)
|
||||
See [Examples/Program_ListenUpdates.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L23)
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace WTelegram
|
|||
|
||||
/// <summary>Retrieve the access_hash associated with this id (for a TL class) if it was collected</summary>
|
||||
/// <remarks>This requires <see cref="CollectAccessHash"/> to be set to <see langword="true"/> first.
|
||||
/// <para>See <see href="https://github.com/wiz0u/WTelegramClient/tree/master/Examples/Program_CollectAccessHash.cs">Examples/Program_CollectAccessHash.cs</see> for how to use this</para></remarks>
|
||||
/// <para>See <see href="https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_CollectAccessHash.cs?ts=4#L22">Examples/Program_CollectAccessHash.cs</see> for how to use this</para></remarks>
|
||||
/// <typeparam name="T">a TL object class. For example User, Channel or Photo</typeparam>
|
||||
public long GetAccessHashFor<T>(long id) where T : IObject
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace WTelegram
|
|||
public partial class Client : IDisposable
|
||||
{
|
||||
/// <summary>This event will be called when unsollicited updates/messages are sent by Telegram servers</summary>
|
||||
/// <remarks>Make your handler <see langword="async"/>, or return <see cref="Task.CompletedTask"/> or <see langword="null"/><br/>See <see href="https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs">Examples/Program_ListenUpdate.cs</see> for how to use this</remarks>
|
||||
/// <remarks>Make your handler <see langword="async"/>, or return <see cref="Task.CompletedTask"/> or <see langword="null"/><br/>See <see href="https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ListenUpdates.cs?ts=4#L23">Examples/Program_ListenUpdate.cs</see> for how to use this</remarks>
|
||||
public event Func<IObject, Task> OnUpdate;
|
||||
/// <summary>Used to create a TcpClient connected to the given address/port, or throw an exception on failure</summary>
|
||||
public TcpFactory TcpHandler { get; set; } = DefaultTcpHandler;
|
||||
|
|
|
|||
|
|
@ -91,6 +91,9 @@ namespace TL
|
|||
else
|
||||
ProcessEntity<MessageEntityCode>();
|
||||
break;
|
||||
case '!' when offset + 1 < sb.Length && sb[offset + 1] == '[':
|
||||
sb.Remove(offset, 1);
|
||||
goto case '[';
|
||||
case '[':
|
||||
entities.Add(new MessageEntityTextUrl { offset = offset, length = -1 });
|
||||
sb.Remove(offset, 1);
|
||||
|
|
@ -112,7 +115,7 @@ namespace TL
|
|||
textUrl.url = sb.ToString(offset + 2, offset2 - offset - 3);
|
||||
if (textUrl.url.StartsWith("tg://user?id=") && long.TryParse(textUrl.url[13..], out var id) && client.GetAccessHashFor<User>(id) is long hash)
|
||||
entities[lastIndex] = new InputMessageEntityMentionName { offset = textUrl.offset, length = textUrl.length, user_id = new InputUser(id, hash) };
|
||||
else if (textUrl.url.StartsWith("emoji?id=") && long.TryParse(textUrl.url[9..], out id))
|
||||
else if ((textUrl.url.StartsWith("tg://emoji?id=") || textUrl.url.StartsWith("emoji?id=")) && long.TryParse(textUrl.url[(textUrl.url.IndexOf('=') + 1)..], out id))
|
||||
if (premium) entities[lastIndex] = new MessageEntityCustomEmoji { offset = textUrl.offset, length = textUrl.length, document_id = id };
|
||||
else entities.RemoveAt(lastIndex);
|
||||
sb.Remove(offset, offset2 - offset);
|
||||
|
|
@ -165,7 +168,7 @@ namespace TL
|
|||
if (entityToMD.TryGetValue(nextEntity.GetType(), out var md))
|
||||
{
|
||||
var closing = (nextEntity.offset + nextEntity.length, md);
|
||||
if (md[0] == '[')
|
||||
if (md[0] is '[' or '!')
|
||||
{
|
||||
if (nextEntity is MessageEntityTextUrl metu)
|
||||
closing.md = $"]({metu.url.Replace("\\", "\\\\").Replace(")", "\\)").Replace(">", "%3E")})";
|
||||
|
|
@ -174,7 +177,7 @@ namespace TL
|
|||
else if (nextEntity is InputMessageEntityMentionName imemn)
|
||||
closing.md = $"](tg://user?id={imemn.user_id.UserId ?? client.UserId})";
|
||||
else if (nextEntity is MessageEntityCustomEmoji mecu)
|
||||
if (premium) closing.md = $"](emoji?id={mecu.document_id})";
|
||||
if (premium) closing.md = $"](tg://emoji?id={mecu.document_id})";
|
||||
else continue;
|
||||
}
|
||||
else if (nextEntity is MessageEntityPre mep)
|
||||
|
|
@ -208,7 +211,7 @@ namespace TL
|
|||
[typeof(MessageEntityUnderline)] = "__",
|
||||
[typeof(MessageEntityStrike)] = "~",
|
||||
[typeof(MessageEntitySpoiler)] = "||",
|
||||
[typeof(MessageEntityCustomEmoji)] = "[",
|
||||
[typeof(MessageEntityCustomEmoji)] = "![",
|
||||
};
|
||||
|
||||
/// <summary>Insert backslashes in front of Markdown reserved characters</summary>
|
||||
|
|
@ -304,8 +307,8 @@ namespace TL
|
|||
if (entities.LastOrDefault(e => e.length == -1) is MessageEntityPre prevEntity)
|
||||
prevEntity.language = tag[21..^1];
|
||||
}
|
||||
else if (premium && tag.StartsWith("tg-emoji id=\""))
|
||||
entities.Add(new MessageEntityCustomEmoji { offset = offset, length = -1, document_id = long.Parse(tag[13..^1]) });
|
||||
else if (premium && (tag.StartsWith("tg-emoji emoji-id=\"") || tag.StartsWith("tg-emoji id=\"")))
|
||||
entities.Add(new MessageEntityCustomEmoji { offset = offset, length = -1, document_id = long.Parse(tag[(tag.IndexOf('=') + 2)..^1]) });
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -361,7 +364,7 @@ namespace TL
|
|||
tag = $"<a href=\"tg://user?id={imemn.user_id.UserId ?? client.UserId}\">";
|
||||
}
|
||||
else if (nextEntity is MessageEntityCustomEmoji mecu)
|
||||
if (premium) tag = $"<tg-emoji id=\"{mecu.document_id}\">";
|
||||
if (premium) tag = $"<tg-emoji emoji-id=\"{mecu.document_id}\">";
|
||||
else continue;
|
||||
else if (nextEntity is MessageEntityPre mep && !string.IsNullOrEmpty(mep.language))
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue