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>
227 lines
7.6 KiB
Markdown
227 lines
7.6 KiB
Markdown
## 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 минут`.
|
||
|