fix(discord): specify hydrated config for auto ack reactions to prevent SecretRef resolution failures#60081
Conversation
Greptile SummaryThis PR fixes silent failures in Discord auto-ACK reactions when using Key changes:
Confidence Score: 4/5Safe to merge — the fix is minimal, targeted, and uses existing typed plumbing that was already in place. The change is a single-line fix per call-site that closes a clear SecretRef regression. The No files require special attention beyond the cosmetic shorthand nit in Prompt To Fix All With AIThis is a comment left during a code review.
Path: extensions/discord/src/monitor/message-handler.process.ts
Line: 201-210
Comment:
**Use ES6 shorthand property syntax for `cfg`**
`cfg: cfg` can be shortened to just `cfg` since the variable name matches the property name. The rest of the codebase (including `deliverDiscordReply` calls nearby) uses shorthand property syntax consistently.
```suggestion
await reactMessageDiscord(messageChannelId, message.id, emoji, {
rest: discordRest,
cfg,
});
```
Same applies to the `removeReaction` callback a few lines below:
```suggestion
await removeReactionDiscord(messageChannelId, message.id, emoji, {
rest: discordRest,
cfg,
});
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(discord): pass hydrated config to ac..." | Re-trigger Greptile |
981da6d to
d3822cf
Compare
99d6d78 to
2ceace5
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2ceace577d
ℹ️ 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".
| isTelegramExecApprovalAuthorizedSender({ cfg, accountId, senderId }) && | ||
| !isTelegramExecApprovalApprover({ cfg, accountId, senderId }) | ||
| ) { | ||
| return { kind: "ignore" }; | ||
| return undefined; |
There was a problem hiding this comment.
Block /approve fallback when Telegram native approvals are off
Returning undefined in this branch re-enables normal /approve handling for senders who are authorized via isTelegramExecApprovalAuthorizedSender but are not approvers. In configs where channels.telegram.execApprovals.enabled is false but approval-target mode still marks the sender as authorized, handleApproveCommand will now fall through to gateway resolution and submit exec.approval.resolve instead of suppressing the command. This bypasses the channel-level disable behavior that was previously enforced by { kind: "ignore" } for this specific sender class.
Useful? React with 👍 / 👎.
2ceace5 to
46cc31b
Compare
…resolution When extracting `reactMessageDiscord`, it defaulted to reading the raw config (which contains `SecretRef`s) if a hydrated `cfg` was omitted. We now pass the pre-resolved `cfg` context into the reaction options so the plugin SDK resolves the token via memory rather than the raw file.
The implementation fix propagates the hydrated cfg to reactMessageDiscord and removeReactionDiscord. Update test assertions to expect the cfg property in the options argument using expect.objectContaining to handle the dynamic session store path.
46cc31b to
0fd5550
Compare
|
Landed via temp rebase onto main.\n\n- Gate: pnpm check; pnpm build; pnpm test -- extensions/discord/src/monitor/message-handler.process.test.ts; pnpm test -- src/auto-reply/reply/commands.test.ts -t "accepts Telegram /approve from exec target recipients when native approvals are disabled"; pnpm test -- src/secrets/runtime.test.ts -t "skips inactive-surface refs and emits diagnostics"\n- Land commit: 0fd5550\n- Merge commit: b7f524a\n\nThanks @FunJim! |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0fd555094c
ℹ️ 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".
| isTelegramExecApprovalAuthorizedSender({ cfg, accountId, senderId }) && | ||
| !isTelegramExecApprovalApprover({ cfg, accountId, senderId }) | ||
| ) { | ||
| return { kind: "ignore" }; | ||
| return undefined; |
There was a problem hiding this comment.
Keep /approve suppressed for non-approver Telegram targets
Returning undefined here makes /approve fall through to the generic handler when native Telegram exec approvals are disabled. In configs where a sender is authorized via exec approval targets but is not an approver, resolveApprovalCommandAuthorization can still treat exec approval as authorized, so the command may proceed to exec.approval.resolve instead of being suppressed, which bypasses the disabled-channel behavior that this branch previously enforced.
Useful? React with 👍 / 👎.
Fixes #57749
Background:
Automatic message reactions in Discord channels (ACK reactions) were silently failing to appear despite the manual CLI command (
openclaw message react) succeeding perfectly.Root Cause:
When the Discord webhook processor emits an ACK reaction, it triggers the callback
setReactionandremoveReactioninsideextensions/discord/src/monitor/message-handler.process.ts. These methods delegate toreactMessageDiscord()andremoveReactionDiscord().However, they were omitting the
cfgproperty in the options payload. Since the config dependency was omitted, thecreateDiscordRestClientfunction automatically retrieved the raw, unhydrated config from disk vialoadConfig(). In deployments using secureSecretRefitems (e.g.file:filemain:/channels/discord/token), it directly triggered anError: channels.discord.token: unresolved SecretRefinternally and aborted the request because it was actively trying to parse the literal URI string as a Discord application token instead of utilizing the hydratedRuntimeEnvobject. In Multi-Account scenarios, it would resolve auth against thedefaultaccount instead of the active account.Fix:
This commit propagates the hydrated
cfg(which contains decrypted variables globally validated by the runtime schema) fromprocessDiscordMessagedown toreactMessageDiscordandremoveReactionDiscord. This bypasses the unhydratedloadConfig()fallback ensuring proper SecretRef parsing.