mirror of
https://github.com/wiz0u/WTelegramClient.git
synced 2025-12-06 06:52:01 +01:00
added MarkdownToEntities
This commit is contained in:
parent
b94ec0abca
commit
e615f83db6
13
EXAMPLES.md
13
EXAMPLES.md
|
|
@ -15,11 +15,12 @@ Remember that these are just simple example codes that you should adjust to your
|
||||||
```csharp
|
```csharp
|
||||||
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
|
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
|
||||||
await client.LoginUserIfNeeded();
|
await client.LoginUserIfNeeded();
|
||||||
var resolved = await client.Contacts_ResolveUsername("username");
|
var resolved = await client.Contacts_ResolveUsername("username"); // without the @
|
||||||
await client.SendMessageAsync(resolved, "Hello!");
|
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.
|
*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.*
|
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.*
|
||||||
|
|
||||||
### Send a message to someone by phone number
|
### Send a message to someone by phone number
|
||||||
```csharp
|
```csharp
|
||||||
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
|
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
|
||||||
|
|
@ -30,6 +31,16 @@ if (contacts.imported.Length > 0)
|
||||||
```
|
```
|
||||||
*Note: To prevent spam, Telegram may restrict your ability to add new phone numbers.*
|
*Note: To prevent spam, Telegram may restrict your ability to add new phone numbers.*
|
||||||
|
|
||||||
|
### Send a Markdown message to ourself (Saved Messages)
|
||||||
|
```csharp
|
||||||
|
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
|
||||||
|
await client.LoginUserIfNeeded();
|
||||||
|
var text = "Hello __dear *friend*__!\nEnjoy this `userbot` written with [WTelegramClient](https://github.com/wiz0u/WTelegramClient)";
|
||||||
|
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.
|
||||||
|
|
||||||
### List all chats (groups/channels) the user is in and send a message to one
|
### List all chats (groups/channels) the user is in and send a message to one
|
||||||
```csharp
|
```csharp
|
||||||
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
|
using var client = new WTelegram.Client(Environment.GetEnvironmentVariable);
|
||||||
|
|
|
||||||
|
|
@ -436,7 +436,7 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB
|
||||||
|
|
||||||
#if !NETCOREAPP2_0_OR_GREATER
|
#if !NETCOREAPP2_0_OR_GREATER
|
||||||
// adapted from https://github.com/dotnet/aspnetcore/blob/main/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/ManagedPbkdf2Provider.cs
|
// adapted from https://github.com/dotnet/aspnetcore/blob/main/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/ManagedPbkdf2Provider.cs
|
||||||
public static byte[] PBKDF2_SHA512(byte[] password, byte[] salt, int iterationCount, int numBytesRequested)
|
private static byte[] PBKDF2_SHA512(byte[] password, byte[] salt, int iterationCount, int numBytesRequested)
|
||||||
{
|
{
|
||||||
// PBKDF2 is defined in NIST SP800-132, Sec. 5.3: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf
|
// PBKDF2 is defined in NIST SP800-132, Sec. 5.3: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf
|
||||||
byte[] retVal = new byte[numBytesRequested];
|
byte[] retVal = new byte[numBytesRequested];
|
||||||
|
|
|
||||||
|
|
@ -353,4 +353,93 @@ namespace TL
|
||||||
return sb.Append('}').ToString();
|
return sb.Append('}').ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Helpers
|
||||||
|
{
|
||||||
|
public static MessageEntity[] MarkdownToEntities(this WTelegram.Client client, ref string text)
|
||||||
|
{
|
||||||
|
var entities = new List<MessageEntity>();
|
||||||
|
var sb = new StringBuilder(text);
|
||||||
|
for (int offset = 0; offset < sb.Length;)
|
||||||
|
{
|
||||||
|
switch (sb[offset])
|
||||||
|
{
|
||||||
|
case '\\': sb.Remove(offset++, 1); break;
|
||||||
|
case '*':
|
||||||
|
ProcessEntity<MessageEntityBold>();
|
||||||
|
break;
|
||||||
|
case '_':
|
||||||
|
if (offset + 1 < sb.Length && sb[offset + 1] == '_')
|
||||||
|
{
|
||||||
|
sb.Remove(offset, 1);
|
||||||
|
ProcessEntity<MessageEntityUnderline>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ProcessEntity<MessageEntityItalic>();
|
||||||
|
break;
|
||||||
|
case '~':
|
||||||
|
ProcessEntity<MessageEntityStrike>();
|
||||||
|
break;
|
||||||
|
case '`':
|
||||||
|
if (offset + 2 < sb.Length && sb[offset + 1] == '`' && sb[offset + 2] == '`')
|
||||||
|
{
|
||||||
|
int header = 3;
|
||||||
|
if (entities.FindLast(e => e.length == 0) is MessageEntityPre pre)
|
||||||
|
pre.length = offset - pre.offset;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (offset + header < sb.Length && !char.IsWhiteSpace(sb[offset + header]))
|
||||||
|
header++;
|
||||||
|
entities.Add(new MessageEntityPre { offset = offset, language = sb.ToString(offset + 3, header - 3) });
|
||||||
|
}
|
||||||
|
sb.Remove(offset, header);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ProcessEntity<MessageEntityCode>();
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
entities.Add(new MessageEntityTextUrl { offset = offset });
|
||||||
|
sb.Remove(offset, 1);
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
if (offset + 1 < sb.Length && sb[offset + 1] == '(' && entities.FindLast(e => e.length == 0) is MessageEntityTextUrl textUrl)
|
||||||
|
{
|
||||||
|
textUrl.length = offset - textUrl.offset;
|
||||||
|
sb.Remove(offset, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
offset++;
|
||||||
|
break;
|
||||||
|
case ')':
|
||||||
|
var lastIndex = entities.FindLastIndex(e => e.length == 0 || e is MessageEntityTextUrl { url: null });
|
||||||
|
MessageEntity entity;
|
||||||
|
if (lastIndex >= 0 && (entity = entities[lastIndex]).length != 0)
|
||||||
|
{
|
||||||
|
var urlStart = entity.offset + entity.length;
|
||||||
|
var urlLength = offset - urlStart;
|
||||||
|
var url = sb.ToString(urlStart, urlLength);
|
||||||
|
sb.Remove(urlStart, urlLength + 1);
|
||||||
|
offset = urlStart;
|
||||||
|
if (url.StartsWith("tg://user?id=") && long.TryParse(url[13..], out var user_id) && client.GetAccessHashFor<User>(user_id) is long hash && hash != 0)
|
||||||
|
entities[lastIndex] = new InputMessageEntityMentionName { offset = entity.offset, length = entity.length, user_id = new InputUser { user_id = user_id, access_hash = hash } };
|
||||||
|
else
|
||||||
|
((MessageEntityTextUrl)entity).url = url;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: offset++; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessEntity<T>() where T : MessageEntity, new()
|
||||||
|
{
|
||||||
|
if (entities.LastOrDefault(e => e.length == 0) is T prevEntity)
|
||||||
|
prevEntity.length = offset - prevEntity.offset;
|
||||||
|
else
|
||||||
|
entities.Add(new T { offset = offset });
|
||||||
|
sb.Remove(offset, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
text = sb.ToString();
|
||||||
|
return entities.Count == 0 ? null : entities.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue