Files
claude-status-webhook/CLAUDE.md
tiennm99 62bf203c22 feat: notify admin via Telegram on webhook errors
Send error details to ADMIN_CHAT_ID (optional secret) whenever the
statuspage webhook handler hits an error path. Uses waitUntil() so
the notification never blocks the 200 response.
2026-04-13 22:50:27 +07:00

4.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project

Telegram bot that forwards status.claude.com (Atlassian Statuspage) webhook notifications to subscribed users. Hosted on Cloudflare Workers.

Commands

  • npm run dev — Start local dev server (wrangler dev, emulates KV + Queues locally)

  • npm run deploy — Deploy to Cloudflare Workers

  • npx wrangler deploy --dry-run — Verify build without deploying

  • node scripts/setup-bot.js — One-time: register bot commands + set Telegram webhook (interactive prompts)

  • npm test — Run tests (vitest + @cloudflare/vitest-pool-workers, runs in Workers runtime)

  • npm run test:watch — Run tests in watch mode

No linter configured.

Secrets (set via wrangler secret put)

  • BOT_TOKEN — Telegram bot token
  • WEBHOOK_SECRET — Secret token in Statuspage webhook URL path
  • ADMIN_CHAT_ID — Telegram chat ID to receive webhook error notifications (optional)

Architecture

Cloudflare Workers with two entry points exported from src/index.js:

  • fetch — Hono.js HTTP handler (routes below)
  • queue — CF Queues consumer for fan-out message delivery

Routes

Method Path Handler Purpose
GET / inline Health check
POST /webhook/telegram bot-commands.js grammY webhookCallback("cloudflare-mod")
POST /webhook/status/:secret statuspage-webhook.js Receives Statuspage webhooks (URL secret)

Data Flow

  1. Statuspage → Worker: Webhook POST → verify URL secret (timing-safe via crypto-utils.js) → parse incident/component event → filter subscribers by type + component → sendBatch to CF Queue. On any error, admin is notified via Telegram (admin-notifier.js, non-blocking via waitUntil)
  2. Queue → Telegram: Consumer processes batches of 30 → sendMessage via telegram-api.js helper → auto-removes blocked subscribers (403/400), retries on 429
  3. User → Bot: Telegram webhook → grammY handles /help, /start, /stop, /status, /subscribe, /history, /uptime commands → reads/writes KV

KV Storage

Per-subscriber keys (no read-modify-write races):

  • sub:{chatId}{ types: ["incident", "component"], components: [] }
  • sub:{chatId}:{threadId}{ types: ["incident"], components: ["API"] }

kv-store.js handles key building/parsing with kv.list({ prefix: "sub:" }) pagination. Subscriber type/component data is stored as KV metadata so getSubscribersByType() uses only list() (O(1)) instead of individual get() calls. threadId can be 0 (General topic), so null checks use != null.

Component-Specific Subscriptions

Subscribers can filter to specific components via /subscribe component <name>. Empty components array = all components (default). Filtering applies to webhook notifications.

Supergroup Topic Support

Bot stores message_thread_id from the topic where /start was sent. Notifications and queue consumer include message_thread_id in sendMessage payload to target the correct topic.

Key Dependencies

  • hono — HTTP routing framework
  • grammy — Telegram Bot API framework (webhook mode for CF Workers)
  • wrangler — CF Workers CLI (dev/deploy)

CF Bindings (wrangler.jsonc)

  • claude_status — KV namespace
  • claude-status — Queue producer/consumer (batch size 30, max retries 3)

Documentation

Detailed docs live in docs/:

  • docs/setup-guide.md — Prerequisites, deployment, local dev
  • docs/system-architecture.md — Entry points, data flow, KV schema, queue, security
  • docs/feature-decisions.md — Evaluated features and rationale for decisions

Code Guidelines

Prefer well-established npm packages over hand-written utilities for common operations (e.g., date formatting, validation, string manipulation). Only write custom utils when the logic is trivial (< 5 lines) or platform-specific (e.g., CF Workers crypto APIs).

README Guidelines

Keep README.md clean and focused: project intro, features, commands, quick start, and links to docs. Move detailed setup, architecture, and decision records to docs/. Do not bloat the README with step-by-step instructions or implementation details.