fix: preserve discord setup channel allowlists (#47788) (thanks @Elde… · openclaw/openclaw@7ed58a3
steipete
·
2026-05-02
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -60,6 +60,7 @@ Docs: https://docs.openclaw.ai
|
60 | 60 | - Proxy/audio: convert standard `FormData` bodies before proxy-backed undici fetches, so audio transcription and multipart uploads no longer send `[object FormData]` when `HTTP_PROXY` or `HTTPS_PROXY` is configured. Fixes #48554. Thanks @dco5. |
61 | 61 | - Discord: allow explicitly configured ack reactions in tool-only guild channels while keeping automatic lifecycle/status reactions suppressed. Fixes #74922. Thanks @samvilian and @BlueBirdBack. |
62 | 62 | - Discord: enable session-backed A2A announce target lookup so `sessions_send` uses the target session's `deliveryContext.accountId` or `lastAccountId` instead of falling back to the default bot in multi-account setups. Fixes #42652; refs #51626 and #44773; supersedes #73975. Thanks @irchelper, @dpalfox, and @Lanfei. |
| 63 | +- Discord/setup: write resolved guild/channel allowlist selections to the selected guild and channel instead of falling back to the wildcard guild during setup. Supersedes #47788. Thanks @Eldersonar. |
63 | 64 | - Discord: treat abort-time Carbon reconnect-exhausted events as expected shutdown during stale-socket restarts, so health-monitor restarts no longer reject the monitor lifecycle. Carries forward #58216; supersedes #73949. Thanks @Perttulands. |
64 | 65 | - Discord/native commands: return an explicit warning when slash command dispatch or direct plugin execution produces no visible reply instead of a success-style completion ack. Fixes #58986; supersedes #62057. Thanks @jb510. |
65 | 66 | - Discord: keep typing indicators alive during long tool runs and auto-compaction while keepalive ticks continue, so active sessions do not appear stalled before the final reply. Thanks @Squirbie. |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -27,13 +27,44 @@ const DISCORD_TOKEN_HELP_LINES = [
|
27 | 27 | `Docs: ${formatDocsLink("/discord", "discord")}`, |
28 | 28 | ]; |
29 | 29 | |
| 30 | +type DiscordGuildChannelAllowlistEntry = { |
| 31 | +guildKey: string; |
| 32 | +channelKey?: string; |
| 33 | +}; |
| 34 | + |
| 35 | +type DiscordSetupAllowlistResolution = { |
| 36 | +resolved?: boolean; |
| 37 | +guildId?: string; |
| 38 | +channelId?: string; |
| 39 | +guildKey?: string; |
| 40 | +channelKey?: string; |
| 41 | +}; |
| 42 | + |
| 43 | +function mapDiscordSetupAllowlistEntries(resolved: unknown): DiscordGuildChannelAllowlistEntry[] { |
| 44 | +if (!Array.isArray(resolved)) { |
| 45 | +return []; |
| 46 | +} |
| 47 | +return resolved.flatMap((entry): DiscordGuildChannelAllowlistEntry[] => { |
| 48 | +if (!entry || typeof entry !== "object") { |
| 49 | +return []; |
| 50 | +} |
| 51 | +const row = entry as DiscordSetupAllowlistResolution; |
| 52 | +if (row.resolved === false) { |
| 53 | +return []; |
| 54 | +} |
| 55 | +const guildKey = normalizeOptionalString(row.guildId ?? row.guildKey); |
| 56 | +if (!guildKey) { |
| 57 | +return []; |
| 58 | +} |
| 59 | +const channelKey = normalizeOptionalString(row.channelId ?? row.channelKey); |
| 60 | +return channelKey ? [{ guildKey, channelKey }] : [{ guildKey }]; |
| 61 | +}); |
| 62 | +} |
| 63 | + |
30 | 64 | function setDiscordGuildChannelAllowlist( |
31 | 65 | cfg: OpenClawConfig, |
32 | 66 | accountId: string, |
33 | | -entries: Array<{ |
34 | | -guildKey: string; |
35 | | -channelKey?: string; |
36 | | -}>, |
| 67 | +entries: DiscordGuildChannelAllowlistEntry[], |
37 | 68 | ): OpenClawConfig { |
38 | 69 | const baseGuilds = |
39 | 70 | accountId === DEFAULT_ACCOUNT_ID |
@@ -152,7 +183,8 @@ export function createDiscordSetupWizardBase(handlers: {
|
152 | 183 | cfg: OpenClawConfig; |
153 | 184 | accountId: string; |
154 | 185 | resolved: unknown; |
155 | | -}) => setDiscordGuildChannelAllowlist(cfg, accountId, resolved as never), |
| 186 | +}) => |
| 187 | +setDiscordGuildChannelAllowlist(cfg, accountId, mapDiscordSetupAllowlistEntries(resolved)), |
156 | 188 | }), |
157 | 189 | allowFrom: createAccountScopedAllowFromSection({ |
158 | 190 | channel, |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -94,3 +94,44 @@ describe("discordSetupWizard.status", () => {
|
94 | 94 | expect(configured).toBe(false); |
95 | 95 | }); |
96 | 96 | }); |
| 97 | + |
| 98 | +describe("discordSetupWizard.groupAccess", () => { |
| 99 | +it("writes resolved Discord channel rows to their selected guild and channel", () => { |
| 100 | +const next = discordSetupWizard.groupAccess?.applyAllowlist?.({ |
| 101 | +cfg: { |
| 102 | +channels: { |
| 103 | +discord: { |
| 104 | +guilds: { |
| 105 | +existing: { |
| 106 | +channels: { |
| 107 | +keep: { enabled: true }, |
| 108 | +}, |
| 109 | +}, |
| 110 | +}, |
| 111 | +}, |
| 112 | +}, |
| 113 | +} as OpenClawConfig, |
| 114 | +accountId: "default", |
| 115 | +resolved: [ |
| 116 | +{ |
| 117 | +input: "OpenClaw/#triage", |
| 118 | +resolved: true, |
| 119 | +guildId: "guild-1", |
| 120 | +channelId: "channel-1", |
| 121 | +}, |
| 122 | +{ |
| 123 | +input: "missing", |
| 124 | +resolved: false, |
| 125 | +}, |
| 126 | +], |
| 127 | +}); |
| 128 | + |
| 129 | +expect(next?.channels?.discord?.guilds?.["guild-1"]?.channels?.["channel-1"]).toEqual({ |
| 130 | +enabled: true, |
| 131 | +}); |
| 132 | +expect(next?.channels?.discord?.guilds?.["*"]).toBeUndefined(); |
| 133 | +expect(next?.channels?.discord?.guilds?.existing?.channels?.keep).toEqual({ |
| 134 | +enabled: true, |
| 135 | +}); |
| 136 | +}); |
| 137 | +}); |
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。