improvement(slack): request the approved mention/assistant/DM scopes, advertised on v2 only (#5898)

Slack app review has since approved `app_mentions:read`, `assistant:write`, and
`im:history` — they are live in the prod app manifest's `oauth_config.scopes.bot`
— but the repo still had them commented out behind a stale "re-add once approved"
TODO. Sim was therefore requesting a narrower grant than the app is entitled to,
so newly connected accounts got tokens missing exactly the scopes backing three
`simSubscribed` events on the native Sim app trigger: `app_mention`
(app_mentions:read), assistant threads (assistant:write), and DMs (im:history).

The requested scope set now matches the manifest's 20 approved bot scopes exactly.

Scopes are per-credential, not per-block (one Slack app -> one `slack` provider ->
one shared token, requested server-side via getCanonicalScopesForProvider), so the
grant itself cannot be scoped to v2. What is per-block is what each picker
advertises and treats as missing, so:

- slack_v2 + the slack_oauth trigger advertise the full set (they host the native
  Sim app trigger that needs it).
- The legacy v1 block stays pinned to the pre-expansion 17 scopes. It has no
  feature needing the new three, and advertising them there would flag every
  existing Slack credential as missing scopes and prompt a needless reconnect.


Claude-Session: https://claude.ai/code/session_018asmKsWQ5Vi7T7wD9uHofz

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Theodore Li
2026-07-23 16:44:37 -04:00
committed by GitHub
co-authored by Claude Opus 4.8
parent bc237a0dcc
commit 84e7aad633
2 changed files with 26 additions and 7 deletions
+23 -1
View File
@@ -7,6 +7,25 @@ import { normalizeFileInput } from '@/blocks/utils'
import type { SlackResponse } from '@/tools/slack/types'
import { getTrigger } from '@/triggers'
/**
* Scopes added for the native Sim Slack app trigger (`slack_oauth`): the shared
* app's `app_mention`, assistant-thread, and DM events don't deliver without
* them. Advertised by `slack_v2` and the trigger only — the legacy block has no
* feature that needs them, and listing them there would flag every existing
* Slack credential as missing scopes and prompt a reconnect.
*
* This only controls what each picker *advertises* and treats as missing. The
* authorization request itself is provider-wide
* (`getCanonicalScopesForProvider('slack')`), so any reconnect grants the full
* set regardless of which block started it.
*/
const SLACK_V2_ONLY_SCOPES = new Set(['app_mentions:read', 'assistant:write', 'im:history'])
/** Slack scopes the legacy v1 block advertises — the set from before the trigger expansion. */
const SLACK_V1_ADVERTISED_SCOPES = getScopesForService('slack').filter(
(scope) => !SLACK_V2_ONLY_SCOPES.has(scope)
)
export const SlackBlock: BlockConfig<SlackResponse> = {
type: 'slack',
name: 'Slack',
@@ -107,7 +126,7 @@ export const SlackBlock: BlockConfig<SlackResponse> = {
canonicalParamId: 'oauthCredential',
mode: 'basic',
serviceId: 'slack',
requiredScopes: getScopesForService('slack'),
requiredScopes: SLACK_V1_ADVERTISED_SCOPES,
placeholder: 'Select Slack workspace',
dependsOn: ['authMethod'],
condition: {
@@ -2642,6 +2661,9 @@ function adaptSubBlockForV2(sb: SubBlockConfig): SubBlockConfig {
...rest,
credentialKind: 'any',
placeholder: 'Select Slack account or bot',
// Full set, unlike v1: v2 hosts the native Sim app trigger, whose events
// need the mention/assistant/DM scopes.
requiredScopes: getScopesForService('slack'),
credentialLabels: {
oauthGroup: 'Sim app',
oauthConnect: 'Connect the Sim app',
+3 -6
View File
@@ -782,12 +782,9 @@ export const OAUTH_PROVIDERS: Record<string, OAuthProviderConfig> = {
'groups:write',
'chat:write',
'chat:write.public',
// TODO: Re-add once Slack app review approves these. Requesting a scope
// the app is not yet approved for makes Slack reject the entire
// authorization with "unapproved permissions requested", breaking connect.
// 'assistant:write',
// 'app_mentions:read',
// 'im:history',
'assistant:write',
'app_mentions:read',
'im:history',
'im:write',
'im:read',
'users:read',