Skip to content

Commit e81631b

Browse files
committed
fix(slack): skip block_suggestion payloads instead of wastefully executing workflows
block_suggestion (external select option loading) requires Slack to receive a synchronous JSON options response within 3 seconds, which this trigger's async fire-and-forget webhook execution model can never provide. It was previously routed through the generic interactivity handler like block_actions/shortcut/view_submission, meaning every keystroke in an external-select typeahead would silently trigger a full (useless) workflow execution. Now explicitly skipped via the existing skip mechanism.
1 parent 70522b0 commit e81631b

2 files changed

Lines changed: 34 additions & 2 deletions

File tree

apps/sim/lib/webhooks/providers/slack.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,23 @@ describe('slackHandler formatInput - interactivity (block_actions)', () => {
157157
})
158158
})
159159

160+
describe('slackHandler formatInput - block_suggestion', () => {
161+
it('skips execution instead of triggering the workflow', async () => {
162+
const { input, skip } = await slackHandler.formatInput!(
163+
ctx({
164+
type: 'block_suggestion',
165+
action_id: 'external_select',
166+
block_id: 'b1',
167+
value: 'sea',
168+
team: { id: 'T1' },
169+
user: { id: 'U1' },
170+
})
171+
)
172+
expect(input).toBeNull()
173+
expect(skip?.message).toBeTruthy()
174+
})
175+
})
176+
160177
describe('slackHandler formatInput - slash commands', () => {
161178
it('maps flat slash-command form fields', async () => {
162179
const { input } = await slackHandler.formatInput!(

apps/sim/lib/webhooks/providers/slack.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ import type {
1717

1818
const logger = createLogger('WebhookProvider:Slack')
1919

20-
const SLACK_MAX_FILE_SIZE = 50 * 1024 * 1024 // 50 MB
20+
/** 50 MB */
21+
const SLACK_MAX_FILE_SIZE = 50 * 1024 * 1024
2122
const SLACK_MAX_FILES = 15
2223

2324
const SLACK_REACTION_EVENTS = new Set(['reaction_added', 'reaction_removed'])
@@ -27,6 +28,11 @@ const SLACK_REACTION_EVENTS = new Set(['reaction_added', 'reaction_removed'])
2728
* `payload` field (button clicks, selects, shortcuts, modal submits). These have
2829
* no Events-API `event` envelope, so they need their own mapping.
2930
* See https://api.slack.com/interactivity/handling#payloads
31+
*
32+
* `block_suggestion` (external select option loading) is deliberately excluded:
33+
* Slack requires a synchronous JSON `options` response within 3 seconds, which
34+
* this trigger's fire-and-forget webhook execution model cannot provide — it is
35+
* skipped explicitly in `formatInput` instead of being routed here.
3036
*/
3137
const SLACK_INTERACTIVE_TYPES = new Set([
3238
'block_actions',
@@ -35,7 +41,6 @@ const SLACK_INTERACTIVE_TYPES = new Set([
3541
'shortcut',
3642
'view_submission',
3743
'view_closed',
38-
'block_suggestion',
3944
])
4045

4146
interface SlackDownloadedFile {
@@ -547,6 +552,16 @@ export const slackHandler: WebhookProviderHandler = {
547552
return { input: { event: formatSlackSlashCommand(b) } }
548553
}
549554

555+
if (b?.type === 'block_suggestion') {
556+
return {
557+
input: null,
558+
skip: {
559+
message:
560+
'Slack block_suggestion payloads require a synchronous options response and cannot be served by an async workflow trigger',
561+
},
562+
}
563+
}
564+
550565
if (
551566
!b?.event &&
552567
((typeof b?.type === 'string' && SLACK_INTERACTIVE_TYPES.has(b.type)) ||

0 commit comments

Comments
 (0)