Files
DBBot-telegram/redme.md
bilal 98b1469488 Improve timeout resilience for Telegram and n8n integrations.
Add configurable Telethon retry/connect settings, enable retry-on-fail for external n8n nodes, and document recovery steps for Telegram and workflow activation timeouts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-24 00:46:26 +03:00

227 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## DBBot: production-схема (отдельные n8n/Qdrant + tg-userbot)
Этот проект рассчитан на ситуацию, когда:
- `n8n` уже запущен и доступен по URL;
- `qdrant` уже запущен отдельно;
- бот в чужую группу добавить нельзя;
- сообщения читаются через `Telethon userbot` из отдельного Docker-контейнера.
## Архитектура
Поток данных:
1. `script.py` (в контейнере) читает историю и новые сообщения из Telegram-группы.
2. Скрипт отправляет события в `n8n` webhook `POST /webhook/tg-inbox`.
3. Единый workflow в `n8n`:
- нормализует метаданные,
- склеивает сообщения в контекстные блоки,
- пишет в `Qdrant`.
4. В этой же схеме работает RAG-ответ через `AI Agent` + `Qdrant Retrieve Tool`.
## Структура проекта
```text
dbbot/
├── redme.md # этот файл
├── script.py # Telethon userbot sender -> n8n webhook
├── requirements.txt # зависимости python
├── Dockerfile # контейнер для script.py
├── .gitignore # исключения (секреты, кеш, сессия)
├── .env.example # пример переменных для контейнера
├── session_data/
│ └── session.session # StringSession (создаешь сам)
└── DBBot Unified n8n Qdrant.json # единый workflow (ingest + rag)
```
## Что подготовить перед первым запуском
### 1) n8n
Импортируй `DBBot Unified n8n Qdrant.json` и привяжи credentials:
- `Qdrant API`
- `Ollama API`
- `Telegram API` (для reply-ветки через Telegram Trigger)
Проверь:
- путь webhook: `tg-inbox`
- workflow переведен в `Active`
### 2) Файл сессии Telethon
Создай файл:
- `session_data/session.session`
Внутри должна быть одна строка `StringSession` без переносов и пробелов по краям.
### 3) Переменные окружения для контейнера
Сделай локальный `.env`:
```bash
cp .env.example .env
```
Заполни значения:
- `TG_API_ID`
- `TG_API_HASH`
- `TG_GROUP_ID` (например `-100...`)
- `SESSION_FILE_PATH=/app/session/session.session`
- `HISTORY_CHECK_FILE=/app/session/history_done.flag`
- `N8N_WEBHOOK_URL=https://<твой-n8n-домен>/webhook/tg-inbox`
- `TG_USE_IPV6=false` (обычно для серверов так стабильнее)
- `TG_CONNECT_TIMEOUT=20`
- `TG_REQUEST_RETRIES=10`
- `TG_CONNECTION_RETRIES=20`
- `TG_RETRY_DELAY=5`
- `TG_RECONNECT_WAIT=15`
Если `n8n` локально, можно `http://localhost:5678/webhook/tg-inbox`.
## Подробный цикл запуска проекта
`docker-compose.yaml` в этом проекте содержит только один сервис: `tg-userbot`.
### Шаг 1. Поднять контейнер tg-userbot
Из корня проекта:
```bash
docker compose up -d --build
```
### Шаг 2. Проверить, что webhook получает данные
1. Открой `Executions` в `n8n`.
2. Убедись, что появились вызовы `Webhook TG Inbox`.
3. Проверь, что далее проходят `Build Context Block` и `Qdrant Insert`.
### Шаг 3. Проверить RAG-ответ
1. Напиши вопрос Telegram-боту, подключенному к `Telegram Trigger` в workflow.
2. Проверь выполнение ветки `AI Agent`.
3. Убедись, что узел `Qdrant Retrieve Tool` вызван и ответ ушел через `Send Telegram Reply`.
## Эксплуатационный цикл (после запуска)
- Скрипт работает в контейнере постоянно:
- при первом запуске делает исторический прогон;
- затем обрабатывает новые сообщения.
- Если нужно повторить историческую загрузку:
1. останови контейнер;
2. удали `session_data/history_done.flag`;
3. запусти контейнер снова.
Команды:
```bash
docker compose stop
rm -f session_data/history_done.flag
docker compose up -d
```
## Управление и диагностика
Логи контейнера:
```bash
docker compose logs -f tg-userbot
```
Проверить, что контейнер жив:
```bash
docker ps --filter name=dbbot-userbot
```
Перезапустить после изменения `.env`:
```bash
docker compose up -d --build --force-recreate
```
Если в логах `Connection to Telegram failed ... TimeoutError`:
1. Проверь доступность Telegram с хоста (фаервол/провайдер/блокировки).
2. Оставь `TG_USE_IPV6=false` в `.env`.
3. Подними таймаут/ретраи, например:
- `TG_CONNECT_TIMEOUT=30`
- `TG_CONNECTION_RETRIES=30`
- `TG_RECONNECT_WAIT=20`
4. Перезапусти контейнер:
```bash
docker compose up -d --build --force-recreate
docker compose logs -f tg-userbot
```
Если в `n8n` при активации workflow ошибка:
`The connection timed out, consider setting the 'Retry on Fail' option`
1. Открой в workflow узлы:
- `Telegram Trigger`
- `Qdrant Insert`
- `Qdrant Retrieve Tool`
- `Embeddings For Insert`
- `Embeddings For Retrieve`
- `Ollama Chat Model`
- `Send Telegram Reply`
2. Для каждого включи `Retry on Fail` и выставь:
- `Max Tries = 5`
- `Wait Between Tries = 5000 ms`
3. Убедись, что из среды `n8n` доступны:
- Telegram API (для `Telegram Trigger`)
- URL Ollama
- URL Qdrant
4. Если снова падает на активации, временно отключи ветку `Telegram Trigger` и активируй ingest-ветку (`Webhook TG Inbox`) отдельно.
## Формат payload, который скрипт шлет в n8n
```json
{
"text": "текст сообщения",
"metadata": {
"date": "2026-06-23T00:00:00Z",
"message_id": 123,
"chat_id": "-100...",
"sender_id": "456",
"sender_name": "@username",
"author_label": "@username",
"author": {
"id": "456",
"username": "username",
"display_name": "Ivan Ivanov",
"label": "@username"
},
"reply_to_message_id": 122,
"replied_to_author_label": "@other_user",
"replied_to_author": {
"id": "777",
"username": "other_user",
"display_name": "Petr Petrov",
"label": "@other_user"
},
"thread_id": "122",
"edit_date": "",
"entities": [
{ "type": "MessageEntityUrl", "offset": 10, "length": 20 }
],
"attachment": {
"has_media": false
},
"group_id": "-100...",
"source": "telegram_group"
}
}
```
## Параметры склейки сообщений в n8n
В узле `Build Context Block`:
- `WINDOW_MS = 20 минут`
- `MAX_MESSAGES = 12`
- `MIN_MESSAGES_TO_FLUSH = 3`
Рекомендации:
- меньше блоки: `MAX_MESSAGES = 8-10`;
- шире контекст: `WINDOW_MS = 30-40 минут`.