diff --git a/Sending-more-than-just-messages.md b/Sending-more-than-just-messages.md new file mode 100644 index 0000000..9166a7c --- /dev/null +++ b/Sending-more-than-just-messages.md @@ -0,0 +1,117 @@ +The current version of the library, v1, does not yet implement some features in the friendly methods, such as spoilers in `client.send_message`. And it never might, as it increases the maintenance burden, but are not so commonly used. However, that doesn't mean the library can't do those things. + + +# Sending stickers + +Stickers are nothing else than ``files``, and when you successfully retrieve the stickers for a certain sticker set, all you will have are ``handles`` to these files. Remember, the files Telegram holds on their servers can be referenced through this pair of ID/hash (unique per user), and you need to use this handle when sending a "document" message. This working example will send yourself the very first sticker you have: + +```python +# Get all the sticker sets this user has +from telethon.tl.functions.messages import GetAllStickersRequest +sticker_sets = await client(GetAllStickersRequest(0)) + +# Choose a sticker set +from telethon.tl.functions.messages import GetStickerSetRequest +from telethon.tl.types import InputStickerSetID +sticker_set = sticker_sets.sets[0] + +# Get the stickers for this sticker set +stickers = await client(GetStickerSetRequest( + stickerset=InputStickerSetID( + id=sticker_set.id, access_hash=sticker_set.access_hash + ), + hash=0 +)) + +# Stickers are nothing more than files, so send that +await client.send_file('me', stickers.documents[0]) +``` + +# Sending reactions + +It works very similar to replying to a message. You need to specify the chat, message ID you wish to react to, and reaction, using :tl:`SendReaction`: + +```python +from telethon.tl.functions.messages import SendReactionRequest +await client(SendReactionRequest( + peer=chat, + msg_id=42, + reaction=[types.ReactionEmoji( + emoticon='❤️' + )] +)) +``` + +Note that you cannot use strings like ``:heart:`` for the reaction. You must use the desired emoji directly. You can most easily achieve this by copy-pasting the emoji from an official application such as Telegram Desktop. + +If for some reason you cannot embed emoji directly into the code, you can also use its unicode escape (which you can find using websites like [unicode-table.com](https://unicode-table.com/en/emoji/)), or install a different package, like [`emoji`](https://pypi.org/project/emoji/): + +```python + # All of these work exactly the same (you only need one): + import emoji + reaction = emoji.emojize(':red_heart:') + reaction = '❤️' + reaction = '\u2764' + + from telethon.tl.functions.messages import SendReactionRequest + await client(SendReactionRequest( + peer=chat, + msg_id=42, + reaction=[types.ReactionEmoji( + emoticon=reaction + )] + )) +``` + +Please make sure to check the help pages of the respective websites you use if you need a more in-depth explanation on how they work. Telethon only needs you to provide the emoji in some form. Some packages or websites can make this easier. + + +# Sending spoilers and custom emoji + +Telethon's v1 `markdown` parser does not offer a way to send spoiler (hidden text) or custom emoji. However, it's easy to add support for them. + +Telethon's [`parse_mode`](https://docs.telethon.dev/en/stable/modules/client.html#telethon.client.messageparse.MessageParseMethods.parse_mode) supports using a custom object with `parse` and `unparse` functions to work. This means it's possible to leverage the current markdown implementation and extend it with custom functionality. + +Copy the following code into your own: + +```python +from telethon.extensions import markdown +from telethon import types + +class CustomMarkdown: + @staticmethod + def parse(text): + text, entities = markdown.parse(text) + for i, e in enumerate(entities): + if isinstance(e, types.MessageEntityTextUrl): + if e.url == 'spoiler': + entities[i] = types.MessageEntitySpoiler(e.offset, e.length) + elif e.url.startswith('emoji/'): + entities[i] = types.MessageEntityCustomEmoji(e.offset, e.length, int(e.url.split('/')[1])) + return text, entities + @staticmethod + def unparse(text, entities): + return markdown.unparse(text, entities) +``` + +This creates a custom class with `parse` and `unparse`. `CustomMarkdown.parse` uses `markdown.parse` (so it works just like the default markdown), but before returning, it scans the parsed text for the following inline URLs: + +```python +message = 'this is a [link text](spoiler) and [❤️](emoji/10002345) too' +``` + +Here, the message contains a `link text` with URL `spoiler`. The above code will replace the URL with [`MessageEntitySpoiler`](https://tl.telethon.dev/constructors/message_entity_spoiler.html). It also contains a URL with `emoji/10002345`, which will be replaced with [`MessageEntityCustomEmoji`](https://tl.telethon.dev/constructors/message_entity_custom_emoji.html). Effectively sending those instead of the URL. + +To use the class, you must change your `client.parse_mode` to it (be sure to use an instance, because the type is callable and the library would attempt to create an instance to parse it): + +```python +client.parse_mode = CustomMarkdown() +``` + +Now, in your message text, you can use inline links which become spoilers and custom emoji! (Note that for custom emoji to work, the inline link text **must** be a normal emoji): + +```python +client.send_message('me', 'hello this is a [hidden text](spoiler), with custom emoji [❤️](emoji/10002345) !') +``` + +You may have noticed the emoji URL is followed by a number. This number is a `document_id`. To find it, the easiest way is to send a message to your own chat with the premium emoji you want to use using an official client, and then use Telethon to print the `message.entities`. It will contain the `document_id` you need to use. diff --git a/Sending-spoilers-and-custom-emoji.md b/Sending-spoilers-and-custom-emoji.md deleted file mode 100644 index ebfb4b9..0000000 --- a/Sending-spoilers-and-custom-emoji.md +++ /dev/null @@ -1,47 +0,0 @@ -Telethon's v1 `markdown` parser does not offer a way to send spoiler (hidden text) or custom emoji. However, it's easy to add support for them. - -Telethon's [`parse_mode`](https://docs.telethon.dev/en/stable/modules/client.html#telethon.client.messageparse.MessageParseMethods.parse_mode) supports using a custom object with `parse` and `unparse` functions to work. This means it's possible to leverage the current markdown implementation and extend it with custom functionality. - -Copy the following code into your own: - -```python -from telethon.extensions import markdown -from telethon import types - -class CustomMarkdown: - @staticmethod - def parse(text): - text, entities = markdown.parse(text) - for i, e in enumerate(entities): - if isinstance(e, types.MessageEntityTextUrl): - if e.url == 'spoiler': - entities[i] = types.MessageEntitySpoiler(e.offset, e.length) - elif e.url.startswith('emoji/'): - entities[i] = types.MessageEntityCustomEmoji(e.offset, e.length, int(e.url.split('/')[1])) - return text, entities - @staticmethod - def unparse(text, entities): - return markdown.unparse(text, entities) -``` - -This creates a custom class with `parse` and `unparse`. `CustomMarkdown.parse` uses `markdown.parse` (so it works just like the default markdown), but before returning, it scans the parsed text for the following inline URLs: - -```python -message = 'this is a [link text](spoiler) and [❤️](emoji/10002345) too' -``` - -Here, the message contains a `link text` with URL `spoiler`. The above code will replace the URL with [`MessageEntitySpoiler`](https://tl.telethon.dev/constructors/message_entity_spoiler.html). It also contains a URL with `emoji/10002345`, which will be replaced with [`MessageEntityCustomEmoji`](https://tl.telethon.dev/constructors/message_entity_custom_emoji.html). Effectively sending those instead of the URL. - -To use the class, you must change your `client.parse_mode` to it (be sure to use an instance, because the type is callable and the library would attempt to create an instance to parse it): - -```python -client.parse_mode = CustomMarkdown() -``` - -Now, in your message text, you can use inline links which become spoilers and custom emoji! (Note that for custom emoji to work, the inline link text **must** be a normal emoji): - -```python -client.send_message('me', 'hello this is a [hidden text](spoiler), with custom emoji [❤️](emoji/10002345) !') -``` - -You may have noticed the emoji URL is followed by a number. This number is a `document_id`. To find it, the easiest way is to send a message to your own chat with the premium emoji you want to use using an official client, and then use Telethon to print the `message.entities`. It will contain the `document_id` you need to use. \ No newline at end of file