feat(nodes): add Slack Events source node#1591
Conversation
Add slack, an ingress source node that authenticates Slack Events API callbacks and routes approved message and reaction events into RocketRide pipelines. It follows the existing source endpoint and response-lane patterns. - Verify request signatures and timestamp freshness before parsing - Route message text and reaction JSON with bounded queueing and deduplication - Add documentation, a native Slack icon, an example pipeline, and focused tests Tests: 61 Slack tests and 304 contract tests passed; live Cursor canvas verification delivered a Slack message and reaction without errors.
🤖 Internal: Discord sync markerAuto-managed by the Discord notification workflow. Stores the linked Discord message ID and forum thread ID. Do not edit or delete. |
📝 WalkthroughWalkthroughAdds a Slack Events source node that verifies callbacks, classifies supported events, deduplicates and queues deliveries, emits text or JSON lanes, manages signing-secret lifecycle, and includes configuration, tests, documentation, and an example pipeline. ChangesSlack Events source
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Slack
participant IEndpoint
participant Queue
participant PipeTarget
Slack->>IEndpoint: POST /slack/events
IEndpoint->>IEndpoint: Verify signature and classify event
IEndpoint->>Queue: Enqueue routed event
Queue->>IEndpoint: Consume event
IEndpoint->>PipeTarget: Write text or JSON entry
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@examples/slack-events.pipe`:
- Around line 10-12: Remove the extraneous google property from the slack node
configuration, leaving only the supported dedupTtlSeconds, queueCapacity, and
signingSecret parameters.
In `@nodes/src/nodes/slack/IEndpoint.py`:
- Around line 48-55: Add PEP 257-compliant docstrings to the IEndpoint class and
its lifecycle/entry-point methods _startup, _shutdown, _run, and scanObjects,
describing each symbol’s purpose and behavior while preserving the existing
implementation.
- Around line 48-176: Add concise PEP 257 docstrings to the IEndpoint class and
its lifecycle entry points, including _startup, _shutdown, _run, and
scanObjects, while preserving behavior. Also document the IGlobal class and its
lifecycle methods in nodes/src/nodes/slack/IGlobal.py lines 29-46; both files
require documentation-only changes.
- Line 121: Update the delivery flow around _consumer_task and _emit_event so
in-flight asyncio.to_thread work remains tracked and is awaited before
_shutdown() tears down the pipe, even when the 5-second drain timeout cancels
the consumer task. Alternatively, make _emit_event pipe writes cooperatively
stoppable before teardown, while preserving shutdown completion semantics. Add a
regression test covering a blocked _emit_event that outlives the drain timeout.
- Around line 56-60: Update _request_handler to avoid calling request.body()
before enforcing a Slack payload size limit. Read the request stream
incrementally with a hard byte cap, stop buffering when the limit is exceeded,
and return HTTP 413; otherwise assemble the bounded raw body and continue the
existing verify_slack_signature flow.
In `@nodes/src/nodes/slack/requirements.txt`:
- Line 1: Update the fastapi dependency declaration in requirements.txt to
require the safe minimum version >=0.111.0, preventing resolution of vulnerable
older Starlette versions while preserving the existing dependency.
In `@nodes/src/nodes/slack/slack_events.py`:
- Around line 105-127: Update classify_event to validate inner_type and the
message channel_type as strings before hash-based operations. Guard the
inner_type membership checks against non-string values, and only call
_MESSAGE_TYPES.get when inner.get('channel_type') is a string; otherwise reject
or leave the event unrouted without raising TypeError.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 5bccfd60-cd2f-432a-b9b5-aaa20a44c4c0
⛔ Files ignored due to path filters (1)
nodes/src/nodes/slack/slack-events.svgis excluded by!**/*.svg
📒 Files selected for processing (14)
examples/slack-events.pipenodes/src/nodes/slack/IEndpoint.pynodes/src/nodes/slack/IGlobal.pynodes/src/nodes/slack/IInstance.pynodes/src/nodes/slack/README.mdnodes/src/nodes/slack/__init__.pynodes/src/nodes/slack/requirements.txtnodes/src/nodes/slack/services.jsonnodes/src/nodes/slack/slack_events.pynodes/test/slack/__init__.pynodes/test/slack/test_endpoint.pynodes/test/slack/test_queue_dedup.pynodes/test/slack/test_routing.pynodes/test/slack/test_signature.py
Bound public callback bodies, reject malformed hash keys, document node lifecycle symbols, and keep in-flight pipe delivery tracked through shutdown. Clean the example configuration and add regression coverage for request limits and shutdown races. Tests: 67 Slack tests and 304 node contract tests passed; ruff, formatting, and gitleaks passed.
Summary
slack, a source node that receives authenticated Slack Events API callbacks at/slack/events.textlane.reaction_addedevents to thejsonlane while retaining the complete Slack envelope as native entry metadata.Type
feature (new pipeline source node) + docs + tests
What changed
app_mention→textmessage.channels→textmessage.groups→textmessage.im→textreaction_added→json503responses when intake is saturated, allowing Slack to retry.examples/slack-events.pipe, connecting text and JSON outputs to response nodes.Why this feature fits this codebase
The implementation follows RocketRide's existing source-node endpoint lifecycle and response-lane patterns. It is node-local and additive: no shared package or engine changes are included in this PR.
The JSON output uses the engine's existing JSON-lane support from #1297.
Security and delivery behavior
401.400.503, allowing Slack to retry.SLACK_SIGNING_SECRET.Queueing and deduplication are intentionally process-local and non-durable. Accepted events can be lost after abrupt process termination, and restarting the process clears deduplication state.
Testing
textlane and a real reaction through thejsonlane with no canvas errors or warnings../builder nodes:docs-generaterefreshed generated docs — invoked throughnodes:build, but skipped because the workspace was on a detached HEAD../builder nodes:testpasses — the Slack suite passes, but the final unfiltered repository run reported unrelated provider-dependent failures outside this node../builder nodes:test-fullpasses — reported unrelated Gretel anonymization failures; no Slack tests failed../builder nodes:test-contractspasses — 304 passed.Checklist
Release note
Slack reaction events require the JSON-lane engine support merged in #1297. That support is present on
developbut was added after the currentserver-v3.3.0public release. Public availability therefore requires the next server release containing #1297.Linked Issue
Closes #1590
Summary by CodeRabbit
/slack/eventswebhook intake.