mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-11 09:41:41 +00:00
fix(telegram): make reaction handling soft-fail and message-id resilient (#20236)
* Telegram: soft-fail reactions and fallback to inbound message id * Telegram: soft-fail missing reaction message id * Update CHANGELOG.md --------- Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
@@ -102,6 +102,46 @@ describe("handleTelegramAction", () => {
|
||||
await expectReactionAdded("extensive");
|
||||
});
|
||||
|
||||
it("accepts snake_case message_id for reactions", async () => {
|
||||
const cfg = {
|
||||
channels: { telegram: { botToken: "tok", reactionLevel: "minimal" } },
|
||||
} as OpenClawConfig;
|
||||
await handleTelegramAction(
|
||||
{
|
||||
action: "react",
|
||||
chatId: "123",
|
||||
message_id: "456",
|
||||
emoji: "✅",
|
||||
},
|
||||
cfg,
|
||||
);
|
||||
expect(reactMessageTelegram).toHaveBeenCalledWith(
|
||||
"123",
|
||||
456,
|
||||
"✅",
|
||||
expect.objectContaining({ token: "tok", remove: false }),
|
||||
);
|
||||
});
|
||||
|
||||
it("soft-fails when messageId is missing", async () => {
|
||||
const cfg = {
|
||||
channels: { telegram: { botToken: "tok", reactionLevel: "minimal" } },
|
||||
} as OpenClawConfig;
|
||||
const result = await handleTelegramAction(
|
||||
{
|
||||
action: "react",
|
||||
chatId: "123",
|
||||
emoji: "✅",
|
||||
},
|
||||
cfg,
|
||||
);
|
||||
expect(result.details).toMatchObject({
|
||||
ok: false,
|
||||
reason: "missing_message_id",
|
||||
});
|
||||
expect(reactMessageTelegram).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("removes reactions on empty emoji", async () => {
|
||||
const cfg = {
|
||||
channels: { telegram: { botToken: "tok", reactionLevel: "minimal" } },
|
||||
@@ -177,18 +217,10 @@ describe("handleTelegramAction", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
level: "off" as const,
|
||||
expectedMessage: /Telegram agent reactions disabled.*reactionLevel="off"/,
|
||||
},
|
||||
{
|
||||
level: "ack" as const,
|
||||
expectedMessage: /Telegram agent reactions disabled.*reactionLevel="ack"/,
|
||||
},
|
||||
])("blocks reactions when reactionLevel is $level", async ({ level, expectedMessage }) => {
|
||||
await expect(
|
||||
handleTelegramAction(
|
||||
it.each(["off", "ack"] as const)(
|
||||
"soft-fails reactions when reactionLevel is %s",
|
||||
async (level) => {
|
||||
const result = await handleTelegramAction(
|
||||
{
|
||||
action: "react",
|
||||
chatId: "123",
|
||||
@@ -196,11 +228,15 @@ describe("handleTelegramAction", () => {
|
||||
emoji: "✅",
|
||||
},
|
||||
reactionConfig(level),
|
||||
),
|
||||
).rejects.toThrow(expectedMessage);
|
||||
});
|
||||
);
|
||||
expect(result.details).toMatchObject({
|
||||
ok: false,
|
||||
reason: "disabled",
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it("also respects legacy actions.reactions gating", async () => {
|
||||
it("soft-fails when reactions are disabled via actions.reactions", async () => {
|
||||
const cfg = {
|
||||
channels: {
|
||||
telegram: {
|
||||
@@ -210,17 +246,19 @@ describe("handleTelegramAction", () => {
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
await expect(
|
||||
handleTelegramAction(
|
||||
{
|
||||
action: "react",
|
||||
chatId: "123",
|
||||
messageId: "456",
|
||||
emoji: "✅",
|
||||
},
|
||||
cfg,
|
||||
),
|
||||
).rejects.toThrow(/Telegram reactions are disabled via actions.reactions/);
|
||||
const result = await handleTelegramAction(
|
||||
{
|
||||
action: "react",
|
||||
chatId: "123",
|
||||
messageId: "456",
|
||||
emoji: "✅",
|
||||
},
|
||||
cfg,
|
||||
);
|
||||
expect(result.details).toMatchObject({
|
||||
ok: false,
|
||||
reason: "disabled",
|
||||
});
|
||||
});
|
||||
|
||||
it("sends a text message", async () => {
|
||||
@@ -634,18 +672,20 @@ describe("handleTelegramAction per-account gating", () => {
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
await expect(
|
||||
handleTelegramAction(
|
||||
{
|
||||
action: "react",
|
||||
chatId: "123",
|
||||
messageId: 1,
|
||||
emoji: "👀",
|
||||
accountId: "media",
|
||||
},
|
||||
cfg,
|
||||
),
|
||||
).rejects.toThrow(/reactions are disabled via actions.reactions/i);
|
||||
const result = await handleTelegramAction(
|
||||
{
|
||||
action: "react",
|
||||
chatId: "123",
|
||||
messageId: 1,
|
||||
emoji: "👀",
|
||||
accountId: "media",
|
||||
},
|
||||
cfg,
|
||||
);
|
||||
expect(result.details).toMatchObject({
|
||||
ok: false,
|
||||
reason: "disabled",
|
||||
});
|
||||
});
|
||||
|
||||
it("allows account to explicitly re-enable top-level disabled reaction gate", async () => {
|
||||
|
||||
Reference in New Issue
Block a user