fix(telegram): preserve sent replies when required pins fail (#129342)

This commit is contained in:
Peter Steinberger
2026-08-25 07:20:39 -07:00
committed by GitHub
parent 712a97d2ab
commit 433cf95d71
2 changed files with 23 additions and 0 deletions
@@ -588,6 +588,9 @@ async function maybePinFirstDeliveredMessage(params: {
disable_notification: !notify,
});
} catch (err) {
if (typeof params.pin === "object" && params.pin.required === true) {
throw err;
}
logVerbose(
`telegram pinChatMessage failed chat=${params.chatId} message=${params.firstDeliveredMessageId}: ${formatErrorMessage(err)}`,
);
@@ -912,6 +915,7 @@ export async function deliverReplies(params: {
replyToId,
replyToMode: params.replyToMode,
progress,
acceptedMessageIds,
recordMessageId,
onPlatformSendDispatch: params.onPlatformSendDispatch,
});
@@ -3121,6 +3121,25 @@ describe("deliverReplies", () => {
expect(pinChatMessage).toHaveBeenCalledTimes(1);
});
it("preserves accepted text delivery when a required pin fails", async () => {
const sendMessage = vi.fn().mockResolvedValue({ message_id: 201, chat: { id: "123" } });
const pinChatMessage = vi.fn().mockRejectedValue(new Error("pin failed"));
await expect(
deliverWith({
replies: [{ text: "hello", delivery: { pin: { enabled: true, required: true } } }],
runtime: createRuntime(),
bot: createBot({ sendMessage, pinChatMessage }),
}),
).rejects.toMatchObject({
code: "CHANNEL_PARTIAL_DELIVERY",
deliveryResult: { messageIds: ["201"], visibleReplySent: true },
});
expect(sendMessage).toHaveBeenCalledTimes(1);
expect(pinChatMessage).toHaveBeenCalledTimes(1);
});
it("rethrows VOICE_MESSAGES_FORBIDDEN when no text fallback is available", async () => {
const { runtime, sendVoice, sendMessage, bot } = createVoiceFailureHarness({
voiceError: createVoiceMessagesForbiddenError(),