Skip to content

feat(slack): reusable custom bot credentials, slack_v2 block (preview), redesigned trigger#5323

Merged
TheodoreSpeaks merged 26 commits into
stagingfrom
improve/slack
Jul 10, 2026
Merged

feat(slack): reusable custom bot credentials, slack_v2 block (preview), redesigned trigger#5323
TheodoreSpeaks merged 26 commits into
stagingfrom
improve/slack

Conversation

@TheodoreSpeaks

@TheodoreSpeaks TheodoreSpeaks commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Redesigned Slack trigger (slack_oauth): single event per trigger block with contextual filters (source/channels/threads/emoji/name), full event catalog, interaction events (block_actions/view_submission) with optional action/callback id filter
  • Reusable custom Slack bots as workspace service-account credentials: set up once via a guided wizard (manifest with full permissions by default, customizable dropdown), one shared ingest URL /api/webhooks/slack/custom/{credentialId} across triggers and actions
  • slack_v2 block: same operations as v1, adds credential-based Custom Bot auth alongside Sim OAuth; hosts the new trigger
  • Preview-gated: slack_v2 + the custom-bot setup surfaces ship behind the block-visibility flag (PREVIEW_BLOCKS=slack_v2 / AppConfig); v1 + legacy slack_webhook trigger stay the GA path until v2 GAs
  • Reconnect for service-account credentials (Slack/Atlassian/Google): rotates secrets in place, same credential id so shares and the Slack ingest URL survive
  • Centralized service-account token resolution (resolveServiceAccountToken) — unknown providers fail loudly instead of silently attempting a Google JWT
  • Shared Slack webhook fan-out dispatcher for the native and custom ingest routes, with skip-reason diagnostics

Type of Change

  • New feature

Testing

Tested manually end-to-end with a custom bot (create, trigger fan-out, assistant DMs, reconnect). bun run lint:check, bun run check:api-validation:strict, bun run check:migrations origin/staging, and the Slack/credential/visibility test suites (280+ tests) pass.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

TheodoreSpeaks and others added 4 commits June 30, 2026 19:59
Add assistant:write, app_mentions:read, and im:history to the Slack bot
OAuth scopes so the Set Assistant Status / Title / Suggested Prompts tools
(assistant.threads.*) work with users' existing Slack credentials — no new
app or credentials required. Restore the action_assistant trigger capability
(scope assistant:write) in the manifest generator.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WpeT8J5yVCrrNQB9Hzm9uS
@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 10, 2026 11:35pm

Request Review

@cursor

cursor Bot commented Jul 1, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Touches authentication (encrypted bot secrets, HMAC verification, OAuth token resolution), multi-tenant webhook routing by semi-public credential ids, and deploy-time team_id derivation—incorrect routing or workspace checks could cross tenants or drop events.

Overview
Introduces reusable custom Slack bot workspace credentials (slack-custom-bot): a wizard mints a stable credential id up front, verifies signing secret + bot token, and exposes one ingest URL /api/webhooks/slack/custom/{credentialId} for every trigger/action on that bot. Credential create/update paths share verifyAndBuildServiceAccountSecret; token issuance goes through resolveServiceAccountToken so Atlassian, Slack bots, and Google each dispatch explicitly and unknown providers error instead of falling through to Google JWT.

Adds slack_v2 (preview-gated like slack_v2 visibility): same Slack operations as v1 but Custom Bot picks a credential instead of pasting a raw token, and hosts the new slack_oauth trigger while v1 keeps legacy slack_webhook. Integrations UI gets Set up a custom bot, reconnect rotates secrets in place (preserving id and ingest URL), and the credential selector supports credentialKind: 'custom-bot'.

Slack trigger redesign (slack_oauth): single event type per trigger with filters (source, channels, threads, emoji, interactions, self/bot drops). Deploy maps Sim appslack_app + routingKey = Slack team_id (from auth.test on the credential owner’s token) and customslack + routingKey = bot credential id. New shared routes POST /api/webhooks/slack (official app, SLACK_SIGNING_SECRET) and POST /api/webhooks/slack/custom/[credentialId] fan out via findWebhooksByRoutingKey and dispatchSlackWebhooks with shared shouldSkipSlackTriggerEvent filtering. Slack channels API treats custom-bot credentials as bot tokens; credential deletion deactivates bound Slack webhooks.

Minor: webhook path may be null for routing-key triggers; credential PATCH returns providerErrorCode for Atlassian reconnect.

Reviewed by Cursor Bugbot for commit 58d2851. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread apps/sim/app/api/webhooks/slack/route.ts Outdated
@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds the redesigned Slack integration path and reusable custom bot credentials. The main changes are:

  • New slack_v2 preview block and redesigned Slack trigger.
  • Custom Slack bot credentials with shared ingest URLs.
  • Native and custom Slack webhook dispatch through shared routing logic.
  • Service-account reconnect and centralized token resolution.
  • Slack event filtering, channel matching, file handling, and credential-owner fixes.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
apps/sim/lib/webhooks/providers/slack.ts Updates Slack event filtering, channel extraction, and token-backed message/file formatting.
apps/sim/lib/webhooks/deploy.ts Updates Slack webhook creation and recreation around native team routing and custom bot credential routing.
apps/sim/app/api/webhooks/slack/route.ts Adds the native Slack app ingest route with team-based fan-out.
apps/sim/app/api/webhooks/slack/custom/[credentialId]/route.ts Adds credential-specific custom bot ingest with per-bot signature verification.
apps/sim/app/api/auth/oauth/utils.ts Centralizes service-account token resolution for Google, Atlassian, and custom Slack bot credentials.

