refactor(discord): share send target resolution and result mapping

This commit is contained in:
Peter Steinberger
2026-02-19 00:28:56 +00:00
parent ac44190952
commit 2dd361c071

View File

@@ -55,6 +55,13 @@ type DiscordSendOpts = {
silent?: boolean; silent?: boolean;
}; };
type DiscordClientRequest = ReturnType<typeof createDiscordClient>["request"];
type DiscordChannelMessageResult = {
id?: string | null;
channel_id?: string | null;
};
/** Discord thread names are capped at 100 characters. */ /** Discord thread names are capped at 100 characters. */
const DISCORD_THREAD_NAME_LIMIT = 100; const DISCORD_THREAD_NAME_LIMIT = 100;
@@ -73,6 +80,27 @@ function isForumLikeType(channelType?: number): boolean {
return channelType === ChannelType.GuildForum || channelType === ChannelType.GuildMedia; return channelType === ChannelType.GuildForum || channelType === ChannelType.GuildMedia;
} }
function toDiscordSendResult(
result: DiscordChannelMessageResult,
fallbackChannelId: string,
): DiscordSendResult {
return {
messageId: result.id ? String(result.id) : "unknown",
channelId: String(result.channel_id ?? fallbackChannelId),
};
}
async function resolveDiscordSendTarget(
to: string,
opts: DiscordSendOpts,
): Promise<{ rest: RequestClient; request: DiscordClientRequest; channelId: string }> {
const cfg = loadConfig();
const { rest, request } = createDiscordClient(opts, cfg);
const recipient = await parseAndResolveRecipient(to, opts.accountId);
const { channelId } = await resolveChannelId(rest, recipient, request);
return { rest, request, channelId };
}
export async function sendMessageDiscord( export async function sendMessageDiscord(
to: string, to: string,
text: string, text: string,
@@ -210,10 +238,13 @@ export async function sendMessageDiscord(
accountId: accountInfo.accountId, accountId: accountInfo.accountId,
direction: "outbound", direction: "outbound",
}); });
return { return toDiscordSendResult(
messageId: messageId ? String(messageId) : "unknown", {
channelId: String(resultChannelId ?? channelId), id: messageId,
}; channel_id: resultChannelId,
},
channelId,
);
} }
let result: { id: string; channel_id: string } | { id: string | null; channel_id: string }; let result: { id: string; channel_id: string } | { id: string | null; channel_id: string };
@@ -261,10 +292,7 @@ export async function sendMessageDiscord(
accountId: accountInfo.accountId, accountId: accountInfo.accountId,
direction: "outbound", direction: "outbound",
}); });
return { return toDiscordSendResult(result, channelId);
messageId: result.id ? String(result.id) : "unknown",
channelId: String(result.channel_id ?? channelId),
};
} }
export async function sendStickerDiscord( export async function sendStickerDiscord(
@@ -272,10 +300,7 @@ export async function sendStickerDiscord(
stickerIds: string[], stickerIds: string[],
opts: DiscordSendOpts & { content?: string } = {}, opts: DiscordSendOpts & { content?: string } = {},
): Promise<DiscordSendResult> { ): Promise<DiscordSendResult> {
const cfg = loadConfig(); const { rest, request, channelId } = await resolveDiscordSendTarget(to, opts);
const { rest, request } = createDiscordClient(opts, cfg);
const recipient = await parseAndResolveRecipient(to, opts.accountId);
const { channelId } = await resolveChannelId(rest, recipient, request);
const content = opts.content?.trim(); const content = opts.content?.trim();
const stickers = normalizeStickerIds(stickerIds); const stickers = normalizeStickerIds(stickerIds);
const res = (await request( const res = (await request(
@@ -288,10 +313,7 @@ export async function sendStickerDiscord(
}) as Promise<{ id: string; channel_id: string }>, }) as Promise<{ id: string; channel_id: string }>,
"sticker", "sticker",
)) as { id: string; channel_id: string }; )) as { id: string; channel_id: string };
return { return toDiscordSendResult(res, channelId);
messageId: res.id ? String(res.id) : "unknown",
channelId: String(res.channel_id ?? channelId),
};
} }
export async function sendPollDiscord( export async function sendPollDiscord(
@@ -299,10 +321,7 @@ export async function sendPollDiscord(
poll: PollInput, poll: PollInput,
opts: DiscordSendOpts & { content?: string } = {}, opts: DiscordSendOpts & { content?: string } = {},
): Promise<DiscordSendResult> { ): Promise<DiscordSendResult> {
const cfg = loadConfig(); const { rest, request, channelId } = await resolveDiscordSendTarget(to, opts);
const { rest, request } = createDiscordClient(opts, cfg);
const recipient = await parseAndResolveRecipient(to, opts.accountId);
const { channelId } = await resolveChannelId(rest, recipient, request);
const content = opts.content?.trim(); const content = opts.content?.trim();
if (poll.durationSeconds !== undefined) { if (poll.durationSeconds !== undefined) {
throw new Error("Discord polls do not support durationSeconds; use durationHours"); throw new Error("Discord polls do not support durationSeconds; use durationHours");
@@ -320,10 +339,7 @@ export async function sendPollDiscord(
}) as Promise<{ id: string; channel_id: string }>, }) as Promise<{ id: string; channel_id: string }>,
"poll", "poll",
)) as { id: string; channel_id: string }; )) as { id: string; channel_id: string };
return { return toDiscordSendResult(res, channelId);
messageId: res.id ? String(res.id) : "unknown",
channelId: String(res.channel_id ?? channelId),
};
} }
type VoiceMessageOpts = { type VoiceMessageOpts = {
@@ -412,10 +428,7 @@ export async function sendVoiceMessageDiscord(
direction: "outbound", direction: "outbound",
}); });
return { return toDiscordSendResult(result, channelId);
messageId: result.id ? String(result.id) : "unknown",
channelId: String(result.channel_id ?? channelId),
};
} catch (err) { } catch (err) {
if (channelId && rest && token) { if (channelId && rest && token) {
throw await buildDiscordSendError(err, { throw await buildDiscordSendError(err, {