feat: add Slack adapter with multi-platform ChatAdapter architecture#259
Open
dogzzdogzz wants to merge 6 commits intoopenabdev:mainfrom
Open
feat: add Slack adapter with multi-platform ChatAdapter architecture#259dogzzdogzz wants to merge 6 commits intoopenabdev:mainfrom
dogzzdogzz wants to merge 6 commits intoopenabdev:mainfrom
Conversation
Introduces a platform-agnostic adapter layer (ChatAdapter trait + AdapterRouter) that decouples session management, streaming, and reactions from any specific chat platform. Refactors Discord support to implement this trait and adds a new Slack adapter using Socket Mode (WebSocket) with auto-reconnect. - Extract ChatAdapter trait with send/edit/thread/react methods + message_limit() - Extract AdapterRouter with shared session routing, edit-streaming, and reactions - Decouple StatusReactionController from serenity types (uses Arc<dyn ChatAdapter>) - Implement DiscordAdapter (ChatAdapter for Discord via serenity) - Implement SlackAdapter (ChatAdapter for Slack via reqwest + tokio-tungstenite) - Add [slack] config section (bot_token, app_token, allowed_channels, allowed_users) - Support running Discord + Slack simultaneously in one process - Session keys namespaced by platform (discord:xxx, slack:xxx) - Unicode emoji → Slack short name mapping for reactions Relates to openabdev#93, openabdev#94, openabdev#86 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract image resize/compress, download+encode, and STT download from discord.rs into shared media.rs module - Both Discord and Slack adapters now use media::download_and_encode_image() and media::download_and_transcribe() with optional auth_token parameter - Move sender context XML wrapping into AdapterRouter.handle_message() (was duplicated in each adapter) - Add image/audio attachment support to Slack adapter via files[] in app_mention events (requires files:read bot scope) - Slack file downloads use Bearer token auth (private URLs) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ollow-up - Fix strip_slack_mention to use LazyLock<Regex> instead of compiling per-call - Fix shorten_thread_name regex to use LazyLock, move to shared format.rs - Resolve Slack display name via users.info API (fallback to user_id) - Handle message events with thread_ts for thread follow-ups without @mention - Fix misleading allowed_channels comment (empty = allow all, not deny all) - Add allowed_channels docs to config.toml.example Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add slack config to values.yaml (enabled, botToken, appToken, allowedChannels, allowedUsers) - Generate [slack] section in configmap.yaml when slack.enabled=true - Store slack-bot-token and slack-app-token in secret.yaml - Inject SLACK_BOT_TOKEN and SLACK_APP_TOKEN env vars in deployment.yaml - Make [discord] section conditional (omitted when no botToken) - Add Slack setup instructions to NOTES.txt - Backward compatible: existing Discord-only configs work unchanged Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update README.md: add Slack to description, architecture diagram, features, Quick Start (Discord/Slack toggle), config example, Helm example, Configuration Reference, and Project Structure - Add docs/slack-bot-howto.md: complete Slack bot setup guide - Add cross-reference from discord-bot-howto.md to slack-bot-howto.md Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
010cd36 to
6f10b36
Compare
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
ChatAdaptertrait +AdapterRouter, decoupling session management, streaming, and reactions from any specific chat platformmedia.rsfor cross-adapter reuseSessionPoolwith namespaced keysCloses #93. Implements Phase 1–3 of RFC #94.
Changes
src/adapter.rsChatAdaptertrait,ChannelRef/MessageRef/SenderContext,AdapterRoutersrc/slack.rsSlackAdapter+ Socket Mode event loopsrc/media.rssrc/discord.rsDiscordAdapterimplementsChatAdapter, delegates to routersrc/reactions.rsArc<dyn ChatAdapter>src/format.rsshorten_thread_name()src/config.rsdiscordnow optional, addedSlackConfigsrc/main.rsconfig.toml.example[slack]section with docscharts/openab/values.yamlslackconfig per agent (enabled, botToken, appToken, allowedChannels, allowedUsers)charts/openab/templates/configmap.yaml[discord]and/or[slack]sectionscharts/openab/templates/secret.yamlslack-bot-token+slack-app-tokenalongside discord tokencharts/openab/templates/deployment.yamlSLACK_BOT_TOKEN+SLACK_APP_TOKENenv varscharts/openab/templates/NOTES.txtDesign Decisions
discord:xxx,slack:xxx) to prevent collisionAdapterRouter(not duplicated per adapter)media.rswith optionalauth_tokenparam (Discord CDN is public, Slack files need Bearer token)eyesnot👀)users.infoAPI (Discord provides names in message payload, Slack only gives user ID)messageevents withthread_tshandled without requiring re-mention (parity with Discord)[discord]section now conditional (omitted when no botToken)Helm Usage
Test plan
cargo build— zero warningscargo test— 26 tests passcargo clippy— cleanhelm template— Discord-only, Slack-only, and both modes validated🤖 Generated with Claude Code