fix(discord): send initial message for non-forum thread creation

When creating a thread in a non-forum channel with the `content` parameter,
the content was silently ignored. This happened because only forum/media
channels support the `message` field in the thread creation request body.

This fix sends the initial message as a separate API call after the thread
is created, ensuring the content parameter works for all thread types.

Fixes the issue where `thread-create` with `message` parameter appeared
to succeed but the message never appeared in the thread.
This commit is contained in:
zerone0x
2026-02-16 15:23:51 +01:00
parent fec4be8dec
commit 857424bbae
2 changed files with 66 additions and 1 deletions

View File

@@ -107,6 +107,61 @@ describe("sendMessageDiscord", () => {
);
});
it("sends initial message for non-forum threads with content", async () => {
const { rest, getMock, postMock } = makeDiscordRest();
getMock.mockResolvedValue({ type: ChannelType.GuildText });
postMock.mockResolvedValue({ id: "t1" });
await createThreadDiscord(
"chan1",
{ name: "thread", content: "Hello thread!" },
{ rest, token: "t" },
);
expect(postMock).toHaveBeenCalledTimes(2);
// First call: create thread
expect(postMock).toHaveBeenNthCalledWith(
1,
Routes.threads("chan1"),
expect.objectContaining({
body: expect.objectContaining({ name: "thread", type: ChannelType.PublicThread }),
}),
);
// Second call: send message to thread
expect(postMock).toHaveBeenNthCalledWith(
2,
Routes.channelMessages("t1"),
expect.objectContaining({
body: { content: "Hello thread!" },
}),
);
});
it("sends initial message for message-attached threads with content", async () => {
const { rest, getMock, postMock } = makeDiscordRest();
postMock.mockResolvedValue({ id: "t1" });
await createThreadDiscord(
"chan1",
{ name: "thread", messageId: "m1", content: "Discussion here" },
{ rest, token: "t" },
);
// Should not detect channel type for message-attached threads
expect(getMock).not.toHaveBeenCalled();
expect(postMock).toHaveBeenCalledTimes(2);
// First call: create thread from message
expect(postMock).toHaveBeenNthCalledWith(
1,
Routes.threads("chan1", "m1"),
expect.objectContaining({ body: { name: "thread" } }),
);
// Second call: send message to thread
expect(postMock).toHaveBeenNthCalledWith(
2,
Routes.channelMessages("t1"),
expect.objectContaining({
body: { content: "Discussion here" },
}),
);
});
it("lists active threads by guild", async () => {
const { rest, getMock } = makeDiscordRest();
getMock.mockResolvedValue({ threads: [] });

View File

@@ -134,7 +134,17 @@ export async function createThreadDiscord(
const route = payload.messageId
? Routes.threads(channelId, payload.messageId)
: Routes.threads(channelId);
return await rest.post(route, { body });
const thread = (await rest.post(route, { body })) as { id: string };
// For non-forum channels, send the initial message separately after thread creation.
// Forum channels handle this via the `message` field in the request body.
if (!isForumLike && payload.content?.trim()) {
await rest.post(Routes.channelMessages(thread.id), {
body: { content: payload.content },
});
}
return thread;
}
export async function listThreadsDiscord(payload: DiscordThreadList, opts: DiscordReactOpts = {}) {