Reviews (15): Last reviewed commit: "fix(slack): 409 on custom-bot name colli..." | Re-trigger Greptile

Comment thread apps/sim/app/api/webhooks/slack/route.ts Outdated
Comment thread apps/sim/lib/webhooks/deploy.ts
Comment thread apps/sim/triggers/slack/oauth.ts Outdated
# Conflicts:
#	apps/sim/blocks/blocks/slack.ts
#	apps/sim/lib/webhooks/deploy.ts
#	packages/db/migrations/meta/0253_snapshot.json
#	packages/db/migrations/meta/_journal.json
#	scripts/check-api-validation-contracts.ts
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile review

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile review — addressed the three findings: (1) unmapped/unselected events now drop instead of bypassing the Operations filter, (2) formatInput resolves the OAuth bot token for slack_app webhooks so reaction-message text works, (3) re-added the includeFiles toggle + token resolution so native file downloads work.

Comment thread apps/sim/app/api/webhooks/slack/route.ts Outdated
Comment thread apps/sim/lib/webhooks/providers/slack.ts Outdated
Comment thread apps/sim/app/api/webhooks/slack/route.ts Outdated
…token via credential owner not execution actor
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile review — addressed both: empty operation selection now fires nothing (no match-all), and the OAuth token is resolved via the credential owner (not the execution actor) so it works in shared workspaces.

Comment thread apps/sim/app/api/webhooks/slack/route.ts Outdated
Comment thread apps/sim/app/api/webhooks/slack/route.ts Outdated
Comment thread apps/sim/lib/webhooks/deploy.ts Outdated
Comment thread apps/sim/app/api/webhooks/slack/route.ts Outdated
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile review

Comment thread apps/sim/lib/webhooks/deploy.ts Outdated
Comment thread apps/sim/lib/webhooks/deploy.ts Outdated
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile review

A teammate deploying a trigger wired to a shared Slack credential isn't the
credential owner; refreshAccessTokenIfNeeded only loads tokens for the owning
user. Resolve the account owner first, mirroring the runtime formatInput path.
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile review

# Conflicts:
#	apps/sim/lib/webhooks/deploy.ts
#	packages/db/migrations/meta/0258_snapshot.json
#	packages/db/migrations/meta/_journal.json
- nullable webhook.path coalesced at correlation/payload/tiktok boundaries
- slack dispatch delegates to staging's dispatchResolvedWebhookTarget
  (shared preprocess/deployment/filter/enqueue lifecycle), keeping the
  skip-reason diagnostics; route tests reworked around that seam
- api-validation route baseline 924 -> 926
@TheodoreSpeaks TheodoreSpeaks changed the title feat(slack): native OAuth trigger, reusable custom bots, slack_v2 block feat(slack): reusable custom bot credentials, slack_v2 block (preview), redesigned trigger Jul 10, 2026
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile review

Comment thread apps/sim/lib/webhooks/deploy.ts
Comment thread apps/sim/lib/webhooks/deploy.ts
…oks on routing transitions

- a bot credential id is semi-public (embedded in Slack Request URLs), so the
  custom deploy branch now rejects credentials outside the workflow's workspace
- needsRecreation also compares path/routingKey, so a row from an older routing
  model can't survive redeploy as a stale delivery surface
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile review

Comment thread apps/sim/lib/webhooks/providers/slack.ts
Comment thread apps/sim/app/api/credentials/route.ts
…rning the existing credential

The service-account dedupe matches on displayName, which defaults to the Slack
team name — shared by every bot in that workspace. A second unnamed bot create
returned the first credential as success, orphaning the new id already pasted
into the Slack Request URL. Same-id replays stay idempotent; different-id
collisions now fail loudly so the wizard prompts for a distinct name.
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile review

Comment thread apps/sim/app/api/credentials/[id]/route.ts
…e/description edits

- PUT credential route now returns the Atlassian provider code (providerErrorCode
  -> code) so reconnect failures map to specific token/domain messages, matching create
- Google/Atlassian reconnect send + seed displayName/description (parity with Slack);
  edits are no longer silently discarded, and empty fields don't clobber existing values

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 470e3c5. Configure here.

Comment thread apps/sim/lib/credentials/service-account-secret.ts
Comment thread apps/sim/lib/webhooks/providers/slack.ts
…ks on reconnect

- the setup wizard now requires a bot name (canAdvance), so the credential name,
  manifest app name, and uniqueness key all use the user's choice instead of the
  shared Slack team-name fallback that collided for a second bot in one workspace
- reconnect that changes the bot user id (recreated Slack app) now updates the
  bot_user_id cached in each bound webhook's providerConfig, so reaction
  self-drop keeps working instead of letting the bot's own reactions re-enter
@TheodoreSpeaks TheodoreSpeaks merged commit f4d47ed into staging Jul 10, 2026
17 checks passed
@TheodoreSpeaks TheodoreSpeaks deleted the improve/slack branch July 10, 2026 23:43
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.

1 participant