refactor: share telegram reply chunk threading

This commit is contained in:
Peter Steinberger 2026-03-14 01:15:35 +00:00
parent 66de7311c7
commit 5197171d7a
2 changed files with 57 additions and 72 deletions

View File

@ -34,13 +34,17 @@ import {
sendTelegramWithThreadFallback, sendTelegramWithThreadFallback,
} from "./delivery.send.js"; } from "./delivery.send.js";
import { resolveTelegramReplyId, type TelegramThreadSpec } from "./helpers.js"; import { resolveTelegramReplyId, type TelegramThreadSpec } from "./helpers.js";
import {
markReplyApplied,
resolveReplyToForSend,
sendChunkedTelegramReplyText,
type DeliveryProgress as ReplyThreadDeliveryProgress,
} from "./reply-threading.js";
const VOICE_FORBIDDEN_RE = /VOICE_MESSAGES_FORBIDDEN/; const VOICE_FORBIDDEN_RE = /VOICE_MESSAGES_FORBIDDEN/;
const CAPTION_TOO_LONG_RE = /caption is too long/i; const CAPTION_TOO_LONG_RE = /caption is too long/i;
type DeliveryProgress = { type DeliveryProgress = ReplyThreadDeliveryProgress & {
hasReplied: boolean;
hasDelivered: boolean;
deliveredCount: number; deliveredCount: number;
}; };
@ -81,22 +85,6 @@ function buildChunkTextResolver(params: {
}; };
} }
function resolveReplyToForSend(params: {
replyToId?: number;
replyToMode: ReplyToMode;
progress: DeliveryProgress;
}): number | undefined {
return params.replyToId && (params.replyToMode === "all" || !params.progress.hasReplied)
? params.replyToId
: undefined;
}
function markReplyApplied(progress: DeliveryProgress, replyToId?: number): void {
if (replyToId && !progress.hasReplied) {
progress.hasReplied = true;
}
}
function markDelivered(progress: DeliveryProgress): void { function markDelivered(progress: DeliveryProgress): void {
progress.hasDelivered = true; progress.hasDelivered = true;
progress.deliveredCount += 1; progress.deliveredCount += 1;
@ -117,39 +105,35 @@ async function deliverTextReply(params: {
progress: DeliveryProgress; progress: DeliveryProgress;
}): Promise<number | undefined> { }): Promise<number | undefined> {
let firstDeliveredMessageId: number | undefined; let firstDeliveredMessageId: number | undefined;
const chunks = params.chunkText(params.replyText); await sendChunkedTelegramReplyText({
for (let i = 0; i < chunks.length; i += 1) { chunks: params.chunkText(params.replyText),
const chunk = chunks[i]; progress: params.progress,
if (!chunk) { replyToId: params.replyToId,
continue; replyToMode: params.replyToMode,
} replyMarkup: params.replyMarkup,
const shouldAttachButtons = i === 0 && params.replyMarkup; replyQuoteText: params.replyQuoteText,
const replyToForChunk = resolveReplyToForSend({ markDelivered,
replyToId: params.replyToId, sendChunk: async ({ chunk, replyToMessageId, replyMarkup, replyQuoteText }) => {
replyToMode: params.replyToMode, const messageId = await sendTelegramText(
progress: params.progress, params.bot,
}); params.chatId,
const messageId = await sendTelegramText( chunk.html,
params.bot, params.runtime,
params.chatId, {
chunk.html, replyToMessageId,
params.runtime, replyQuoteText,
{ thread: params.thread,
replyToMessageId: replyToForChunk, textMode: "html",
replyQuoteText: params.replyQuoteText, plainText: chunk.text,
thread: params.thread, linkPreview: params.linkPreview,
textMode: "html", replyMarkup,
plainText: chunk.text, },
linkPreview: params.linkPreview, );
replyMarkup: shouldAttachButtons ? params.replyMarkup : undefined, if (firstDeliveredMessageId == null) {
}, firstDeliveredMessageId = messageId;
); }
if (firstDeliveredMessageId == null) { },
firstDeliveredMessageId = messageId; });
}
markReplyApplied(params.progress, replyToForChunk);
markDelivered(params.progress);
}
return firstDeliveredMessageId; return firstDeliveredMessageId;
} }
@ -166,25 +150,24 @@ async function sendPendingFollowUpText(params: {
replyToMode: ReplyToMode; replyToMode: ReplyToMode;
progress: DeliveryProgress; progress: DeliveryProgress;
}): Promise<void> { }): Promise<void> {
const chunks = params.chunkText(params.text); await sendChunkedTelegramReplyText({
for (let i = 0; i < chunks.length; i += 1) { chunks: params.chunkText(params.text),
const chunk = chunks[i]; progress: params.progress,
const replyToForFollowUp = resolveReplyToForSend({ replyToId: params.replyToId,
replyToId: params.replyToId, replyToMode: params.replyToMode,
replyToMode: params.replyToMode, replyMarkup: params.replyMarkup,
progress: params.progress, markDelivered,
}); sendChunk: async ({ chunk, replyToMessageId, replyMarkup }) => {
await sendTelegramText(params.bot, params.chatId, chunk.html, params.runtime, { await sendTelegramText(params.bot, params.chatId, chunk.html, params.runtime, {
replyToMessageId: replyToForFollowUp, replyToMessageId,
thread: params.thread, thread: params.thread,
textMode: "html", textMode: "html",
plainText: chunk.text, plainText: chunk.text,
linkPreview: params.linkPreview, linkPreview: params.linkPreview,
replyMarkup: i === 0 ? params.replyMarkup : undefined, replyMarkup,
}); });
markReplyApplied(params.progress, replyToForFollowUp); },
markDelivered(params.progress); });
}
} }
function isVoiceMessagesForbidden(err: unknown): boolean { function isVoiceMessagesForbidden(err: unknown): boolean {

View File

@ -40,6 +40,7 @@ export async function sendChunkedTelegramReplyText<TChunk, TReplyMarkup = unknow
replyMarkup?: TReplyMarkup; replyMarkup?: TReplyMarkup;
replyQuoteText?: string; replyQuoteText?: string;
quoteOnlyOnFirstChunk?: boolean; quoteOnlyOnFirstChunk?: boolean;
markDelivered?: (progress: DeliveryProgress) => void;
sendChunk: (opts: { sendChunk: (opts: {
chunk: TChunk; chunk: TChunk;
isFirstChunk: boolean; isFirstChunk: boolean;
@ -48,6 +49,7 @@ export async function sendChunkedTelegramReplyText<TChunk, TReplyMarkup = unknow
replyQuoteText?: string; replyQuoteText?: string;
}) => Promise<void>; }) => Promise<void>;
}): Promise<void> { }): Promise<void> {
const applyDelivered = params.markDelivered ?? markDelivered;
for (let i = 0; i < params.chunks.length; i += 1) { for (let i = 0; i < params.chunks.length; i += 1) {
const chunk = params.chunks[i]; const chunk = params.chunks[i];
if (!chunk) { if (!chunk) {
@ -71,6 +73,6 @@ export async function sendChunkedTelegramReplyText<TChunk, TReplyMarkup = unknow
replyQuoteText: shouldAttachQuote ? params.replyQuoteText : undefined, replyQuoteText: shouldAttachQuote ? params.replyQuoteText : undefined,
}); });
markReplyApplied(params.progress, replyToMessageId); markReplyApplied(params.progress, replyToMessageId);
markDelivered(params.progress); applyDelivered(params.progress);
} }
} }