mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
fix(slack): treat HTTP mode accounts as configured [AI-assisted] (openclaw#30571) thanks @liuxiaopai-ai
Verified: - pnpm build - pnpm check - pnpm test:macmini Co-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
@@ -91,6 +91,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Cron/Schedule errors: notify users when a job is auto-disabled after repeated schedule computation failures. (#29098) Thanks .
|
||||
- Cron/Schedule errors: notify users when a job is auto-disabled after repeated schedule computation failures. (#29098) Thanks .
|
||||
- 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.
|
||||
- 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)
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
const handleSlackActionMock = vi.fn();
|
||||
@@ -104,3 +105,42 @@ describe("slackPlugin outbound", () => {
|
||||
expect(result).toEqual({ channel: "slack", messageId: "m-media" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("slackPlugin config", () => {
|
||||
it("treats HTTP mode accounts with bot token + signing secret as configured", () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
channels: {
|
||||
slack: {
|
||||
mode: "http",
|
||||
botToken: "xoxb-http",
|
||||
signingSecret: "secret-http",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const account = slackPlugin.config.resolveAccount(cfg, "default");
|
||||
const configured = slackPlugin.config.isConfigured?.(account, cfg);
|
||||
const snapshot = slackPlugin.status?.buildAccountSnapshot?.({ account, runtime: undefined });
|
||||
|
||||
expect(configured).toBe(true);
|
||||
expect(snapshot?.configured).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps socket mode requiring app token", () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
channels: {
|
||||
slack: {
|
||||
mode: "socket",
|
||||
botToken: "xoxb-socket",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const account = slackPlugin.config.resolveAccount(cfg, "default");
|
||||
const configured = slackPlugin.config.isConfigured?.(account, cfg);
|
||||
const snapshot = slackPlugin.status?.buildAccountSnapshot?.({ account, runtime: undefined });
|
||||
|
||||
expect(configured).toBe(false);
|
||||
expect(snapshot?.configured).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,6 +51,18 @@ function getTokenForOperation(
|
||||
return botToken ?? userToken;
|
||||
}
|
||||
|
||||
function isSlackAccountConfigured(account: ResolvedSlackAccount): boolean {
|
||||
const mode = account.config.mode ?? "socket";
|
||||
const hasBotToken = Boolean(account.botToken?.trim());
|
||||
if (!hasBotToken) {
|
||||
return false;
|
||||
}
|
||||
if (mode === "http") {
|
||||
return Boolean(account.config.signingSecret?.trim());
|
||||
}
|
||||
return Boolean(account.appToken?.trim());
|
||||
}
|
||||
|
||||
export const slackPlugin: ChannelPlugin<ResolvedSlackAccount> = {
|
||||
id: "slack",
|
||||
meta: {
|
||||
@@ -116,12 +128,12 @@ export const slackPlugin: ChannelPlugin<ResolvedSlackAccount> = {
|
||||
accountId,
|
||||
clearBaseFields: ["botToken", "appToken", "name"],
|
||||
}),
|
||||
isConfigured: (account) => Boolean(account.botToken && account.appToken),
|
||||
isConfigured: (account) => isSlackAccountConfigured(account),
|
||||
describeAccount: (account) => ({
|
||||
accountId: account.accountId,
|
||||
name: account.name,
|
||||
enabled: account.enabled,
|
||||
configured: Boolean(account.botToken && account.appToken),
|
||||
configured: isSlackAccountConfigured(account),
|
||||
botTokenSource: account.botTokenSource,
|
||||
appTokenSource: account.appTokenSource,
|
||||
}),
|
||||
@@ -382,7 +394,7 @@ export const slackPlugin: ChannelPlugin<ResolvedSlackAccount> = {
|
||||
return await getSlackRuntime().channel.slack.probeSlack(token, timeoutMs);
|
||||
},
|
||||
buildAccountSnapshot: ({ account, runtime, probe }) => {
|
||||
const configured = Boolean(account.botToken && account.appToken);
|
||||
const configured = isSlackAccountConfigured(account);
|
||||
return {
|
||||
accountId: account.accountId,
|
||||
name: account.name,
|
||||
|
||||
Reference in New Issue
Block a user