Skip to content

fix: strip Slack approval buttons immediately on click#51

Merged
yourbuddyconner merged 1 commit into
yourbuddyconner:mainfrom
tkhq:fix/slack-approval-button-lag
May 9, 2026
Merged

fix: strip Slack approval buttons immediately on click#51
yourbuddyconner merged 1 commit into
yourbuddyconner:mainfrom
tkhq:fix/slack-approval-button-lag

Conversation

@figitaki
Copy link
Copy Markdown
Collaborator

@figitaki figitaki commented May 8, 2026

Summary

  • Slack interactive prompts kept their Approve/Deny buttons clickable for the entire duration of the underlying tool execution. The handler returned 200 within Slack's 3-second deadline (packages/worker/src/routes/slack-events.ts:659), which dropped Slack's spinner, but the message wasn't actually updated until the DO finished executeActionAndSend (session-agent.ts:5836) and only then called chat.update. On slow actions that gap was many seconds, during which users could re-click Approve.
  • Fix: before scheduling the DO call, POST to the payload's response_url with replace_original: true and the original blocks minus the actions block, plus a "⏳ Processing…" context line. The DO's existing final-state chat.update still runs at the end and overwrites with "✅ Approved by …" / "❌ Denied by …".
  • Slack-only change. No ChannelTransport interface change. Wrapped in try/catch — if response_url fails the old behavior is preserved.

Test plan

  • pnpm typecheck passes (verified locally)
  • Deploy to dev: ENVIRONMENT=dev make deploy-worker
  • Trigger an approval-gated action in Slack, click Approve — buttons should disappear within ~500ms and be replaced by "⏳ Processing…", then by "✅ Approved by …" once the action completes
  • Repeat with Deny — same intermediate state, then "❌ Denied by …"
  • Try a slow approval (real third-party API call) and confirm buttons stay gone for the entire processing window
  • Check make logs-cloudflare for [Slack Interactive] response_url update failed warnings — should be zero

The interactive handler returned 200 to Slack right away (to meet the
3-second ack deadline) and only updated the message via chat.update
after the DO finished executing the approved action. For slow tool
calls that gap was many seconds, during which Slack dropped its
spinner but the buttons stayed enabled — letting users re-click
Approve/Deny while processing was already underway.

Now we POST to the payload's response_url before scheduling the DO
call to replace the actions block with a "⏳ Processing…" context.
The DO's existing final-state chat.update still runs at the end and
overwrites with "✅ Approved by …" / "❌ Denied by …".
@figitaki figitaki requested a review from yourbuddyconner May 8, 2026 23:06
@figitaki
Copy link
Copy Markdown
Collaborator Author

figitaki commented May 8, 2026

We really need zod and/or the slack sdk. Too many unsafe casts throughout the codebase.

@yourbuddyconner yourbuddyconner merged commit e9c85af into yourbuddyconner:main May 9, 2026
1 check passed
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