From f3da2920974634b2cf2c391ec93ef66c99609a13 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 17 Mar 2026 04:55:07 +0000 Subject: [PATCH] refactor(slack): share plugin base config --- extensions/slack/src/channel.setup.ts | 57 +++----------------------- extensions/slack/src/channel.ts | 59 +++++---------------------- 2 files changed, 17 insertions(+), 99 deletions(-) diff --git a/extensions/slack/src/channel.setup.ts b/extensions/slack/src/channel.setup.ts index 2fbaac93ab6..854e1782315 100644 --- a/extensions/slack/src/channel.setup.ts +++ b/extensions/slack/src/channel.setup.ts @@ -1,57 +1,12 @@ -import { - buildChannelConfigSchema, - getChatChannelMeta, - SlackConfigSchema, - type ChannelPlugin, -} from "openclaw/plugin-sdk/slack"; +import { type ChannelPlugin } from "openclaw/plugin-sdk/slack"; import { type ResolvedSlackAccount } from "./accounts.js"; -import { isSlackInteractiveRepliesEnabled } from "./interactive-replies.js"; import { slackSetupAdapter } from "./setup-core.js"; import { slackSetupWizard } from "./setup-surface.js"; -import { isSlackPluginAccountConfigured, slackConfigAccessors, slackConfigBase } from "./shared.js"; +import { createSlackPluginBase } from "./shared.js"; export const slackSetupPlugin: ChannelPlugin = { - id: "slack", - meta: { - ...getChatChannelMeta("slack"), - preferSessionLookupForAnnounceTarget: true, - }, - setupWizard: slackSetupWizard, - capabilities: { - chatTypes: ["direct", "channel", "thread"], - reactions: true, - threads: true, - media: true, - nativeCommands: true, - }, - agentPrompt: { - messageToolHints: ({ cfg, accountId }) => - isSlackInteractiveRepliesEnabled({ cfg, accountId }) - ? [ - "- Slack interactive replies: use `[[slack_buttons: Label:value, Other:other]]` to add action buttons that route clicks back as Slack interaction system events.", - "- Slack selects: use `[[slack_select: Placeholder | Label:value, Other:other]]` to add a static select menu that routes the chosen value back as a Slack interaction system event.", - ] - : [ - "- Slack interactive replies are disabled. If needed, ask to set `channels.slack.capabilities.interactiveReplies=true` (or the same under `channels.slack.accounts..capabilities`).", - ], - }, - streaming: { - blockStreamingCoalesceDefaults: { minChars: 1500, idleMs: 1000 }, - }, - reload: { configPrefixes: ["channels.slack"] }, - configSchema: buildChannelConfigSchema(SlackConfigSchema), - config: { - ...slackConfigBase, - isConfigured: (account) => isSlackPluginAccountConfigured(account), - describeAccount: (account) => ({ - accountId: account.accountId, - name: account.name, - enabled: account.enabled, - configured: isSlackPluginAccountConfigured(account), - botTokenSource: account.botTokenSource, - appTokenSource: account.appTokenSource, - }), - ...slackConfigAccessors, - }, - setup: slackSetupAdapter, + ...createSlackPluginBase({ + setupWizard: slackSetupWizard, + setup: slackSetupAdapter, + }), }; diff --git a/extensions/slack/src/channel.ts b/extensions/slack/src/channel.ts index cdddeadebfe..66e640e1bcf 100644 --- a/extensions/slack/src/channel.ts +++ b/extensions/slack/src/channel.ts @@ -15,9 +15,7 @@ import { } from "openclaw/plugin-sdk/core"; import { buildComputedAccountStatusSnapshot, - buildChannelConfigSchema, DEFAULT_ACCOUNT_ID, - getChatChannelMeta, listSlackDirectoryGroupsFromConfig, listSlackDirectoryPeersFromConfig, looksLikeSlackTargetId, @@ -27,7 +25,6 @@ import { resolveConfiguredFromRequiredCredentialStatuses, resolveSlackGroupRequireMention, resolveSlackGroupToolPolicy, - SlackConfigSchema, type ChannelPlugin, type OpenClawConfig, } from "openclaw/plugin-sdk/slack"; @@ -50,11 +47,15 @@ import { getSlackRuntime } from "./runtime.js"; import { fetchSlackScopes } from "./scopes.js"; import { slackSetupAdapter } from "./setup-core.js"; import { slackSetupWizard } from "./setup-surface.js"; -import { isSlackPluginAccountConfigured, slackConfigAccessors, slackConfigBase } from "./shared.js"; +import { + createSlackPluginBase, + isSlackPluginAccountConfigured, + slackConfigAccessors, + SLACK_CHANNEL, +} from "./shared.js"; import { parseSlackTarget } from "./targets.js"; import { buildSlackThreadingToolContext } from "./threading-tool-context.js"; -const meta = getChatChannelMeta("slack"); const SLACK_CHANNEL_TYPE_CACHE = new Map(); // Select the appropriate Slack token for read/write operations. @@ -329,12 +330,10 @@ async function resolveSlackAllowlistNames(params: { } export const slackPlugin: ChannelPlugin = { - id: "slack", - meta: { - ...meta, - preferSessionLookupForAnnounceTarget: true, - }, - setupWizard: slackSetupWizard, + ...createSlackPluginBase({ + setupWizard: slackSetupWizard, + setup: slackSetupAdapter, + }), pairing: { idLabel: "slackUserId", normalizeAllowEntry: (entry) => entry.replace(/^(slack|user):/i, ""), @@ -363,42 +362,6 @@ export const slackPlugin: ChannelPlugin = { } }, }, - capabilities: { - chatTypes: ["direct", "channel", "thread"], - reactions: true, - threads: true, - media: true, - nativeCommands: true, - }, - agentPrompt: { - messageToolHints: ({ cfg, accountId }) => - isSlackInteractiveRepliesEnabled({ cfg, accountId }) - ? [ - "- Slack interactive replies: use `[[slack_buttons: Label:value, Other:other]]` to add action buttons that route clicks back as Slack interaction system events.", - "- Slack selects: use `[[slack_select: Placeholder | Label:value, Other:other]]` to add a static select menu that routes the chosen value back as a Slack interaction system event.", - ] - : [ - "- Slack interactive replies are disabled. If needed, ask to set `channels.slack.capabilities.interactiveReplies=true` (or the same under `channels.slack.accounts..capabilities`).", - ], - }, - streaming: { - blockStreamingCoalesceDefaults: { minChars: 1500, idleMs: 1000 }, - }, - reload: { configPrefixes: ["channels.slack"] }, - configSchema: buildChannelConfigSchema(SlackConfigSchema), - config: { - ...slackConfigBase, - isConfigured: (account) => isSlackPluginAccountConfigured(account), - describeAccount: (account) => ({ - accountId: account.accountId, - name: account.name, - enabled: account.enabled, - configured: isSlackPluginAccountConfigured(account), - botTokenSource: account.botTokenSource, - appTokenSource: account.appTokenSource, - }), - ...slackConfigAccessors, - }, allowlist: { supportsScope: ({ scope }) => scope === "dm", readConfig: ({ cfg, accountId }) => @@ -561,7 +524,7 @@ export const slackPlugin: ChannelPlugin = { extractToolSend: ({ args }) => extractSlackToolSend(args), handleAction: async (ctx) => await handleSlackMessageAction({ - providerId: meta.id, + providerId: SLACK_CHANNEL, ctx, includeReadThreadId: true, invoke: async (action, cfg, toolContext) =>