Skip to content

Commit 4da4cc9

Browse files
Mark LTakhoffman
andauthored
fix(slack): treat HTTP mode accounts as configured [AI-assisted] (#30571) thanks @liuxiaopai-ai
Verified: - pnpm build - pnpm check - pnpm test:macmini Co-authored-by: liuxiaopai-ai <[email protected]> Co-authored-by: Tak Hoffman <[email protected]>
1 parent e3ba59d commit 4da4cc9

File tree

3 files changed

+56
-3
lines changed

3 files changed

+56
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ Docs: https://docs.openclaw.ai
9191
- Cron/Schedule errors: notify users when a job is auto-disabled after repeated schedule computation failures. (#29098) Thanks .
9292
- Cron/Schedule errors: notify users when a job is auto-disabled after repeated schedule computation failures. (#29098) Thanks .
9393
- File tools/tilde paths: expand `~/...` against the user home directory before workspace-root checks in host file read/write/edit paths, while preserving root-boundary enforcement so outside-root targets remain blocked. (#29779) Thanks @Glucksberg.
94+
- Slack/HTTP mode startup: treat Slack HTTP accounts as configured when `botToken` + `signingSecret` are present (without requiring `appToken`) in channel config/runtime status so webhook mode is not silently skipped. (#30567)
9495
- Onboarding/Custom providers: raise default custom-provider model context window to the runtime hard minimum (16k) and auto-heal existing custom model entries below that threshold during reconfiguration, preventing immediate `Model context window too small (4096 tokens)` failures. (#21653) Thanks @r4jiv007.
9596
- Web UI/Assistant text: strip internal `<relevant-memories>...</relevant-memories>` scaffolding from rendered assistant messages (while preserving code-fence literals), preventing memory-context leakage in chat output for models that echo internal blocks. (#29851) Thanks @Valkster70.
9697
- Dashboard/Sessions: allow authenticated Control UI clients to delete and patch sessions while still blocking regular webchat clients from session mutation RPCs, fixing Dashboard session delete failures. (#21264) Thanks @jskoiz.

extensions/slack/src/channel.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { OpenClawConfig } from "openclaw/plugin-sdk";
12
import { describe, expect, it, vi } from "vitest";
23

34
const handleSlackActionMock = vi.fn();
@@ -104,3 +105,42 @@ describe("slackPlugin outbound", () => {
104105
expect(result).toEqual({ channel: "slack", messageId: "m-media" });
105106
});
106107
});
108+
109+
describe("slackPlugin config", () => {
110+
it("treats HTTP mode accounts with bot token + signing secret as configured", () => {
111+
const cfg: OpenClawConfig = {
112+
channels: {
113+
slack: {
114+
mode: "http",
115+
botToken: "xoxb-http",
116+
signingSecret: "secret-http",
117+
},
118+
},
119+
};
120+
121+
const account = slackPlugin.config.resolveAccount(cfg, "default");
122+
const configured = slackPlugin.config.isConfigured?.(account, cfg);
123+
const snapshot = slackPlugin.status?.buildAccountSnapshot?.({ account, runtime: undefined });
124+
125+
expect(configured).toBe(true);
126+
expect(snapshot?.configured).toBe(true);
127+
});
128+
129+
it("keeps socket mode requiring app token", () => {
130+
const cfg: OpenClawConfig = {
131+
channels: {
132+
slack: {
133+
mode: "socket",
134+
botToken: "xoxb-socket",
135+
},
136+
},
137+
};
138+
139+
const account = slackPlugin.config.resolveAccount(cfg, "default");
140+
const configured = slackPlugin.config.isConfigured?.(account, cfg);
141+
const snapshot = slackPlugin.status?.buildAccountSnapshot?.({ account, runtime: undefined });
142+
143+
expect(configured).toBe(false);
144+
expect(snapshot?.configured).toBe(false);
145+
});
146+
});

extensions/slack/src/channel.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,18 @@ function getTokenForOperation(
5151
return botToken ?? userToken;
5252
}
5353

54+
function isSlackAccountConfigured(account: ResolvedSlackAccount): boolean {
55+
const mode = account.config.mode ?? "socket";
56+
const hasBotToken = Boolean(account.botToken?.trim());
57+
if (!hasBotToken) {
58+
return false;
59+
}
60+
if (mode === "http") {
61+
return Boolean(account.config.signingSecret?.trim());
62+
}
63+
return Boolean(account.appToken?.trim());
64+
}
65+
5466
export const slackPlugin: ChannelPlugin<ResolvedSlackAccount> = {
5567
id: "slack",
5668
meta: {
@@ -116,12 +128,12 @@ export const slackPlugin: ChannelPlugin<ResolvedSlackAccount> = {
116128
accountId,
117129
clearBaseFields: ["botToken", "appToken", "name"],
118130
}),
119-
isConfigured: (account) => Boolean(account.botToken && account.appToken),
131+
isConfigured: (account) => isSlackAccountConfigured(account),
120132
describeAccount: (account) => ({
121133
accountId: account.accountId,
122134
name: account.name,
123135
enabled: account.enabled,
124-
configured: Boolean(account.botToken && account.appToken),
136+
configured: isSlackAccountConfigured(account),
125137
botTokenSource: account.botTokenSource,
126138
appTokenSource: account.appTokenSource,
127139
}),
@@ -382,7 +394,7 @@ export const slackPlugin: ChannelPlugin<ResolvedSlackAccount> = {
382394
return await getSlackRuntime().channel.slack.probeSlack(token, timeoutMs);
383395
},
384396
buildAccountSnapshot: ({ account, runtime, probe }) => {
385-
const configured = Boolean(account.botToken && account.appToken);
397+
const configured = isSlackAccountConfigured(account);
386398
return {
387399
accountId: account.accountId,
388400
name: account.name,

0 commit comments

Comments
 (0)