fix(telegram): correlate deliveries to explicit topics

Use the explicit topic selected by Telegram sends when recording delivery correlation, preventing successful message, poll, and sticker actions from leaving the matching inbound event falsely undelivered.
This commit is contained in:
Peter Steinberger
2026-08-04 10:21:32 -07:00
committed by GitHub
parent ef11eae39b
commit 7a0a4c5f2a
2 changed files with 43 additions and 9 deletions
+42 -8
View File
@@ -1117,12 +1117,37 @@ describe("handleTelegramAction", () => {
endUserRequest();
});
it("marks topic room-event delivery when send uses a separate thread id", async () => {
it.each([
{
label: "a separate forum topic",
to: "-100123",
threadId: 77,
expectedTarget: "-100123:topic:77",
},
{
label: "an explicit forum topic instead of a stale embedded topic",
to: "-100123:topic:271",
threadId: 404,
expectedTarget: "-100123:topic:404",
},
{
label: "an explicit private-chat topic instead of a stale embedded topic",
to: "123:topic:7",
threadId: 11,
expectedTarget: "123:topic:11",
},
{
label: "an explicitly selected General forum topic",
to: "-100123:topic:271",
threadId: 1,
expectedTarget: "-100123:topic:1",
},
])("marks topic room-event delivery for $label", async ({ to, threadId, expectedTarget }) => {
let count = 0;
const end = telegramInboundEventDelivery.begin(
"telegram-session",
{
outboundTo: "-100123:topic:77",
outboundTo: expectedTarget,
markInboundEventDelivered: () => {
count += 1;
},
@@ -1133,14 +1158,16 @@ describe("handleTelegramAction", () => {
await handleTelegramAction(
{
action: "sendMessage",
to: "-100123",
threadId: 77,
to,
threadId,
content: "Hello from a room event topic",
},
telegramConfig(),
{ sessionKey: "telegram-session", inboundEventKind: "room_event" },
);
const sent = mockCall(sendMessageTelegram, 0, "room event topic send");
expect(requireRecord(sent[2], "room event topic options").messageThreadId).toBe(threadId);
expect(count).toBe(1);
end();
});
@@ -1177,7 +1204,8 @@ describe("handleTelegramAction", () => {
name: "poll",
params: {
action: "poll",
to: "@testchannel",
to: "-100123:topic:271",
threadId: 404,
question: "Ready?",
answers: ["Yes", "No"],
},
@@ -1187,17 +1215,18 @@ describe("handleTelegramAction", () => {
name: "sticker",
params: {
action: "sendSticker",
to: "@testchannel",
to: "-100123:topic:271",
threadId: 404,
fileId: "sticker-1",
},
cfg: telegramConfig({ actions: { sticker: true } }),
},
])("marks room-event delivery after successful $name actions", async ({ params, cfg }) => {
])("marks room-event delivery after successful $name actions", async ({ name, params, cfg }) => {
let count = 0;
const end = telegramInboundEventDelivery.begin(
"telegram-session",
{
outboundTo: "@testchannel",
outboundTo: "-100123:topic:404",
markInboundEventDelivered: () => {
count += 1;
},
@@ -1210,6 +1239,11 @@ describe("handleTelegramAction", () => {
inboundEventKind: "room_event",
});
const sent =
name === "poll"
? mockCall(sendPollTelegram, 0, "room event topic poll")
: mockCall(sendStickerTelegram, 0, "room event topic sticker");
expect(requireRecord(sent[2], "room event topic options").messageThreadId).toBe(404);
expect(count).toBe(1);
end();
});
+1 -1
View File
@@ -161,7 +161,7 @@ function resolveActionTopicNameCacheScope(cfg: OpenClawConfig, accountId?: strin
function formatTelegramDeliveryTarget(to: string, messageThreadId?: number | null): string {
const parsed = parseTelegramTarget(to);
const topicId = parsed.messageThreadId ?? messageThreadId;
const topicId = messageThreadId ?? parsed.messageThreadId;
if (topicId == null) {
return to;
}