diff --git a/extensions/slack/src/channel.ts b/extensions/slack/src/channel.ts index 74b283884a7..2980316a138 100644 --- a/extensions/slack/src/channel.ts +++ b/extensions/slack/src/channel.ts @@ -24,6 +24,7 @@ import { type ChannelPlugin, type OpenClawConfig, } from "openclaw/plugin-sdk/slack"; +import { createSlackActions } from "../../../src/channels/plugins/slack.actions.js"; import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js"; import { normalizeOutboundThreadId } from "../../../src/infra/outbound/thread-id.js"; import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js"; @@ -36,8 +37,6 @@ import { import { parseSlackBlocksInput } from "./blocks-input.js"; import { createSlackWebClient } from "./client.js"; import { isSlackInteractiveRepliesEnabled } from "./interactive-replies.js"; -import { handleSlackMessageAction } from "./message-action-dispatch.js"; -import { extractSlackToolSend, listSlackMessageActions } from "./message-actions.js"; import { normalizeAllowListLower } from "./monitor/allow-list.js"; import type { SlackProbe } from "./probe.js"; import { resolveSlackUserAllowlist } from "./resolve-users.js"; @@ -319,6 +318,12 @@ const slackSetupWizard = createSlackSetupWizardProxy(async () => ({ slackSetupWizard: (await loadSlackChannelRuntime()).slackSetupWizard, })); +const slackActions = createSlackActions("slack", { + invoke: () => async (action, cfg, toolContext) => + await getSlackRuntime().channel.slack.handleSlackAction(action, cfg, toolContext), + skipNormalizeChannelId: true, +}); + export const slackPlugin: ChannelPlugin = { ...createSlackPluginBase({ setupWizard: slackSetupWizard, @@ -506,28 +511,7 @@ export const slackPlugin: ChannelPlugin = { return resolved.map((entry) => toResolvedTarget(entry, entry.note)); }, }, - actions: { - listActions: ({ cfg }) => listSlackMessageActions(cfg), - getCapabilities: ({ cfg }) => { - const capabilities = new Set<"interactive" | "blocks">(); - if (listSlackMessageActions(cfg).includes("send")) { - capabilities.add("blocks"); - } - if (isSlackInteractiveRepliesEnabled({ cfg })) { - capabilities.add("interactive"); - } - return Array.from(capabilities); - }, - extractToolSend: ({ args }) => extractSlackToolSend(args), - handleAction: async (ctx) => - await handleSlackMessageAction({ - providerId: "slack", - ctx, - includeReadThreadId: true, - invoke: async (action, cfg, toolContext) => - await getSlackRuntime().channel.slack.handleSlackAction(action, cfg, toolContext), - }), - }, + actions: slackActions, outbound: { deliveryMode: "direct", chunker: null, diff --git a/src/channels/plugins/slack.actions.ts b/src/channels/plugins/slack.actions.ts index 7e74af7058d..df53d1ff0e0 100644 --- a/src/channels/plugins/slack.actions.ts +++ b/src/channels/plugins/slack.actions.ts @@ -6,9 +6,20 @@ import { resolveSlackChannelId, } from "../../plugin-sdk-internal/slack.js"; import { handleSlackMessageAction } from "../../plugin-sdk/slack-message-actions.js"; -import type { ChannelMessageActionAdapter } from "./types.js"; +import type { ChannelMessageActionAdapter, ChannelMessageActionContext } from "./types.js"; -export function createSlackActions(providerId: string): ChannelMessageActionAdapter { +type SlackActionAdapterOptions = { + includeReadThreadId?: boolean; + invoke?: ( + ctx: ChannelMessageActionContext, + ) => Parameters[0]["invoke"]; + skipNormalizeChannelId?: boolean; +}; + +export function createSlackActions( + providerId: string, + options?: SlackActionAdapterOptions, +): ChannelMessageActionAdapter { return { listActions: ({ cfg }) => listSlackMessageActions(cfg), getCapabilities: ({ cfg }) => { @@ -23,16 +34,19 @@ export function createSlackActions(providerId: string): ChannelMessageActionAdap }, extractToolSend: ({ args }) => extractSlackToolSend(args), handleAction: async (ctx) => { - return await handleSlackMessageAction({ - providerId, - ctx, - normalizeChannelId: resolveSlackChannelId, - includeReadThreadId: true, - invoke: async (action, cfg, toolContext) => + const invoke = + options?.invoke?.(ctx) ?? + (async (action, cfg, toolContext) => await handleSlackAction(action, cfg, { ...(toolContext as SlackActionContext | undefined), mediaLocalRoots: ctx.mediaLocalRoots, - }), + })); + return await handleSlackMessageAction({ + providerId, + ctx, + normalizeChannelId: options?.skipNormalizeChannelId ? undefined : resolveSlackChannelId, + includeReadThreadId: options?.includeReadThreadId ?? true, + invoke, }); }, };