JavaRush /Курсы /Модуль 4: FastAPI /Асинхронное чтение и отправка сообщений

Асинхронное чтение и отправка сообщений

Модуль 4: FastAPI
19 уровень , 4 лекция
Открыта

Телеграм работает в режиме реального времени. Люди отправляют сообщения, каналы публикуют обновления, боты реагируют на команды. Асинхронный подход идеален для этой задачи, поскольку позволяет:

  • Обрабатывать несколько входящих и исходящих сообщений одновременно.
  • Быстро реагировать на события в реальном времени (например, новые сообщения в чате).
  • Поддерживать высокую производительность, т.к. процесс не блокируется долгими задачами.

Если вы будете использовать синхронный подход, то каждая операция (отправка или получение сообщения) будет "замораживать" выполнение программы, пока она не завершится. Асинхронность – ваш билет в мир более быстрых и эффективных приложений.


Асинхронное чтение сообщений

  1. Работа с асинхронными задачами

    В библиотеке Telethon все взаимодействие с Telegram API построено на асинхронных методах. Наша задача – использовать async def и ключевое слово await, чтобы взаимодействовать с функциями библиотеки.

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

    
    from telethon import TelegramClient
    
    # Конфигурация: замените своими значениями
    api_id = 'YOUR_API_ID'
    api_hash = 'YOUR_API_HASH'
    
    async def read_messages():
        # Создаем клиента
        async with TelegramClient('session_name', api_id, api_hash) as client:
            # Указываем чат или канал: username или ID
            chat = 'some_channel_or_chat'
            
            # Получаем последние 10 сообщений
            async for message in client.iter_messages(chat, limit=10):
                print(f"Сообщение от {message.sender_id}: {message.text}")
    
    # Запуск асинхронной функции
    import asyncio
    asyncio.run(read_messages())
        

    Как это работает?

    1. Мы используем async with TelegramClient, чтобы автоматически подключаться и отключаться от API.
    2. Метод iter_messages возвращает сообщения как асинхронный генератор. Это позволяет получать сообщения по одному, не загружая всё сразу в память.
    3. message.sender_id – идентификатор отправителя сообщения. message.text – это текст сообщения.
  2. Обработка новых сообщений

    Теперь давайте научимся отслеживать новые сообщения в реальном времени. Для этого мы будем использовать событийно-ориентированный API Telethon.

    
    from telethon import TelegramClient, events
    
    # Конфигурация: замените своими значениями
    api_id = 'YOUR_API_ID'
    api_hash = 'YOUR_API_HASH'
    
    async def main():
        async with TelegramClient('session_name', api_id, api_hash) as client:
            @client.on(events.NewMessage(chats='some_channel_or_chat'))
            async def handler(event):
                print(f"Новое сообщение: {event.raw_text}")
    
            print("Ожидаем новые сообщения...")
            await client.run_until_disconnected()
    
    import asyncio
    asyncio.run(main())
        

    Что здесь происходит?

    1. Мы используем @client.on(events.NewMessage) для регистрации обработчика новых сообщений.
    2. Аргумент chats='some_channel_or_chat' указывает, что мы хотим отслеживать сообщения только из конкретного чата/канала. Можно оставить пустым, чтобы отлавливать сообщения из всех чатов.
    3. event.raw_text содержит текст нового сообщения.
    4. Метод run_until_disconnected позволяет нашему клиенту оставаться активным, чтобы он мог получать события.

Асинхронная отправка сообщений

Отправка сообщений Telegram API так же проста, как их чтение. Рассмотрим несколько сценариев.

  1. Отправка простого сообщения
    
    from telethon import TelegramClient
    
    # Конфигурация: замените своими значениями
    api_id = 'YOUR_API_ID'
    api_hash = 'YOUR_API_HASH'
    
    async def send_message():
        async with TelegramClient('session_name', api_id, api_hash) as client:
            chat = 'some_channel_or_chat'
            await client.send_message(chat, 'Привет, это моя первая отправка сообщения через Telethon!')
    
    import asyncio
    asyncio.run(send_message())
        

    Как это работает?

    • Мы используем метод send_message, чтобы отправить текстовое сообщение в чат/канал.
    • Первый аргумент – это указание чата/канала (может быть username, ID или даже объект, полученный ранее).
    • Второй аргумент – текст сообщения.

Отправка мультимедиа

В Telegram можно отправлять не только текст, но и изображения, видео, аудиофайлы и документы. Вот так выглядит отправка изображения:


from telethon import TelegramClient

# Конфигурация: замените своими значениями
api_id = 'YOUR_API_ID'
api_hash = 'YOUR_API_HASH'

async def send_photo():
    async with TelegramClient('session_name', api_id, api_hash) as client:
        chat = 'some_channel_or_chat'
        await client.send_file(chat, 'path/to/your/photo.jpg', caption='Вот моя фотография!')

import asyncio
asyncio.run(send_photo())

Как это работает?

  • Метод send_file отправляет файл в чат/канал.
  • Опциональный аргумент caption добавляет подпись к файлу.

Обработка сообщений: читаем и отправляем одновременно

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


from telethon import TelegramClient, events

# Конфигурация: замените своими значениями
api_id = 'YOUR_API_ID'
api_hash = 'YOUR_API_HASH'

async def main():
    async with TelegramClient('session_name', api_id, api_hash) as client:
        @client.on(events.NewMessage(chats='some_channel_or_chat'))
        async def handler(event):
            incoming_message = event.raw_text
            print(f"Получено сообщение: {incoming_message}")

            # Ответим на сообщение
            await event.reply(f"Вы сказали: {incoming_message}")

        print("Бот запущен, ожидаем сообщения...")
        await client.run_until_disconnected()

import asyncio
asyncio.run(main())

Типичные ошибки и советы

При работе с асинхронным программированием в Telethon вы можете столкнуться с несколькими подводными камнями:

  • Ошибка "Event loop is closed": это связано с тем, как asyncio работает в некоторых средах (например, Windows). Исправление – добавить asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) перед запуском скрипта.
  • Блокировка операций: если вы выполняете тяжелые задачи внутри асинхронной функции, это может заблокировать процесс. Используйте asyncio.to_thread, чтобы выполнять синхронные задачи в отдельном потоке.
  • Ограничения Telegram API: Telegram может ограничить отправку сообщений (спам-фильтр). Убедитесь, что вы соблюдаете их документацию.

Теперь вы можете читать и отправлять сообщения с помощью Telethon как настоящий профессионал! В следующей лекции мы погрузимся в обработку событий в реальном времени, чтобы ещё больше автоматизировать взаимодействие с Telegram. 🚀

1
Задача
Модуль 4: FastAPI, 19 уровень, 4 лекция
Недоступна
Асинхронное чтение сообщений из чата
Асинхронное чтение сообщений из чата
1
Задача
Модуль 4: FastAPI, 19 уровень, 4 лекция
Недоступна
Асинхронная отправка сообщения в чат
Асинхронная отправка сообщения в чат
3
Опрос
Введение в Telethon, 19 уровень, 4 лекция
Недоступен
Введение в Telethon
Введение в Telethon
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