Skip to content

feat: slack integration#2794

Merged
brojd merged 32 commits intomainfrom
brojd/slack-integration
Feb 20, 2026
Merged

feat: slack integration#2794
brojd merged 32 commits intomainfrom
brojd/slack-integration

Conversation

@brojd
Copy link
Copy Markdown
Contributor

@brojd brojd commented Feb 14, 2026

No description provided.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Feb 14, 2026

Claude finished @brojd's task in 3m 5s —— View job


PR Review: Slack Integration

  • Read repository guidelines (CLAUDE.md)
  • Gather context on PR changes
  • Review backend changes (chatops routes, slack provider, models)
  • Review frontend changes (slack page, setup dialogs, shared components)
  • Review tests
  • Review documentation and API spec changes
  • Post comprehensive review

Overview

This PR adds Slack as a second ChatOps provider alongside the existing MS Teams integration. The implementation follows the established ChatOpsProvider interface pattern, adding a SlackProvider, webhook routes (events, interactive actions, slash commands), a full frontend setup wizard, and channel/agent binding management UI.

The architecture is well-structured — the new Slack provider slots cleanly into the existing ChatOps framework, and the code reuses shared infrastructure (channel bindings model, ChatOpsManager, access control) rather than duplicating it.


Strengths

  • Security is solid. The SlackProvider.validateWebhookRequest correctly uses HMAC SHA256 with timingSafeEqual, includes replay attack protection (5-minute timestamp window), and captures the raw body via a preParsing hook before Fastify's JSON parser consumes it. All three Slack endpoints (events, interactive, slash commands) validate signatures before processing.
  • User access control is consistent. Every Slack entry point (event webhook, interactive button click, slash command) resolves the sender's email via getUserEmail(), verifies they're a registered Archestra user, and the processMessage flow validates team-based agent access — matching the MS Teams security model.
  • Deduplication is well-handled. The in-memory recentlyProcessedSlackEvents map provides a fast first-pass filter for the duplicate message/app_mention events Slack fires, with the database-level ChatOpsProcessedMessageModel.tryMarkAsProcessed() as the authoritative dedup. The map has a safety bound (10K entries with 10% eviction) and 30s TTL.
  • Async message processing. The Slack event webhook correctly returns 200 immediately and processes the message asynchronously to stay within Slack's 3-second timeout, with error logging on the background promise.
  • Clean frontend UX. The setup wizard with manifest generation, step-by-step instructions, and video guides is polished. The SetupDialog/StepCard extraction creates reusable components shared with the MS Teams flow.

Issues & Suggestions

1. Bot token exposed in placeholder text (Low - UX)

platform/frontend/src/components/slack-setup-dialog.tsx:576-578

The StepConfigForm shows the current bot token in the placeholder: Current: ${creds.botToken}. While creds.botToken comes from the status API which returns a masked value (xox•••••••), this pattern is fragile — if the masking logic changes, the real token could leak into the placeholder. Consider using a static placeholder like "Bot token configured" instead.

2. conversations.list pagination not handled (Medium - Functional)

platform/backend/src/agents/chatops/slack-provider.ts:386-390

const result = await this.client.conversations.list({
  types: "public_channel,private_channel",
  exclude_archived: true,
  limit: 999,
});

Slack's conversations.list API paginates results and the limit parameter caps at 1000 per page. For workspaces with >999 channels where the bot is a member, this silently drops channels. The limit: 999 comment suggests awareness of the boundary but doesn't handle the response_metadata.next_cursor for pagination. For a first iteration this is likely acceptable, but worth noting as a known limitation or adding cursor-based pagination.

Fix this →

3. Slack user email cache has no negative caching (Low - Performance)

platform/backend/src/agents/chatops/slack-provider.ts:350-378

The getUserEmail method caches successful email lookups for 5 minutes but doesn't cache negative results (users without email). If a user without a configured email repeatedly messages, every message triggers a Slack API call. Consider caching null results for a shorter TTL (e.g., 1 minute) to reduce API calls.

4. Missing @fastify/formbody dependency documentation (Low - DevEx)

platform/backend/package.json:+1

The Slack interactive and slash command endpoints receive application/x-www-form-urlencoded payloads. The captureSlackRawBody preParsing hook captures the raw body before parsing, but the code relies on Fastify having a form body parser registered. The new @slack/web-api dependency is added, but there's no explicit mention of the form body parser dependency. If @fastify/formbody is already registered globally, this works — but it's worth verifying.

5. Grip icon import unused after refactor (Nit)

platform/frontend/src/app/agent-triggers/slack/page.tsx:8

Grip is imported from lucide-react and is used in the agent table actions. This is fine, just confirming it's intentional — it's used on line 462.

6. Consider extracting shared chatops command handling (Low - Maintainability)

