Modernize: express-slack/request -> Bolt, Block Kit buttons, add Docker + deploy - #13
Open
ddbruce wants to merge 1 commit into
Open
Modernize: express-slack/request -> Bolt, Block Kit buttons, add Docker + deploy#13ddbruce wants to merge 1 commit into
ddbruce wants to merge 1 commit into
Conversation
…er + deploy Behavior-preserving modernization. Same behavior: an external dispatch POST to /tmd_slack_notification (or _long) posts the dispatch to the responding and dispatch channels; during the day-crew window (05:55–18:05) the responding message carries Yes/No buttons; clicking a button (within 12 minutes) looks up the user and posts "<name> is RESPONDING / NOT RESPONDING"; late clicks get the same ephemeral notice. SDK / framework: - Replace the ABANDONED express-slack wrapper and the DEPRECATED request lib with @slack/bolt 4.x. Bolt's ExpressReceiver verifies the button interactions via signing secret (the old setup did not verify them at all) and also hosts the external dispatch webhooks as plain Express routes + a /health route. - Drop axios: its only use was the out-of-service check, which never worked (see below). dotenv added for config. Buttons -> Block Kit: - The interactive "Are you responding?" message's Yes/No buttons are now Block Kit (action_id responding_yes/responding_no, values yes/no) inside a colored attachment, so the orange color bar is preserved. The other, non-interactive messages keep their colored attachments unchanged. Config / packaging: - Externalize config to env vars (.env + dotenv): SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET (new), AIR_CHANNEL, DISPATCH_CHANNEL, VERIFICATION_TOKEN, PORT (default 5939). Removes the hardcoded channel IDs and port, the var.js/data.json config + OAuth store, and the express-slack OAuth scopes. - Add a Dockerfile (there was none): node:24-alpine, npm ci, non-root, HEALTHCHECK. Add ESLint 9 flat config, Jest tests (9), GitHub Actions CI, and scripts/deploy.sh + config.example.sh (amd64 -> GHCR -> Coolify redeploy). Pre-existing bug (NOT silently changed): the original areOos() out-of-service override called axios.get without await and compared a Promise to 1, so it always evaluated false and never affected message selection. Behavior is preserved (the override stays disabled); OOS_URL/OOS_TOKEN are kept in config for when the feature is fixed. See the PR to decide whether to enable it. Verified: 9 unit tests pass; boots on Bolt 4 (/health 200; dispatch webhook rejects bad verification with 401 and echoes on good; unsigned /slack/events 401); amd64 image builds with 0 npm vulnerabilities. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Modernizes
airoff its abandonedexpress-slackwrapper and the deprecatedrequestlibrary onto@slack/bolt, converts the Yes/No response buttons to Block Kit (your choice), and adds the container + deploy tooling it never had. Same behavior: a dispatch POST posts to the responding + dispatch channels; during the day-crew window (05:55–18:05) the responding message carries Yes/No buttons; clicking within 12 minutes looks up the user and posts "name is RESPONDING / NOT RESPONDING"; late clicks get the same ephemeral notice.Verified: 9 unit tests pass; boots on Bolt 4 (
/health→ 200; dispatch webhook rejects bad verification with 401 and echoes dispatch on good; unsigned/slack/events→ 401); amd64 image builds with 0 npm vulnerabilities.Changes
express-slack(abandoned) +request(deprecated) →@slack/bolt4.x. Bolt'sExpressReceiververifies button interactions via the signing secret (the old code did not verify them) and also hosts the external dispatch webhooks (/tmd_slack_notification,/tmd_slack_notification_long) as plain Express routes plus/health. Droppedaxios(its only use was the dead OOS check); addeddotenv.action_idresponding_yes/responding_no, valuesyes/no) placed inside a colored attachment so the orange color bar is preserved. The other non-interactive messages keep their colored attachments unchanged..env+ dotenv):SLACK_BOT_TOKEN,SLACK_SIGNING_SECRET(new),AIR_CHANNEL,DISPATCH_CHANNEL,VERIFICATION_TOKEN,PORT(default 5939). Removes the hardcoded channel IDs + port, thevar.js/data.jsonconfig & OAuth store, and the express-slack OAuth scopes.node:24-alpine,npm ci, non-root,HEALTHCHECK; ESLint 9 flat config; Jest tests; GitHub Actions CI;scripts/deploy.sh+config.example.sh.https://<host>/slack/events(was/slack_response).SLACK_SIGNING_SECRET) — from the Slack app's Basic Information. The old code didn't verify button requests at all; Bolt requires it./tmd_slack_notification/_longwith theverificationfield (nowVERIFICATION_TOKEN) — unchanged.🐞 Pre-existing bug — your call (NOT silently changed)
The original out-of-service override (
areOos()) calledaxios.get(...)withoutawaitand compared a Promise to1, so it always evaluated false and never affected which message was posted. I preserved that behavior (the override stays disabled) rather than change it silently.OOS_URL/OOS_TOKENremain in config. Want me to actually enable the OOS check (so off-hours OOS calls show the responding message)? Say the word and I'll wire it up with properawait+ error handling.Verify in staging
/tmd_slack_notificationduring the day → Yes/No buttons appear; click each → status message posts with the right name./tmd_slack_notification_long→ longtone notices in both channels.Recommended follow-ups (NOT done)