Follow-up from #82
#82 wires up a real notifier for help-wanted-role events (interest expressed, role filled). The agreed-on first-cut shape is email-only via Resend — covered in that issue.
This issue tracks the Slack DM channel, deliberately deferred until we tackle deeper Slack integration.
Why deferred
The Notifier interface in apps/api/src/notify/index.ts already accepts maintainerSlackHandle per notification, so the data flow is ready. What's missing is the credential trust — sending a DM from a workspace bot requires either:
- A workspace-installed Slack app with
chat:write scope + a bot token (the easiest path).
- SAML IdP-side identity assertions extended to support delegated Slack actions (much heavier).
We're already the SAML IdP for codeforphilly.slack.com (specs/api/saml.md), but that's an inbound SAML flow (user signs into Slack via us). Sending DMs out to Slack is the inverse — we'd be initiating a workspace action on a member's behalf. Cleaner to do that via a dedicated Slack app with its own token.
Scope (when picked up)
- Add a
SlackDmNotifier implementation alongside EmailNotifier.
- A new env var (
SLACK_BOT_TOKEN) — sealed-secret in the cluster repo.
- Map Slack handles → user IDs via
users.lookupByEmail (or users.list cached) since handles can change. Skip if the handle doesn't resolve.
- Compound notifier: try Slack DM first, fall back to email if Slack delivery fails or the recipient has no Slack handle. (Or run both — pick when implementing.)
- Failure logging at the same envelope as today's notifier.
Related
Follow-up from #82
#82 wires up a real notifier for help-wanted-role events (interest expressed, role filled). The agreed-on first-cut shape is email-only via Resend — covered in that issue.
This issue tracks the Slack DM channel, deliberately deferred until we tackle deeper Slack integration.
Why deferred
The Notifier interface in
apps/api/src/notify/index.tsalready acceptsmaintainerSlackHandleper notification, so the data flow is ready. What's missing is the credential trust — sending a DM from a workspace bot requires either:chat:writescope + a bot token (the easiest path).We're already the SAML IdP for
codeforphilly.slack.com(specs/api/saml.md), but that's an inbound SAML flow (user signs into Slack via us). Sending DMs out to Slack is the inverse — we'd be initiating a workspace action on a member's behalf. Cleaner to do that via a dedicated Slack app with its own token.Scope (when picked up)
SlackDmNotifierimplementation alongsideEmailNotifier.SLACK_BOT_TOKEN) — sealed-secret in the cluster repo.users.lookupByEmail(orusers.listcached) since handles can change. Skip if the handle doesn't resolve.Related
specs/behaviors/help-wanted-roles.md— what gets delivered