mirror of
https://github.com/farcasclaudiu/openclaw.git
synced 2026-06-28 21:01:43 +03:00
refactor(slack): dedupe outbound hook handling
This commit is contained in:
@@ -17,6 +17,35 @@ function resolveSlackSendIdentity(identity?: OutboundIdentity): SlackSendIdentit
|
|||||||
return { username, iconUrl, iconEmoji };
|
return { username, iconUrl, iconEmoji };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function applySlackMessageSendingHooks(params: {
|
||||||
|
to: string;
|
||||||
|
text: string;
|
||||||
|
threadTs?: string;
|
||||||
|
accountId?: string;
|
||||||
|
mediaUrl?: string;
|
||||||
|
}): Promise<{ cancelled: boolean; text: string }> {
|
||||||
|
const hookRunner = getGlobalHookRunner();
|
||||||
|
if (!hookRunner?.hasHooks("message_sending")) {
|
||||||
|
return { cancelled: false, text: params.text };
|
||||||
|
}
|
||||||
|
const hookResult = await hookRunner.runMessageSending(
|
||||||
|
{
|
||||||
|
to: params.to,
|
||||||
|
content: params.text,
|
||||||
|
metadata: {
|
||||||
|
threadTs: params.threadTs,
|
||||||
|
channelId: params.to,
|
||||||
|
...(params.mediaUrl ? { mediaUrl: params.mediaUrl } : {}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ channelId: "slack", accountId: params.accountId ?? undefined },
|
||||||
|
);
|
||||||
|
if (hookResult?.cancel) {
|
||||||
|
return { cancelled: true, text: params.text };
|
||||||
|
}
|
||||||
|
return { cancelled: false, text: hookResult?.content ?? params.text };
|
||||||
|
}
|
||||||
|
|
||||||
export const slackOutbound: ChannelOutboundAdapter = {
|
export const slackOutbound: ChannelOutboundAdapter = {
|
||||||
deliveryMode: "direct",
|
deliveryMode: "direct",
|
||||||
chunker: null,
|
chunker: null,
|
||||||
@@ -25,30 +54,23 @@ export const slackOutbound: ChannelOutboundAdapter = {
|
|||||||
const send = deps?.sendSlack ?? sendMessageSlack;
|
const send = deps?.sendSlack ?? sendMessageSlack;
|
||||||
// Use threadId fallback so routed tool notifications stay in the Slack thread.
|
// Use threadId fallback so routed tool notifications stay in the Slack thread.
|
||||||
const threadTs = replyToId ?? (threadId != null ? String(threadId) : undefined);
|
const threadTs = replyToId ?? (threadId != null ? String(threadId) : undefined);
|
||||||
let finalText = text;
|
const hookResult = await applySlackMessageSendingHooks({
|
||||||
|
to,
|
||||||
// Run message_sending hooks (e.g. thread-ownership can cancel the send).
|
text,
|
||||||
const hookRunner = getGlobalHookRunner();
|
threadTs,
|
||||||
if (hookRunner?.hasHooks("message_sending")) {
|
accountId: accountId ?? undefined,
|
||||||
const hookResult = await hookRunner.runMessageSending(
|
});
|
||||||
{ to, content: text, metadata: { threadTs, channelId: to } },
|
if (hookResult.cancelled) {
|
||||||
{ channelId: "slack", accountId: accountId ?? undefined },
|
return {
|
||||||
);
|
channel: "slack",
|
||||||
if (hookResult?.cancel) {
|
messageId: "cancelled-by-hook",
|
||||||
return {
|
channelId: to,
|
||||||
channel: "slack",
|
meta: { cancelled: true },
|
||||||
messageId: "cancelled-by-hook",
|
};
|
||||||
channelId: to,
|
|
||||||
meta: { cancelled: true },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (hookResult?.content) {
|
|
||||||
finalText = hookResult.content;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const slackIdentity = resolveSlackSendIdentity(identity);
|
const slackIdentity = resolveSlackSendIdentity(identity);
|
||||||
const result = await send(to, finalText, {
|
const result = await send(to, hookResult.text, {
|
||||||
threadTs,
|
threadTs,
|
||||||
accountId: accountId ?? undefined,
|
accountId: accountId ?? undefined,
|
||||||
...(slackIdentity ? { identity: slackIdentity } : {}),
|
...(slackIdentity ? { identity: slackIdentity } : {}),
|
||||||
@@ -59,30 +81,24 @@ export const slackOutbound: ChannelOutboundAdapter = {
|
|||||||
const send = deps?.sendSlack ?? sendMessageSlack;
|
const send = deps?.sendSlack ?? sendMessageSlack;
|
||||||
// Use threadId fallback so routed tool notifications stay in the Slack thread.
|
// Use threadId fallback so routed tool notifications stay in the Slack thread.
|
||||||
const threadTs = replyToId ?? (threadId != null ? String(threadId) : undefined);
|
const threadTs = replyToId ?? (threadId != null ? String(threadId) : undefined);
|
||||||
let finalText = text;
|
const hookResult = await applySlackMessageSendingHooks({
|
||||||
|
to,
|
||||||
// Run message_sending hooks (e.g. thread-ownership can cancel the send).
|
text,
|
||||||
const hookRunner = getGlobalHookRunner();
|
threadTs,
|
||||||
if (hookRunner?.hasHooks("message_sending")) {
|
mediaUrl,
|
||||||
const hookResult = await hookRunner.runMessageSending(
|
accountId: accountId ?? undefined,
|
||||||
{ to, content: text, metadata: { threadTs, channelId: to, mediaUrl } },
|
});
|
||||||
{ channelId: "slack", accountId: accountId ?? undefined },
|
if (hookResult.cancelled) {
|
||||||
);
|
return {
|
||||||
if (hookResult?.cancel) {
|
channel: "slack",
|
||||||
return {
|
messageId: "cancelled-by-hook",
|
||||||
channel: "slack",
|
channelId: to,
|
||||||
messageId: "cancelled-by-hook",
|
meta: { cancelled: true },
|
||||||
channelId: to,
|
};
|
||||||
meta: { cancelled: true },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (hookResult?.content) {
|
|
||||||
finalText = hookResult.content;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const slackIdentity = resolveSlackSendIdentity(identity);
|
const slackIdentity = resolveSlackSendIdentity(identity);
|
||||||
const result = await send(to, finalText, {
|
const result = await send(to, hookResult.text, {
|
||||||
mediaUrl,
|
mediaUrl,
|
||||||
threadTs,
|
threadTs,
|
||||||
accountId: accountId ?? undefined,
|
accountId: accountId ?? undefined,
|
||||||
|
|||||||
Reference in New Issue
Block a user