Skip to content

feat(slack): add relay mode for incoming messages#94707

Merged
pashpashpash merged 7 commits into
mainfrom
codex/slack-relay-send-identity
Jun 21, 2026
Merged

feat(slack): add relay mode for incoming messages#94707
pashpashpash merged 7 commits into
mainfrom
codex/slack-relay-send-identity

Conversation

@sjf-oa

@sjf-oa sjf-oa commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

OpenClaw gateways currently need to own Slack Socket Mode connections directly. That makes it difficult for an external openclaw-slack-router to maintain the Slack connection and route user-group mentions to the appropriate gateway.

This change adds a Slack relay connection mode so a gateway can receive routed Slack events over a websocket while continuing to use Slack’s Web API for outbound messages.

Why This Change Was Made

Relay mode authenticates with a bearer token and gatewayId, reconnects using the existing Slack backoff policy, serializes inbound frame handling, reports connection health, and dispatches events through the normal Slack message handler. Relay events are treated as authorized mentions because the router has already selected the target gateway, and OpenClaw acknowledges each valid routed Slack message delivery after message handling completes.

The router can provide username, icon_url, or icon_emoji in its websocket hello frame. OpenClaw stores that identity per Slack account and uses it for outbound chat.postMessage calls unless the caller supplies an explicit identity. The stored identity is cleared when the relay disconnects or the provider stops.

Relay mode adds these settings at the top level or per account:

  • mode: "relay"
  • relay.url
  • relay.authToken (including SecretInput resolution and secret-audit support)
  • relay.gatewayId

Relay accounts still require a bot token for outbound Slack API calls, but do not require a Slack app token or HTTP signing secret. Existing Socket Mode and HTTP behavior remains unchanged.

User Impact

Operators can run Slack connectivity through a central router and route user-group mentions to the correct OpenClaw gateway without changing the existing Slack processing, persona, or outbound delivery path.

The change also exposes the new mode through Slack account inspection, setup metadata, configuration schemas, UI hints, and generated channel metadata.

Evidence

@openclaw-barnacle openclaw-barnacle Bot added channel: slack Channel integration: slack scripts Repository scripts size: L maintainer Maintainer-authored PR labels Jun 18, 2026
@clawsweeper

clawsweeper Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 21, 2026, 9:46 AM ET / 13:46 UTC.

Summary
The PR adds Slack mode: "relay" with reverse WebSocket ingress, relay auth and gateway config, relay-provided outbound identity, schema/docs/SecretRef metadata, tests, generated metadata, and a Slack plugin-local ws dependency.

PR surface: Source +778, Tests +375, Docs +48, Config +1, Generated 0, Other +3. Total +1205 across 34 files.

Reproducibility: not applicable. this is a feature PR, not a current-main bug report; the supplied proof demonstrates after-fix relay behavior rather than a failing reproduction path.

Review metrics: 2 noteworthy metrics.

  • Slack relay config surface: 1 mode added, 3 relay fields added, 2 SecretRef targets added. These become operator-facing setup, validation, secret-audit, and upgrade contracts before merge.
  • Dependency graph surface: 1 runtime dependency added, 2 lock/shrinkwrap artifacts changed. The Slack plugin supply-chain surface changes and the dependency guard requires maintainer or security approval.

Stored data model
Persistent data-model change detected: unknown-data-model-change: src/config/bundled-channel-config-metadata.generated.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Obtain maintainer/security approval for the relay trust boundary and current-head ws dependency graph change.
  • Clear or approve the failing dependency guard for the exact current head.

Mantis proof suggestion
A native Slack smoke would add maintainer-visible proof for routed relay delivery, thread affinity, ACK behavior, and custom identity in the real transport. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis slack desktop smoke: verify Slack relay routed messages reply in-thread and preserve relay identity on the latest head.

