refactor: share telegram payload send flow

This commit is contained in:
Peter Steinberger
2026-03-10 20:43:56 +00:00
parent a455c0cc3d
commit bc1cc2e50f
4 changed files with 140 additions and 85 deletions

View File

@@ -1,3 +1,4 @@
import type { ReplyPayload } from "../../../auto-reply/types.js";
import type { OutboundSendDeps } from "../../../infra/outbound/deliver.js";
import type { TelegramInlineButtons } from "../../../telegram/button-types.js";
import { markdownToTelegramHtmlChunks } from "../../../telegram/format.js";
@@ -8,16 +9,19 @@ import {
import { sendMessageTelegram } from "../../../telegram/send.js";
import type { ChannelOutboundAdapter } from "../types.js";
type TelegramSendFn = typeof sendMessageTelegram;
type TelegramSendOpts = Parameters<TelegramSendFn>[2];
function resolveTelegramSendContext(params: {
cfg: NonNullable<Parameters<typeof sendMessageTelegram>[2]>["cfg"];
cfg: NonNullable<TelegramSendOpts>["cfg"];
deps?: OutboundSendDeps;
accountId?: string | null;
replyToId?: string | null;
threadId?: string | number | null;
}): {
send: typeof sendMessageTelegram;
send: TelegramSendFn;
baseOpts: {
cfg: NonNullable<Parameters<typeof sendMessageTelegram>[2]>["cfg"];
cfg: NonNullable<TelegramSendOpts>["cfg"];
verbose: false;
textMode: "html";
messageThreadId?: number;
@@ -39,6 +43,49 @@ function resolveTelegramSendContext(params: {
};
}
export async function sendTelegramPayloadMessages(params: {
send: TelegramSendFn;
to: string;
payload: ReplyPayload;
baseOpts: Omit<NonNullable<TelegramSendOpts>, "buttons" | "mediaUrl" | "quoteText">;
}): Promise<Awaited<ReturnType<TelegramSendFn>>> {
const telegramData = params.payload.channelData?.telegram as
| { buttons?: TelegramInlineButtons; quoteText?: string }
| undefined;
const quoteText =
typeof telegramData?.quoteText === "string" ? telegramData.quoteText : undefined;
const text = params.payload.text ?? "";
const mediaUrls = params.payload.mediaUrls?.length
? params.payload.mediaUrls
: params.payload.mediaUrl
? [params.payload.mediaUrl]
: [];
const payloadOpts = {
...params.baseOpts,
quoteText,
};
if (mediaUrls.length === 0) {
return await params.send(params.to, text, {
...payloadOpts,
buttons: telegramData?.buttons,
});
}
// Telegram allows reply_markup on media; attach buttons only to the first send.
let finalResult: Awaited<ReturnType<TelegramSendFn>> | undefined;
for (let i = 0; i < mediaUrls.length; i += 1) {
const mediaUrl = mediaUrls[i];
const isFirst = i === 0;
finalResult = await params.send(params.to, isFirst ? text : "", {
...payloadOpts,
mediaUrl,
...(isFirst ? { buttons: telegramData?.buttons } : {}),
});
}
return finalResult ?? { messageId: "unknown", chatId: params.to };
}
export const telegramOutbound: ChannelOutboundAdapter = {
deliveryMode: "direct",
chunker: markdownToTelegramHtmlChunks,
@@ -92,48 +139,22 @@ export const telegramOutbound: ChannelOutboundAdapter = {
replyToId,
threadId,
}) => {
const { send, baseOpts: contextOpts } = resolveTelegramSendContext({
const { send, baseOpts } = resolveTelegramSendContext({
cfg,
deps,
accountId,
replyToId,
threadId,
});
const telegramData = payload.channelData?.telegram as
| { buttons?: TelegramInlineButtons; quoteText?: string }
| undefined;
const quoteText =
typeof telegramData?.quoteText === "string" ? telegramData.quoteText : undefined;
const text = payload.text ?? "";
const mediaUrls = payload.mediaUrls?.length
? payload.mediaUrls
: payload.mediaUrl
? [payload.mediaUrl]
: [];
const payloadOpts = {
...contextOpts,
quoteText,
mediaLocalRoots,
};
if (mediaUrls.length === 0) {
const result = await send(to, text, {
...payloadOpts,
buttons: telegramData?.buttons,
});
return { channel: "telegram", ...result };
}
// Telegram allows reply_markup on media; attach buttons only to first send.
let finalResult: Awaited<ReturnType<typeof send>> | undefined;
for (let i = 0; i < mediaUrls.length; i += 1) {
const mediaUrl = mediaUrls[i];
const isFirst = i === 0;
finalResult = await send(to, isFirst ? text : "", {
...payloadOpts,
mediaUrl,
...(isFirst ? { buttons: telegramData?.buttons } : {}),
});
}
return { channel: "telegram", ...(finalResult ?? { messageId: "unknown", chatId: to }) };
const result = await sendTelegramPayloadMessages({
send,
to,
payload,
baseOpts: {
...baseOpts,
mediaLocalRoots,
},
});
return { channel: "telegram", ...result };
},
};

View File

@@ -53,6 +53,7 @@ export {
parseTelegramThreadId,
} from "../telegram/outbound-params.js";
export { collectTelegramStatusIssues } from "../channels/plugins/status-issues/telegram.js";
export { sendTelegramPayloadMessages } from "../channels/plugins/outbound/telegram.js";
export {
resolveAllowlistProviderRuntimeGroupPolicy,