mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-11-04 01:47:27 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			254 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			254 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
Messages
 | 
						|
========
 | 
						|
 | 
						|
.. currentmodule:: telethon
 | 
						|
 | 
						|
.. role:: underline
 | 
						|
    :class: underline
 | 
						|
 | 
						|
.. role:: strikethrough
 | 
						|
    :class: strikethrough
 | 
						|
 | 
						|
.. role:: spoiler
 | 
						|
    :class: spoiler
 | 
						|
 | 
						|
Messages are at the heart of a messaging platform.
 | 
						|
In Telethon, you will be using the :class:`~types.Message` class to interact with them.
 | 
						|
 | 
						|
 | 
						|
Fetching messages
 | 
						|
-----------------
 | 
						|
 | 
						|
The most common way to actively fetch messages using the :meth:`Client.get_messages` method:
 | 
						|
 | 
						|
.. code-block:: python
 | 
						|
 | 
						|
    # Get the last message in a chat (by setting the limit to 1).
 | 
						|
    last_message = (await client.get_messages(chat, 1))[0]
 | 
						|
 | 
						|
    # Iterate over all messages in a chat, starting from the oldest message (by using reversed).
 | 
						|
    async for message in reversed(client.get_messages(chat)):
 | 
						|
        print(message.sender.name, message.text_html)
 | 
						|
 | 
						|
You can also perform a fuzzy text search with the :meth:`Client.search_messages` method.
 | 
						|
The search will be performed server-side by Telegram, so the rules for how it works are also fuzzy.
 | 
						|
 | 
						|
If you want to search for messages in all the chats you're part of, you can use :meth:`Client.search_all_messages`.
 | 
						|
 | 
						|
Lastly, :meth:`Client.send_message` *also* returns the :class:`~types.Message` that you just sent.
 | 
						|
 | 
						|
The most common way to passively listen to incoming messages is using the :class:`~events.NewMessage` event:
 | 
						|
 | 
						|
.. code-block:: python
 | 
						|
 | 
						|
    from telethon import events
 | 
						|
 | 
						|
    @client.on(events.NewMessage)
 | 
						|
    async def first(event):
 | 
						|
        print(event.chat.name, ':', event.text)
 | 
						|
 | 
						|
.. seealso::
 | 
						|
 | 
						|
    The :doc:`updates` concept for an in-depth explanation on using events.
 | 
						|
 | 
						|
 | 
						|
.. _formatting:
 | 
						|
 | 
						|
Formatting messages
 | 
						|
-------------------
 | 
						|
 | 
						|
The library supports 3 formatting modes: no formatting, CommonMark, HTML.
 | 
						|
 | 
						|
Telegram does not natively support markdown or HTML.
 | 
						|
Clients such as Telethon parse the text into a list of formatting :tl:`MessageEntity` at different offsets.
 | 
						|
 | 
						|
Note that `CommonMark's markdown <https://commonmark.org/>`_ is not fully compatible with :term:`HTTP Bot API`'s
 | 
						|
