fix(telegram): include DM topic thread id in replies (#18586)
This commit is contained in:
@@ -167,7 +167,7 @@ describe("deliverReplies", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("does not include message_thread_id for DMs (threads don't exist in private chats)", async () => {
|
||||
it("includes message_thread_id for DM topics", async () => {
|
||||
const runtime = createRuntime();
|
||||
const sendMessage = vi.fn().mockResolvedValue({
|
||||
message_id: 4,
|
||||
@@ -179,14 +179,14 @@ describe("deliverReplies", () => {
|
||||
replies: [{ text: "Hello" }],
|
||||
runtime,
|
||||
bot,
|
||||
thread: { id: 1, scope: "dm" },
|
||||
thread: { id: 42, scope: "dm" },
|
||||
});
|
||||
|
||||
expect(sendMessage).toHaveBeenCalledWith(
|
||||
"123",
|
||||
expect.any(String),
|
||||
expect.not.objectContaining({
|
||||
message_thread_id: 1,
|
||||
expect.objectContaining({
|
||||
message_thread_id: 42,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -43,15 +43,21 @@ describe("buildTelegramThreadParams", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("skips thread id for dm threads (DMs don't have threads)", () => {
|
||||
expect(buildTelegramThreadParams({ id: 1, scope: "dm" })).toBeUndefined();
|
||||
expect(buildTelegramThreadParams({ id: 2, scope: "dm" })).toBeUndefined();
|
||||
it("includes thread id for dm topics", () => {
|
||||
expect(buildTelegramThreadParams({ id: 1, scope: "dm" })).toEqual({
|
||||
message_thread_id: 1,
|
||||
});
|
||||
expect(buildTelegramThreadParams({ id: 2, scope: "dm" })).toEqual({
|
||||
message_thread_id: 2,
|
||||
});
|
||||
});
|
||||
|
||||
it("normalizes and skips thread id for dm threads even with edge values", () => {
|
||||
it("normalizes dm thread ids and skips non-positive values", () => {
|
||||
expect(buildTelegramThreadParams({ id: 0, scope: "dm" })).toBeUndefined();
|
||||
expect(buildTelegramThreadParams({ id: -1, scope: "dm" })).toBeUndefined();
|
||||
expect(buildTelegramThreadParams({ id: 1.9, scope: "dm" })).toBeUndefined();
|
||||
expect(buildTelegramThreadParams({ id: 1.9, scope: "dm" })).toEqual({
|
||||
message_thread_id: 1,
|
||||
});
|
||||
});
|
||||
|
||||
it("handles thread id 0 for non-dm scopes", () => {
|
||||
|
||||
@@ -114,7 +114,7 @@ export function resolveTelegramThreadSpec(params: {
|
||||
* Build thread params for Telegram API calls (messages, media).
|
||||
*
|
||||
* IMPORTANT: Thread IDs behave differently based on chat type:
|
||||
* - DMs (private chats): Never send thread_id (threads don't exist)
|
||||
* - DMs (private chats): Include message_thread_id when present (DM topics)
|
||||
* - Forum topics: Skip thread_id=1 (General topic), include others
|
||||
* - Regular groups: Thread IDs are ignored by Telegram
|
||||
*
|
||||
@@ -130,9 +130,8 @@ export function buildTelegramThreadParams(thread?: TelegramThreadSpec | null) {
|
||||
}
|
||||
const normalized = Math.trunc(thread.id);
|
||||
|
||||
// Never send thread_id for DMs (threads don't exist in private chats)
|
||||
if (thread.scope === "dm") {
|
||||
return undefined;
|
||||
return normalized > 0 ? { message_thread_id: normalized } : undefined;
|
||||
}
|
||||
|
||||
// Telegram rejects message_thread_id=1 for General forum topic
|
||||
|
||||
@@ -86,12 +86,14 @@ describe("createTelegramDraftStream", () => {
|
||||
await vi.waitFor(() => expect(api.sendMessage).toHaveBeenCalledWith(123, "Hello", undefined));
|
||||
});
|
||||
|
||||
it("omits message_thread_id for dm threads and clears preview on cleanup", async () => {
|
||||
it("includes message_thread_id for dm threads and clears preview on cleanup", async () => {
|
||||
const api = createMockDraftApi();
|
||||
const stream = createThreadedDraftStream(api, { id: 1, scope: "dm" });
|
||||
const stream = createThreadedDraftStream(api, { id: 42, scope: "dm" });
|
||||
|
||||
stream.update("Hello");
|
||||
await vi.waitFor(() => expect(api.sendMessage).toHaveBeenCalledWith(123, "Hello", undefined));
|
||||
await vi.waitFor(() =>
|
||||
expect(api.sendMessage).toHaveBeenCalledWith(123, "Hello", { message_thread_id: 42 }),
|
||||
);
|
||||
await stream.clear();
|
||||
|
||||
expect(api.deleteMessage).toHaveBeenCalledWith(123, 17);
|
||||
|
||||
Reference in New Issue
Block a user