fix(discord): report actual delivered message kinds (#128575)

This commit is contained in:
Peter Steinberger
2026-08-24 00:05:07 -07:00
committed by GitHub
parent 45d6a08a0a
commit 65bcdf2f26
2 changed files with 30 additions and 23 deletions
+21 -21
View File
@@ -208,6 +208,17 @@ export async function sendMessageDiscord(
// Forum/Media channels reject POST /messages; auto-create a thread post instead.
const channel = await resolveDiscordChannel(rest, channelId);
const deliveredResults: DiscordSendResult[] = [];
let deliveryThreadId: string | undefined;
const reportResult: DiscordSendProgress = async (progressResult, kind, replyToId) => {
const deliveredResult = toDiscordSendResult(progressResult, deliveryThreadId ?? channelId, {
kind,
threadId: deliveryThreadId,
reply: createReusableDiscordReplyReference(replyToId),
});
deliveredResults.push(deliveredResult);
await opts.onDeliveryResult?.(deliveredResult);
};
if (isForumLikeChannel(channel)) {
if (((channel.flags ?? 0) & DISCORD_FORUM_REQUIRE_TAG_FLAG) !== 0) {
@@ -275,6 +286,7 @@ export async function sendMessageDiscord(
}
const threadId = threadRes.id;
deliveryThreadId = threadId;
const messageId = threadRes.message?.id ?? threadId;
const resultChannelId = threadRes.message?.channel_id ?? threadId;
const remainingChunks = chunks.slice(1);
@@ -286,13 +298,8 @@ export async function sendMessageDiscord(
channelId,
{ kind: "text", threadId },
);
const deliveredResults: DiscordSendResult[] = [starterResult];
deliveredResults.push(starterResult);
await opts.onDeliveryResult?.(starterResult);
const reportThreadResult: DiscordSendProgress = async (result, kind) => {
const deliveredResult = toDiscordSendResult(result, threadId, { kind, threadId });
deliveredResults.push(deliveredResult);
await opts.onDeliveryResult?.(deliveredResult);
};
try {
if (opts.mediaUrl) {
@@ -314,7 +321,7 @@ export async function sendMessageDiscord(
suppressEmbeds,
allowedMentions: opts.allowedMentions,
maxChars: textLimit,
onResult: reportThreadResult,
onResult: reportResult,
onPlatformSendDispatch: opts.onPlatformSendDispatch,
});
await sendDiscordThreadTextChunks({
@@ -328,7 +335,7 @@ export async function sendMessageDiscord(
silent: opts.silent,
suppressEmbeds,
allowedMentions: opts.allowedMentions,
onResult: reportThreadResult,
onResult: reportResult,
onPlatformSendDispatch: opts.onPlatformSendDispatch,
});
} else {
@@ -343,7 +350,7 @@ export async function sendMessageDiscord(
silent: opts.silent,
suppressEmbeds,
allowedMentions: opts.allowedMentions,
onResult: reportThreadResult,
onResult: reportResult,
onPlatformSendDispatch: opts.onPlatformSendDispatch,
});
}
@@ -369,14 +376,6 @@ export async function sendMessageDiscord(
}
let result: DiscordChannelMessageResult;
const reportResult: DiscordSendProgress = async (progressResult, kind, replyToId) => {
await opts.onDeliveryResult?.(
toDiscordSendResult(progressResult, channelId, {
kind,
reply: createReusableDiscordReplyReference(replyToId),
}),
);
};
try {
if (opts.mediaUrl) {
result = await sendDiscordMedia({
@@ -436,10 +435,11 @@ export async function sendMessageDiscord(
accountId: accountInfo.accountId,
direction: "outbound",
});
return toDiscordSendResult(result, channelId, {
kind: opts.mediaUrl ? "media" : opts.components || opts.embeds ? "card" : "text",
reply: opts.reply,
});
return {
messageId: result.id || "unknown",
channelId: result.channel_id ?? channelId,
receipt: createDiscordSendReceiptFromResults({ results: deliveredResults }),
};
}
export async function sendStickerDiscord(
@@ -392,7 +392,7 @@ describe("sendMessageDiscord", () => {
];
const onDeliveryResult = vi.fn();
await sendMessageDiscord("channel:789", "a".repeat(2_500), {
const result = await sendMessageDiscord("channel:789", "a".repeat(2_500), {
rest,
token: "t",
cfg: DISCORD_TEST_CFG,
@@ -415,6 +415,7 @@ describe("sendMessageDiscord", () => {
"card",
"text",
]);
expect(result.receipt.parts.map(({ kind }) => kind)).toEqual(["card", "text"]);
});
it("delivers embed-only and native Components V2 messages over real HTTP", async () => {
@@ -1008,6 +1009,7 @@ describe("sendMessageDiscord", () => {
});
expect(res.messageId).toBe("fallback-msg");
expectSingleReceiptPart(res.receipt, { platformMessageId: "fallback-msg", kind: "text" });
expect(postMock).toHaveBeenCalledTimes(2);
expectBodyFileName(requireRestBody(postMock, 0), "photo.jpg");
const fallbackBody = requireRestBody(postMock, 1);
@@ -1199,17 +1201,20 @@ describe("sendMessageDiscord", () => {
name: "preserves reply reference across all text chunks by default",
params: { text: "a".repeat(2001) },
expectsSecondReply: true,
expectedKinds: ["text", "text"],
},
{
name: "limits reply reference to the first text chunk when requested",
params: { text: "a".repeat(2001), replyScope: "first" as const },
expectsSecondReply: false,
checksReceipt: true,
expectedKinds: ["text", "text"],
},
{
name: "preserves reply reference for follow-up text chunks after media caption split by default",
params: { text: "a".repeat(2500), mediaUrl: "file:///tmp/photo.jpg" },
expectsSecondReply: true,
expectedKinds: ["media", "text"],
},
{
name: "limits media caption reply reference to the first physical message when requested",
@@ -1219,9 +1224,11 @@ describe("sendMessageDiscord", () => {
replyScope: "first" as const,
},
expectsSecondReply: false,
expectedKinds: ["media", "text"],
},
])("$name", async ({ params, expectsSecondReply, checksReceipt }) => {
])("$name", async ({ params, expectsSecondReply, checksReceipt, expectedKinds }) => {
const { firstBody, secondBody, result } = await sendChunkedReplyAndCollectBodies(params);
expect(result.receipt.parts.map(({ kind }) => kind)).toEqual(expectedKinds);
expectReplyReference(firstBody, "orig-123");
if (expectsSecondReply) {
expectReplyReference(secondBody, "orig-123");