refactor: share slack and telegram action helpers

This commit is contained in:
Peter Steinberger
2026-03-26 19:07:35 +00:00
parent a1a9819be8
commit 8f1716ae5a
9 changed files with 129 additions and 172 deletions

View File

@@ -0,0 +1,17 @@
import { parseTelegramTarget } from "./targets.js";
export function resolveTelegramAutoThreadId(params: {
to: string;
toolContext?: { currentThreadTs?: string; currentChannelId?: string };
}): string | undefined {
const context = params.toolContext;
if (!context?.currentThreadTs || !context.currentChannelId) {
return undefined;
}
const parsedTo = parseTelegramTarget(params.to);
const parsedChannel = parseTelegramTarget(context.currentChannelId);
if (parsedTo.chatId.toLowerCase() !== parsedChannel.chatId.toLowerCase()) {
return undefined;
}
return context.currentThreadTs;
}

View File

@@ -7,8 +7,6 @@ import { createAllowlistProviderRouteAllowlistWarningCollector } from "openclaw/
import { attachChannelToResult } from "openclaw/plugin-sdk/channel-send-result";
import { createChatChannelPlugin } from "openclaw/plugin-sdk/core";
import { createChannelDirectoryAdapter } from "openclaw/plugin-sdk/directory-runtime";
import { resolveExecApprovalCommandDisplay } from "openclaw/plugin-sdk/infra-runtime";
import { buildExecApprovalPendingReplyPayload } from "openclaw/plugin-sdk/infra-runtime";
import {
resolveOutboundSendDep,
type OutboundSendDeps,
@@ -40,13 +38,17 @@ import {
resolveTelegramAccount,
type ResolvedTelegramAccount,
} from "./accounts.js";
import { buildTelegramExecApprovalButtons } from "./approval-buttons.js";
import { resolveTelegramAutoThreadId } from "./action-threading.js";
import { auditTelegramGroupMembership, collectTelegramUnmentionedGroupIds } from "./audit.js";
import { buildTelegramGroupPeerId } from "./bot/helpers.js";
import {
listTelegramDirectoryGroupsFromConfig,
listTelegramDirectoryPeersFromConfig,
} from "./directory-config.js";
import {
buildTelegramExecApprovalPendingPayload,
shouldSuppressTelegramExecApprovalForwardingFallback,
} from "./exec-approval-forwarding.js";
import {
isTelegramExecApprovalClientEnabled,
resolveTelegramExecApprovalTarget,
@@ -138,22 +140,6 @@ async function sendTelegramOutbound(params: {
);
}
function resolveTelegramAutoThreadId(params: {
to: string;
toolContext?: { currentThreadTs?: string; currentChannelId?: string };
}): string | undefined {
const context = params.toolContext;
if (!context?.currentThreadTs || !context.currentChannelId) {
return undefined;
}
const parsedTo = parseTelegramTarget(params.to);
const parsedChannel = parseTelegramTarget(context.currentChannelId);
if (parsedTo.chatId.toLowerCase() !== parsedChannel.chatId.toLowerCase()) {
return undefined;
}
return context.currentThreadTs;
}
function normalizeTelegramAcpConversationId(conversationId: string) {
const parsed = parseTelegramTopicConversation({ conversationId });
if (!parsed || !parsed.chatId.startsWith("-")) {
@@ -393,44 +379,10 @@ export const telegramPlugin = createChatChannelPlugin({
? { kind: "enabled" }
: { kind: "disabled" },
hasConfiguredDmRoute: ({ cfg }) => hasTelegramExecApprovalDmRoute(cfg),
shouldSuppressForwardingFallback: ({ cfg, target, request }) => {
const channel = normalizeMessageChannel(target.channel) ?? target.channel;
if (channel !== "telegram") {
return false;
}
const requestChannel = normalizeMessageChannel(request.request.turnSourceChannel ?? "");
if (requestChannel !== "telegram") {
return false;
}
const accountId = target.accountId?.trim() || request.request.turnSourceAccountId?.trim();
return isTelegramExecApprovalClientEnabled({ cfg, accountId });
},
buildPendingPayload: ({ request, nowMs }) => {
const payload = buildExecApprovalPendingReplyPayload({
approvalId: request.id,
approvalSlug: request.id.slice(0, 8),
approvalCommandId: request.id,
command: resolveExecApprovalCommandDisplay(request.request).commandText,
cwd: request.request.cwd ?? undefined,
host: request.request.host === "node" ? "node" : "gateway",
nodeId: request.request.nodeId ?? undefined,
expiresAtMs: request.expiresAtMs,
nowMs,
});
const buttons = buildTelegramExecApprovalButtons(request.id);
if (!buttons) {
return payload;
}
return {
...payload,
channelData: {
...payload.channelData,
telegram: {
buttons,
},
},
};
},
shouldSuppressForwardingFallback: (params) =>
shouldSuppressTelegramExecApprovalForwardingFallback(params),
buildPendingPayload: ({ request, nowMs }) =>
buildTelegramExecApprovalPendingPayload({ request, nowMs }),
beforeDeliverPending: async ({ cfg, target, payload }) => {
const hasExecApprovalData =
payload.channelData &&

View File

@@ -0,0 +1,55 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import type { ExecApprovalRequest } from "openclaw/plugin-sdk/infra-runtime";
import {
buildExecApprovalPendingReplyPayload,
resolveExecApprovalCommandDisplay,
} from "openclaw/plugin-sdk/infra-runtime";
import { normalizeMessageChannel } from "openclaw/plugin-sdk/routing";
import { buildTelegramExecApprovalButtons } from "./approval-buttons.js";
import { isTelegramExecApprovalClientEnabled } from "./exec-approvals.js";
export function shouldSuppressTelegramExecApprovalForwardingFallback(params: {
cfg: OpenClawConfig;
target: { channel: string; accountId?: string | null };
request: ExecApprovalRequest;
}): boolean {
const channel = normalizeMessageChannel(params.target.channel) ?? params.target.channel;
if (channel !== "telegram") {
return false;
}
const requestChannel = normalizeMessageChannel(params.request.request.turnSourceChannel ?? "");
if (requestChannel !== "telegram") {
return false;
}
const accountId =
params.target.accountId?.trim() || params.request.request.turnSourceAccountId?.trim();
return isTelegramExecApprovalClientEnabled({ cfg: params.cfg, accountId });
}
export function buildTelegramExecApprovalPendingPayload(params: {
request: ExecApprovalRequest;
nowMs: number;
}) {
const payload = buildExecApprovalPendingReplyPayload({
approvalId: params.request.id,
approvalSlug: params.request.id.slice(0, 8),
approvalCommandId: params.request.id,
command: resolveExecApprovalCommandDisplay(params.request.request).commandText,
cwd: params.request.request.cwd ?? undefined,
host: params.request.request.host === "node" ? "node" : "gateway",
nodeId: params.request.request.nodeId ?? undefined,
expiresAtMs: params.request.expiresAtMs,
nowMs: params.nowMs,
});
const buttons = buildTelegramExecApprovalButtons(params.request.id);
if (!buttons) {
return payload;
}
return {
...payload,
channelData: {
...payload.channelData,
telegram: { buttons },
},
};
}