Skip to content

feat(slack): handle global and message shortcuts#94881

Merged
steipete merged 8 commits into
mainfrom
feat/slack-shortcuts-63920
Jun 19, 2026
Merged

feat(slack): handle global and message shortcuts#94881
steipete merged 8 commits into
mainfrom
feat/slack-shortcuts-63920

Conversation

@steipete

Copy link
Copy Markdown
Contributor

Summary

  • register Slack global and message shortcuts through Bolt's generic shortcut matcher
  • acknowledge payloads before routing, then apply existing Slack app/team, sender, DM, and channel authorization
  • route global shortcuts to the actor's direct session and message shortcuts with selected-message channel/thread context
  • sanitize queued system events; omit Slack tokens and redact trigger/response URLs

Closes #63920.

Release-note context: Slack apps can now expose configured global and message shortcuts to agents as structured interaction events.

Verification

  • node scripts/run-vitest.mjs extensions/slack/src/monitor/events/interactions.test.ts extensions/slack/src/monitor/context.test.ts — 52 passed
  • pnpm tsgo:extensions
  • pnpm tsgo:extensions:test
  • autoreview — clean, no accepted/actionable findings (0.87)
  • Azure Crabbox pnpm check:changed — passed (run_a7002d4ea5b4, cbx_d0ab4caaa906)

Real behavior proof

Behavior addressed: Slack global and message shortcut payloads are acknowledged, authorized, routed, sanitized, and queued as structured Slack interaction: events.

Real environment tested: macOS Node test environment plus Azure Crabbox Linux (Standard_D32ads_v6).

Exact steps or command run after this patch: node scripts/run-vitest.mjs extensions/slack/src/monitor/events/interactions.test.ts extensions/slack/src/monitor/context.test.ts; remote env OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1 OPENCLAW_CHANGED_LANES_RAW_SYNC=1 CI=1 corepack pnpm check:changed.

Evidence after fix: 52 focused tests passed; extension production/test typechecks passed; remote changed gate passed all selected extension/docs checks.

Observed result after fix: global shortcuts target the actor's direct delivery/session context; message shortcuts retain channel, selected message, and thread context; policy-rejected or mismatched payloads are acknowledged and dropped; sensitive Slack fields do not reach agent context.

What was not tested: end-to-end invocation from a live Slack app with configured shortcut callback IDs; no suitable live app configuration was available in this task.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: slack Channel integration: slack size: M maintainer Maintainer-authored PR labels Jun 19, 2026
@clawsweeper

clawsweeper Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 19, 2026, 9:04 AM ET / 13:04 UTC.

Summary
The PR branch registers a generic Slack shortcut listener, routes authorized global and message shortcuts into sanitized system events, and updates Slack tests and docs.

Reproducibility: yes. for the source-level gap: current main and v2026.6.8 have block-action and modal handlers but no Slack shortcut listener. The PR fix itself still lacks live Slack invocation proof.

Review metrics: 2 noteworthy metrics.

  • Live Slack Shortcut Invocations: 0 tested. The changed behavior is a real Slack transport path, so tests and CI do not prove configured shortcuts are delivered and routed.
  • Generic Shortcut Matchers: 1 added. Matching every non-empty callback ID is a product and compatibility scope decision for existing Slack app configurations.

Stored data model
Persistent data-model change detected: serialized state: src/plugins/runtime/runtime-web-channel-plugin.ts, unknown-data-model-change: src/plugins/openai-compatible-embedding-provider.test.ts, unknown-data-model-change: src/plugins/openai-compatible-embedding-provider.ts, unknown-truncated-pull-files, vector/embedding metadata: docs/channels/slack.md, vector/embedding metadata: src/plugins/openai-compatible-embedding-provider.test.ts, and 1 more. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #63920
Summary: This PR is the active candidate fix for the open Slack global/message shortcut issue; the Microsoft tracker only references it as part of a broad list.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦐 gold shrimp
Result: blocked until real behavior proof from a real setup is added.

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

Rank-up moves:

  • [P2] Add selected-message timestamp fallback with a root-message shortcut regression test.
  • Attach redacted live Slack global and message shortcut proof, or get an explicit maintainer proof override.
  • Have a maintainer accept or narrow the generic shortcut matcher scope after a refreshed merge-result review.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR provides tests, typechecks, Testbox, and CI, but it explicitly says no live configured Slack shortcut invocation was tested; add redacted live output, logs, terminal proof, screenshot/video, or a maintainer proof override, then update the PR body so ClawSweeper re-reviews or ask a maintainer to comment @clawsweeper re-review.

Mantis proof suggestion
A real Slack shortcut invocation would materially prove the transport path that tests and CI do not cover. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis slack desktop smoke: verify a configured Slack global shortcut and message shortcut are acknowledged and routed to the correct OpenClaw session with redacted payload/log proof.

