



























@@ -401,6 +401,81 @@ describe("createTelegramBot", () => {
401401expect(harness.sequentializeKey).toBe(getTelegramSequentialKey);
402402});
403403404+it("answers callback queries before same-chat sequentialize delays handlers", async () => {
405+installPerKeySequentializer();
406+createTelegramBot({ token: "tok" });
407+const callbackHandler = requireValue(
408+getOnHandler("callback_query") as
409+| ((ctx: Record<string, unknown>) => Promise<void>)
410+| undefined,
411+"callback_query handler",
412+);
413+let releaseBusyUpdate: (() => void) | undefined;
414+const busyUpdateGate = new Promise<void>((resolve) => {
415+releaseBusyUpdate = resolve;
416+});
417+const busyMessagePayload = {
418+chat: { id: 1234, type: "private" },
419+date: 1736380800,
420+from: { id: 9, first_name: "Ada", username: "ada_bot" },
421+message_id: 41,
422+text: "busy",
423+};
424+const callbackQueryPayload = {
425+id: "cbq-pre-sequentialize-1",
426+data: "cmd:option_a",
427+from: { id: 9, first_name: "Ada", username: "ada_bot" },
428+message: {
429+chat: { id: 1234, type: "private" },
430+date: 1736380800,
431+message_id: 42,
432+},
433+};
434+const busyMessage = {
435+update: { update_id: 401, message: busyMessagePayload },
436+message: busyMessagePayload,
437+me: { username: "openclaw_bot" },
438+};
439+const callbackCtx = {
440+update: { update_id: 402, callback_query: callbackQueryPayload },
441+callbackQuery: callbackQueryPayload,
442+me: { username: "openclaw_bot" },
443+getFile: async () => ({ download: async () => new Uint8Array() }),
444+};
445+446+const busyPromise = runTelegramMiddlewareChain({
447+ctx: busyMessage,
448+finalHandler: async () => {
449+await busyUpdateGate;
450+},
451+});
452+await flushTelegramTestMicrotasks();
453+454+let callbackHandlerStarted = false;
455+const callbackPromise = runTelegramMiddlewareChain({
456+ctx: callbackCtx,
457+finalHandler: async (ctx) => {
458+callbackHandlerStarted = true;
459+await callbackHandler(ctx);
460+},
461+});
462+await flushTelegramTestMicrotasks();
463+464+expect(callbackHandlerStarted).toBe(false);
465+expect(answerCallbackQuerySpy).toHaveBeenCalledTimes(1);
466+expect(answerCallbackQuerySpy).toHaveBeenCalledWith("cbq-pre-sequentialize-1");
467+468+if (!releaseBusyUpdate) {
469+throw new Error("Expected Telegram busy update release callback to be initialized");
470+}
471+releaseBusyUpdate();
472+await busyPromise;
473+await callbackPromise;
474+475+expect(replySpy).toHaveBeenCalledTimes(1);
476+expect(answerCallbackQuerySpy).toHaveBeenCalledTimes(1);
477+});
478+404479it("lets /status bypass a busy Telegram topic lane", async () => {
405480installPerKeySequentializer();
406481loadConfig.mockReturnValue({
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。