Whisper Bot: голосовые сообщения в текст прямо в Telegram
Голосовые сообщения в Telegram — удобно отправлять, неудобно получать. Особенно если это длинное сообщение в шумном месте, или ты хочешь быстро найти в нём конкретное слово, или просто не хочешь слушать.
Я написал Whisper Bot — бот, которому пересылаешь голосовое или видеосообщение, и он возвращает текст.
Модель работает локально — faster-whisper на CPU, без облаков. Поддерживает русский и английский, язык выбирается прямо в чате кнопкой. Бот закрытый: работает только для пользователей из белого списка, которым ты выдал доступ.
Самое интересное здесь — не сама транскрипция, а архитектура. Whisper на CPU работает не мгновенно: секунд тридцать, иногда больше, в зависимости от длины записи. Если запускать это прямо в обработчике сообщений, бот будет просто висеть всё это время. Поэтому транскрипция вынесена в отдельный воркер через Huey и Redis: бот принимает задачу, кладёт в очередь, воркер берёт и обрабатывает, бот забирает результат и отвечает.
bot.py ──▶ Redis ──▶ huey-worker ──▶ faster-whisper
└──────────────────────────────────────────▶ ответ пользователю
Три контейнера: сам бот, Redis, воркер — один docker compose up и всё запущено.
Есть ещё один слой, который делает результат лучше. Сырая транскрипция часто содержит ошибки — Whisper мог расслышать не то слово. Поверх транскрипции можно подключить языковую модель через OpenRouter: она получает текст с пометкой, что это STT-результат, и исправляет только явные ошибки распознавания — без перефразирования, без изменения смысла. Если ключа нет — этот шаг просто пропускается, бот работает и без него.
OPENROUTER_API_KEY=***
OPENROUTER_MODEL_NAME=openai/gpt-oss-20b:free
Модель, языки, размер beam-а — всё через .env. Модели Whisper скачиваются один раз и хранятся в примонтированной папке, при перезапуске контейнера перекачки нет.
Администратор управляет списком пользователей через команды: добавить, удалить, посмотреть статистику. Статистика показывает сколько пользователей активны сегодня и за неделю, сколько запросов обработано. Удобно понимать, что бот вообще используется.
Для личного использования или небольшой команды — закрывает задачу полностью.