Отправка, получение, редактирование и удаление сообщений. Форматирование текста, ссылки предпросмотра.
Ключевая идея: Сообщения — это основа взаимодействия в Telegram. Telethon предоставляет мощные инструменты для отправки, получения, редактирования и удаления сообщений с поддержкой форматирования, пересылки и ответов.
Метод get_messages() возвращает список сообщений из чата:
# Получаем последние 10 сообщений из чата
messages = await client.get_messages('chat_username', limit=10)
for msg in messages:
print(f'[{msg.date}] {msg.text}')iter_messagesДля большого количества сообщений используйте асинхронный итератор:
# Постраничная загрузка — сообщения подгружаются порциями по 100 штук
async for message in client.iter_messages('chat_username', limit=500):
if message.text and 'важно' in message.text.lower():
print(f'Нашёл важное: {message.text[:50]}')Ключевая идея:
iter_messagesзагружает сообщения порциями (по умолчанию по 100), что экономит память при работе с большими объёмами данных.get_messagesзагружает всё сразу.
# Только сообщения от конкретного пользователя
async for msg in client.iter_messages(chat, from_user='username'):
print(msg.text)
# Только сообщения с определённым текстом (поиск)
async for msg in client.iter_messages(chat, search='ключевое слово'):
print(msg.text)
# Сообщения после определённой даты
async for msg in client.iter_messages(chat, min_id=1000):
print(msg.id, msg.text)Базовая отправка сообщения:
# Отправка в чат по username
await client.send_message('chat_username', 'Привет всем!')
# Отправка по ID чата (полученного ранее)
await client.send_message(chat_id, 'Сообщение по ID')
# Отправка самому себе (Saved Messages)
await client.send_message('me', 'Заметка для себя')Telethon поддерживает Markdown и HTML:
# Markdown-форматирование
await client.send_message(
chat,
'**Жирный текст** и *курсив*',
parse_mode='md'
)
# HTML-форматирование
await client.send_message(
chat,
'<b>Жирный текст</b> и <i>курсив</i>',
parse_mode='html'
)Правило: Telethon также поддерживает entity-объекты для точного контроля форматирования. Это самый надёжный способ, не зависящий от парсера.
from telethon.tl.types import MessageEntityBold, MessageEntityTextUrl
text = 'Жирный текст и ссылка'
entities = [
MessageEntityBold(offset=0, length=12), # «Жирный текст»
MessageEntityTextUrl(offset=17, length=5, url='https://example.com') # «ссылка»
]
await client.send_message(chat, text, formatting_entities=entities)Для ответа на сообщение используйте reply_to:
# Ответ на конкретное сообщение по ID
await client.send_message(
chat,
'Это ответ на твоё сообщение',
reply_to=12345 # ID сообщения
)
# Ответ на объект сообщения
original_msg = await client.get_messages(chat, ids=12345)
await client.send_message(
chat,
'Ответ с цитированием',
reply_to=original_msg
)await client.send_message(
chat,
'Согласен с этим',
reply_to=12345,
# Telegram автоматически процитирует первые строки оригинала
)Метод forward_messages() пересылает сообщения:
# Пересылка одного сообщения
await client.forward_messages(
'destination_chat',
messages=12345, # ID сообщения
from_peer='source_chat'
)
# Пересылка нескольких сообщений
await client.forward_messages(
'destination_chat',
messages=[12345, 12346, 12347],
from_peer='source_chat'
)Начиная с определённых версий Telegram, можно пересылать без метаданных автора:
from telethon.tl.functions.channels import GetMessagesRequest
# Пересылка с скрытием автора (drop_author)
await client.forward_messages(
'destination_chat',
messages=msg_ids,
from_peer='source_chat',
drop_author=True # Скрывает оригинального автора
)Метод edit_message() изменяет текст существующего сообщения:
# Редактирование по ID
await client.edit_message(
chat,
message=12345,
text='Новый текст сообщения'
)
# Редактирование с форматированием
await client.edit_message(
chat,
message=12345,
text='**Обновлённый** текст',
parse_mode='md'
)Важно: редактировать можно только свои сообщения. При попытке редактировать чужое возникнет ошибка. Боты могут редактировать сообщения только в чатах, где они имеют соответствующие права.
await client.edit_message(
chat,
message=12345,
text='Исправленный текст без уведомления',
no_webpage=True # Не генерировать предпросмотр ссылки
)Метод delete_messages() удаляет сообщения:
# Удаление одного сообщения
await client.delete_messages(chat, messages=[12345])
# Удаление нескольких сообщений
await client.delete_messages(chat, messages=[12345, 12346, 12347])В группах и каналах можно удалить сообщение у всех:
from telethon.tl.functions.messages import DeleteMessagesRequest
# revoke=True удаляет у всех (только для своих сообщений)
await client.delete_messages(chat, messages=[12345], revoke=True)Правило:
revoke=Trueработает только для ваших собственных сообщений. Чужие сообщения можно удалить только для себя.
Закреплённое сообщение отображается вверху чата:
# Закрепление сообщения
await client.pin_message(chat, message=12345)
# Закрепление без уведомления
await client.pin_message(chat, message=12345, notify=False)
# Открепление
await client.unpin_message(chat, message=12345)# Одно сообщение по ID
msg = await client.get_messages(chat, ids=12345)
print(msg.text)
# Несколько сообщений по списку ID
messages = await client.get_messages(chat, ids=[12345, 12346, 12347])
for msg in messages:
print(msg.text)Важно: если сообщение не найдено (удалено или неверный ID), метод вернёт
None. Всегда проверяйте результат.
Объект Message содержит множество атрибутов:
msg = await client.get_messages(chat, ids=12345)
# Основные свойства
print(msg.id) # Уникальный ID сообщения
print(msg.text) # Текст сообщения
print(msg.raw_text) # Сырой текст без форматирования
print(msg.date) # Дата отправки (datetime)
print(msg.edit_date) # Дата редактирования (None если не редактировалось)
print(msg.out) # True если это ваше сообщение
print(msg.mentioned) # True если вас упомянули
print(msg.media) # Медиаобъект (фото, видео, документ)
print(msg.reply_to) # Информация об ответе
print(msg.views) # Количество просмотров (каналы)
print(msg.forwards) # Количество пересылокif msg.media:
print('Сообщение содержит медиа')
if msg.reply_to:
print(f'Это ответ на сообщение {msg.reply_to.reply_to_msg_id}')
if msg.out:
print('Это моё сообщение')| Ошибка | Причина | Решение |
|---|---|---|
ChatWriteForbiddenError | Нет прав на отправку в чате | Проверьте права, используйте бота |
MessageIdInvalidError | Неверный ID сообщения | Проверьте ID, убедитесь что сообщение существует |
MessageNotModifiedError | Текст не изменился | Проверьте, отличается ли новый текст |
MessageDeleteForbiddenError | Нет прав на удаление | Проверьте права администратора |
MessageEmptyError | Пустое сообщение | Пропустите такие сообщения |
from telethon.errors import (
ChatWriteForbiddenError,
MessageIdInvalidError,
MessageNotModifiedError
)
async def safe_send(chat, text):
try:
await client.send_message(chat, text)
except ChatWriteForbiddenError:
print('Нет прав на отправку в этом чате')
except FloodWaitError as e:
print(f'FloodWait: ждём {e.seconds} сек')Для отправки нескольких сообщений используйте asyncio.gather():
# Параллельная отправка (быстрее, но рискованнее для FloodWait)
tasks = [
client.send_message(chat, f'Сообщение {i}')
for i in range(5)
]
await asyncio.gather(*tasks)Правило: при пакетной отправке внимательно следите за лимитами. Telegram может вернуть
FloodWaitErrorпри слишком частых запросах.
Сообщения — это только начало. Следующая тема — работа с чатами и каналами — научит вас управлять подписками, получать участников и анализировать активность.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.