7.5 KiB
Архитектура сервиса T2S Telegram Bot
Описание
Сервис реализует двухбота — один для пользователей (озвучка текста в голос), второй для администратора (логи и копии озвучек). Оба бота запускаются в одном Docker-контейнере в рамках одного asyncio-процесса.
Компоненты
┌─────────────────────────────────────────────────────┐
│ Docker Container │
│ ┌──────────────────────────────────────────────┐ │
│ │ Python 3.12 процесс │ │
│ │ │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ User Bot App │ │ Admin Bot App │ │ │
│ │ │ (Application) │ │ (Application) │ │ │
│ │ │ │ │ │ │ │
│ │ │ Token: │ │ Token: │ │ │
│ │ │ USER_BOT_TOKEN │ │ ADMIN_BOT_TOKEN│ │ │
│ │ └───────┬─────────┘ └────────┬────────┘ │ │
│ │ │ │ │ │
│ │ │ Admin Bot │ │ │
│ │ │ Instance │ │ │
│ │ └──────┬───────────────┘ │ │
│ │ │ (Bot token=ADMIN_BOT_TOKEN) │ │
│ │ ▼ │ │
│ │ ┌────────────────────────────┐ │ │
│ │ │ edge-tts (TTS) │ │ │
│ │ │ Microsoft TTS Service │ │ │
│ │ │ via websocket/HTTP │ │ │
│ │ │ Voice: ru-RU-DmitryNeural │ │ │
│ │ └────────────────────────────┘ │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
Потоки данных
Пользовательский поток
Пользователь ──текст──▶ User Bot App ──TTS──▶ edge-tts
│
User Bot App ◀──audio.ogg────────────┘
│
голосовое сообщение
│
▼
Пользователь
Администраторский поток
User Bot App ──текст + user info──▶ Admin Bot (прямой Bot-клиент)
│
голосовое + подпись
│
▼
Администратор
Детали реализации
bot.py — точка входа
async def main():
admin_app = Application.builder().token(ADMIN_TOKEN).build()
user_app = Application.builder().token(USER_TOKEN).build()
# Оба запускаются внутри вложенных async with
Ключевые решения:
-
Один процесс — два
Applicationвнутри вложенныхasync with. Это позволяет разделять память (переменнаяadmin_chat_id) и не усложнять инфраструктуру. -
Отдельный Bot-клиент для админа —
admin_bot = Bot(token=ADMIN_TOKEN)создаётся как экземплярtelegram.Bot, а неApplication. Это лёгкий HTTP-клиент для отправки сообщений без полного цикла поллинга. -
Временные файлы — TTS генерируется в
NamedTemporaryFile(suffix='.ogg'), файл открывается для чтения, отправляется, затем удаляется вfinally. Никакого накопления мусора.
Озвучка (edge-tts)
- Библиотека
edge-ttsэмулирует запрос к Microsoft Edge TTS API - Не требует API-ключа, бесплатно
- Голос кешируется при первом вызове (скачивается в
~/.cache/edge-tts/) - Формат вывода — Ogg Opus (нативно поддерживается Telegram как голосовое сообщение)
- Асинхронный вызов:
await edge_tts.Communicate(text, voice).save(path)
Telegram Bot API
- Используется
python-telegram-botv21+ (синтаксисApplication,async with) - Long-polling (без webhook — не требует публичного HTTPS-адреса)
send_action(action='record_voice')показывает индикатор "запись голоса"
Обработка ошибок
| Сценарий | Реакция |
|---|---|
| edge-tts недоступен | Исключение в communicate.save() → ошибка в лог |
Админ не запустил /start |
admin_chat_id is None → лог warning + без уведомления |
| Ошибка отправки админу | try/except → лог error, пользователь всё равно получает ответ |
| Временный файл не удалился | try/unlink в finally — silent ignore |
Сетевая модель
Container ──443/tcp──▶ api.telegram.org (боты)
Container ──443/tcp──▶ speech.microsoft.com (edge-tts)
Исходящие HTTPS-соединения. Входящих нет — только long-polling к Telegram API.
Зависимости
python:3.12-slim— base image (~130 MB)python-telegram-bot >=21, <22— Telegram APIedge-tts >=6, <7— Microsoft TTShttpx— HTTP-клиент PTBaiohttp— HTTP-клиент edge-tts
Конфигурация
Вся конфигурация через переменные окружения (файл .env):
USER_BOT_TOKEN=*** # Токен пользовательского бота (Telegram BotFather)
ADMIN_BOT_TOKEN=*** # Токен админского бота
TTS_VOICE=ru-RU-DmitryNeural # Голос edge-tts (опционально)
Docker
# docker-compose.yml
services:
t2s:
build: ./app
container_name: t2s-telegram-bot
restart: always
env_file: .env
Сборка при заблокированном Docker Hub:
DOCKER_BUILDKIT=0 docker build --network=host -t t2s-telegram-bot ./app