Skip to content

Commit 630ac27

Browse files
committed
fix(telegram): preserve buttons on deduped preview finals
1 parent 5e8b8ae commit 630ac27

2 files changed

Lines changed: 46 additions & 1 deletion

File tree

extensions/telegram/src/bot-message-dispatch.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,31 @@ describe("dispatchTelegramMessage draft streaming", () => {
565565
expect(answerDraftStream.clear).not.toHaveBeenCalled();
566566
});
567567

568+
it("attaches buttons before deduping a preview-streamed final", async () => {
569+
const { answerDraftStream } = setupDraftStreams({ answerMessageId: 2001 });
570+
const buttons = [[{ text: "OK", callback_data: "ok" }]];
571+
dispatchReplyWithBufferedBlockDispatcher.mockImplementation(
572+
async ({ dispatcherOptions, replyOptions }) => {
573+
await replyOptions?.onPartialReply?.({ text: "Choose" });
574+
await dispatcherOptions.deliver(
575+
{ text: "Choose", channelData: { telegram: { buttons } } },
576+
{ kind: "final" },
577+
);
578+
return { queuedFinal: true };
579+
},
580+
);
581+
582+
await dispatchWithContext({ context: createContext() });
583+
584+
expect(answerDraftStream.update).toHaveBeenCalledWith("Choose");
585+
expect(mockCallArg(editMessageTelegram)).toBe(123);
586+
expect(mockCallArg(editMessageTelegram, 0, 1)).toBe(2001);
587+
expect(mockCallArg(editMessageTelegram, 0, 2)).toBe("Choose");
588+
expectRecordFields(mockCallArg(editMessageTelegram, 0, 3), { buttons });
589+
expect(deliverReplies).not.toHaveBeenCalled();
590+
expect(answerDraftStream.clear).not.toHaveBeenCalled();
591+
});
592+
568593
it("dedups each per-block final against a multi-block preview", async () => {
569594
// Preview streams "First block\n\nSecond block" once; the reply pipeline
570595
// then emits two separate final payloads ("First block" and "Second block")

extensions/telegram/src/bot-message-dispatch.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1345,6 +1345,7 @@ export const dispatchTelegramMessage = async ({
13451345
return;
13461346
}
13471347
const effectivePayload = deduped;
1348+
const telegramButtons = resolvePayloadTelegramInlineButtons(effectivePayload);
13481349

13491350
// Preview-streamed final dedup (channel-layer replacement
13501351
// for the previous core-layer suppression introduced by
@@ -1371,6 +1372,26 @@ export const dispatchTelegramMessage = async ({
13711372
answerLane.lastPartialText,
13721373
);
13731374
if (isPreviewStreamedText(effectivePayload.text, previewDedupeText)) {
1375+
if (telegramButtons) {
1376+
try {
1377+
await (telegramDeps.editMessageTelegram ?? editMessageTelegram)(
1378+
chatId,
1379+
previewMessageId,
1380+
effectivePayload.text ?? answerLane.lastPartialText,
1381+
{
1382+
api: bot.api,
1383+
cfg,
1384+
accountId: route.accountId,
1385+
linkPreview: telegramCfg.linkPreview,
1386+
buttons: telegramButtons,
1387+
},
1388+
);
1389+
} catch (err) {
1390+
logVerbose(
1391+
`telegram: preview-finalized button edit failed: ${formatErrorMessage(err)}`,
1392+
);
1393+
}
1394+
}
13741395
answerLane.finalized = true;
13751396
deliveryState.markDelivered();
13761397
emitPreviewFinalizedHook({
@@ -1399,7 +1420,6 @@ export const dispatchTelegramMessage = async ({
13991420
queuedFinal = true;
14001421
return;
14011422
}
1402-
const telegramButtons = resolvePayloadTelegramInlineButtons(effectivePayload);
14031423
const split = splitTextIntoLaneSegments(
14041424
{ text: effectivePayload.text },
14051425
payload.isReasoning,

0 commit comments

Comments
 (0)