fix(telegram): treat no-op editMessage as success

This commit is contained in:
Peter Steinberger
2026-02-16 04:18:17 +01:00
parent 7089885ac4
commit ac2ede5bb1
2 changed files with 40 additions and 2 deletions

View File

@@ -1321,6 +1321,22 @@ describe("editMessageTelegram", () => {
);
});
it("treats 'message is not modified' as success", async () => {
botApi.editMessageText.mockRejectedValueOnce(
new Error(
"400: Bad Request: message is not modified: specified new message content and reply markup are exactly the same as a current content and reply markup of the message",
),
);
await expect(
editMessageTelegram("123", 1, "hi", {
token: "tok",
cfg: {},
}),
).resolves.toEqual({ ok: true, messageId: "1", chatId: "123" });
expect(botApi.editMessageText).toHaveBeenCalledTimes(1);
});
it("disables link previews when linkPreview is false", async () => {
botApi.editMessageText.mockResolvedValue({ message_id: 1, chat: { id: "123" } });

View File

@@ -74,6 +74,8 @@ type TelegramReactionOpts = {
const PARSE_ERR_RE = /can't parse entities|parse entities|find end of the entity/i;
const THREAD_NOT_FOUND_RE = /400:\s*Bad Request:\s*message thread not found/i;
const MESSAGE_NOT_MODIFIED_RE =
/400:\s*Bad Request:\s*message is not modified|MESSAGE_NOT_MODIFIED/i;
const diagLogger = createSubsystemLogger("telegram/diagnostic");
function createTelegramHttpLogger(cfg: ReturnType<typeof loadConfig>) {
@@ -182,6 +184,10 @@ function isTelegramThreadNotFoundError(err: unknown): boolean {
return THREAD_NOT_FOUND_RE.test(formatErrorMessage(err));
}
function isTelegramMessageNotModifiedError(err: unknown): boolean {
return MESSAGE_NOT_MODIFIED_RE.test(formatErrorMessage(err));
}
function hasMessageThreadIdParam(params?: Record<string, unknown>): boolean {
if (!params) {
return false;
@@ -730,10 +736,15 @@ export async function editMessageTelegram(
verbose: opts.verbose,
});
const logHttpError = createTelegramHttpLogger(cfg);
const requestWithDiag = <T>(fn: () => Promise<T>, label?: string) =>
const requestWithDiag = <T>(
fn: () => Promise<T>,
label?: string,
shouldLog?: (err: unknown) => boolean,
) =>
withTelegramApiErrorLogging({
operation: label ?? "request",
fn: () => request(fn, label),
shouldLog,
}).catch((err) => {
logHttpError(label ?? "request", err);
throw err;
@@ -768,7 +779,12 @@ export async function editMessageTelegram(
await requestWithDiag(
() => api.editMessageText(chatId, messageId, htmlText, editParams),
"editMessage",
(err) => !isTelegramMessageNotModifiedError(err),
).catch(async (err) => {
if (isTelegramMessageNotModifiedError(err)) {
return;
}
// Telegram rejects malformed HTML. Fall back to plain text.
const errText = formatErrorMessage(err);
if (PARSE_ERR_RE.test(errText)) {
@@ -788,7 +804,13 @@ export async function editMessageTelegram(
? api.editMessageText(chatId, messageId, text, plainParams)
: api.editMessageText(chatId, messageId, text),
"editMessage-plain",
);
(plainErr) => !isTelegramMessageNotModifiedError(plainErr),
).catch((plainErr) => {
if (isTelegramMessageNotModifiedError(plainErr)) {
return;
}
throw plainErr;
});
}
throw err;
});