Add follow-up question support to Slack request action#2399
Open
ravikiranvm wants to merge 2 commits into
Open
Add follow-up question support to Slack request action#2399ravikiranvm wants to merge 2 commits into
ravikiranvm wants to merge 2 commits into
Conversation
Extends the follow-up question capability shipped for Teams (#2398) to the Slack Request Action block. Buttons with a follow-up question become link buttons opening the collect_input.html page in both interaction modes; the interactions endpoint skips resuming for those clicks so the browser form owns the resume, and the answer surfaces in the step output as parameters.answer. The shared buildWrapperUrl helper moves from the Teams block to @openops/common so both blocks use one implementation. Button texts are stored emoji-normalized in followUpActions and the actionClicked resume param, fixing a latent emoji-button resume mismatch in non-interaction mode. Part of OPS-4626. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends the “follow-up question” flow (previously added for Teams) to the Slack Request Action block. It adds optional per-button follow-up question metadata, routes follow-up clicks through the browser-based collect_input.html form in both Slack interaction modes, and exposes typed answers back to workflows as parameters.answer (plus any other non-routing resume query params).
Changes:
- Add follow-up question / answer format / no-answer option support to Slack request-action buttons, using
collect_input.htmlto gather input before resuming. - Prevent
/v1/slack/interactionsfrom resuming executions for follow-up button clicks by checking message metadata (followUpActions) via a small helper with unit + integration tests. - Move
buildWrapperUrlinto@openops/commonfor shared Slack/Teams behavior and update imports/exports/tests accordingly.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| packages/server/api/test/unit/slack/is-follow-up-action.test.ts | Unit tests for follow-up action detection helper. |
| packages/server/api/test/integration/cloud/slack-integration/slack-interaction.test.ts | Integration coverage ensuring follow-up clicks do not trigger resume, while normal clicks still do. |
| packages/server/api/src/app/slack/slack-interaction-module.ts | Skips resume when the interaction corresponds to a follow-up action. |
| packages/server/api/src/app/slack/is-follow-up-action.ts | New pure helper to decide whether an interaction is a follow-up action. |
| packages/openops/test/build-wrapper-url.test.ts | Updates tests to the new buildWrapperUrl module location. |
| packages/openops/src/lib/build-wrapper-url.ts | New shared wrapper URL builder supporting both resume and collect-input pages. |
| packages/openops/src/index.ts | Exposes buildWrapperUrl from @openops/common. |
| packages/blocks/slack/test/wait-for-interaction.test.ts | Updates expectations and adds tests for surfacing extra resume params as parameters (incl. pollution-key exclusions). |
| packages/blocks/slack/test/wait-for-action.test.ts | Updates action result expectations to include parameters. |
| packages/blocks/slack/test/request-action-message.test.ts | Adds coverage for follow-up buttons, wrapper URLs, followUpActions metadata, and emoji normalization. |
| packages/blocks/slack/src/lib/common/wait-for-interaction.ts | Adds parameters to output, derived from resume query params excluding routing/pollution keys. |
| packages/blocks/slack/src/lib/common/props.ts | Adds new optional follow-up-related button properties to Slack Request Action UI. |
| packages/blocks/slack/src/lib/actions/request-action-message.ts | Generates follow-up wrapper URLs, stores normalized followUpActions, and normalizes button text for resume matching. |
| packages/blocks/microsoft-teams/src/lib/actions/request-action-message.ts | Switches to importing shared buildWrapperUrl from @openops/common. |
|
MarceloRGonc
approved these changes
Jul 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Part of OPS-4626
Extends the follow-up question capability shipped for Teams in #2398 to the Slack Request Action block: any action button can ask the person a question in the browser before the workflow resumes, and the workflow receives the typed answer.
What's new
parameters.answer(all non-routing resume query params are exposed underparameters, mirroring the Teams block)buildWrapperUrlmoves from the Teams block to@openops/commonso both blocks share one implementation (the Teams block now imports it from there; behavior unchanged)The Slack-specific part
Slack runs in two modes, and the browser form works in both:
SLACK_ENABLE_INTERACTIONS=false): buttons are already link buttons — a follow-up button openscollect_input.htmlinstead ofresume_execution.html.urlso Slack opens the form — but Slack still sends an interaction payload for link buttons, so the message metadata now carriesfollowUpActions(the follow-up button texts) and/v1/slack/interactionsskips resuming for those clicks, letting the browser form own the resume. The check lives in a small pure helper (is-follow-up-action.ts) with its own unit tests, plus endpoint-level integration tests asserting the resume webhook is not fired for follow-up clicks and still fires for normal ones.Slack modals (
views.open) were considered and deliberately not used: they require a bot token +trigger_idwithin 3 seconds, while the interactions endpoint is a credential-free relay (signature check +response_urlonly), and non-interaction mode would still need the browser form anyway. One codepath covers both modes.Emoji normalization fix
Slack interaction payloads return button text in emoji-shortcode form (
🎲arrives as:game_die:), which is why message matching already normalizes vianormalizeEmojiString. Button texts are now stored normalized infollowUpActionsand in theactionClickedresume param baked into link-button URLs — the latter fixes a latent bug where a unicode-emoji button in non-interaction mode never matched on resume and the flow hung until timeout.Safety
followUpActionsmetadata and behave exactly as before (covered by tests)parametersTesting Checklist
Unit/integration: blocks-slack 99 tests, blocks-microsoft-teams 57, openops-common 460, server-api slack unit 19 — all passing; lint clean on all four projects.