Risk before merge

  • [P1] The relay router becomes part of Slack authorization because routed frames enter OpenClaw as authorized Slack activations.
  • [P1] The PR adds a new operator-facing Slack mode, three relay config fields, and two relay SecretRef targets that need setup, validation, docs, and upgrade ownership.
  • [P1] The new Slack plugin-local ws runtime dependency changes package and lock/shrinkwrap surfaces, and the dependency guard is failing until authorized approval or dependency removal happens for the current head.
  • [P1] Relay ACK and routing semantics create a new OpenClaw-to-router delivery contract where maintainers need to own message loss, duplication, and retry behavior before landing.

Maintainer options:

  1. Require current-head security and dependency sign-off (recommended)
    Keep the branch open until an authorized maintainer or security reviewer approves the relay trust boundary and exact ws dependency graph change for the current head.
  2. Sponsor relay as a managed Slack deployment mode
    Maintainers can intentionally accept the new mode after owning the operator docs, route-table trust model, dependency addition, and upgrade implications.
  3. Consolidate with trusted-upstream work
    Pause or close this branch if maintainers prefer to fold reverse WebSocket relay into the broader trusted Slack ingress proposal instead of shipping a separate mode.

Next step before merge

  • [P2] Protected-label, dependency-approval, security-boundary, and product-direction decisions make this human-review only; no narrow ClawSweeper repair remains after the latest ACK and identity fixes.

Security
Needs attention: The diff introduces a new Slack ingress trust boundary and dependency graph change that need maintainer/security approval before merge.

Review details

Best possible solution:

Have maintainers/security explicitly sponsor the relay trust boundary and dependency graph change, then either land this Slack-plugin implementation with green current-head checks or consolidate it with the trusted-upstream direction if one trusted Slack ingress primitive is preferred.

Do we have a high-confidence way to reproduce the issue?

Not applicable: this is a feature PR, not a current-main bug report; the supplied proof demonstrates after-fix relay behavior rather than a failing reproduction path.

Is this the best way to solve the issue?

Unclear until maintainer/security decision: the Slack plugin boundary is plausible and the current head addresses ACK and identity handling, but maintainers must decide whether relay should ship separately or be consolidated with trusted-upstream work.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 11a2e03bd4de.

Label changes

Label changes:

  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • remove rating: 🦐 gold shrimp: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.

Label justifications:

  • P2: This is a bounded Slack channel feature with compatibility and security-boundary merge risk, not a current production outage.
  • merge-risk: 🚨 compatibility: The PR adds a new Slack mode, relay config fields, SecretRef targets, setup metadata, docs, and a dependency graph change.
  • merge-risk: 🚨 message-delivery: The relay path changes acknowledgement timing and creates a router-visible delivery contract for inbound Slack messages.
  • merge-risk: 🚨 security-boundary: Relay frames are bearer-authenticated by an external router and then enter OpenClaw as authorized Slack activations.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (live_output): Live Slack proof shows routed relay delivery, relay identity, correlated ACKs, reconnect behavior, and zero pending deliveries in the router snapshot; latest ACK timing is additionally covered by focused tests.
  • proof: sufficient: Contributor real behavior proof is sufficient. Live Slack proof shows routed relay delivery, relay identity, correlated ACKs, reconnect behavior, and zero pending deliveries in the router snapshot; latest ACK timing is additionally covered by focused tests.
Evidence reviewed

PR surface:

Source +778, Tests +375, Docs +48, Config +1, Generated 0, Other +3. Total +1205 across 34 files.

View PR surface stats
Area Files Added Removed Net
Source 21 909 131 +778
Tests 6 383 8 +375
Docs 3 52 4 +48
Config 1 1 0 +1
Generated 1 8 8 0
Other 2 6 3 +3
Total 34 1359 154 +1205

Security concerns:

  • [medium] Relay trust boundary needs approval — extensions/slack/src/monitor/relay-source.ts:242
    Relay frames are bearer-authenticated to a router and then dispatched as authorized Slack mentions, so maintainers/security need to approve the threat model, replay/reject semantics, and operator documentation.
    Confidence: 0.9
  • [medium] Dependency graph approval is unresolved — extensions/slack/package.json:15
    The PR adds a direct ws runtime dependency and changes lock/shrinkwrap files; the repository dependency guard requires admin/security approval for the exact head or removal of the dependency graph changes.
    Confidence: 0.95