platform/backend/src/routes/chatops.ts

The Slack event webhook (lines 572-661) duplicates some of the pattern from the MS Teams webhook: sender email resolution → user verification → binding lookup → agent selection card / process message. The slash command endpoint also has a similar flow. While the current duplication is manageable, if a third provider is added, consider extracting a shared handleIncomingMessage helper that encapsulates the common flow (resolve email → verify user → check binding → route to selection card or processMessage).

7. SlackAgentSetupDialog and EnableAgentsDialog have duplicated agent toggle logic (Nit)

platform/frontend/src/components/slack-agent-setup-dialog.tsx:55-154 and platform/frontend/src/components/enable-agents-dialog.tsx:22-119

The StepEnableSlack component in SlackAgentSetupDialog and the EnableAgentsDialog have nearly identical agent toggle logic and UI. EnableAgentsDialog is the more generic version (accepts a provider prop). Consider whether SlackAgentSetupDialog step 1 could use EnableAgentsDialog directly or share more of the component.

8. Unused import: Grip` in ms-teams page (Nit - cleanup)

Checking the ms-teams page changes — this is a separate file and already existed. No issue here.


Security Review

  • HMAC verification: Correctly implemented with timingSafeEqual and replay attack protection. The raw body is captured before JSON parsing to ensure signature verification operates on the exact bytes Slack signed.
  • User identity: All three Slack endpoints resolve user email via the Slack users.info API (with caching) and verify against registered Archestra users before processing.
  • Access control: The processMessage flow in ChatOpsManager performs team-based agent access validation, consistent with MS Teams.
  • Rate limiting: All three Slack webhook endpoints have IP-based rate limiting via the shared isRateLimited utility.
  • Config endpoint protection: The PUT /api/chatops/config/slack endpoint is correctly gated behind !config.production || config.isQuickstart, matching the MS Teams config endpoint pattern.
  • RBAC: New routes (UpdateSlackChatOpsConfig, RefreshChatOpsChannelDiscovery) are registered in routes.ts and have proper permission entries in access-control.ts.

No security concerns found.


Tests Review

  • slack-provider.test.ts (565 lines): Comprehensive unit tests covering webhook validation (valid signatures, replay attacks, missing headers, timing-safe comparison), event parsing (messages, app_mentions, bot message filtering, DM handling, thread replies), sendReply, sendAgentSelectionCard, getThreadHistory, getUserEmail (with caching), discoverChannels, and parseInteractivePayload. Good coverage.
  • chatops-slash-command.test.ts (246 lines): Integration tests for the slash command endpoint covering /archestra-help, /archestra-status, /archestra-select-agent, and unknown commands, with proper signature validation and user verification mocking.
  • chatops-manager.test.ts: Updated with +2/-0 to include the Slack provider in the mock setup.

The test coverage is thorough for a new feature. The Playwright E2E tests all pass (431 passed, 4 flaky).


Summary

This is a well-implemented Slack integration that follows the established patterns in the codebase. The security model is consistent, the UI is polished with good guided setup flows, and the test coverage is solid. The issues noted above are mostly minor — the pagination limitation in discoverChannels is the most notable functional gap but is acceptable for an initial release.

Verdict: Looks good to merge with the optional improvements noted above.

@London-Cat
Copy link
Copy Markdown
Collaborator

London-Cat commented Feb 14, 2026

📊 Reputation Summary

User Rep Pull Requests Activity Assigned Core Reactions
brojd ⚡ 1823 89✅ 1🔄 10❌ 28 issues, 50 comments 4

How is the score calculated? Read about it in the Reputation Bot repository 🤖

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 14, 2026

Playwright test results

passed  434 passed
flaky  1 flaky

Details

stats  435 tests across 48 suites
duration  5 minutes, 41 seconds
commit  f46218a

Flaky tests

api › api/llm-proxy/token-cost-limits.spec.ts › LLMProxy-TokenCostLimits-Zhipuai › blocks request when profile token cost limit is exceeded

@brojd brojd changed the title WIP: slack integration feat: slack integration Feb 18, 2026
@brojd brojd added this pull request to the merge queue Feb 19, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Feb 19, 2026
@brojd brojd enabled auto-merge February 20, 2026 09:47
@brojd brojd added this pull request to the merge queue Feb 20, 2026
Merged via the queue into main with commit e155823 Feb 20, 2026
44 checks passed
@brojd brojd deleted the brojd/slack-integration branch February 20, 2026 10:04
joeyorlando added a commit that referenced this pull request Feb 23, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.0.48](platform-v1.0.46...platform-v1.0.48)
(2026-02-23)


### Features

* add labels support to MCP catalog items
([#2931](#2931))
([b4cf3af](b4cf3af))
* add Perplexity AI LLM provider support
([#2467](#2467))
([c41f7a5](c41f7a5))
* add require approval
([#2908](#2908))
([02d7497](02d7497))
* add role & permissions card to My Account settings
([#2956](#2956))
([ae99b0e](ae99b0e))
* add SSRF protection via k8s `NetworkPolicy` for MCP servers
([#2904](#2904))
([c90cc52](c90cc52))
* add tolerations support to Helm chart
([#2878](#2878))
([6d92250](6d92250))
* advanced search palette with product navigation and shortcuts
([#2246](#2246))
([883d621](883d621))
* merge token_price into models table with custom price overrides
([#2938](#2938))
([9b5a887](9b5a887))
* provider settings page, multi-key support, virtual API keys, per-key
base URLs
([#2918](#2918))
([8802b6a](8802b6a))
* slack integration
([#2794](#2794))
([e155823](e155823))
* split "profile" RBAC resource into agent, mcpGateway, and llmProxy
([#2888](#2888))
([102cd04](102cd04))


### Bug Fixes

* add backend validation for org logo (base64 + png)
([#2834](#2834))
([5cdce48](5cdce48))
* add RFC 8707 resource parameter to OAuth authorization URL
([#2954](#2954))
([f3ac5fb](f3ac5fb))
* address dependabot security alerts for ajv, hono, and qs
([#2937](#2937))
([c9e84be](c9e84be))
* agent version history doesn't work
([#2869](#2869))
([ebd4a65](ebd4a65))
* auto-hide row selection count in pagination for certain pages
([#2890](#2890))
([484463c](484463c))
* bug with fastest model and other minor fixes
([#2901](#2901))
([e5df7af](e5df7af))
* double-slash in Grafana API paths by stripping trailing slash
([#2905](#2905))
([835f617](835f617))
* dynamic credential handling in agent tools editor
([#2873](#2873))
([cc825fc](cc825fc))
* ensure K8s Service names comply with 63-char DNS label limit for long
MCP names
([#2841](#2841))
([27e9239](27e9239))
* fix CVEs
([#2909](#2909))
([1899754](1899754))
* fix external agent tco panel
([#2891](#2891))
([4cefd4a](4cefd4a))
* invalidate correct query key when security setting changes
([#2951](#2951))
([fe9f8f3](fe9f8f3))
* nonadmin users handling
([#2837](#2837))
([8334376](8334376))
* Ollama/vLLM streaming tool calls in chat
([#2894](#2894))
([c6bd0d3](c6bd0d3))
* polish tool requires approval
([#2945](#2945))
([01e140d](01e140d))
* preserve OAuth consent redirect after sign-in
([#2917](#2917))
([3c992cc](3c992cc))
* preserve tool selection after sorting in tools table
([#2813](#2813))
([b4705d9](b4705d9))
* reduce db pool size to not exceed max_connections during rollout
([#2940](#2940))
([3fe9782](3fe9782))
* resolve Sentry issues - N+1 queries, empty update crash, FK violation
([#2902](#2902))
([b1ed940](b1ed940))
* support `thoughtSignature` preservation in Gemini 3 streaming
([#2897](#2897))
([9036f8e](9036f8e))
* use self-hosted fonts to fix Docker build failures with Turbopack
([#2911](#2911))
([b607c34](b607c34))
* use shadcn datepicker and fix dialog reopen bug for virtual API keys
([#2944](#2944))
([f61f871](f61f871))
* vault e2e tests skipping on CI due to multi-replica deployment
([#2906](#2906))
([885aaae](885aaae))


### Code Refactoring

* extract shared proxy preHandler utility
([#2874](#2874))
([78a5fdd](78a5fdd))


### Miscellaneous Chores

* add debug logs for execution metric deduplication
([#2886](#2886))
([28612e7](28612e7))
* clean-up tool duplicates
([#2916](#2916))
([970d5fb](970d5fb))
* do not use tool.mcp_server_Id
([#2848](#2848))
([bb2b6e6](bb2b6e6))
* improve agent triggers
([#2946](#2946))
([a73b86e](a73b86e))
* improve ux of agent triggers
([#2932](#2932))
([1db1f16](1db1f16))
* **release:** bump version
([#2961](#2961))
([e2438f7](e2438f7))
* **release:** bump version
([#2963](#2963))
([981a9f5](981a9f5))
* remove redundant info box from Setup Slack
([#2923](#2923))
([a0fe384](a0fe384))
* support dm with archestra bots
([#2924](#2924))
([54398b9](54398b9))
* use secrets manager for slack and teams
([#2920](#2920))
([63d45d8](63d45d8))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: archestra-ci[bot] <222894074+archestra-ci[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Joey Orlando <joey@archestra.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants