Bridges third-party status pages into Webex spaces via RSS polling and inbound webhooks (Statuspage / Status.io / Uptime Kuma / generic). Includes an interactive Webex bot (websocket transport) that lets space members register sources with an Adaptive Card instead of hand-editing config/feeds.json: help, add, list, webhook <key>, remove <key>. Ships with an atomic JSON store (per-file mutex, tmp+rename), parallel RSS polling, and unit tests via node:test. All secrets are sourced from environment variables (see .env.example); no credentials in the repo. Co-authored-by: Cursor <cursoragent@cursor.com>
110 lines
4 KiB
Markdown
110 lines
4 KiB
Markdown
# aeStatusPage
|
|
|
|
Small Node.js service that bridges third-party status pages into Webex spaces.
|
|
It can consume:
|
|
|
|
- RSS / Atom feeds (polled every 5 minutes)
|
|
- Inbound webhooks in Atlassian Statuspage, Status.io, or Uptime Kuma format
|
|
- Anything else you point at it (raw dump)
|
|
|
|
It also runs a Webex bot so you can register new sources from inside a space
|
|
with a card-based UI instead of hand-editing `config/feeds.json`.
|
|
|
|
## Configure
|
|
|
|
Copy `.env.example` to `.env` and set the values, at minimum:
|
|
|
|
| Variable | Purpose |
|
|
| --- | --- |
|
|
| `WEBEX_BOT_TOKEN` | Bearer token for the Webex bot user (required) |
|
|
| `PUBLIC_BASE_URL` | Public https URL where this service is reachable; used to show users the correct webhook URL |
|
|
| `SERVER_PORT` | Override the port from `config/config.json` (default 1449) |
|
|
| `SERVER_NAME` | Cosmetic name used in log lines |
|
|
| `BOT_ENABLED` | Set to `false` to disable the interactive chat bot |
|
|
|
|
`config/config.json` should now only contain non-secret configuration.
|
|
|
|
## Run
|
|
|
|
**Node version.** The Docker image runs on Node 20 (`node:20`). For local
|
|
development, use Node 20.x — Node 21+ breaks `webex-node-bot-framework`'s
|
|
transitive `webex` dep, which tries to write to the now read-only global
|
|
`navigator`. The app will still start on newer Node hosts, but the interactive
|
|
chat bot will be disabled with a warning logged. Set `BOT_ENABLED=false` to
|
|
suppress the warning if you don't want the bot in dev.
|
|
|
|
```bash
|
|
npm install
|
|
npm start
|
|
```
|
|
|
|
or Docker:
|
|
|
|
```bash
|
|
docker build -t aestatuspage .
|
|
docker run --env-file .env -p 1449:1449 \
|
|
-v $(pwd)/config:/usr/src/app/config \
|
|
-v $(pwd)/logs:/usr/src/app/logs \
|
|
aestatuspage
|
|
```
|
|
|
|
## Register a source from Webex
|
|
|
|
1. Invite the bot user to the space.
|
|
2. Type `help` — you'll see the available commands.
|
|
3. Type `add` — the bot posts an Adaptive Card. Fill in:
|
|
- a short key (used as the webhook URL slug)
|
|
- a friendly name
|
|
- source type: `RSS`, `Webhook`, or `Both`
|
|
- the RSS URL and/or the webhook payload format
|
|
4. On submit the bot saves the entry to `config/feeds.json` atomically and
|
|
posts back the exact webhook URL you should configure in your upstream
|
|
status provider (Statuspage, Status.io, Uptime Kuma, ...).
|
|
|
|
Other commands:
|
|
|
|
- `list` — show sources currently posting to this space
|
|
- `webhook <key>` — echo back the inbound webhook URL for a provider
|
|
- `remove <key>` — stop posting a provider to this space
|
|
|
|
The bot uses Webex's websocket transport, so it does not require an inbound
|
|
webhook URL to work as a chat bot. `PUBLIC_BASE_URL` is only used to show
|
|
users the correct URL for **status page** webhooks.
|
|
|
|
## HTTP endpoints
|
|
|
|
| Method + path | Purpose |
|
|
| --- | --- |
|
|
| `GET /healthCheck` | Liveness probe |
|
|
| `GET /feeds` | Dumps the current `feeds.json` |
|
|
| `GET /webhookEvents` | Dumps recent webhook events (in-memory) |
|
|
| `GET /refreshFeeds` | Re-reads `feeds.json` from disk without restarting |
|
|
| `GET /checkRSSFeed?site=<url>` | Debug: fetch + parse a feed and return it |
|
|
| `GET /cleanOldFiles` | Manually trigger old-log cleanup |
|
|
| `GET /:provider/go` | Redirect to the provider's `siteUrl` |
|
|
| `POST /:provider` | Inbound status webhook (Statuspage / Status.io / Uptime Kuma / generic) |
|
|
| `POST /rssTest?provider=<key>` | Debug: send a fake RSS item as if it had come through the feed |
|
|
|
|
## Tests
|
|
|
|
```bash
|
|
npm test
|
|
```
|
|
|
|
Runs `node --test` against `test/**/*.test.js`. No test framework
|
|
dependencies — everything is Node built-ins.
|
|
|
|
## Layout
|
|
|
|
```
|
|
index.js HTTP server, cron loop, webhook processors
|
|
src/atomicJson.js Atomic JSON read/write with per-file mutex
|
|
src/providerStore.js Typed wrapper around feeds.json (add/remove/list)
|
|
src/cards.js Adaptive Card templates used by the bot
|
|
src/webexBot.js webex-node-bot-framework wiring (websocket mode)
|
|
config/config.json Non-secret configuration
|
|
config/feeds.json Registered providers (mutated at runtime)
|
|
config/rssFeedCache.json Dedup cache for RSS items already posted
|
|
logs/ Rolling per-day log files
|
|
test/ Unit tests
|
|
```
|