mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
fix(telegram): land #34983 from @HOYALIM
Landed from contributor PR #34983 by @HOYALIM. Co-authored-by: Ho Lim <subhoya@gmail.com>
This commit is contained in:
@@ -320,6 +320,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Exec approvals/config fallback: inherit `ask` from `exec-approvals.json` when `tools.exec.ask` is unset, so local full/off defaults no longer fall back to `on-miss` for exec tool and `nodes run`. Landed from contributor PR #29187 by @Bartok9. Thanks @Bartok9.
|
||||
- Exec approvals/allow-always shell scripts: persist and match script paths for wrapper invocations like `bash scripts/foo.sh` while still blocking `-c`/`-s` wrapper bypasses. Landed from contributor PR #35137 by @yuweuii. Thanks @yuweuii.
|
||||
- Queue/followup dedupe across drain restarts: dedupe queued redelivery `message_id` values after queue recreation so busy-session followups no longer duplicate on replayed inbound events. Landed from contributor PR #33168 by @rylena. Thanks @rylena.
|
||||
- Telegram/preview-final edit idempotence: treat `message is not modified` errors during preview finalization as delivered so partial-stream final replies do not fall back to duplicate sends. Landed from contributor PR #34983 by @HOYALIM. Thanks @HOYALIM.
|
||||
|
||||
## 2026.3.2
|
||||
|
||||
|
||||
@@ -146,6 +146,30 @@ describe("createLaneTextDeliverer", () => {
|
||||
expect(harness.log).toHaveBeenCalledWith(expect.stringContaining("treating as delivered"));
|
||||
});
|
||||
|
||||
it("treats 'message is not modified' preview edit errors as delivered", async () => {
|
||||
const harness = createHarness({ answerMessageId: 999 });
|
||||
harness.editPreview.mockRejectedValue(
|
||||
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",
|
||||
),
|
||||
);
|
||||
|
||||
const result = await harness.deliverLaneText({
|
||||
laneName: "answer",
|
||||
text: "Hello final",
|
||||
payload: { text: "Hello final" },
|
||||
infoKind: "final",
|
||||
});
|
||||
|
||||
expect(result).toBe("preview-finalized");
|
||||
expect(harness.editPreview).toHaveBeenCalledTimes(1);
|
||||
expect(harness.sendPayload).not.toHaveBeenCalled();
|
||||
expect(harness.markDelivered).toHaveBeenCalledTimes(1);
|
||||
expect(harness.log).toHaveBeenCalledWith(
|
||||
expect.stringContaining('edit returned "message is not modified"; treating as delivered'),
|
||||
);
|
||||
});
|
||||
|
||||
it("falls back to normal delivery when editing an existing preview fails", async () => {
|
||||
const harness = createHarness({ answerMessageId: 999 });
|
||||
harness.editPreview.mockRejectedValue(new Error("500: preview edit failed"));
|
||||
|
||||
@@ -2,6 +2,23 @@ import type { ReplyPayload } from "../auto-reply/types.js";
|
||||
import type { TelegramInlineButtons } from "./button-types.js";
|
||||
import type { TelegramDraftStream } from "./draft-stream.js";
|
||||
|
||||
const MESSAGE_NOT_MODIFIED_RE =
|
||||
/400:\s*Bad Request:\s*message is not modified|MESSAGE_NOT_MODIFIED/i;
|
||||
|
||||
function isMessageNotModifiedError(err: unknown): boolean {
|
||||
const text =
|
||||
typeof err === "string"
|
||||
? err
|
||||
: err instanceof Error
|
||||
? err.message
|
||||
: typeof err === "object" && err && "description" in err
|
||||
? typeof err.description === "string"
|
||||
? err.description
|
||||
: ""
|
||||
: "";
|
||||
return MESSAGE_NOT_MODIFIED_RE.test(text);
|
||||
}
|
||||
|
||||
export type LaneName = "answer" | "reasoning";
|
||||
|
||||
export type DraftLaneState = {
|
||||
@@ -216,6 +233,13 @@ export function createLaneTextDeliverer(params: CreateLaneTextDelivererParams) {
|
||||
params.markDelivered();
|
||||
return true;
|
||||
} catch (err) {
|
||||
if (isMessageNotModifiedError(err)) {
|
||||
params.log(
|
||||
`telegram: ${args.laneName} preview ${args.context} edit returned "message is not modified"; treating as delivered`,
|
||||
);
|
||||
params.markDelivered();
|
||||
return true;
|
||||
}
|
||||
if (args.treatEditFailureAsDelivered) {
|
||||
params.log(
|
||||
`telegram: ${args.laneName} preview ${args.context} edit failed after stop-created flush; treating as delivered (${String(err)})`,
|
||||
|
||||
Reference in New Issue
Block a user