`MarkdownV2 style <https://core.telegram.org/bots/api#markdownv2-style>`_, and does not support spoilers::
 | 
						|
 | 
						|
    *italic* and _italic_
 | 
						|
    **bold** and __bold__
 | 
						|
    # headings are underlined
 | 
						|
    ~~strikethrough~~
 | 
						|
    [inline URL](https://www.example.com/)
 | 
						|
    [inline mention](tg://user?id=ab1234cd6789)
 | 
						|
    custom emoji image with 
 | 
						|
    `inline code`
 | 
						|
    ```python
 | 
						|
    multiline pre-formatted
 | 
						|
    block with optional language
 | 
						|
    ```
 | 
						|
 | 
						|
HTML is also not fully compatible with :term:`HTTP Bot API`'s
 | 
						|
`MarkdownV2 style <https://core.telegram.org/bots/api#markdownv2-style>`_,
 | 
						|
and instead favours more standard `HTML elements <https://developer.mozilla.org/en-US/docs/Web/HTML/Element>`_:
 | 
						|
 | 
						|
* ``strong`` and ``b`` for **bold**.
 | 
						|
* ``em`` and ``i`` for *italics*.
 | 
						|
* ``u`` for :underline:`underlined text`.
 | 
						|
* ``del`` and ``s`` for :strikethrough:`strikethrough`.
 | 
						|
* ``blockquote`` for quotes.
 | 
						|
* ``details`` for :spoiler:`hidden text` (spoiler).
 | 
						|
* ``code`` for ``inline code``
 | 
						|
* ``pre`` for multiple lines of code.
 | 
						|
* ``a`` for links.
 | 
						|
* ``img`` for inline images (only custom emoji).
 | 
						|
 | 
						|
Both markdown and HTML recognise the following special URLs using the ``tg:`` protocol:
 | 
						|
 | 
						|
* ``tg://user?id=ab1234cd6789`` for inline mentions.
 | 
						|
  To make sure the mention works, use :attr:`types.PackedChat.hex`.
 | 
						|
  You can also use :attr:`types.User.id`, but the mention will fail if the user is not in cache.
 | 
						|
* ``tg://emoji?id=1234567890`` for custom emoji.
 | 
						|
  You must use the document identifier as the value.
 | 
						|
  The alt-text of the image **must** be a emoji such as 👍.
 | 
						|
 | 
						|
 | 
						|
To obtain a message's text formatted, use :attr:`types.Message.text_markdown` or :attr:`types.Message.text_html`.
 | 
						|
 | 
						|
To send a message with formatted text, use the ``markdown`` or ``html`` parameters in :meth:`Client.send_message`.
 | 
						|
 | 
						|
When sending files, the format is appended to the name of the ``caption`` parameter, either ``caption_markdown`` or ``caption_html``.
 | 
						|
 | 
						|
 | 
						|
Link previews
 | 
						|
^^^^^^^^^^^^^
 | 
						|
 | 
						|
Link previews are treated as a type of media automatically generated by Telegram.
 | 
						|
This means you cannot have both a link preview and other media in the same message.
 | 
						|
 | 
						|
The ``link_preview`` parameter indicates whether link previews are *allowed* to be present.
 | 
						|
If Telegram is unable to generate a link preview for any of the links, there won't be a link preview.
 | 
						|
 | 
						|
By default, link previews are not enabled.
 | 
						|
This is done to prevent sending things you did not explicitly intend to send.
 | 
						|
Unlike the official clients, which do not have a GUI to "enable" the preview, you can easily enable them from code.
 | 
						|
 | 
						|
Telegram will attempt to generate a preview for all links contained in the message in order.
 | 
						|
You can use this to your advantage, and hide a link to a photo in the first space or invisible character like ``'\u2063'``.
 | 
						|
Note that avid users *will* be able to find out the link. It is not secret!
 | 
						|
 | 
						|
Link previews of photos won't show under the photos of the chat,
 | 
						|
but it requires a server hosting the image, a public address, and Telegram to be able to generate a preview.
 | 
						|
 | 
						|
To regenerate a preview, send the corresponding link to `@WebpageBot <https://t.me/WebpageBot>`_.
 | 
						|
 | 
						|
 | 
						|
Message identifiers
 | 
						|
-------------------
 | 
						|
 | 
						|
This is an in-depth explanation for how the :attr:`types.Message.id` works.
 | 
						|
 | 
						|
.. note::
 | 
						|
 | 
						|
    You can safely skip this section if you're not interested.
 | 
						|
 | 
						|
Every account, whether it's an user account or bot account, has its own message counter.
 | 
						|
This counter starts at 1, and is incremented by 1 every time a new message is received.
 | 
						|
In private conversations or small groups, each account will receive a copy each message.
 | 
						|
The message identifier will be based on the message counter of the receiving account.
 | 
						|
 | 
						|
In megagroups and broadcast channels, the message counter instead belongs to the channel itself.
 | 
						|
It also starts at 1 and is incremented by 1 for every message sent to the group or channel.
 | 
						|
This means every account will see the same message identifier for a given mesasge in a group or channel.
 | 
						|
 | 
						|
This design has the following implications:
 | 
						|
 | 
						|
* The message identifier alone is enough to uniquely identify a message only if it's not from a megagroup or channel.
 | 
						|
  This is why :class:`events.MessageDeleted` does not need to (and doesn't always) include chat information.
 | 
						|
* Messages cannot be deleted for one-side only in megagroups or channels.
 | 
						|
  Because every account shares the same identifier for the message, it cannot be deleted only for some.
 | 
						|
* Links to messages only work for everyone inside megagroups or channels.
 | 
						|
  In private conversations and small groups, each account will have their own counter, and the identifiers won't match.
 | 
						|
 | 
						|
Let's look at a concrete example.
 | 
						|
 | 
						|
* You are logged in as User-A.
 | 
						|
* Both User-B and User-C are your mutual contacts.
 | 
						|
* You have share a small group called Group-S with User-B.
 | 
						|
* You also share a megagroup called Group-M with User-C.
 | 
						|
 | 
						|
.. graphviz::
 | 
						|
    :caption: Demo scenario
 | 
						|
 | 
						|
    digraph scenario {
 | 
						|
        "User A" [shape=trapezium];
 | 
						|
        "User B" [shape=box];
 | 
						|
        "User C" [shape=box];
 | 
						|
 | 
						|
        "User A" -> "User B";
 | 
						|
        "User A" -> "User C";
 | 
						|
 | 
						|
        "Group-S" -> "User A";
 | 
						|
        "Group-S" -> "User B";
 | 
						|
 | 
						|
        "Group-M" -> "User A";
 | 
						|
        "Group-M" -> "User C";
 | 
						|
    }
 | 
						|
 | 
						|
Every account and channel has just been created.
 | 
						|
This means everyone has a message counter of one.
 | 
						|
 | 
						|
First, User-A will sent a welcome message to both User-B and User-C::
 | 
						|
 | 
						|
    User-A → User-B: Hey, welcome!
 | 
						|
    User-A → User-C: ¡Bienvenido!
 | 
						|
 | 
						|
* For User-A, "Hey, welcome!" will have the message identifier 1. The message with "¡Bienvenido!" will have an ID of 2.
 | 
						|
* For User-B, "Hey, welcome" will have ID 1.
 | 
						|
* For User-B, "¡Bienvenido!" will have ID 1.
 | 
						|
 | 
						|
.. csv-table:: Message identifiers
 | 
						|
   :header: "Message", "User-A", "User-B", "User-C", "Group-S", "Group-M"
 | 
						|
 | 
						|
   "Hey, welcome!", 1, 1, "", "", ""
 | 
						|
   "¡Bienvenido!", 2, "", 1, "", ""
 | 
						|
 | 
						|
Next, User-B and User-C will respond to User-A::
 | 
						|
 | 
						|
    User-B → User-A: Thanks!
 | 
						|
    User-C → User-A: Gracias :)
 | 
						|
 | 
						|
.. csv-table:: Message identifiers
 | 
						|
   :header: "Message", "User-A", "User-B", "User-C", "Group-S", "Group-M"
 | 
						|
 | 
						|
   "Hey, welcome!", 1, 1, "", "", ""
 | 
						|
   "¡Bienvenido!", 2, "", 1, "", ""
 | 
						|
   "Thanks!", 3, 2, "", "", ""
 | 
						|
   "Gracias :)", 4, "", 2, "", ""
 | 
						|
 | 
						|
Notice how for each message, the counter goes up by one, and they are independent.
 | 
						|
 | 
						|
Let's see what happens when User-B sends a message to Group-S::
 | 
						|
 | 
						|
    User-B → Group-S: Nice group
 | 
						|
 | 
						|
.. csv-table:: Message identifiers
 | 
						|
   :header: "Message", "User-A", "User-B", "User-C", "Group-S", "Group-M"
 | 
						|
 | 
						|
   "Hey, welcome!", 1, 1, "", "", ""
 | 
						|
   "¡Bienvenido!", 2, "", 1, "", ""
 | 
						|
   "Thanks!", 3, 2, "", "", ""
 | 
						|
   "Gracias :)", 4, "", 2, "", ""
 | 
						|
   "Nice group", 5, 3, "", "", ""
 | 
						|
 | 
						|
While the message was sent to a different chat, the group itself doesn't have a counter.
 | 
						|
The message identifiers are still unique for each account.
 | 
						|
The chat where the message was sent can be completely ignored.
 | 
						|
 | 
						|
Megagroups behave differently::
 | 
						|
 | 
						|
    User-C → Group-M: Buen grupo
 | 
						|
 | 
						|
.. csv-table:: Message identifiers
 | 
						|
   :header: "Message", "User-A", "User-B", "User-C", "Group-S", "Group-M"
 | 
						|
 | 
						|
   "Hey, welcome!", 1, 1, "", "", ""
 | 
						|
   "¡Bienvenido!", 2, "", 1, "", ""
 | 
						|
   "Thanks!", 3, 2, "", "", ""
 | 
						|
   "Gracias :)", 4, "", 2, "", ""
 | 
						|
   "Nice group", 5, 3, "", "", ""
 | 
						|
   "Buen grupo", "", "", "", "", 1
 | 
						|
 | 
						|
The group has its own message counter.
 | 
						|
Each user won't get a copy of the message with their own identifier, but rather everyone sees the same message.
 |