Skip to content

feat(slack): add Send and Wait for Response component#3093

Open
nenadilic84 wants to merge 11 commits intosuperplanehq:mainfrom
nenadilic84:feat/slack-send-and-wait
Open

feat(slack): add Send and Wait for Response component#3093
nenadilic84 wants to merge 11 commits intosuperplanehq:mainfrom
nenadilic84:feat/slack-send-and-wait

Conversation

@nenadilic84
Copy link

Summary

  • Implements the Slack "Send and Wait for Response" component (slack.sendAndWait) that sends a message with configurable buttons to a Slack channel and pauses the workflow until a user clicks a button or an optional timeout expires
  • Implements handleInteractivity() in the Slack integration to route button click payloads from Slack to subscribed components via the existing subscription mechanism
  • Adds chat.update client method for updating messages after interaction (showing which button was clicked, or indicating timeout)
  • Includes full frontend mapper with custom state handling (waiting, received, timed_out)

Architecture

The component follows the established async execution pattern (similar to the Approval component):

  1. Execute() sends a Block Kit message with buttons via chat.postMessage, stores the message timestamp as a KV for correlation, optionally schedules a timeout action, and returns nil without emitting — leaving the execution in a waiting state
  2. handleInteractivity() (new) parses Slack's form-urlencoded interaction payload, lists subscriptions matching interactivityTypes, and routes the payload via SendMessage()
  3. OnIntegrationMessage() receives the interaction and emits it as an event for the node's queue
  4. ProcessQueueItem() finds the waiting execution via FindExecutionByKV("message_ts", ...) and completes it by emitting on the received channel
  5. HandleAction("timeout") completes the execution on the timeout channel if no response arrives in time

Configuration

Field Type Required Description
Channel integration-resource Yes Slack channel or DM
Message text Yes Message text (supports Slack markdown)
Timeout number No Max seconds to wait
Buttons list (1-4 items) Yes Each with name (label) and value

Output Channels

  • Received: Emitted when a user clicks a button; payload includes value and user info
  • Timeout: Emitted when no button click within the configured timeout

Files Changed

New files:

  • pkg/integrations/slack/send_and_wait.go — Core component implementation
  • pkg/integrations/slack/send_and_wait_test.go — Tests for setup, execute, actions, queue processing, and helpers
  • pkg/integrations/slack/example_output_send_and_wait.json — Example output
  • web_src/src/pages/workflowv2/mappers/slack/send_and_wait.ts — Frontend mapper

Modified files:

  • pkg/integrations/slack/slack.go — Register component, implement handleInteractivity(), extend SubscriptionConfiguration
  • pkg/integrations/slack/client.go — Add UpdateMessage method
  • pkg/integrations/slack/example.go — Add ExampleOutput() for SendAndWait
  • web_src/src/pages/workflowv2/mappers/slack/index.ts — Register mapper and state registry

Test plan

  • Unit tests pass for Setup validation (missing channel, message, buttons, too many buttons)
  • Unit tests pass for Execute (sends Block Kit message, stores KV, schedules timeout)
  • Unit tests pass for ProcessQueueItem (routes interactions to waiting executions)
  • Unit tests pass for HandleAction timeout (emits on timeout channel)
  • Unit tests pass for OnIntegrationMessage (filters non-superplane interactions)
  • Unit tests pass for helper functions (extractMessageTS, extractButtonValue, etc.)
  • Integration test: send message with buttons, click button, verify workflow continues
  • Integration test: send message with timeout, let it expire, verify timeout channel

Closes #2338

@nenadilic84 nenadilic84 force-pushed the feat/slack-send-and-wait branch from e23d895 to aedb2ab Compare February 13, 2026 11:57
@nenadilic84 nenadilic84 force-pushed the feat/slack-send-and-wait branch 2 times, most recently from 92c94c4 to a3615fe Compare February 13, 2026 12:16
@nenadilic84
Copy link
Author

Demo video coming shortly — recording the end-to-end flow (integration setup + sending a message with buttons and receiving a user response).

@nenadilic84 nenadilic84 force-pushed the feat/slack-send-and-wait branch from 6c8f5f7 to e1051f4 Compare February 13, 2026 15:07
@nenadilic84 nenadilic84 force-pushed the feat/slack-send-and-wait branch from 1a34853 to 77d94f4 Compare February 14, 2026 07:13
Copy link

@cursor cursor bot left a comment

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 and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

ropsii and others added 10 commits February 14, 2026 12:40
Signed-off-by: Nenad Ilic <nenadilic84@gmail.com>
…uperplanehq#3111)

Signed-off-by: Lucas Pinheiro <lucas@superplane.com>
Signed-off-by: Nenad Ilic <nenadilic84@gmail.com>
Implement the Slack "Send and Wait for Response" component that sends
a message with configurable buttons to a channel and pauses the
workflow until a user clicks a button or the timeout expires.

Key changes:
- New SendAndWait component implementing IntegrationComponent interface
- Implement handleInteractivity() to route Slack block_actions to
  subscribed components via the subscription mechanism
- Add chat.update client method for updating messages after interaction
- Frontend mapper with custom state handling (waiting/received/timed_out)
- Comprehensive test coverage for setup, execute, actions, and
  queue processing

Closes superplanehq#2338

Signed-off-by: Nenad Ilic <nenadilic84@gmail.com>
- Propagate FindExecutionByKV errors instead of silently dequeuing,
  allowing the framework to retry on transient failures
- Fix float-to-Duration conversion to preserve fractional seconds

Signed-off-by: Nenad Ilic <nenadilic84@gmail.com>
Signed-off-by: Nenad Ilic <nenadilic84@gmail.com>
Replace shorthand {color, label} with full EventStateStyle interface
properties (icon, textColor, backgroundColor, badgeColor, label) for
the waiting and timed_out states in the sendAndWait event state map.

Signed-off-by: Nenad Ilic <nenadilic84@gmail.com>
Signed-off-by: Nenad Ilic <nenadilic84@gmail.com>
- Replace manual prefix check with magic number in isSuperplaneInteraction
  with strings.HasPrefix for clarity and safety
- Add "Received" label to the received state entry in sendAndWait event
  state map to fix display inconsistency with other labeled states

Signed-off-by: Nenad Ilic <nenadilic84@gmail.com>
Reorder the getState function to check for framework-level states
(error, cancellation) before metadata-driven states (waiting,
timed_out, received). This prevents cancelled or errored executions
from incorrectly displaying as "Waiting" in the UI when the Cancel
method doesn't update metadata.

Follows the same pattern used by the Approval component's
approvalStateFunction.

Signed-off-by: Nenad Ilic <nenadilic84@gmail.com>
Extract identical sendAndWaitEventSections and sendTextMessageEventSections
into a shared slackEventSections helper in base.ts. Both functions had
byte-for-byte identical logic for building event sections, creating a
maintenance risk if one copy were updated without the other.

Signed-off-by: Nenad Ilic <nenadilic84@gmail.com>
@nenadilic84 nenadilic84 force-pushed the feat/slack-send-and-wait branch from abb8963 to 51e05af Compare February 14, 2026 12:40
The deduplication of slackEventSections into base.ts and the
corresponding update to send_text_message.ts introduced formatting
that did not match Prettier's style. This fixes the CI format check
failure.

Signed-off-by: Nenad Ilic <nenadilic84@users.noreply.github.com>
Signed-off-by: Nenad Ilic <nenadilic84@gmail.com>
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.

[Slack] Send and Wait for Response

3 participants