fix(telegram): preserve explicit empty media captions (#116984)

Co-authored-by: Peter Steinberger <steipete@macos.shared>
This commit is contained in:
Peter Steinberger
2026-07-31 11:46:34 -07:00
committed by GitHub
parent 36b80ada3c
commit be93d44275
3 changed files with 60 additions and 5 deletions
@@ -1854,21 +1854,26 @@ describe("handleTelegramAction", () => {
expect(requireRecord(call[3], "reply markup edit options").token).toBe("tok");
});
it("uses Telegram caption edits when editMessage receives a caption", async () => {
it.each([
{ description: "non-empty", caption: "Updated caption", richMessages: false },
{ description: "empty", caption: "", richMessages: false },
{ description: "non-empty rich", caption: "Updated caption", richMessages: true },
{ description: "empty rich", caption: "", richMessages: true },
])("uses Telegram caption edits for $description captions", async ({ caption, richMessages }) => {
await handleTelegramAction(
{
action: "editMessage",
chatId: "123456",
messageId: 321,
caption: "Updated caption",
caption,
},
telegramConfig(),
telegramConfig(richMessages ? { richMessages: true } : undefined),
);
const call = mockCall(editMessageTelegram, 0, "caption edit");
expect(call[0]).toBe("123456");
expect(call[1]).toBe(321);
expect(call[2]).toBe("Updated caption");
expect(call[2]).toBe(caption);
expect(requireRecord(call[3], "caption edit options").editMode).toBe("caption");
});
+2 -1
View File
@@ -739,7 +739,8 @@ export async function handleTelegramAction(
const content =
readStringParam(params, "content", { allowEmpty: false }) ??
readStringParam(params, "message", { allowEmpty: false });
const caption = readStringParam(params, "caption", { allowEmpty: false });
// Telegram treats an explicit empty caption as a request to remove it.
const caption = readStringParam(params, "caption", { allowEmpty: true });
const buttons = resolveTelegramButtonsFromParams(params, undefined, {
allowWebAppButtons: resolveTelegramTargetChatType(chatId ?? "") === "direct",
});
@@ -0,0 +1,49 @@
import { describe, expect, it } from "vitest";
import {
getTelegramSendTestMocks,
importTelegramSendModule,
installTelegramSendTestHooks,
} from "./send.test-harness.js";
installTelegramSendTestHooks();
const { botApi, loadConfig } = getTelegramSendTestMocks();
const { editMessageTelegram } = await importTelegramSendModule();
describe("Telegram caption edits", () => {
it.each([
{
description: "non-empty plain",
caption: "Updated **caption**",
expected: "Updated <b>caption</b>",
richMessages: false,
},
{ description: "empty plain", caption: "", expected: "", richMessages: false },
{
description: "non-empty rich",
caption: "Updated **caption**",
expected: "Updated <b>caption</b>",
richMessages: true,
},
{ description: "empty rich", caption: "", expected: "", richMessages: true },
])(
"preserves $description captions at the Bot API boundary",
async ({ caption, expected, richMessages }) => {
loadConfig.mockReturnValue({ channels: { telegram: { botToken: "tok", richMessages } } });
botApi.editMessageCaption.mockResolvedValue({ message_id: 321, chat: { id: "123456" } });
await editMessageTelegram("123456", 321, caption, {
cfg: { channels: { telegram: { botToken: "tok", richMessages } } },
token: "tok",
accountId: "default",
editMode: "caption",
});
expect(botApi.editMessageText).not.toHaveBeenCalled();
expect(botApi.editMessageCaption).toHaveBeenCalledWith("123456", 321, {
caption: expected,
parse_mode: "HTML",
});
},
);
});