SETUP.md step 2 told operators to store the Slack token/signing secret in SSM Parameter Store, which (a) violates the secrets-and-config handbook (API tokens/signing values must live in Secrets Manager) and (b) contradicts the IaC — the stack reads Secrets Manager and the IAM roles only grant secretsmanager:GetSecretValue on afterhours-shift-manager/*, so following the old instructions would break the deploy. - Section 2 now uses `aws secretsmanager create-secret` for all five secrets (slack-bot-token, slack-signing-secret, 3cx-domain/client-id/client-secret) — the 3CX secrets were also previously undocumented. - The Slack channel ID is not a secret; documented as the `ShiftChannel` deploy parameter (--parameter-overrides) instead of an SSM SecureString. Addresses violation 2 of #68.
4.2 KiB
After-Hours Shift Manager — Setup Guide
1. Create a Slack App
- Go to api.slack.com/apps → Create New App → From scratch
- Name:
After-Hours Shift Manager, pick your workspace - Under OAuth & Permissions, add these Bot Token Scopes:
chat:write— post messages to channelscommands— register slash commandschat:write.public— post to channels the bot isn't in
- Under Slash Commands, create a new command:
- Command:
/oncall - Request URL:
(fill in after deploy — see step 4) - Short Description:
Manage after-hours on-call shifts - Usage Hint:
[schedule | pick <date> | drop <date> | swap <date> @person | register <ext> | roster | help]
- Command:
- Under Interactivity & Shortcuts, toggle ON:
- Request URL: same URL as the slash command (the
/slack/eventsendpoint)
- Request URL: same URL as the slash command (the
- Install to Workspace — approve the permissions
- Copy the Bot User OAuth Token (
xoxb-...) and Signing Secret (under Basic Information)
2. Store Secrets in AWS Secrets Manager
The stack reads these from Secrets Manager (the IAM roles grant
secretsmanager:GetSecretValue on afterhours-shift-manager/*):
# Slack
aws secretsmanager create-secret \
--name afterhours-shift-manager/slack-bot-token \
--secret-string "xoxb-YOUR-BOT-TOKEN"
aws secretsmanager create-secret \
--name afterhours-shift-manager/slack-signing-secret \
--secret-string "YOUR-SIGNING-SECRET"
# 3CX Queue XAPI (used by roster-sync and ring-scheduler)
aws secretsmanager create-secret \
--name afterhours-shift-manager/3cx-domain \
--secret-string "yourcompany.3cx.us"
aws secretsmanager create-secret \
--name afterhours-shift-manager/3cx-client-id \
--secret-string "YOUR-3CX-CLIENT-ID"
aws secretsmanager create-secret \
--name afterhours-shift-manager/3cx-client-secret \
--secret-string "YOUR-3CX-CLIENT-SECRET"
The Slack channel ID is not a secret — it's passed as the
ShiftChanneldeploy parameter in step 3, not stored in Secrets Manager or SSM.
3. Deploy the Stack
# Build and deploy. ShiftChannel is the Slack channel ID for schedule posts
# (right-click the channel in Slack → Copy link → the ID is the last segment).
sam build
sam deploy --guided \
--stack-name afterhours-shift-manager \
--region us-east-1 \
--parameter-overrides ShiftChannel=C0XXXXXXX QueueNumber=801
# Note the SlackBotApiUrl output — you'll need it for step 4
4. Set the Slack Request URL
After deploy, copy the SlackBotApiUrl from the SAM output. Go back to your Slack app settings:
- Slash Commands → edit
/oncall→ set Request URL to the output URL - Interactivity & Shortcuts → set Request URL to the same URL
5. Seed the Schedule
python scripts/seed_schedule.py
This populates the DynamoDB table with the employee roster and default weekly schedule.
6. Invite the Bot & Register Users
- Create a channel (e.g.
#after-hours-shifts) and invite the bot:/invite @After-Hours Shift Manager - Each employee links their Slack account by running:
(using their own extension number)/oncall register 114
7. Update the 3CX Scheduler (optional)
To have the 3CX scheduler read overrides from DynamoDB (so Slack-driven changes apply to future dates automatically), deploy the updated 3CX scheduler from the feature/dynamodb-shift-integration branch. See that branch's changes for details.
Without this step, the Slack bot still works — it invokes the 3CX scheduler Lambda directly for same-day changes. Future-date overrides would only take effect if the scheduler reads DynamoDB.
Commands Reference
| Command | Description |
|---|---|
/oncall |
Show this week's schedule |
/oncall next |
Show next week's schedule |
/oncall pick <date> |
Pick up a shift |
/oncall drop <date> |
Drop your shift (marks it open) |
/oncall swap <date> @person |
Hand your shift to someone else |
/oncall register <ext> |
Link your Slack to your extension |
/oncall roster |
Show all employees and their link status |
/oncall help |
Show help |
Dates can be: today, tomorrow, monday–sunday, 4/5, 2026-04-05