RU EN HE
Обо мне Проекты Блог
← Назад к блогу
Автоматизация на Python

Интеграция Telegram-ботов с очередями задач: aiogram + RQ + Valkey

Введение

Telegram-боты — мощный инструмент для автоматизации рабочих процессов. Однако обработка тяжёлых задач непосредственно в обработчиках бота блокирует event loop и приводит к задержкам в ответах. Решение — разделение на асинхронный бот (aiogram) и фоновые воркеры (RQ + Valkey).

Архитектура системы

Полный цикл обработки запроса выглядит так: пользователь отправляет сообщение → бот получает его через aiogram → бот ставит задачу в очередь RQ через Valkey → RQ-воркер обрабатывает задачу → воркер отправляет результат обратно через Telegram API с привязкой к исходному сообщению.

Бот: приём и постановка в очередь

from aiogram import Bot, Dispatcher, types
from redis import Redis
from rq import Queue

bot = Bot(token=BOT_TOKEN) dp = Dispatcher() redis_conn = Redis(host=‘localhost’, port=6379) task_queue = Queue(‘telegram’, connection=redis_conn)

@dp.message() async def handle_message(message: types.Message): # Ставим задачу в очередь, не блокируя бот task_queue.enqueue( ‘workers.send_text_task’, chat_id=message.chat.id, text=message.text, reply_to=message.message_id ) await message.reply(“⏳ Обрабатываю запрос…”)

Воркер: обработка и ответ

# workers.py
import asyncio
from aiogram import Bot

def send_text_task(chat_id, text, reply_to): # Обрабатываем задачу (может быть долгой операцией) result = process_heavy_task(text)

# Отправляем результат через бот _run_async_task( _reply_message(chat_id, result, reply_to) )

async def _reply_message(chat_id, text, reply_to): bot = Bot(token=BOT_TOKEN) await bot.send_message( chat_id=chat_id, text=text, reply_to_message_id=reply_to ) await bot.session.close()

def _run_async_task(coro): loop = asyncio.new_event_loop() try: loop.run_until_complete(coro) finally: loop.close()

ValkeyPersistence для хранения состояния

Для отслеживания статуса задач мы используем Valkey (совместимый с Redis). FinishedJobRegistry позволяет боту периодически проверять завершённые задачи и уведомлять пользователей о результатах.

reply_to_message_id для тредов

Важная деталь — сохранение message_id исходного сообщения и передача его в reply_to_message_id при ответе. Это создаёт естественный тред в чате и помогает пользователю связать ответ с запросом, особенно когда несколько запросов обрабатываются параллельно.

Контейнеризация

Бот и воркеры работают в отдельных контейнерах внутри одного Podman-пода. Valkey также запущен в поде, обеспечивая коммуникацию через localhost.

Заключение

Разделение Telegram-бота на фронтенд (aiogram) и бэкенд (RQ-воркеры) обеспечивает отзывчивость бота и масштабируемость обработки. Valkey служит как брокером сообщений, так и хранилищем состояния.