diff --git a/extensions/discord/src/channel.ts b/extensions/discord/src/channel.ts index 97c33185a0f..bbd86d997e6 100644 --- a/extensions/discord/src/channel.ts +++ b/extensions/discord/src/channel.ts @@ -98,6 +98,22 @@ function resolveRuntimeDiscordMessageActions() { } } +function resolveOptionalDiscordRuntime() { + try { + return getDiscordRuntime(); + } catch { + return null; + } +} + +function resolveDiscordSend(deps?: { [channelId: string]: unknown }): DiscordSendFn { + return ( + resolveOutboundSendDep(deps, "discord") ?? + resolveOptionalDiscordRuntime()?.channel?.discord?.sendMessageDiscord ?? + sendMessageDiscord + ); +} + const discordMessageActions = { describeMessageTool: ( ctx: Parameters>[0], @@ -685,7 +701,7 @@ export const discordPlugin: ChannelPlugin attachedResults: { channel: "discord", sendText: async ({ cfg, to, text, accountId, deps, replyToId, silent }) => { - const send = resolveOutboundSendDep(deps, "discord") ?? sendMessageDiscord; + const send = resolveDiscordSend(deps); return await send(to, text, { verbose: false, cfg, @@ -705,7 +721,7 @@ export const discordPlugin: ChannelPlugin replyToId, silent, }) => { - const send = resolveOutboundSendDep(deps, "discord") ?? sendMessageDiscord; + const send = resolveDiscordSend(deps); return await send(to, text, { verbose: false, cfg, diff --git a/extensions/discord/src/runtime.ts b/extensions/discord/src/runtime.ts index abbfa6c2302..0ab6e8e6d2c 100644 --- a/extensions/discord/src/runtime.ts +++ b/extensions/discord/src/runtime.ts @@ -3,6 +3,7 @@ import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store"; type DiscordChannelRuntime = { messageActions?: typeof import("./channel-actions.js").discordMessageActions; + sendMessageDiscord?: typeof import("./send.js").sendMessageDiscord; }; export type DiscordRuntime = PluginRuntime & { diff --git a/extensions/feishu/src/reply-dispatcher-runtime-api.ts b/extensions/feishu/src/reply-dispatcher-runtime-api.ts index 7a26b9b6406..90a5b1b94e6 100644 --- a/extensions/feishu/src/reply-dispatcher-runtime-api.ts +++ b/extensions/feishu/src/reply-dispatcher-runtime-api.ts @@ -1,2 +1,7 @@ -export type { ClawdbotConfig, OutboundIdentity, ReplyPayload, RuntimeEnv } from "../runtime-api.js"; -export { createReplyPrefixContext } from "openclaw/plugin-sdk/feishu"; +export { + createReplyPrefixContext, + type ClawdbotConfig, + type OutboundIdentity, + type ReplyPayload, + type RuntimeEnv, +} from "../runtime-api.js"; diff --git a/extensions/slack/src/channel.ts b/extensions/slack/src/channel.ts index 5175e9a3cd5..2132d11d3d3 100644 --- a/extensions/slack/src/channel.ts +++ b/extensions/slack/src/channel.ts @@ -66,7 +66,7 @@ import { type ChannelPlugin, type OpenClawConfig, } from "./runtime-api.js"; -import { getSlackRuntime } from "./runtime.js"; +import { getOptionalSlackRuntime, getSlackRuntime } from "./runtime.js"; import { fetchSlackScopes } from "./scopes.js"; import { sendMessageSlack } from "./send.js"; import { slackSetupAdapter } from "./setup-core.js"; @@ -96,6 +96,10 @@ function resolveSlackProbe() { return probeSlack; } +function resolveSlackHandleAction() { + return getOptionalSlackRuntime()?.channel?.slack?.handleSlackAction ?? handleSlackAction; +} + // Select the appropriate Slack token for read/write operations. function getTokenForOperation( account: ResolvedSlackAccount, @@ -364,7 +368,7 @@ export const slackPlugin: ChannelPlugin = crea }, actions: createSlackActions(SLACK_CHANNEL, { invoke: async (action, cfg, toolContext) => - await handleSlackAction( + await resolveSlackHandleAction()( action, cfg as OpenClawConfig, toolContext as SlackActionContext | undefined, diff --git a/extensions/slack/src/runtime.ts b/extensions/slack/src/runtime.ts index 7b623eaafb5..e0241e6c3a9 100644 --- a/extensions/slack/src/runtime.ts +++ b/extensions/slack/src/runtime.ts @@ -1,9 +1,20 @@ import type { PluginRuntime } from "openclaw/plugin-sdk/core"; import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store"; +type SlackChannelRuntime = { + handleSlackAction?: typeof import("./action-runtime.js").handleSlackAction; +}; + +export type SlackRuntime = PluginRuntime & { + channel: PluginRuntime["channel"] & { + slack?: SlackChannelRuntime; + }; +}; + const { setRuntime: setSlackRuntime, clearRuntime: clearSlackRuntime, + tryGetRuntime: getOptionalSlackRuntime, getRuntime: getSlackRuntime, -} = createPluginRuntimeStore("Slack runtime not initialized"); -export { clearSlackRuntime, getSlackRuntime, setSlackRuntime }; +} = createPluginRuntimeStore("Slack runtime not initialized"); +export { clearSlackRuntime, getOptionalSlackRuntime, getSlackRuntime, setSlackRuntime };