diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index e5b9ee6..55f9400 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -227,10 +227,37 @@ jobs: TELEGRAM_BOT_TOKEN: ${{ steps.telegram-token.outputs.token }} run: bun run ops:telegram:commands set + - name: Load webhook secret + id: webhook-secret + run: | + set +e + secret_name="telegram-webhook-secret" + if [[ "${SERVICE_SUFFIX}" == "dev" ]]; then + secret_name="telegram-webhook-secret-test" + fi + secret="$(gcloud secrets versions access latest \ + --secret "${secret_name}" \ + --project "${{ vars.GCP_PROJECT_ID }}" 2>/dev/null)" + status=$? + set -e + + if [[ $status -eq 0 && -n "$secret" ]]; then + echo "::add-mask::$secret" + { + echo "available=true" + echo "secret<> "$GITHUB_OUTPUT" + else + echo "available=false" >> "$GITHUB_OUTPUT" + fi + - name: Set Telegram Webhook - if: ${{ steps.telegram-token.outputs.available == 'true' }} + if: ${{ steps.telegram-token.outputs.available == 'true' && steps.webhook-secret.outputs.available == 'true' }} env: TELEGRAM_BOT_TOKEN: ${{ steps.telegram-token.outputs.token }} + TELEGRAM_WEBHOOK_SECRET: ${{ steps.webhook-secret.outputs.secret }} run: | SERVICE_URL=$(gcloud run services describe "household-${SERVICE_SUFFIX}-bot-api" \ --region "${GCP_REGION}" \ @@ -238,4 +265,13 @@ jobs: --format 'value(status.url)') export TELEGRAM_WEBHOOK_URL="$SERVICE_URL/webhook/telegram" + echo "Setting webhook to: $TELEGRAM_WEBHOOK_URL" bun run ops:telegram:webhook set + + - name: Verify Telegram Webhook + if: ${{ steps.telegram-token.outputs.available == 'true' }} + env: + TELEGRAM_BOT_TOKEN: ${{ steps.telegram-token.outputs.token }} + run: | + echo "Checking webhook status..." + bun run ops:telegram:webhook info | jq -r '.url, .last_error_message' || true diff --git a/scripts/ops/telegram-webhook.ts b/scripts/ops/telegram-webhook.ts index 09015f8..18c61e3 100644 --- a/scripts/ops/telegram-webhook.ts +++ b/scripts/ops/telegram-webhook.ts @@ -51,15 +51,21 @@ async function run(): Promise { return } case 'set': { - const params = new URLSearchParams({ - url: requireEnv('TELEGRAM_WEBHOOK_URL') - }) - + const webhookUrl = requireEnv('TELEGRAM_WEBHOOK_URL') const secretToken = process.env.TELEGRAM_WEBHOOK_SECRET?.trim() - if (secretToken) { - params.set('secret_token', secretToken) + + if (!secretToken) { + console.error( + 'WARNING: TELEGRAM_WEBHOOK_SECRET not set - webhook will be set without secret token' + ) + throw new Error('TELEGRAM_WEBHOOK_SECRET is required for secure webhook setup') } + const params = new URLSearchParams({ + url: webhookUrl, + secret_token: secretToken + }) + const maxConnections = process.env.TELEGRAM_MAX_CONNECTIONS?.trim() if (maxConnections) { params.set('max_connections', maxConnections) @@ -70,6 +76,7 @@ async function run(): Promise { params.set('drop_pending_updates', dropPendingUpdates) } + console.log(`Setting webhook to: ${webhookUrl}`) const result = await telegramRequest(botToken, 'setWebhook', params) console.log(JSON.stringify({ ok: true, result }, null, 2)) return