fix(discord): use fetch with proper headers for voice message upload

The @buape/carbon RequestClient wasn't setting Content-Type: application/json
for the attachments endpoint request. Use native fetch with explicit headers
for the upload URL request.

Also pass token through to sendDiscordVoiceMessage for authorization.
This commit is contained in:
nyanjou
2026-02-02 17:13:49 +01:00
committed by Shadow
parent a09e4fac3f
commit 36525a974e
2 changed files with 33 additions and 17 deletions

View File

@@ -38,7 +38,11 @@ export async function handleDiscordMessageAction(
required: true, required: true,
allowEmpty: true, allowEmpty: true,
}); });
const mediaUrl = readStringParam(params, "media", { trim: false }); // Support media, path, and filePath for media URL
const mediaUrl =
readStringParam(params, "media", { trim: false }) ??
readStringParam(params, "path", { trim: false }) ??
readStringParam(params, "filePath", { trim: false });
const replyTo = readStringParam(params, "replyTo"); const replyTo = readStringParam(params, "replyTo");
const embeds = Array.isArray(params.embeds) ? params.embeds : undefined; const embeds = Array.isArray(params.embeds) ? params.embeds : undefined;
const asVoice = params.asVoice === true; const asVoice = params.asVoice === true;

View File

@@ -241,26 +241,38 @@ export async function sendDiscordVoiceMessage(
metadata: VoiceMessageMetadata, metadata: VoiceMessageMetadata,
replyTo: string | undefined, replyTo: string | undefined,
request: RetryRunner, request: RetryRunner,
token: string,
): Promise<{ id: string; channel_id: string }> { ): Promise<{ id: string; channel_id: string }> {
const filename = "voice-message.ogg"; const filename = "voice-message.ogg";
const fileSize = audioBuffer.byteLength; const fileSize = audioBuffer.byteLength;
// Step 1: Request upload URL // Step 1: Request upload URL (using fetch directly for proper headers)
const uploadUrlResponse = (await request( const uploadUrlRes = await fetch(
() => `https://discord.com/api/v10/channels/${channelId}/attachments`,
rest.post(`/channels/${channelId}/attachments`, { {
body: { method: "POST",
files: [ headers: {
{ "Content-Type": "application/json",
filename, Authorization: `Bot ${token}`,
file_size: fileSize, },
id: "0", body: JSON.stringify({
}, files: [
], {
}, filename,
}) as Promise<UploadUrlResponse>, file_size: fileSize,
"voice-upload-url", id: "0",
)) as UploadUrlResponse; },
],
}),
},
);
if (!uploadUrlRes.ok) {
const errorBody = await uploadUrlRes.text();
throw new Error(`Failed to get upload URL: ${uploadUrlRes.status} ${errorBody}`);
}
const uploadUrlResponse = (await uploadUrlRes.json()) as UploadUrlResponse;
if (!uploadUrlResponse.attachments?.[0]) { if (!uploadUrlResponse.attachments?.[0]) {
throw new Error("Failed to get upload URL for voice message"); throw new Error("Failed to get upload URL for voice message");