Node/Express service that:
- Receives Appspace outbound webhooks, enriches with Workspace ONE MDM
data (matched by serial), and posts Adaptive Card alerts to Webex.
- Runs a Webex bot in WebSocket mode with two commands:
* `offline [filter]` - lists currently offline / lost / failed
Appspace devices, enriched with per-device MDM facts + console links.
* `restart-offline [filter]` - sends WS1 SoftReset (reboot) to every
currently-offline device that has a WS1 record. Capped at 50 per
invocation with bounded concurrency to protect the WS1 API.
Notes on hardening already applied:
- In-flight promise coalescing in mdm.js and index.js so burst webhook
traffic can't stampede the WS1 token / device-cache refresh or the
Appspace token refresh.
- Structured logger that serializes Error instances (message, stack,
code, axios response.status/data) instead of stringifying to "{}".
- Webex 7439-char message-limit handling: `offline` builds its body
incrementally against a character budget and reports accurate
"N more not shown" truncation.
- Uses string phrases for `framework.hears(...)` so the framework's
`(^| )phrase($| )` wrapper handles group-space @mentions correctly,
and a shared `extractFilterArg()` helper so filter parsing works
identically in DMs and mentioned messages.
Config, Docker, smoke-test profile, and healthcheck included.
Secrets are managed via `.env` (gitignored); see `.env.example`.
Co-authored-by: Cursor <cursoragent@cursor.com>
23 lines
1.3 KiB
JSON
23 lines
1.3 KiB
JSON
{
|
|
"name": "appspace-webex-alerts",
|
|
"version": "1.0.0",
|
|
"main": "index.js",
|
|
"scripts": {
|
|
"start": "node index.js",
|
|
"dev": "node index.js",
|
|
"offline:legacy": "node query-offline.js",
|
|
"docker:dev": "docker compose --profile dev up app-dev",
|
|
"docker:prod": "docker compose up -d",
|
|
"docker:smoke": "echo '🚀 Running Docker smoke test (build + health check)...' && docker compose --profile smoke build smoke-test && docker compose --profile smoke up -d smoke-test && (for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30; do status=$(docker inspect --format='{{.State.Health.Status}}' appspace-smoke-test 2>/dev/null || echo 'none'); if [ \"$status\" = 'healthy' ]; then echo '✅ Smoke test PASSED: container healthcheck is healthy'; success=1; break; fi; sleep 1; done; if [ -z \"$success\" ]; then echo \"❌ Smoke test FAILED: final health status was $status\"; docker compose --profile smoke logs --tail=100 smoke-test; false; fi) ; docker compose --profile smoke down --remove-orphans smoke-test 2>/dev/null || true"
|
|
},
|
|
"dependencies": {
|
|
"axios": "^1.7.2",
|
|
"body-parser": "^1.20.2",
|
|
"dotenv": "^16.4.5",
|
|
"express": "^4.19.2",
|
|
"webex-node-bot-framework": "^2.5.1"
|
|
},
|
|
"devDependencies": {
|
|
"nodemon": "^3.1.14"
|
|
}
|
|
}
|