Risk before merge

  • [P1] Root-message Slack shortcuts can enqueue without threadId, which can route follow-up delivery to channel-level context instead of the selected message thread.
  • [P1] The PR only provides mocked/unit and hosted check proof; no configured Slack global or message shortcut was invoked in a real Slack app after the patch.
  • [P1] The generic app.shortcut(/.+/) listener makes every non-empty configured shortcut callback ID OpenClaw-visible, so maintainers need to accept that product/compatibility scope or narrow it before merge.
  • [P1] The PR has a protected maintainer label and a stale-base GitHub diff, so maintainers should review the refreshed merge result before treating it as Slack-only.

Maintainer options:

  1. Fix Thread Fallback And Prove Shortcuts (recommended)
    Add the selected-message timestamp fallback with a root-message shortcut regression test, then attach redacted live Slack global and message shortcut proof before merge.
  2. Maintainer Accepts Scope With Override
    A maintainer can explicitly accept the generic callback matcher scope and waive live Slack proof after reviewing the configured-app constraints and merge result.
  3. Pause Until A Slack App Is Available
    Keep the PR open but paused if no configured Slack workspace can exercise both shortcut types yet.

Next step before merge

  • [P2] Protected-label handling, missing live proof, and generic matcher scope require maintainer judgment even though the thread fallback bug is mechanically fixable.

Security
Cleared: No concrete security or supply-chain regression was found in the focused Slack shortcut path; the reviewed concern is compatibility/message-delivery rather than a security boundary issue.

Review findings

  • [P2] Fall back to the selected message timestamp — extensions/slack/src/monitor/events/interactions.shortcuts.ts:10-12
Review details

Best possible solution:

Land a rebased Slack-focused implementation after falling back to the selected message timestamp for root-message shortcuts, adding regression coverage, and attaching live Slack proof or an explicit maintainer proof override.

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

Yes for the source-level gap: current main and v2026.6.8 have block-action and modal handlers but no Slack shortcut listener. The PR fix itself still lacks live Slack invocation proof.

Is this the best way to solve the issue?

No, not yet: the Slack plugin is the right owner boundary, but the implementation needs selected-message timestamp fallback, focused regression coverage, and maintainer acceptance of the generic matcher scope.

Full review comments:

  • [P2] Fall back to the selected message timestamp — extensions/slack/src/monitor/events/interactions.shortcuts.ts:10-12
    For message shortcuts on root channel messages, Slack's payload can include the selected message as message.ts without message.thread_ts; returning undefined here loses the selected-message thread for the session key and delivery context. Fall back to message.ts/message_ts and cover that root-message case. (docs.slack.dev)
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P2: The PR addresses a bounded Slack channel feature with message-delivery impact, but it is not a core outage.
  • merge-risk: 🚨 compatibility: The generic Slack shortcut matcher changes how configured Slack app shortcuts enter OpenClaw and needs maintainer acceptance before merge.
  • merge-risk: 🚨 message-delivery: Shortcut routing chooses the Slack user, channel, and thread that receive follow-up agent delivery.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR provides tests, typechecks, Testbox, and CI, but it explicitly says no live configured Slack shortcut invocation was tested; add redacted live output, logs, terminal proof, screenshot/video, or a maintainer proof override, then update the PR body so ClawSweeper re-reviews or ask a maintainer to comment @clawsweeper re-review.
Evidence reviewed

What I checked:

Likely related people:

  • steipete: Prior merged history shows repeated Slack interaction/channel-runtime refactors on the central interaction files, and this author also has current branch/domain context beyond being the PR opener. (role: major refactor and adjacent owner; confidence: high; commits: 9cd9c7a48841, ccf54f263a3e; files: extensions/slack/src/monitor/events/interactions.ts, extensions/slack/src/monitor/events/interactions.block-actions.ts, extensions/slack/src/monitor/events/interactions.modal.ts)
  • vincentkoc: Merged history connects this person to Slack interactive reply parity, shared interactive rendering, and interaction registration context. (role: recent area contributor; confidence: high; commits: 98f222a66122, c7d31bae8a67, eb51ba5c1dbc; files: extensions/slack/src/monitor/events/interactions.ts, extensions/slack/src/monitor/events/interactions.block-actions.ts, extensions/slack/src/monitor/context.ts)
  • eleqtrizit: Merged Slack interaction allowlist/auth work is directly relevant because shortcut ingress must preserve the same acknowledgement and authorization boundary. (role: interaction auth contributor; confidence: medium; commits: 1c35795fce9a; files: extensions/slack/src/monitor/events/interactions.block-actions.ts, extensions/slack/src/monitor/events/interactions.modal.ts, extensions/slack/src/monitor/events/interactions.test.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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2477da066c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (isMessageShortcut && !channelId) {
params.ctx.runtime.log?.(
`slack:interaction drop shortcut callback=${callbackId} user=${userId} reason=missing-channel`,
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Route message shortcuts to the selected message thread

When a message shortcut is invoked on a normal channel message, Slack’s payload carries the selected message timestamp as message.ts/message_ts, while message.thread_ts is absent; Slack’s own Bolt shortcut guide uses that timestamp as the thread_ts for replies (https://docs.slack.dev/interactivity/implementing-shortcuts/). Because this line only reads message.thread_ts, ordinary message shortcuts enqueue with threadId: undefined and resolve the channel-level session, so any agent reply/tool delivery goes to the whole channel instead of the selected message’s thread. Use the selected message timestamp as the fallback thread id for message shortcuts.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 19, 2026
@blacksmith-sh

blacksmith-sh Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Blacksmith runners detected OOM events on the following jobs:

Job Details
checks-node-agentic-control-plane-runtime-config View Job

@steipete steipete requested a review from a team as a code owner June 19, 2026 11:30
@openclaw-barnacle openclaw-barnacle Bot added channel: imessage Channel integration: imessage channel: msteams Channel integration: msteams channel: signal Channel integration: signal channel: telegram Channel integration: telegram channel: voice-call Channel integration: voice-call channel: whatsapp-web Channel integration: whatsapp-web app: ios App: ios gateway Gateway runtime cli CLI command changes scripts Repository scripts commands Command implementations agents Agent runtime and tooling labels Jun 19, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 19, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c94074b2b0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +121 to +122
releaseInFinally = false;
return responseWithRelease(response, release);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Release guarded Graph responses for zero-length bodies

When Graph returns a successful non-null status with Content-Length: 0, readOptionalGraphJson returns without reading the body; since releaseInFinally is disabled here and responseWithRelease only calls the SSRF guard's release after the wrapped stream is drained or cancelled, the guarded dispatcher/timeout remains open. The same leak happens for success callers such as deleteGraphRequest that ignore the returned Response; treat zero-length responses like null-body statuses or make void callers drain/cancel the returned body.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 19, 2026
@openclaw-barnacle openclaw-barnacle Bot added the channel: mattermost Channel integration: mattermost label Jun 19, 2026
@steipete

steipete commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

Land-ready verification for 32dea12d7a784f15ea4af6faaa3464bb8b28ce54:

  • Adds Slack global and message shortcut handling with immediate acknowledgement, authenticated routing, message context, payload redaction, and setup docs.
  • Focused local proof: 52 tests passed; production and test tsgo checks passed.
  • Changed-surface Testbox proof: run_a7002d4ea5b4 passed; unrelated failing shard rerun passed 68 tests.
  • Fresh autoreview: no actionable findings.
  • Exact-head hosted CI release gate after protocol-generator synchronization: 27827434898 passed.
  • Repository-native scripts/pr prepare-run 94881 passed.

Known gap: no live Slack app shortcut invocation; signed/authenticated request, ACK timing, routing, and redaction are covered through the HTTP handler tests.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f1483d2fb3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +61 to +63
if let appGroupStateDirURL {
return appGroupStateDirURL
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Migrate legacy iOS identity before switching directories

When an existing iOS install upgrades with the new App Group entitlement, containerURL(forSecurityApplicationGroupIdentifier:) will start returning a shared container even though the previous device.json / device-auth.json still live under Application Support. Because this now selects the empty App Group directory before the legacy directory, DeviceIdentityStore.loadOrCreate(profile: .primary) generates a new device id and DeviceAuthStore stops seeing the saved device token, so already-paired apps can no longer reconnect without re-pairing. Prefer migrating/copying the legacy identity/auth files into the App Group on first launch before making this the primary location.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added the merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. label Jun 19, 2026
@openclaw-barnacle openclaw-barnacle Bot added the channel: discord Channel integration: discord label Jun 19, 2026
@openclaw-barnacle openclaw-barnacle Bot added extensions: xai channel: zaloclawbot Channel integration: zaloclawbot labels Jun 19, 2026
@openclaw-barnacle openclaw-barnacle Bot added the app: web-ui App: web-ui label Jun 19, 2026
@steipete steipete merged commit 341ae21 into main Jun 19, 2026
164 of 166 checks passed
@steipete steipete deleted the feat/slack-shortcuts-63920 branch June 19, 2026 13:12
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 20, 2026
Merged via squash.

Prepared head SHA: 32dea12
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Reviewed-by: @steipete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: ios App: ios app: web-ui App: web-ui channel: discord Channel integration: discord channel: imessage Channel integration: imessage channel: mattermost Channel integration: mattermost channel: msteams Channel integration: msteams channel: signal Channel integration: signal channel: slack Channel integration: slack channel: sms Channel integration: sms channel: telegram Channel integration: telegram channel: voice-call Channel integration: voice-call channel: whatsapp-web Channel integration: whatsapp-web channel: zaloclawbot Channel integration: zaloclawbot cli CLI command changes commands Command implementations docs Improvements or additions to documentation extensions: acpx extensions: github-copilot extensions: xai gateway Gateway runtime 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. P2 Normal backlog priority with limited blast radius. plugin: google-meet rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. scripts Repository scripts size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose Slack message_action and global shortcut events via channels.slack

1 participant