From 6703e734bfb11e471b2fa8be5eb3023266cb8e39 Mon Sep 17 00:00:00 2001 From: DanliaQwerty20 Date: Sun, 4 Oct 2026 13:41:28 +0300 Subject: [PATCH] fix: retry real Telegram webhook setup --- .env.example | 2 ++ README.md | 3 +++ docs/development.md | 3 +++ scripts/check-compose.ps1 | 13 +++++++++ scripts/start-telegram-real.ps1 | 48 +++++++++++++++++++++++++-------- 5 files changed, 58 insertions(+), 11 deletions(-) diff --git a/.env.example b/.env.example index 9acc3f9..f40f148 100644 --- a/.env.example +++ b/.env.example @@ -39,6 +39,8 @@ TELEGRAM_TOKEN_KEY_BASE64=derive-from-local-webhook-secret # Для ручной проверки настоящего бота раскомментируй и заполни только в локальном .env. # TELEGRAM_REAL_BOT_TOKEN= # TELEGRAM_REAL_WEBHOOK_SECRET= +TELEGRAM_WEBHOOK_SET_ATTEMPTS=12 +TELEGRAM_WEBHOOK_SET_DELAY_SECONDS=10 AGENT_RUNTIME_PORT=18080 # Опциональный профиль task services:model:up. API key для локальной Ollama не нужен. diff --git a/README.md b/README.md index 8ded89a..6198b2e 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,9 @@ task telegram:real:down Quick Tunnel предназначен только для ручной локальной проверки. Команда не печатает bot token и не сохраняет его в Compose-файлах. После живого прогона в тесты переносятся только обезличенные формы Telegram Update и Bot API response. +Если новый адрес ещё не виден DNS-серверам Telegram, команда ограниченно повторяет `setWebhook`. +Число попыток и задержка задаются через `TELEGRAM_WEBHOOK_SET_ATTEMPTS` и +`TELEGRAM_WEBHOOK_SET_DELAY_SECONDS`. `TEST_LAB_PATH` по умолчанию указывает на соседний `../portable-agent-test-lab`; путь можно переопределить в `.env`. Channel Gateway доступен на `http://localhost:18084`, Agent Runtime — на diff --git a/docs/development.md b/docs/development.md index f40a8ec..7873f3f 100644 --- a/docs/development.md +++ b/docs/development.md @@ -53,6 +53,9 @@ bot token для разработки и CI не требуется. Когда нужно проверить настоящий Telegram, добавь `TELEGRAM_REAL_BOT_TOKEN` и `TELEGRAM_REAL_WEBHOOK_SECRET` в игнорируемый `.env`, затем выполни `task telegram:real:up`. Команда поднимет временный HTTPS tunnel, проверит bot token и зарегистрирует защищённый webhook. +Если DNS нового Quick Tunnel распространяется с задержкой, команда ограниченно повторит регистрацию. +Предел и пауза задаются через `TELEGRAM_WEBHOOK_SET_ATTEMPTS` и +`TELEGRAM_WEBHOOK_SET_DELAY_SECONDS`. После ручного сценария выполни `task telegram:real:down`: внешний webhook будет удалён до возврата адаптера к fake API. diff --git a/scripts/check-compose.ps1 b/scripts/check-compose.ps1 index b2a5de8..2af6085 100644 --- a/scripts/check-compose.ps1 +++ b/scripts/check-compose.ps1 @@ -317,11 +317,24 @@ foreach ($required in @("TELEGRAM_REAL_BOT_TOKEN", "TELEGRAM_REAL_WEBHOOK_SECRET } } $realTelegramScript = Get-Content -Raw -LiteralPath "scripts/start-telegram-real.ps1" +$envExample = Get-Content -Raw -LiteralPath ".env.example" foreach ($required in @("getMe", "setWebhook", "getWebhookInfo", "trycloudflare", "allowed_updates", "callback_query")) { if ($realTelegramScript -notmatch [regex]::Escape($required)) { throw "Запуск настоящего Telegram не содержит $required." } } +foreach ($setting in @("TELEGRAM_WEBHOOK_SET_ATTEMPTS", "TELEGRAM_WEBHOOK_SET_DELAY_SECONDS")) { + if ($envExample -notmatch "(?m)^$setting=[1-9][0-9]*\r?$") { + throw "В .env.example нет положительной настройки $setting." + } + if ($realTelegramScript -notmatch [regex]::Escape($setting)) { + throw "Запуск настоящего Telegram не использует $setting." + } +} +if ($realTelegramScript -notmatch 'for \(\$attempt = 1; \$attempt -le \$webhookAttempts' ` + -or $realTelegramScript -notmatch 'Start-Sleep -Seconds \$webhookDelaySeconds') { + throw "Настройка Telegram webhook должна повторяться, пока DNS Quick Tunnel распространяется." +} if ($realTelegramScript -notmatch '\[switch\]\$Model' ` -or $realTelegramScript -notmatch 'compose/model.local.yaml') { throw "Настоящий Telegram должен поддерживать тот же локальный AI-профиль." diff --git a/scripts/start-telegram-real.ps1 b/scripts/start-telegram-real.ps1 index 352ffed..a184840 100644 --- a/scripts/start-telegram-real.ps1 +++ b/scripts/start-telegram-real.ps1 @@ -6,12 +6,22 @@ $ErrorActionPreference = "Stop" $token = Get-LocalSetting "TELEGRAM_REAL_BOT_TOKEN" $webhookSecret = Get-LocalSetting "TELEGRAM_REAL_WEBHOOK_SECRET" +$webhookAttemptsText = Get-LocalSetting "TELEGRAM_WEBHOOK_SET_ATTEMPTS" +$webhookDelayText = Get-LocalSetting "TELEGRAM_WEBHOOK_SET_DELAY_SECONDS" if ($token -notmatch '^\d+:[A-Za-z0-9_-]{20,}$') { throw "Set a valid TELEGRAM_REAL_BOT_TOKEN from BotFather in local .env." } if ($webhookSecret -notmatch '^[A-Za-z0-9_-]{32,256}$') { throw "TELEGRAM_REAL_WEBHOOK_SECRET must contain 32-256 characters: A-Z, a-z, 0-9, _ or -." } +$webhookAttempts = 0 +$webhookDelaySeconds = 0 +if (-not [int]::TryParse($webhookAttemptsText, [ref]$webhookAttempts) -or $webhookAttempts -lt 1) { + throw "TELEGRAM_WEBHOOK_SET_ATTEMPTS must be a positive integer." +} +if (-not [int]::TryParse($webhookDelayText, [ref]$webhookDelaySeconds) -or $webhookDelaySeconds -lt 1) { + throw "TELEGRAM_WEBHOOK_SET_DELAY_SECONDS must be a positive integer." +} $env:TELEGRAM_REAL_BOT_TOKEN = $token $env:TELEGRAM_REAL_WEBHOOK_SECRET = $webhookSecret @@ -56,19 +66,35 @@ $apiUrl = "https://api.telegram.org/bot$token" try { $bot = Invoke-RestMethod -Method Post -Uri "$apiUrl/getMe" if (-not $bot.ok -or -not $bot.result.username) { throw "invalid getMe" } - $hook = Invoke-RestMethod -Method Post -Uri "$apiUrl/setWebhook" -ContentType "application/json" -Body (@{ - url = "$tunnelUrl/webhooks/telegram" - secret_token = $webhookSecret - allowed_updates = @("message", "callback_query") - drop_pending_updates = $false - } | ConvertTo-Json) - if (-not $hook.ok) { throw "invalid setWebhook" } - $info = Invoke-RestMethod -Method Post -Uri "$apiUrl/getWebhookInfo" - if (-not $info.ok -or $info.result.url -ne "$tunnelUrl/webhooks/telegram") { - throw "invalid getWebhookInfo" +} catch { + throw "Telegram Bot API rejected the bot token. Secrets were not printed." +} + +$webhookBody = @{ + url = "$tunnelUrl/webhooks/telegram" + secret_token = $webhookSecret + allowed_updates = @("message", "callback_query") + drop_pending_updates = $false +} | ConvertTo-Json +$hookReady = $false +for ($attempt = 1; $attempt -le $webhookAttempts -and -not $hookReady; $attempt += 1) { + try { + $hook = Invoke-RestMethod -Method Post -Uri "$apiUrl/setWebhook" ` + -ContentType "application/json" -Body $webhookBody + $hookReady = [bool]$hook.ok + } catch { + if ($attempt -eq $webhookAttempts) { break } } + if (-not $hookReady) { Start-Sleep -Seconds $webhookDelaySeconds } +} +if (-not $hookReady) { + throw "Telegram did not accept the temporary webhook after $webhookAttempts attempts. Secrets were not printed." +} +try { + $info = Invoke-RestMethod -Method Post -Uri "$apiUrl/getWebhookInfo" + if (-not $info.ok -or $info.result.url -ne "$tunnelUrl/webhooks/telegram") { throw "invalid webhook" } } catch { - throw "Telegram Bot API rejected the bot token or temporary webhook. Secrets were not printed." + throw "Telegram did not confirm the temporary webhook. Secrets were not printed." } Write-Host "Real Telegram connected: @$($bot.result.username)"