mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-19 04:53:30 +01:00
feat: send voice messages (#10462)
* feat: send voice messages * fix: title reference Co-authored-by: ckohen <chaikohen@gmail.com> * docs: clarify voice message attachment properties in documentation --------- Co-authored-by: ckohen <chaikohen@gmail.com>
This commit is contained in:
@@ -22,7 +22,8 @@ class GuildForumThreadManager extends ThreadManager {
|
|||||||
* @typedef {BaseMessageOptions} GuildForumThreadMessageCreateOptions
|
* @typedef {BaseMessageOptions} GuildForumThreadMessageCreateOptions
|
||||||
* @property {StickerResolvable} [stickers] The stickers to send with the message
|
* @property {StickerResolvable} [stickers] The stickers to send with the message
|
||||||
* @property {BitFieldResolvable} [flags] The flags to send with the message
|
* @property {BitFieldResolvable} [flags] The flags to send with the message
|
||||||
* <info>Only `MessageFlags.SuppressEmbeds` and `MessageFlags.SuppressNotifications` can be set.</info>
|
* <info>Only {@link MessageFlags.SuppressEmbeds}, {@link MessageFlags.SuppressNotifications}, and
|
||||||
|
* {@link MessageFlags.IsVoiceMessage} can be set.</info>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,9 +5,12 @@ const { basename, flatten } = require('../util/Util.js');
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} AttachmentPayload
|
* @typedef {Object} AttachmentPayload
|
||||||
* @property {?string} name The name of the attachment
|
|
||||||
* @property {Stream|BufferResolvable} attachment The attachment in this payload
|
* @property {Stream|BufferResolvable} attachment The attachment in this payload
|
||||||
* @property {?string} description The description of the attachment
|
* @property {string} [name] The name of the attachment
|
||||||
|
* @property {string} [description] The description of the attachment
|
||||||
|
* @property {title} [title] The title of the attachment
|
||||||
|
* @property {string} [waveform] The base64 encoded byte array representing a sampled waveform (from voice message attachments)
|
||||||
|
* @property {number} [duration] The duration of the attachment in seconds (from voice message attachments)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,7 +118,7 @@ class Attachment {
|
|||||||
if ('duration_secs' in data) {
|
if ('duration_secs' in data) {
|
||||||
/**
|
/**
|
||||||
* The duration of this attachment in seconds
|
* The duration of this attachment in seconds
|
||||||
* <info>This will only be available if the attachment is an audio file.</info>
|
* <info>This will only be available if the attachment is the audio file from a voice message.</info>
|
||||||
*
|
*
|
||||||
* @type {?number}
|
* @type {?number}
|
||||||
*/
|
*/
|
||||||
@@ -127,7 +130,7 @@ class Attachment {
|
|||||||
if ('waveform' in data) {
|
if ('waveform' in data) {
|
||||||
/**
|
/**
|
||||||
* The base64 encoded byte array representing a sampled waveform
|
* The base64 encoded byte array representing a sampled waveform
|
||||||
* <info>This will only be available if the attachment is an audio file.</info>
|
* <info>This will only be available if this attachment is the audio file from a voice message.</info>
|
||||||
*
|
*
|
||||||
* @type {?string}
|
* @type {?string}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,18 +17,43 @@ class AttachmentBuilder {
|
|||||||
* @type {BufferResolvable|Stream}
|
* @type {BufferResolvable|Stream}
|
||||||
*/
|
*/
|
||||||
this.attachment = attachment;
|
this.attachment = attachment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of this attachment
|
* The name of this attachment
|
||||||
*
|
*
|
||||||
* @type {?string}
|
* @type {?string}
|
||||||
*/
|
*/
|
||||||
this.name = data.name;
|
this.name = data.name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The description of the attachment
|
* The description of the attachment
|
||||||
*
|
*
|
||||||
* @type {?string}
|
* @type {?string}
|
||||||
*/
|
*/
|
||||||
this.description = data.description;
|
this.description = data.description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The title of the attachment
|
||||||
|
*
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.title = data.title;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base64 encoded byte array representing a sampled waveform
|
||||||
|
* <info>This is only for voice message attachments.</info>
|
||||||
|
*
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.waveform = data.waveform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The duration of the attachment in seconds
|
||||||
|
* <info>This is only for voice message attachments.</info>
|
||||||
|
*
|
||||||
|
* @type {?number}
|
||||||
|
*/
|
||||||
|
this.duration = data.duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,6 +89,41 @@ class AttachmentBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the title of this attachment.
|
||||||
|
*
|
||||||
|
* @param {string} title The title of the file
|
||||||
|
* @returns {AttachmentBuilder} This attachment
|
||||||
|
*/
|
||||||
|
setTitle(title) {
|
||||||
|
this.title = title;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the waveform of this attachment.
|
||||||
|
* <info>This is only for voice message attachments.</info>
|
||||||
|
*
|
||||||
|
* @param {string} waveform The base64 encoded byte array representing a sampled waveform
|
||||||
|
* @returns {AttachmentBuilder} This attachment
|
||||||
|
*/
|
||||||
|
setWaveform(waveform) {
|
||||||
|
this.waveform = waveform;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the duration of this attachment.
|
||||||
|
* <info>This is only for voice message attachments.</info>
|
||||||
|
*
|
||||||
|
* @param {number} duration The duration of the attachment in seconds
|
||||||
|
* @returns {AttachmentBuilder} This attachment
|
||||||
|
*/
|
||||||
|
setDuration(duration) {
|
||||||
|
this.duration = duration;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether this attachment is a spoiler
|
* Sets whether this attachment is a spoiler
|
||||||
*
|
*
|
||||||
@@ -119,4 +179,7 @@ exports.AttachmentBuilder = AttachmentBuilder;
|
|||||||
* @typedef {Object} AttachmentData
|
* @typedef {Object} AttachmentData
|
||||||
* @property {string} [name] The name of the attachment
|
* @property {string} [name] The name of the attachment
|
||||||
* @property {string} [description] The description of the attachment
|
* @property {string} [description] The description of the attachment
|
||||||
|
* @property {string} [title] The title of the attachment
|
||||||
|
* @property {string} [waveform] The base64 encoded byte array representing a sampled waveform (for voice message attachments)
|
||||||
|
* @property {number} [duration] The duration of the attachment in seconds (for voice message attachments)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -192,6 +192,9 @@ class MessagePayload {
|
|||||||
const attachments = this.options.files?.map((file, index) => ({
|
const attachments = this.options.files?.map((file, index) => ({
|
||||||
id: index.toString(),
|
id: index.toString(),
|
||||||
description: file.description,
|
description: file.description,
|
||||||
|
title: file.title,
|
||||||
|
waveform: file.waveform,
|
||||||
|
duration_secs: file.duration,
|
||||||
}));
|
}));
|
||||||
if (Array.isArray(this.options.attachments)) {
|
if (Array.isArray(this.options.attachments)) {
|
||||||
this.options.attachments.push(...(attachments ?? []));
|
this.options.attachments.push(...(attachments ?? []));
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ class Webhook {
|
|||||||
* @typedef {BaseMessageOptionsWithPoll} WebhookMessageCreateOptions
|
* @typedef {BaseMessageOptionsWithPoll} WebhookMessageCreateOptions
|
||||||
* @property {boolean} [tts=false] Whether the message should be spoken aloud
|
* @property {boolean} [tts=false] Whether the message should be spoken aloud
|
||||||
* @property {MessageFlags} [flags] Which flags to set for the message.
|
* @property {MessageFlags} [flags] Which flags to set for the message.
|
||||||
* <info>Only the {@link MessageFlags.SuppressEmbeds} flag can be set.</info>
|
* <info>Only {@link MessageFlags.SuppressEmbeds} and {@link MessageFlags.IsVoiceMessage} can be set.</info>
|
||||||
* @property {string} [username=this.name] Username override for the message
|
* @property {string} [username=this.name] Username override for the message
|
||||||
* @property {string} [avatarURL] Avatar URL override for the message
|
* @property {string} [avatarURL] Avatar URL override for the message
|
||||||
* @property {Snowflake} [threadId] The id of the thread in the channel to send to.
|
* @property {Snowflake} [threadId] The id of the thread in the channel to send to.
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ class InteractionResponses {
|
|||||||
* @property {boolean} [tts=false] Whether the message should be spoken aloud
|
* @property {boolean} [tts=false] Whether the message should be spoken aloud
|
||||||
* @property {boolean} [withResponse] Whether to return an {@link InteractionCallbackResponse} as the response
|
* @property {boolean} [withResponse] Whether to return an {@link InteractionCallbackResponse} as the response
|
||||||
* @property {MessageFlagsResolvable} [flags] Which flags to set for the message.
|
* @property {MessageFlagsResolvable} [flags] Which flags to set for the message.
|
||||||
* <info>Only `MessageFlags.Ephemeral`, `MessageFlags.SuppressEmbeds`, and `MessageFlags.SuppressNotifications`
|
* <info>Only {@link MessageFlags.Ephemeral}, {@link MessageFlags.SuppressEmbeds},
|
||||||
* can be set.</info>
|
* {@link MessageFlags.SuppressNotifications}, and {@link MessageFlags.IsVoiceMessage} can be set.</info>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -114,8 +114,8 @@ class TextBasedChannel {
|
|||||||
* that message will be returned and no new message will be created
|
* that message will be returned and no new message will be created
|
||||||
* @property {StickerResolvable[]} [stickers=[]] The stickers to send in the message
|
* @property {StickerResolvable[]} [stickers=[]] The stickers to send in the message
|
||||||
* @property {MessageFlags} [flags] Which flags to set for the message.
|
* @property {MessageFlags} [flags] Which flags to set for the message.
|
||||||
* <info>Only {@link MessageFlags.SuppressEmbeds}, {@link MessageFlags.SuppressNotifications} and
|
* <info>Only {@link MessageFlags.SuppressEmbeds}, {@link MessageFlags.SuppressNotifications},
|
||||||
* {@link MessageFlags.IsComponentsV2} can be set.</info>
|
* {@link MessageFlags.IsComponentsV2}, and {@link MessageFlags.IsVoiceMessage} can be set.</info>
|
||||||
* <info>{@link MessageFlags.IsComponentsV2} is required if passing components that aren't action rows</info>
|
* <info>{@link MessageFlags.IsComponentsV2} is required if passing components that aren't action rows</info>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
25
packages/discord.js/typings/index.d.ts
vendored
25
packages/discord.js/typings/index.d.ts
vendored
@@ -2249,10 +2249,16 @@ export class AttachmentBuilder {
|
|||||||
public attachment: BufferResolvable | Stream;
|
public attachment: BufferResolvable | Stream;
|
||||||
public description: string | null;
|
public description: string | null;
|
||||||
public name: string | null;
|
public name: string | null;
|
||||||
|
public title: string | null;
|
||||||
|
public waveform: string | null;
|
||||||
|
public duration: number | null;
|
||||||
public get spoiler(): boolean;
|
public get spoiler(): boolean;
|
||||||
public setDescription(description: string): this;
|
public setDescription(description: string): this;
|
||||||
public setFile(attachment: BufferResolvable | Stream, name?: string): this;
|
public setFile(attachment: BufferResolvable | Stream, name?: string): this;
|
||||||
public setName(name: string): this;
|
public setName(name: string): this;
|
||||||
|
public setTitle(title: string): this;
|
||||||
|
public setWaveform(waveform: string): this;
|
||||||
|
public setDuration(duration: number): this;
|
||||||
public setSpoiler(spoiler?: boolean): this;
|
public setSpoiler(spoiler?: boolean): this;
|
||||||
public toJSON(): unknown;
|
public toJSON(): unknown;
|
||||||
public static from(other: JSONEncodable<AttachmentPayload>): AttachmentBuilder;
|
public static from(other: JSONEncodable<AttachmentPayload>): AttachmentBuilder;
|
||||||
@@ -4828,7 +4834,10 @@ export interface BaseApplicationCommandData {
|
|||||||
|
|
||||||
export interface AttachmentData {
|
export interface AttachmentData {
|
||||||
description?: string;
|
description?: string;
|
||||||
|
duration?: number;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
title?: string;
|
||||||
|
waveform?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CommandOptionDataTypeResolvable = ApplicationCommandOptionType;
|
export type CommandOptionDataTypeResolvable = ApplicationCommandOptionType;
|
||||||
@@ -5878,7 +5887,10 @@ export interface FetchThreadsOptions {
|
|||||||
export interface AttachmentPayload {
|
export interface AttachmentPayload {
|
||||||
attachment: BufferResolvable | Stream;
|
attachment: BufferResolvable | Stream;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
duration?: number;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
title?: string;
|
||||||
|
waveform?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GlobalSweepFilter<Key, Value> = () =>
|
export type GlobalSweepFilter<Key, Value> = () =>
|
||||||
@@ -6398,9 +6410,13 @@ export interface InteractionDeferUpdateOptions {
|
|||||||
export interface InteractionReplyOptions extends BaseMessageOptions, MessageOptionsPoll {
|
export interface InteractionReplyOptions extends BaseMessageOptions, MessageOptionsPoll {
|
||||||
flags?:
|
flags?:
|
||||||
| BitFieldResolvable<
|
| BitFieldResolvable<
|
||||||
Extract<MessageFlagsString, 'Ephemeral' | 'IsComponentsV2' | 'SuppressEmbeds' | 'SuppressNotifications'>,
|
Extract<
|
||||||
|
MessageFlagsString,
|
||||||
|
'Ephemeral' | 'IsComponentsV2' | 'IsVoiceMessage' | 'SuppressEmbeds' | 'SuppressNotifications'
|
||||||
|
>,
|
||||||
| MessageFlags.Ephemeral
|
| MessageFlags.Ephemeral
|
||||||
| MessageFlags.IsComponentsV2
|
| MessageFlags.IsComponentsV2
|
||||||
|
| MessageFlags.IsVoiceMessage
|
||||||
| MessageFlags.SuppressEmbeds
|
| MessageFlags.SuppressEmbeds
|
||||||
| MessageFlags.SuppressNotifications
|
| MessageFlags.SuppressNotifications
|
||||||
>
|
>
|
||||||
@@ -6577,8 +6593,11 @@ export interface MessageOptionsPoll {
|
|||||||
export interface MessageOptionsFlags {
|
export interface MessageOptionsFlags {
|
||||||
flags?:
|
flags?:
|
||||||
| BitFieldResolvable<
|
| BitFieldResolvable<
|
||||||
Extract<MessageFlagsString, 'IsComponentsV2' | 'SuppressEmbeds' | 'SuppressNotifications'>,
|
Extract<MessageFlagsString, 'IsComponentsV2' | 'IsVoiceMessage' | 'SuppressEmbeds' | 'SuppressNotifications'>,
|
||||||
MessageFlags.IsComponentsV2 | MessageFlags.SuppressEmbeds | MessageFlags.SuppressNotifications
|
| MessageFlags.IsComponentsV2
|
||||||
|
| MessageFlags.IsVoiceMessage
|
||||||
|
| MessageFlags.SuppressEmbeds
|
||||||
|
| MessageFlags.SuppressNotifications
|
||||||
>
|
>
|
||||||
| undefined;
|
| undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3000,3 +3000,23 @@ await guildScheduledEventManager.edit(snowflake, { recurrenceRule: null });
|
|||||||
byMonth: [GuildScheduledEventRecurrenceRuleMonth.May],
|
byMonth: [GuildScheduledEventRecurrenceRuleMonth.May],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await textChannel.send({
|
||||||
|
files: [
|
||||||
|
new AttachmentBuilder('https://example.com/voice-message.ogg')
|
||||||
|
.setDuration(2)
|
||||||
|
.setWaveform('AFUqPDw3Eg2hh4+gopOYj4xthU4='),
|
||||||
|
],
|
||||||
|
flags: MessageFlags.IsVoiceMessage,
|
||||||
|
});
|
||||||
|
|
||||||
|
await textChannel.send({
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
attachment: 'https://example.com/voice-message.ogg',
|
||||||
|
duration: 2,
|
||||||
|
waveform: 'AFUqPDw3Eg2hh4+gopOYj4xthU4=',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
flags: MessageFlags.IsVoiceMessage,
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user