Сущность в сообщении (MessageEntity)



MessageEntity — Это специальный тип сущности в текстовом сообщении Telegram, который используется для выделения определенных частей текста, таких как хэштеги, имена пользователей, URL-адреса и т.д.

Пример сущностей MessageEntity:

{
    "_": "MessageEntity",   # Это поле обозначает тип объекта, в данном случае, это "MessageEntity".
    "type": "MessageEntityType.CUSTOM_EMOJI", # Указывает на тип сущности, в данном случае, это пользовательский эмодзи (CUSTOM_EMOJI).
    "offset": 24,           # Смещение сущности в тексте сообщения, начиная с 24-го символа в кодировке UTF-16.
    "length": 2,            # Длина сущности, занимает 2 символа в тексте сообщения.
    "custom_emoji_id": 5337316769467285    # Уникальный идентификатор пользовательского эмодзи.
},
​​​​​​​{
    "_": "MessageEntity",
    "type": "MessageEntityType.URL",
    "offset": 0,
    "length": 33
}

Чтобы лучше понять о чём идёт речь, запустите следующий код, и найдите поля MessageEntity.

from pyrogram import Client

api_id = 2*********2
api_hash = "8*****************7"
app = Client("my_session", api_id=api_id, api_hash=api_hash)

def main():
    with app:
        group_url = "test"
        messages = app.search_messages(group_url)
        for message in messages:
            print(message)
main()

Вот основные параметры MessageEntity:

type (MessageEntityType) — этот параметр определяет тип сущности. В Telegram есть разные типы сущностей, такие как хэштеги, упоминания пользователей, ссылки и другие. Каждый тип имеет свои особенности и способы обработки в клиенте Telegram. Например, хэштеги начинаются с символа #, а упоминания пользователей с @.

Вот список типов сущностей сообщений, которые описаны на странице:

MessageEntityType.MENTION: Упоминание пользователя с @username
MessageEntityType.HASHTAG: Хештег с #hashtag
MessageEntityType.CASHTAG: Кэштег с $USD
MessageEntityType.BOT_COMMAND: Команда бота, например /start
MessageEntityType.URL: URL-адреса, например https://pyrogram.org
MessageEntityType.EMAIL: Электронная почта, например do-not-reply@pyrogram.org
MessageEntityType.PHONE_NUMBER: Номер телефона, например +1-123-456-7890
MessageEntityType.BOLD: Жирный текст
MessageEntityType.ITALIC: Курсивный текст
MessageEntityType.UNDERLINE: Подчеркнутый текст
MessageEntityType.STRIKETHROUGH: Текст с зачеркиванием
MessageEntityType.SPOILER: Текст спойлера
MessageEntityType.CODE: Строка моноширинного шрифта
MessageEntityType.PRE: Блок моноширинного шрифта (с указанием языка)
MessageEntityType.BLOCKQUOTE: Текст цитаты
MessageEntityType.TEXT_LINK: Для кликабельных текстовых URL
MessageEntityType.TEXT_MENTION: Для упоминания пользователей без имени пользователя (с указанием пользователя)
MessageEntityType.BANK_CARD: Текст банковской карты
MessageEntityType.CUSTOM_EMOJI: Пользовательские эмодзи
MessageEntityType.UNKNOWN: Неизвестный тип сущности сообщения

​​​​​​​​​​​​​offset (int) — смещение указывает на позицию в тексте сообщения, с которой начинается сущность. Оно измеряется в кодовых единицах UTF-16, что важно для правильного определения начала сущности, особенно если текст содержит символы, занимающие более одной кодовой единицы, например эмодзи или некоторые специальные символы.

length (int) — длина сущности также измеряется в кодовых единицах UTF-16 и указывает, сколько символов занимает сущность в тексте сообщения.

url (str, опционально) — этот параметр присутствует только для сущностей типа TEXT_LINK. Он содержит URL, который будет открыт в браузере пользователя, когда тот нажмет на соответствующую часть текста в сообщении(встроенные ссылки).

​​​​user (User, опционально) — для сущностей типа TEXT_MENTION, этот параметр содержит объект пользователя (User), который был упомянут в сообщении. Это позволяет клиенту Telegram предоставить дополнительную информацию о пользователе, например, его имя и фотографию профиля.

language (str, опционально) — этот параметр используется для сущностей типа pre, которые обычно представляют блоки предварительно отформатированного текста, часто используемого для отображения кода. Параметр language указывает на язык программирования кода, что может быть использовано для его синтаксической подсветки.

custom_emoji_id (int, опционально) — для сущностей типа CUSTOM_EMOJI, этот параметр содержит уникальный идентификатор пользовательского эмодзи. С помощью метода get_custom_emoji_stickers() можно получить полную информацию о стикере, который соответствует этому идентификатору.

