fix(slack): resolve channel names via directory for cross-account messaging#8024
Conversation
…saging The looksLikeSlackTargetId function was incorrectly treating channel names like #general as IDs, bypassing directory lookup. This caused cross-account messaging to fail with 'channel_not_found' because: 1. User in Workspace B sends to #main (channel in Workspace A) 2. #main was treated as an ID (not resolved via directory) 3. Slack API received '#main' instead of the actual channel ID 4. Error: channel_not_found The fix: - Only treat #/@ prefixed strings as IDs if followed by valid Slack ID pattern - Channel names (#general, #main) now go through directory lookup - Directory lookup uses the correct accountId to fetch channels from the right workspace Also added: - Debug logging for cross-account send troubleshooting - Unit tests for looksLikeSlackTargetId behavior Fixes openclaw#8018
| function resolveReadToken(params: DirectoryConfigParams): string | undefined { | ||
| const account = resolveSlackAccount({ cfg: params.cfg, accountId: params.accountId }); | ||
| const userToken = account.config.userToken?.trim() || undefined; | ||
| return userToken ?? account.botToken?.trim(); | ||
| const token = userToken ?? account.botToken?.trim(); | ||
| logVerbose( | ||
| `slack directory: resolveReadToken accountId=${params.accountId ?? "default"} resolvedAccountId=${account.accountId} hasToken=${Boolean(token)}`, | ||
| ); | ||
| return token; |
There was a problem hiding this comment.
[P2] The new verbose log includes accountId / resolvedAccountId on every directory lookup. If logVerbose is enabled in prod, this can add a lot of log volume during paginated users.list / conversations.list calls; consider gating to only log when token is missing or when params.accountId differs from account.accountId to keep logs actionable.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/slack/directory-live.ts
Line: 38:45
Comment:
[P2] The new verbose log includes `accountId` / `resolvedAccountId` on every directory lookup. If `logVerbose` is enabled in prod, this can add a lot of log volume during paginated `users.list` / `conversations.list` calls; consider gating to only log when `token` is missing or when `params.accountId` differs from `account.accountId` to keep logs actionable.
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.| // Only treat #/@ prefixed strings as IDs if followed by a valid Slack ID pattern. | ||
| // This allows channel/user names (e.g., #general, @john) to be resolved via directory lookup. | ||
| if (/^#[CUWGD][A-Z0-9]{8,}$/i.test(trimmed)) { | ||
| return true; | ||
| } | ||
| if (/^@[UW][A-Z0-9]{8,}$/i.test(trimmed)) { | ||
| return true; | ||
| } | ||
| return /^[CUWGD][A-Z0-9]{8,}$/i.test(trimmed); |
There was a problem hiding this comment.
[P3] The regexes now accept lowercase IDs because of the /i flag. Slack IDs are typically uppercase; if lowercase input should not be treated as an ID (and instead go through directory resolution), consider dropping /i so #c123... doesn’t bypass lookup unexpectedly.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/channels/plugins/normalize/slack.ts
Line: 22:30
Comment:
[P3] The regexes now accept lowercase IDs because of the `/i` flag. Slack IDs are typically uppercase; if lowercase input should *not* be treated as an ID (and instead go through directory resolution), consider dropping `/i` so `#c123...` doesn’t bypass lookup unexpectedly.
How can I resolve this? If you propose a fix, please make it concise.
Additional Comments (2)
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/infra/outbound/target-resolver.ts
Line: 1:12
Comment:
[P0] `logVerbose` is imported but never used in this file, which will fail lint/TS builds if you have `noUnusedLocals`/lint rules enabled.
```suggestion
import type {
ChannelDirectoryEntry,
ChannelDirectoryEntryKind,
ChannelId,
} from "../../channels/plugins/types.js";
import type { OpenClawConfig } from "../../config/config.js";
import { getChannelPlugin } from "../../channels/plugins/index.js";
import { defaultRuntime, type RuntimeEnv } from "../../runtime.js";
import { buildDirectoryCacheKey, DirectoryCache } from "./directory-cache.js";
import { ambiguousTargetError, unknownTargetError } from "./target-errors.js";
```
How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/slack/send.ts
Line: 136:144
Comment:
[P2] `logVerbose` logs the raw `to` value. If callers pass user-provided text here, this can leak internal channel/user names into logs; consider logging the normalized/parsed recipient kind + id instead (or redacting) so verbose logs stay safe to enable.
How can I resolve this? If you propose a fix, please make it concise. |
|
Hey! 👋 Just checking in - any updates on this PR? We're eagerly waiting for this fix to enable our multi-workspace setup. All CI checks are green, so hopefully it's ready for review? Thanks! 🌻 |
bfc1ccb to
f92900f
Compare
Summary
Fixes #8018 - Cross-account Slack messaging fails with
channel_not_foundThe Problem
When using
channels.slack.accountsfor multi-workspace setup:#main(a channel in Workspace A)looksLikeSlackTargetIdfunction incorrectly treats#mainas a valid ID#maininstead of the channel IDC12345678channel_not_founderrorThe Fix
Updated
looksLikeSlackTargetIdto only treat#/@prefixed strings as IDs when followed by a valid Slack ID pattern (e.g.,#C12345678,@U12345678).Channel/user names like
#general,#main,@johnnow correctly go through directory lookup, which:accountIdparameterChanges
src/channels/plugins/normalize/slack.ts: Fixed ID pattern matchingsrc/channels/plugins/normalize/slack.test.ts: Added unit testssrc/infra/outbound/target-resolver.ts: Added debug loggingsrc/slack/directory-live.ts: Added debug loggingsrc/slack/send.ts: Added debug loggingTesting
The new unit tests verify:
C12345678,#C12345678) are recognized as IDs ✅#general,#main) are NOT recognized as IDs ✅ (triggers directory lookup)@john,@sebastian) are NOT recognized as IDs ✅ (triggers directory lookup)🌻 Created by Emma (AI Assistant) to help with Issue #8018
Greptile Overview
Greptile Summary
Fixes Slack target normalization so
#channel/@usernames no longer get misclassified as IDs in multi-workspace setups.looksLikeSlackTargetIdnow only treats#/@-prefixed strings as IDs when they match Slack ID patterns (e.g.#C…,@U…), which ensures directory lookup runs with the specifiedaccountIdand resolves to the correct workspace’s channel/user IDs. Adds unit tests for the new ID-vs-name behavior and introduces additional verbose debug logs in Slack directory token resolution and Slack send path.Confidence Score: 4/5
logVerboseimport in target-resolver which can break CI/lint. Added logging appears non-functional but may increase log volume / leak identifiers when verbose is enabled.(2/5) Greptile learns from your feedback when you react with thumbs up/down!