RU EN HE
About Projects Blog
← Back to blog
Python Automation & Integration

Integrating Telegram Bots with Task Queues: aiogram + RQ + Valkey

Introduction

Telegram bots are a powerful tool for workflow automation. However, processing heavy tasks directly in bot handlers blocks the event loop and leads to response delays. The solution is to separate the async bot (aiogram) from background workers (RQ + Valkey).

System Architecture

The complete request processing cycle works as follows: user sends a message → bot receives it via aiogram → bot enqueues a task in RQ via Valkey → RQ worker processes the task → worker sends the result back via Telegram API, linked to the original message.

Bot: Receiving and Enqueueing

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

bot = Bot(token=BOT_TOKEN) dp = Dispatcher() 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(“⏳ Processing request…”)

Worker: Processing and Responding

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()

ValkeyPersistence for State Storage

To track task statuses, we use Valkey (Redis-compatible). FinishedJobRegistry allows the bot to periodically check completed tasks and notify users of results. The worker stores results with TTL to prevent memory bloat.

reply_to_message_id for Threading

An important detail is preserving the original message_id and passing it to reply_to_message_id when responding. This creates a natural thread in the chat and helps the user link the response to their request, especially when multiple requests are being processed in parallel.

Containerization

The bot and workers run in separate containers within a single Podman pod. Valkey also runs in the pod, providing communication via localhost. This simplifies deployment and ensures all components share the same network.

Conclusion

Separating a Telegram bot into a frontend (aiogram) and backend (RQ workers) ensures bot responsiveness and processing scalability. Valkey serves as both message broker and state store.