Код ниже проверит во всех найденных сообщениях учебной группы  все сущности с помощью ​​​​​​​message.entities.

from pyrogram import Client

api_id = 1111
api_hash = ""
app = Client("my_session", api_id=api_id, api_hash=api_hash)
def main():
    with app:
        group_url = "test"
        messages = app.get_chat_history(group_url)
        for message in messages:
            if message.entities:                 # Проверяем, есть ли сущности в сообщении
                for entity in message.entities:  # Проходим по всем сущностям
                    print(entity)
main()

Этот код показал нам сообщения, в которых есть сущности, но это мало похоже на то, что нам необходимо. Вероятно, у вас появился вопрос: а как же все-таки извлечь саму сущность из сообщения, ссылку или emoji?

def main():
    with app:                             
        group_url = "test" 
        messages = app.get_chat_history(group_url)  # Получаем историю чата для указанной группы
        for message in messages:          # Перебираем все сообщения в истории чата
            if message.entities:          # Проверяем, есть ли у сообщения сущности (например, ссылки)
                for entity in message.entities:  # Перебираем все сущности в сообщении
                    if entity.url:        # Проверяем, содержит ли сущность URL
                        print(entity.url) 
main()

Для каждого сообщения в истории чата скрипт проверяет наличие «сущностей» (entities), которые могут быть, например, форматированием или ссылками. Если сущности присутствуют, скрипт дополнительно проверяет каждую сущность на наличие URL. Если URL найден, он выводится в консоль.

Запустите код, и ради интереса добавьте любой другой чат, и понаблюдайте за сущностями. Все возможные сущности перечислены выше, под спойлером.

from pyrogram import Client

api_id = 1111
api_hash = ""
app = Client("my_session", api_id=api_id, api_hash=api_hash)

def main():
    with app:
        group_url = "test"
        messages = app.get_chat_history(group_url,limit=100)  # Получаем историю чата для указанной группы
        for message in messages:
            if message.entities:
                for entity in message.entities:
                    entity_type = entity.type
                    print(f"Найдена сущность: {entity_type}\n")  # Отладочное сообщение
                    print('==>',message.text)
                    print('------------------------------\n')
main()

Получение истории чата:

С помощью метода get_chat_history извлекается история чата для группы с идентификатором group_url. Лимит установлен на 100 сообщений.

messages = app.get_chat_history(group_url,limit=100)

​​​​​​​​​​​​​Обработка каждого сообщения:

Цикл перебирает все полученные сообщения.

for message in messages:

Проверка наличия сущностей в сообщении:

Если в сообщении есть сущности (например, ссылки, хэштеги, упоминания и т.д.), код переходит к их обработке.

if message.entities:

Перебор всех сущностей в сообщении:

Цикл перебирает все сущности в каждом сообщении.

for entity in message.entities:

Вывод типа сущности и текста сообщения:

Для каждой сущности выводится её тип и текст сообщения, в котором она содержится. После каждого сообщения выводится разделительная линия для удобства чтения.

entity_type = entity.type
print(f"Найдена сущность: {entity_type}\n")  # Отладочное сообщение
print('==>',message.text)
print('------------------------------\n')

Пример извлечения информации из сущности определенного типа (MessageEntityType.URL)

from pyrogram import Client
from pyrogram.enums import MessageEntityType

api_id = 1111
api_hash = ""
app = Client("my_session", api_id=api_id, api_hash=api_hash)
def main():
    with app:
        group_url = "test"
        # Получаем историю чата для указанной группы
        messages = app.get_chat_history(group_url,limit=100) 
        for message in messages:
            # Проверка сообщения на наличие entities
            if message.entities:
                for entity in message.entities:
                    # Извлечение url из сущностей типа MessageEntityType.URL
                    if entity.type == MessageEntityType.URL:
                        # обратите внимание на структуру entity MessageEntityType.URL
                        print(f'{entity.type}:\n {entity}')
                        # текст url извлекается исходя из позиций начала и конца текста
                        url = message.text[entity.offset: entity.offset + entity.length]
                        print(f'{url = }\n')
main()

Вывод:

MessageEntityType.URL:
 {
    "_": "MessageEntity",
    "type": "MessageEntityType.URL",
    "offset": 0,
    "length": 33
}
url = 'https://peps.python.org/pep-0570/'
...
...
MessageEntityType.URL:
 {
    "_": "MessageEntity",
    "type": "MessageEntityType.URL",
    "offset": 0,
    "length": 33
}
url = 'https://peps.python.org/pep-0563/'

При работе с entity обращайте внимание на их структуру, она может отличаться у разных типов.

Попробуйте самостоятельно распечатать print(entity) для типа MessageEntityType.TEXT_LINK и понять, каким образом из него можно получить url.



Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: