Files
claude-status-webhook/CLAUDE.md
tiennm99 d78e761731 feat: add metrics tracking and remove unsupported HMAC verification
- Add metrics.js tracking webhooks, messages, cron, commands
- Add GET /metrics/:secret endpoint (text + JSON format)
- Remove HMAC verification (Statuspage doesn't support it)
- Extract validateSecret helper in index.js
- Integrate trackMetrics across webhook, queue, cron, bot handlers
2026-04-09 00:48:42 +07:00

3.6 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 (requires BOT_TOKEN and WORKER_URL env vars)

No test framework configured yet. No linter configured.

Secrets (set via wrangler secret put)

  • BOT_TOKEN — Telegram bot token
  • WEBHOOK_SECRET — Secret token in Statuspage webhook URL path

Architecture

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

  • fetch — Hono.js HTTP handler (routes below)
  • queue — CF Queues consumer for fan-out message delivery
  • scheduled — CF Cron Trigger (every 5 min) for status polling safety net

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)
GET /metrics/:secret inline Bot statistics (text or ?format=json)
GET /migrate/:secret inline One-time KV migration (remove after use)

Data Flow

  1. Statuspage → Worker: Webhook POST → verify URL secret (timing-safe) → parse incident/component event → filter subscribers by type + component → sendBatch to CF Queue
  2. Cron → Worker: Every 5 min → fetch summary → compare with last-status KV → notify on changes → update stored state
  3. Queue → Telegram: Consumer processes batches of 30 → sendMessage via telegram-api.js helper → auto-removes blocked subscribers (403/400), retries on 429
  4. 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"] }

Special keys:

  • last-status — JSON snapshot of component statuses for cron comparison
  • metrics — Counters for webhooks, messages, cron checks, commands

kv-store.js handles key building/parsing with kv.list({ prefix: "sub:" }) pagination. 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 both webhook and cron 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)
  • Cron: */5 * * * * — triggers scheduled export every 5 minutes