What I checked:

Likely related people:

  • steipete: GitHub commit history shows repeated recent work on Slack provider, message handling, send behavior, and Slack docs that this relay mode extends. (role: recent Slack runtime and docs contributor; confidence: high; commits: efd1a9ace6f5, 8539e0283a55, c49d909b60a6; files: extensions/slack/src/monitor/provider.ts, extensions/slack/src/monitor/message-handler.ts, extensions/slack/src/send.ts)
  • vincentkoc: History shows recent Slack inbound retry work adjacent to the relay ACK and message delivery path. (role: recent Slack runtime contributor; confidence: medium; commits: c73e80b5a78d; files: extensions/slack/src/monitor/message-handler.ts)
  • suboss87: Recent Slack Socket Mode reconnect policy work is adjacent to the relay reconnect and transport behavior. (role: adjacent Slack transport contributor; confidence: medium; commits: 01dcaba78dde; files: extensions/slack/src/monitor/provider.ts, docs/channels/slack.md)
  • scoootscooob: The Slack implementation was moved into the current extensions/slack/src plugin boundary by this contributor, which is the boundary this feature changes. (role: Slack plugin boundary refactor contributor; confidence: medium; commits: 8746362f5ebf; files: extensions/slack/src/monitor/provider.ts, extensions/slack/src/monitor/message-handler.ts, extensions/slack/src/send.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 automation 🚨 May affect CI, automerge, proof capture, label sync, or maintainer automation. labels Jun 18, 2026
@sjf-oa
sjf-oa requested a review from kevinslin June 19, 2026 01:37
@sjf-oa
sjf-oa marked this pull request as ready for review June 19, 2026 01:37
@sjf-oa
sjf-oa requested a review from a team as a code owner June 19, 2026 01:37
@github-actions

github-actions Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Dependency Guard

This PR changes dependency-related files. Maintainers should confirm these changes are intentional.

Changed files:

  • extensions/slack/npm-shrinkwrap.json
  • extensions/slack/package.json
  • pnpm-lock.yaml

Maintainer follow-up:

  • Review whether the dependency changes are intentional.
  • Inspect resolved package deltas when lockfile, shrinkwrap, or workspace dependency policy changes are present.
  • Treat package-lock.json and npm-shrinkwrap.json diffs as security-review surfaces.
  • Run pnpm deps:changes:report -- --base-ref origin/main --markdown /tmp/dependency-changes.md --json /tmp/dependency-changes.json locally for detailed release-style evidence.

@github-actions github-actions Bot added the dependencies-changed PR changes dependency-related files label Jun 19, 2026
@github-actions

github-actions Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Dependency graph changes are blocked

OpenClaw does not accept dependency graph changes through PRs unless a repository admin or security explicitly authorizes the current head SHA. Dependency updates are generated internally by maintainers so external PRs cannot change the resolved graph.

Detected dependency graph changes:

  • extensions/slack/npm-shrinkwrap.json changed.
  • pnpm-lock.yaml changed.
  • extensions/slack/package.json changed dependencies.

Auto-scrub was not attempted because this PR changes package manifest dependency graph fields:

  • extensions/slack/package.json changed dependencies.

Dependency graph changes must be reviewed by security or handled by maintainers internally. Please remove lockfile changes manually if they are not needed.

To remove lockfile changes, restore them from the target branch:

git fetch origin
git checkout 'origin/main' -- 'extensions/slack/npm-shrinkwrap.json' 'pnpm-lock.yaml'
git commit -m 'chore: remove dependency lockfile change'
git push

If this PR intentionally needs a dependency graph change, ask a repository admin or member of @openclaw/openclaw-secops to comment:

/allow-dependencies-change

The action will approve the current head SHA (1c55e2898a928ce5295a4bf604c82a2bc9e1f14d) when it reruns. A later push requires a fresh approval.

@clawsweeper clawsweeper Bot added the proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. label Jun 19, 2026
@sjf-oa
sjf-oa force-pushed the codex/slack-relay-send-identity branch from 78b1994 to b480796 Compare June 19, 2026 01:46
@openclaw-barnacle openclaw-barnacle Bot removed the scripts Repository scripts label Jun 19, 2026
@sjf-oa
sjf-oa force-pushed the codex/slack-relay-send-identity branch from b480796 to cd3a3e2 Compare June 19, 2026 01:49
@sjf-oa
sjf-oa requested review from a team and steipete as code owners June 19, 2026 01:49
@sjf-oa
sjf-oa changed the base branch from release/2026.6.5 to main June 19, 2026 01:49
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord channel: googlechat Channel integration: googlechat channel: imessage Channel integration: imessage channel: line Channel integration: line channel: matrix Channel integration: matrix labels Jun 19, 2026
@pash-openai

Copy link
Copy Markdown
Contributor

Pilot end-to-end evidence from the repaired relay head:

  • OpenClaw source: a9eb249084f887ccd6f36506dceffdf4066f5c1e
  • Gateway image: openaiapistaging.azurecr.io/api/claw-gateway@sha256:d6942e1ee857c2ff6042a1f6355c4fc63c4a828ac7c45e0a1ef4840a70e690f3
  • Router source: dd94974658d72f623e7dc1575e511d181f048437
  • Router image: openaiapistaging.azurecr.io/api/openclaw-slack-router@sha256:e4fb3517c65ca0dc70dcfef8849aa1698c83217995bfdf67fc61377f956998c5
  • Gateway configuration source: 0bc4d4e2145ae6db487af6577fd922fa73b795f7

Observed Slack round trips through the central router and the two relay-connected gateways:

  • Kevin team user-group route: router selected route:user_group destination:kevinlin; Claw replied KEVIN_SLACK_OK_2.
  • Nik team user-group route: router selected route:user_group destination:pash; Claw replied NIK_EXPLICIT_OK.
  • Kevin follow-up without another mention: router selected route:thread_affinity destination:kevinlin; Claw replied KEVIN_AFFINITY_OK_2.
  • Nik follow-up without another mention: router selected route:thread_affinity destination:pash; Claw replied NIK_AFFINITY_OK_2.
  • Untagged channel default: router selected route:channel_default destination:pash; Claw replied PASH_ROUTER_OK_2.
  • Pash gateway restart: router observed the gateway disconnect and automatic re-registration. A subsequent untagged channel-default turn completed through codex/gpt-5.5, and Claw replied PASH_RESTART_OK_3.

Both permanent gateway smoke turns also completed through the bundled Codex provider (codex/gpt-5.5) without an OpenAI API key: PASH_CODEX_OK and KEVIN_CODEX_OK.

Two pilot-level environment issues remain outside this relay implementation: Slack reports num_connections: 2 for the shared Socket Mode token, so a second unknown consumer can receive some events before the router; and the shared Slack app currently renders outbound replies under the app name Claw rather than the configured per-gateway usernames. The relay, correlated routing, reconnect behavior, normal Slack dispatch, and Slack Web API replies are otherwise working end to end.

@pash-openai

Copy link
Copy Markdown
Contributor

Final pilot evidence from the repaired relay head 2a20fb23091abcb9d74abd9ed19880cca8d5b704:

The outbound identity fix deliberately bypasses Slack's native streaming API whenever a routed custom identity is present, because Slack's streaming methods do not expose chat:write.customize username/icon fields. Those replies use the identity-capable draft/standard posting path instead.

One operational issue remains outside this PR: Socket Mode reports another consumer for the same app token, so that external consumer can intermittently receive a human event before this router does. The gateway pods do not hold the app token or run direct Socket Mode. Removing the unknown consumer or rotating the app token is still required for deterministic single-consumer routing.

The remaining expected merge blocker is the dependency guard approval for the Slack plugin-local ws dependency. The pinned pilot image and both live round trips above use the repaired implementation.

@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: slack Channel integration: slack dependencies-changed PR changes dependency-related files docs Improvements or additions to documentation maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. scripts Repository scripts size: XL status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants