fix(relay): route async Slack messages to correct channel instead of DMs - #1845
Merged
Merged
Conversation
Fixes three bugs causing async/cross-channel Slack messages to land in DMs or fail silently: 1. routing_target_from_metadata now extracts channel_id for Slack relay messages, so proactive broadcasts target the originating channel instead of falling back to sender_id (user's DM) 2. Lightweight routine JobContext carries notify metadata (owner_id, notify_channel, notify_user) so the message tool can resolve the correct delivery target — previously ..Default::default() left metadata as null 3. Routine creation auto-captures source channel/target from ctx.metadata when the LLM omits delivery params, so routines created from a Slack channel know where to send results Also: - Clarified message tool channel/target parameter descriptions to prevent LLM confusion between transport names and Slack channel IDs - IronClaw proxy_provider now checks Slack ok=false and surfaces errors instead of silently succeeding Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Code Review
This pull request improves notification routing and error handling for routines and Slack integrations. Key updates include passing notification metadata into lightweight routine contexts, adding channel_id to routing target extraction, and implementing explicit Slack API error handling in the relay client. The RoutineCreateTool now correctly falls back to context metadata for delivery configuration when parameters are omitted. Feedback was provided to use a more idiomatic approach for checking the Slack API response status.
|
|
||
| // Slack API always returns HTTP 200 but signals errors via {"ok": false}. | ||
| // Surface these as relay errors so callers get actionable feedback. | ||
| if json.get("ok") == Some(&serde_json::Value::Bool(false)) { |
Contributor
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
henrypark133
approved these changes
Mar 31, 2026
JZKK720
pushed a commit
to JZKK720/ironclaw
that referenced
this pull request
Apr 1, 2026
…DMs (nearai#1845) * fix(relay): route async Slack messages to correct channel instead of DMs Fixes three bugs causing async/cross-channel Slack messages to land in DMs or fail silently: 1. routing_target_from_metadata now extracts channel_id for Slack relay messages, so proactive broadcasts target the originating channel instead of falling back to sender_id (user's DM) 2. Lightweight routine JobContext carries notify metadata (owner_id, notify_channel, notify_user) so the message tool can resolve the correct delivery target — previously ..Default::default() left metadata as null 3. Routine creation auto-captures source channel/target from ctx.metadata when the LLM omits delivery params, so routines created from a Slack channel know where to send results Also: - Clarified message tool channel/target parameter descriptions to prevent LLM confusion between transport names and Slack channel IDs - IronClaw proxy_provider now checks Slack ok=false and surfaces errors instead of silently succeeding Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style: apply cargo fmt Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Apr 1, 2026
serrrfirat
pushed a commit
that referenced
this pull request
Apr 5, 2026
…DMs (#1845) * fix(relay): route async Slack messages to correct channel instead of DMs Fixes three bugs causing async/cross-channel Slack messages to land in DMs or fail silently: 1. routing_target_from_metadata now extracts channel_id for Slack relay messages, so proactive broadcasts target the originating channel instead of falling back to sender_id (user's DM) 2. Lightweight routine JobContext carries notify metadata (owner_id, notify_channel, notify_user) so the message tool can resolve the correct delivery target — previously ..Default::default() left metadata as null 3. Routine creation auto-captures source channel/target from ctx.metadata when the LLM omits delivery params, so routines created from a Slack channel know where to send results Also: - Clarified message tool channel/target parameter descriptions to prevent LLM confusion between transport names and Slack channel IDs - IronClaw proxy_provider now checks Slack ok=false and surfaces errors instead of silently succeeding Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style: apply cargo fmt Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
drchirag1991
pushed a commit
to drchirag1991/ironclaw
that referenced
this pull request
Apr 8, 2026
…DMs (nearai#1845) * fix(relay): route async Slack messages to correct channel instead of DMs Fixes three bugs causing async/cross-channel Slack messages to land in DMs or fail silently: 1. routing_target_from_metadata now extracts channel_id for Slack relay messages, so proactive broadcasts target the originating channel instead of falling back to sender_id (user's DM) 2. Lightweight routine JobContext carries notify metadata (owner_id, notify_channel, notify_user) so the message tool can resolve the correct delivery target — previously ..Default::default() left metadata as null 3. Routine creation auto-captures source channel/target from ctx.metadata when the LLM omits delivery params, so routines created from a Slack channel know where to send results Also: - Clarified message tool channel/target parameter descriptions to prevent LLM confusion between transport names and Slack channel IDs - IronClaw proxy_provider now checks Slack ok=false and surfaces errors instead of silently succeeding Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style: apply cargo fmt Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merged
Merged
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.
Summary
channel_idfrom Slack relay metadata, so proactivebroadcast()calls target the originating channel (e.g.C088K6C3SQZ) instead of falling back tosender_id(user's DMU07PQGFUDQV)notify_channel/notify_user/owner_idin metadata — previously..Default::default()left it null, losing all delivery routingctx.metadatawhen the LLM omitsdelivery.channel/delivery.userchannel= transport name (slack-relay),target= Slack channel/user IDok=falseand surfaces errors (e.g.invalid_thread_ts) instead of silently succeedingEvidence from relay logs
After this fix,
routing_targetreturnsC088K6C3SQZ(the Slack channel) and routine creation captures it asnotify.user.Test plan
message(channel: "slack-relay", target: "C088K6C3SQZ")works🤖 Generated with Claude Code