fix(telegram): surface REACTION_INVALID as non-fatal warning (#14340)

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
0xRain
2026-02-12 14:28:47 +08:00
committed by GitHub
parent 4094cef233
commit 4b86c9e555
3 changed files with 49 additions and 3 deletions

View File

@@ -59,6 +59,37 @@ describe("handleTelegramAction", () => {
);
});
it("surfaces non-fatal reaction warnings", async () => {
reactMessageTelegram.mockResolvedValueOnce({
ok: false,
warning: "Reaction unavailable: ✅",
});
const cfg = {
channels: { telegram: { botToken: "tok", reactionLevel: "minimal" } },
} as OpenClawConfig;
const result = await handleTelegramAction(
{
action: "react",
chatId: "123",
messageId: "456",
emoji: "✅",
},
cfg,
);
const textPayload = result.content.find((item) => item.type === "text");
expect(textPayload?.type).toBe("text");
const parsed = JSON.parse((textPayload as { type: "text"; text: string }).text) as {
ok: boolean;
warning?: string;
added?: string;
};
expect(parsed).toMatchObject({
ok: false,
warning: "Reaction unavailable: ✅",
added: "✅",
});
});
it("adds reactions when reactionLevel is extensive", async () => {
const cfg = {
channels: { telegram: { botToken: "tok", reactionLevel: "extensive" } },

View File

@@ -109,11 +109,18 @@ export async function handleTelegramAction(
"Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.",
);
}
await reactMessageTelegram(chatId ?? "", messageId ?? 0, emoji ?? "", {
const reactionResult = await reactMessageTelegram(chatId ?? "", messageId ?? 0, emoji ?? "", {
token,
remove,
accountId: accountId ?? undefined,
});
if (!reactionResult.ok) {
return jsonResult({
ok: false,
warning: reactionResult.warning,
...(remove || isEmpty ? { removed: true } : { added: emoji }),
});
}
if (!remove && !isEmpty) {
return jsonResult({ ok: true, added: emoji });
}

View File

@@ -596,7 +596,7 @@ export async function reactMessageTelegram(
messageIdInput: string | number,
emoji: string,
opts: TelegramReactionOpts = {},
): Promise<{ ok: true }> {
): Promise<{ ok: true } | { ok: false; warning: string }> {
const cfg = loadConfig();
const account = resolveTelegramAccount({
cfg,
@@ -633,7 +633,15 @@ export async function reactMessageTelegram(
if (typeof api.setMessageReaction !== "function") {
throw new Error("Telegram reactions are unavailable in this bot API.");
}
await requestWithDiag(() => api.setMessageReaction(chatId, messageId, reactions), "reaction");
try {
await requestWithDiag(() => api.setMessageReaction(chatId, messageId, reactions), "reaction");
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
if (/REACTION_INVALID/i.test(msg)) {
return { ok: false as const, warning: `Reaction unavailable: ${trimmedEmoji}` };
}
throw err;
}
return { ok: true };
}