From 98b1469488b3a6a6eeaa6a08c4b20271c18a5137 Mon Sep 17 00:00:00 2001 From: bilal Date: Wed, 24 Jun 2026 00:46:26 +0300 Subject: [PATCH] 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 --- .env.example | 8 ++++++- DBBot Unified n8n Qdrant.json | 35 ++++++++++++++++++++++++------ redme.md | 41 +++++++++++++++++++++++++++++++++++ script.py | 38 ++++++++++++++++++++++++++++++-- 4 files changed, 112 insertions(+), 10 deletions(-) diff --git a/.env.example b/.env.example index 358b546..3a38881 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,12 @@ TG_API_ID=12345678 TG_API_HASH=your_telegram_api_hash TG_GROUP_ID=-1001234567890 -N8N_WEBHOOK_URL=http://n8n:5678/webhook/tg-inbox +N8N_WEBHOOK_URL=http://your-n8n-host:5678/webhook/tg-inbox SESSION_FILE_PATH=/app/session/session.session HISTORY_CHECK_FILE=/app/session/history_done.flag +TG_USE_IPV6=false +TG_CONNECT_TIMEOUT=20 +TG_REQUEST_RETRIES=10 +TG_CONNECTION_RETRIES=20 +TG_RETRY_DELAY=5 +TG_RECONNECT_WAIT=15 diff --git a/DBBot Unified n8n Qdrant.json b/DBBot Unified n8n Qdrant.json index 61cfb4d..11d006c 100644 --- a/DBBot Unified n8n Qdrant.json +++ b/DBBot Unified n8n Qdrant.json @@ -69,7 +69,10 @@ -120 ], "id": "2444f3f3-d57d-45fa-b80e-e40f73f0c70f", - "name": "Qdrant Insert" + "name": "Qdrant Insert", + "retryOnFail": true, + "maxTries": 5, + "waitBetweenTries": 5000 }, { "parameters": { @@ -131,7 +134,10 @@ 56 ], "id": "5f48d9eb-ec81-4a00-b2fa-ec6a1fc2f009", - "name": "Embeddings For Insert" + "name": "Embeddings For Insert", + "retryOnFail": true, + "maxTries": 5, + "waitBetweenTries": 5000 }, { "parameters": { @@ -147,7 +153,10 @@ 288 ], "id": "163fbd89-644c-4858-a2ce-8c572a2d3593", - "name": "Telegram Trigger" + "name": "Telegram Trigger", + "retryOnFail": true, + "maxTries": 5, + "waitBetweenTries": 5000 }, { "parameters": { @@ -178,7 +187,10 @@ 496 ], "id": "3c7db13e-1be9-4f2f-ab26-a613db89ea71", - "name": "Ollama Chat Model" + "name": "Ollama Chat Model", + "retryOnFail": true, + "maxTries": 5, + "waitBetweenTries": 5000 }, { "parameters": { @@ -200,7 +212,10 @@ 528 ], "id": "2f204e2e-58e7-4514-9f3c-3e23949f8520", - "name": "Qdrant Retrieve Tool" + "name": "Qdrant Retrieve Tool", + "retryOnFail": true, + "maxTries": 5, + "waitBetweenTries": 5000 }, { "parameters": { @@ -213,7 +228,10 @@ 704 ], "id": "e5d5f376-bb95-4a16-ab11-e5e3e7d74524", - "name": "Embeddings For Retrieve" + "name": "Embeddings For Retrieve", + "retryOnFail": true, + "maxTries": 5, + "waitBetweenTries": 5000 }, { "parameters": { @@ -243,7 +261,10 @@ 288 ], "id": "e8476b38-8344-4aaf-828e-5da8344b79d2", - "name": "Send Telegram Reply" + "name": "Send Telegram Reply", + "retryOnFail": true, + "maxTries": 5, + "waitBetweenTries": 5000 } ], "pinData": {}, diff --git a/redme.md b/redme.md index 2d4f48e..c55f4e8 100644 --- a/redme.md +++ b/redme.md @@ -67,6 +67,12 @@ cp .env.example .env - `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`. @@ -132,6 +138,41 @@ docker ps --filter name=dbbot-userbot 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 diff --git a/script.py b/script.py index aed1cab..bb82dc5 100644 --- a/script.py +++ b/script.py @@ -13,6 +13,12 @@ N8N_WEBHOOK_URL = os.getenv("N8N_WEBHOOK_URL", "http://n8n:5678/webhook/tg-inbox HISTORY_CHECK_FILE = os.getenv("HISTORY_CHECK_FILE", "/app/session/history_done.flag") SESSION_FILE_PATH = os.getenv("SESSION_FILE_PATH", "/app/session/session.session") SESSION_STRING = os.getenv("TG_SESSION_STRING", "") +TG_USE_IPV6 = os.getenv("TG_USE_IPV6", "false").lower() in {"1", "true", "yes"} +TG_CONNECT_TIMEOUT = int(os.getenv("TG_CONNECT_TIMEOUT", "20")) +TG_REQUEST_RETRIES = int(os.getenv("TG_REQUEST_RETRIES", "10")) +TG_CONNECTION_RETRIES = int(os.getenv("TG_CONNECTION_RETRIES", "20")) +TG_RETRY_DELAY = int(os.getenv("TG_RETRY_DELAY", "5")) +TG_RECONNECT_WAIT = int(os.getenv("TG_RECONNECT_WAIT", "15")) def load_session_string() -> str: @@ -39,7 +45,17 @@ def validate_config() -> None: validate_config() -client = TelegramClient(StringSession(load_session_string()), API_ID, API_HASH) +client = TelegramClient( + StringSession(load_session_string()), + API_ID, + API_HASH, + use_ipv6=TG_USE_IPV6, + timeout=TG_CONNECT_TIMEOUT, + request_retries=TG_REQUEST_RETRIES, + connection_retries=TG_CONNECTION_RETRIES, + retry_delay=TG_RETRY_DELAY, + auto_reconnect=True, +) def build_author(sender) -> dict: if not sender: @@ -130,7 +146,25 @@ async def handler(event): await send_to_n8n(event.message) async def main(): - await client.start() + print( + "Connecting to Telegram with settings:", + { + "use_ipv6": TG_USE_IPV6, + "connect_timeout": TG_CONNECT_TIMEOUT, + "request_retries": TG_REQUEST_RETRIES, + "connection_retries": TG_CONNECTION_RETRIES, + "retry_delay": TG_RETRY_DELAY, + }, + ) + + while True: + try: + await client.start() + break + except Exception as e: + print(f"Telegram connect failed: {e}. Retrying in {TG_RECONNECT_WAIT}s...") + await asyncio.sleep(TG_RECONNECT_WAIT) + print("UserBot started...") if not os.path.exists(HISTORY_CHECK_FILE):