mirror of
https://github.com/discordjs/discord.js.git
synced 2026-06-01 08:30:08 +00:00
fix(MessagePayload): allow AttachmentBuilder in files payload (#11423)
* fix(MessagePayload): allow AttachmentBuilder in files payload * fix: typo * chore: apply suggestions from code review Co-authored-by: Almeida <github@almeidx.dev> --------- Co-authored-by: Almeida <github@almeidx.dev> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const { Buffer } = require('node:buffer');
|
||||
const { isJSONEncodable, lazy } = require('@discordjs/util');
|
||||
const { isJSONEncodable, isRawFileEncodable, lazy } = require('@discordjs/util');
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const { DiscordjsError, DiscordjsRangeError, ErrorCodes } = require('../errors/index.js');
|
||||
const { resolveFile } = require('../util/DataResolver.js');
|
||||
@@ -190,16 +190,24 @@ class MessagePayload {
|
||||
}
|
||||
}
|
||||
|
||||
const attachments = this.options.files?.map((file, index) => ({
|
||||
id: index.toString(),
|
||||
description: file.description,
|
||||
title: file.title,
|
||||
waveform: file.waveform,
|
||||
duration_secs: file.duration,
|
||||
}));
|
||||
let attachments = this.options.files?.map((file, index) =>
|
||||
isRawFileEncodable(file)
|
||||
? {
|
||||
id: index.toString(),
|
||||
...file.toJSON(),
|
||||
}
|
||||
: {
|
||||
id: index.toString(),
|
||||
description: file.description,
|
||||
title: file.title,
|
||||
waveform: file.waveform,
|
||||
duration_secs: file.duration,
|
||||
},
|
||||
);
|
||||
|
||||
// Only passable during edits
|
||||
if (Array.isArray(this.options.attachments)) {
|
||||
attachments ??= [];
|
||||
attachments.push(
|
||||
// Note how we don't check for file body encodable, since we aren't expecting file data here
|
||||
...this.options.attachments.map(attachment => (isJSONEncodable(attachment) ? attachment.toJSON() : attachment)),
|
||||
@@ -276,6 +284,8 @@ class MessagePayload {
|
||||
if (ownAttachment) {
|
||||
attachment = fileLike;
|
||||
name = findName(attachment);
|
||||
} else if (isRawFileEncodable(fileLike)) {
|
||||
return fileLike.getRawFile();
|
||||
} else {
|
||||
attachment = fileLike.attachment;
|
||||
name = fileLike.name ?? findName(attachment);
|
||||
|
||||
@@ -88,7 +88,7 @@ class TextBasedChannel {
|
||||
* @property {Array<(EmbedBuilder|Embed|APIEmbed)>} [embeds] The embeds for the message
|
||||
* @property {MessageMentionOptions} [allowedMentions] Which mentions should be parsed from the message content
|
||||
* (see {@link https://discord.com/developers/docs/resources/message#allowed-mentions-object here} for more details)
|
||||
* @property {Array<(Attachment|AttachmentPayload|BufferResolvable|FileBodyEncodable<APIAttachment>|Stream)>} [files]
|
||||
* @property {Array<(Attachment|AttachmentPayload|BufferResolvable|RawFileEncodable|Stream)>} [files]
|
||||
* The files to send with the message.
|
||||
* @property {Array<(ActionRowBuilder|MessageTopLevelComponent|APIMessageTopLevelComponent)>} [components]
|
||||
* Action rows containing interactive components for the message (buttons, select menus) and other
|
||||
|
||||
4
packages/discord.js/typings/index.d.ts
vendored
4
packages/discord.js/typings/index.d.ts
vendored
@@ -4,7 +4,7 @@ import { Stream } from 'node:stream';
|
||||
import { MessagePort, Worker } from 'node:worker_threads';
|
||||
import { Collection, ReadonlyCollection } from '@discordjs/collection';
|
||||
import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions, EmojiURLOptions } from '@discordjs/rest';
|
||||
import { Awaitable, FileBodyEncodable, JSONEncodable } from '@discordjs/util';
|
||||
import { Awaitable, FileBodyEncodable, JSONEncodable, RawFileEncodable } from '@discordjs/util';
|
||||
import { WebSocketManager, WebSocketManagerOptions } from '@discordjs/ws';
|
||||
import { AsyncEventEmitter } from '@vladfrangu/async_event_emitter';
|
||||
import {
|
||||
@@ -6754,7 +6754,7 @@ export interface BaseMessageOptions {
|
||||
)[];
|
||||
content?: string | null;
|
||||
embeds?: readonly (APIEmbed | JSONEncodable<APIEmbed>)[];
|
||||
files?: readonly (Attachment | AttachmentPayload | BufferResolvable | FileBodyEncodable<APIAttachment> | Stream)[];
|
||||
files?: readonly (Attachment | AttachmentPayload | BufferResolvable | RawFileEncodable | Stream)[];
|
||||
}
|
||||
|
||||
export interface BaseMessageSendOptions extends BaseMessageOptions {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { RESTAPIAttachment } from 'discord-api-types/v10';
|
||||
import type { RawFile } from './RawFile.js';
|
||||
|
||||
/**
|
||||
@@ -59,3 +60,24 @@ export interface FileBodyEncodable<BodyValue> {
|
||||
export function isFileBodyEncodable(maybeEncodable: unknown): maybeEncodable is FileBodyEncodable<unknown> {
|
||||
return maybeEncodable !== null && typeof maybeEncodable === 'object' && 'toFileBody' in maybeEncodable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an object capable of representing itself as a raw file attachment.
|
||||
* Objects implementing this interface can return binary file data to be sent as part of
|
||||
* multipart/form-data requests.
|
||||
*/
|
||||
export interface RawFileEncodable extends JSONEncodable<RESTAPIAttachment> {
|
||||
/**
|
||||
* Returns the raw file of an attachment.
|
||||
*/
|
||||
getRawFile(): Partial<RawFile> | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if an object is raw file encodable or not.
|
||||
*
|
||||
* @param maybeEncodable - The object to check against
|
||||
*/
|
||||
export function isRawFileEncodable(maybeEncodable: unknown): maybeEncodable is RawFileEncodable {
|
||||
return isJSONEncodable(maybeEncodable) && 'getRawFile' in maybeEncodable;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user