Add Slack and Microsoft Teams as channel adapters#1
Closed
AutomationEdgeHQ wants to merge 3 commits into
Closed
Conversation
Mirrors the existing Telegram channel pattern to add two new chat platforms. Reuses the cross-channel infrastructure already in place: the user_channels table, /verify command, system-message dispatch, and adapter base class. Slack - SlackAdapter (lib/channels/slack.js) handles Events API webhooks, signature verification (HMAC-SHA256 of v0:<ts>:<body>), url_verification challenges, app_mention/message.im events, file attachments (images + audio transcription via AssemblyAI when configured), and threaded replies via thread_ts. - HTTP helpers in lib/tools/slack.js use raw fetch against the Slack Web API — no @slack/web-api dependency added. Microsoft Teams - TeamsAdapter (lib/channels/teams.js) handles Bot Framework Activity webhooks with hand-rolled JWT validation against Microsoft's JWKS (cached 24h) — avoids pulling botbuilder (~5MB+). - Replies sent via the Bot Framework Connector REST API with a client-credentials access token (cached + auto-refreshed). - Typing indicator re-emitted every 8s while AI processes. - File attachment downloads left as a follow-up (needs Graph auth path); text messages fully supported. API routing - /slack/events and /teams/events added to PUBLIC_ROUTES and the catch-all api/index.js POST switch. - pushToDefaultChannel extended to dispatch to Slack and Teams adapters. Teams pushes require a serviceUrl captured from inbound messages, so system notifications only flow after the user has messaged the bot. Admin UI (mirrors Telegram exactly) - /profile/slack and /profile/teams tabs for users to link their channel via a one-time /verify <code> flow. - /admin/event-handler/slack and /teams pages for admins to paste credentials, see the webhook/messaging URL, and validate. - New SlackIcon and TeamsIcon SVGs. Database - No schema changes. Slack rows use channel='slack', Teams use channel='teams' in the existing user_channels table. Env vars (templates/.env.example) - SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET - TEAMS_APP_ID, TEAMS_APP_PASSWORD Docs - docs/CHAT_INTEGRATIONS.md extended with end-to-end client setup walkthroughs for both platforms (Slack app creation + scopes, Azure Bot registration + manifest sideload).
The previous commit added the Slack/Teams adapters, server actions, and React page components but did not include the consumer-facing Next.js route files. Without those, /profile/slack, /profile/teams, /admin/event-handler/slack, and /admin/event-handler/teams all 404. Adds: - web/app/profile/slack/page.js - web/app/profile/teams/page.js - web/app/admin/event-handler/slack/page.js - web/app/admin/event-handler/teams/page.js Each mirrors the existing Telegram route exactly — auth check, fetch initial state via the matching backend module, render the component. - lib/chat/components/index.js: export ProfileSlackPage, ProfileTeamsPage, ApiKeysSlackPage, ApiKeysTeamsPage so the route files can import them from 'thepopebot/chat'. - lib/chat/components/settings-secrets-layout.jsx: add Slack + Teams tabs to EVENT_HANDLER_TABS so the admin sidebar nav exposes them. - docker/event-handler/Dockerfile: optional dev tarball install. If a thepopebot-*.tgz exists alongside (created via `npm pack`), install from it instead of the npm registry. Lets contributors test working-tree changes in Docker without publishing. - .gitignore: thepopebot-*.tgz so packed tarballs don't get committed.
…Tenant ID support - api/index.js: handle url_verification before credential check (Slack challenge arrives before creds are entered) - lib/config.js: register SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET, TEAMS_APP_ID, TEAMS_APP_PASSWORD, TEAMS_TENANT_ID in SECRET_KEYS - lib/channels/commands/index.js: accept ! prefix in addition to / (Slack and Teams both intercept /verify natively) - lib/tools/teams.js: dynamic token endpoint via getTokenEndpoint() — reads TEAMS_TENANT_ID for Single Tenant support, falls back to botframework.com for Multi Tenant - lib/chat/actions.js: add TEAMS_TENANT_ID to API_KEY_SECRETS; return tenantIdSet from getTeamsStatus - lib/chat/components/profile-page.jsx: show !verify (not /verify) in Slack and Teams binding flow - lib/chat/components/settings-secrets-page.jsx: add collapsible setup guides for Slack and Teams; add Tenant ID field (Step 2) to Teams section Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Owner
Author
|
Superseded by cross-fork PR stephengpope#257. Closing internal draft to keep a single canonical thread. |
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
POST /api/slack/events,POST /api/teams/events/admin/event-handler/slackand/teamsfor credentials,/profile/slackand/profile/teamsfor per-user linkinguser_channelstableWhy this design
The original AE spec suggested Vercel's
chat+@chat-adapter/*SDK, App Router per-route files,lib/bot.ts(TypeScript), Redis state, and a new/notify-channelendpoint. None of that fits the framework as built — thepopebot is JS-ESM, uses a catch-allapi/index.jsrouter, already has its own channel adapter system (lib/channels/base.js), keeps channel state in SQLite, and routes notifications throughlib/db/messages.js. So this PR instead mirrorslib/channels/telegram.jsexactly. No new runtime dependencies were added — Slack uses rawfetch, Teams uses hand-rolled JWT validation against Microsoft's JWKS (avoids pullingbotbuilder~5MB+).What's in
lib/channels/slack.js—SlackAdapter(HMAC signature verification,url_verification,app_mention/message.im, files, threaded replies, AssemblyAI audio transcription)lib/channels/teams.js—TeamsAdapter(Bot Framework JWT validation, Activity parsing, Connector REST sends, typing activity)lib/tools/slack.js,lib/tools/teams.js— HTTP/crypto helpersapi/index.js—/slack/events,/teams/eventsinPUBLIC_ROUTES, switch cases,pushToDefaultChannelextended for both channelslib/chat/slack-profile.js,lib/chat/teams-profile.js— backend state loaderslib/chat/actions.js— server actions:getSlackStatus,validateSlackToken,issueSlackCode,unlinkSlackChannel,setSlackSystemMessages(and Teams equivalents).SLACK_*/TEAMS_*added toAPI_KEY_SECRETS.lib/chat/components/profile-page.jsx—ProfileSlackPage,ProfileTeamsPage+ tab entrieslib/chat/components/settings-secrets-page.jsx—ApiKeysSlackPage,ApiKeysTeamsPage(3-step guided setup each)lib/chat/components/icons.jsx—SlackIcon,TeamsIcontemplates/.env.example—SLACK_BOT_TOKEN,SLACK_SIGNING_SECRET,TEAMS_APP_ID,TEAMS_APP_PASSWORDdocs/CHAT_INTEGRATIONS.md— full client setup walkthroughs for both platformsWhat's NOT in (intentional follow-ups)
serviceUrl. Captured per inbound message; persistence ontouser_channelsfor the first-push-before-inbound case is a future enhancement./notify-channelHTTP endpoint — existinglib/db/messages.jsalready fans out cross-channel via the adapter system.@slack/web-apiandbotbuilderwere considered and dropped — rawfetch+ hand-rolled JWT keep the dep tree clean.Webhook URLs to register
<APP_URL>/api/slack/events<APP_URL>/api/teams/eventsTest plan
ledger:devDocker image and point a local jay-bot install at iturl_verificationchallenge/profile/slack→/verify <code>flow → confirmuser_channelsrow/verify <code>Upstreaming
This branch is meant to be offerable to
stephengpope/thepopebotonce tested. Themainbranch of this fork is untouched — Phase 2 (survey-server + Ledger white-label) layers on top later.🤖 Generated with Claude Code