Skip to content

Commit e84c497

Browse files
committed
feat: send voice messages
1 parent c0c1ac2 commit e84c497

File tree

9 files changed

+113
-15
lines changed

9 files changed

+113
-15
lines changed

packages/discord.js/src/managers/GuildForumThreadManager.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ class GuildForumThreadManager extends ThreadManager {
2222
* @typedef {BaseMessageOptions} GuildForumThreadMessageCreateOptions
2323
* @property {StickerResolvable} [stickers] The stickers to send with the message
2424
* @property {BitFieldResolvable} [flags] The flags to send with the message
25-
* <info>Only `MessageFlags.SuppressEmbeds` and `MessageFlags.SuppressNotifications` can be set.</info>
25+
* <info>Only {@link MessageFlags.SuppressEmbeds}, {@link MessageFlags.SuppressNotifications}, and
26+
* {@link MessageFlags.IsVoiceMessage} can be set.</info>
2627
*/
2728

2829
/**

packages/discord.js/src/structures/Attachment.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ const { basename, flatten } = require('../util/Util.js');
55

66
/**
77
* @typedef {Object} AttachmentPayload
8-
* @property {?string} name The name of the attachment
98
* @property {Stream|BufferResolvable} attachment The attachment in this payload
10-
* @property {?string} description The description of the attachment
9+
* @property {string} [name] The name of the attachment
10+
* @property {string} [description] The description of the attachment
11+
* @property {title} [title] The title of the attachment
12+
* @property {string} [waveform] The base64 encoded byte array representing a sampled waveform
13+
* @property {number} [duration] The duration of the attachment in seconds
1114
*/
1215

1316
/**

packages/discord.js/src/structures/AttachmentBuilder.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,41 @@ class AttachmentBuilder {
1717
* @type {BufferResolvable|Stream}
1818
*/
1919
this.attachment = attachment;
20+
2021
/**
2122
* The name of this attachment
2223
*
2324
* @type {?string}
2425
*/
2526
this.name = data.name;
27+
2628
/**
2729
* The description of the attachment
2830
*
2931
* @type {?string}
3032
*/
3133
this.description = data.description;
34+
35+
/**
36+
* The title of the attachment
37+
*
38+
* @type {?string}
39+
*/
40+
this.title = data.title;
41+
42+
/**
43+
* The base64 encoded byte array representing a sampled waveform
44+
*
45+
* @type {?string}
46+
*/
47+
this.waveform = data.waveform;
48+
49+
/**
50+
* The duration of the attachment in seconds
51+
*
52+
* @type {?number}
53+
*/
54+
this.duration = data.duration;
3255
}
3356

3457
/**
@@ -64,6 +87,39 @@ class AttachmentBuilder {
6487
return this;
6588
}
6689

90+
/**
91+
* Sets the title of this attachment.
92+
*
93+
* @param {string} title The title of the file
94+
* @returns {AttachmentBuilder} This attachment
95+
*/
96+
setTitle(title) {
97+
this.title = title;
98+
return this;
99+
}
100+
101+
/**
102+
* Sets the waveform of this attachment.
103+
*
104+
* @param {string} waveform The base64 encoded byte array representing a sampled waveform
105+
* @returns {AttachmentBuilder} This attachment
106+
*/
107+
setWaveform(waveform) {
108+
this.waveform = waveform;
109+
return this;
110+
}
111+
112+
/**
113+
* Sets the duration of this attachment.
114+
*
115+
* @param {number} duration The duration of the attachment in seconds
116+
* @returns {AttachmentBuilder} This attachment
117+
*/
118+
setDuration(duration) {
119+
this.duration = duration;
120+
return this;
121+
}
122+
67123
/**
68124
* Sets whether this attachment is a spoiler
69125
*
@@ -119,4 +175,7 @@ exports.AttachmentBuilder = AttachmentBuilder;
119175
* @typedef {Object} AttachmentData
120176
* @property {string} [name] The name of the attachment
121177
* @property {string} [description] The description of the attachment
178+
* @property {string} [title] The title of the attachment
179+
* @property {string} [waveform] The base64 encoded byte array representing a sampled waveform
180+
* @property {number} [duration] The duration of the attachment in seconds
122181
*/

packages/discord.js/src/structures/MessagePayload.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ class MessagePayload {
192192
const attachments = this.options.files?.map((file, index) => ({
193193
id: index.toString(),
194194
description: file.description,
195+
title: file.name,
196+
waveform: file.waveform,
197+
duration_secs: file.duration,
195198
}));
196199
if (Array.isArray(this.options.attachments)) {
197200
this.options.attachments.push(...(attachments ?? []));

packages/discord.js/src/structures/Webhook.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ class Webhook {
142142
* @typedef {BaseMessageOptionsWithPoll} WebhookMessageCreateOptions
143143
* @property {boolean} [tts=false] Whether the message should be spoken aloud
144144
* @property {MessageFlags} [flags] Which flags to set for the message.
145-
* <info>Only the {@link MessageFlags.SuppressEmbeds} flag can be set.</info>
145+
* <info>Only {@link MessageFlags.SuppressEmbeds} and {@link MessageFlags.IsVoiceMessage} can be set.</info>
146146
* @property {string} [username=this.name] Username override for the message
147147
* @property {string} [avatarURL] Avatar URL override for the message
148148
* @property {Snowflake} [threadId] The id of the thread in the channel to send to.

packages/discord.js/src/structures/interfaces/InteractionResponses.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ class InteractionResponses {
4545
* @property {boolean} [tts=false] Whether the message should be spoken aloud
4646
* @property {boolean} [withResponse] Whether to return an {@link InteractionCallbackResponse} as the response
4747
* @property {MessageFlagsResolvable} [flags] Which flags to set for the message.
48-
* <info>Only `MessageFlags.Ephemeral`, `MessageFlags.SuppressEmbeds`, and `MessageFlags.SuppressNotifications`
49-
* can be set.</info>
48+
* <info>Only {@link MessageFlags.Ephemeral}, {@link MessageFlags.SuppressEmbeds},
49+
* {@link MessageFlags.SuppressNotifications}, and {@link MessageFlags.IsVoiceMessage} can be set.</info>
5050
*/
5151

5252
/**

packages/discord.js/src/structures/interfaces/TextBasedChannel.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ class TextBasedChannel {
114114
* that message will be returned and no new message will be created
115115
* @property {StickerResolvable[]} [stickers=[]] The stickers to send in the message
116116
* @property {MessageFlags} [flags] Which flags to set for the message.
117-
* <info>Only {@link MessageFlags.SuppressEmbeds}, {@link MessageFlags.SuppressNotifications} and
118-
* {@link MessageFlags.IsComponentsV2} can be set.</info>
117+
* <info>Only {@link MessageFlags.SuppressEmbeds}, {@link MessageFlags.SuppressNotifications},
118+
* {@link MessageFlags.IsComponentsV2}, and {@link MessageFlags.IsVoiceMessage} can be set.</info>
119119
* <info>{@link MessageFlags.IsComponentsV2} is required if passing components that aren't action rows</info>
120120
*/
121121

packages/discord.js/typings/index.d.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2244,10 +2244,16 @@ export class AttachmentBuilder {
22442244
public attachment: BufferResolvable | Stream;
22452245
public description: string | null;
22462246
public name: string | null;
2247+
public title: string | null;
2248+
public waveform: string | null;
2249+
public duration: number | null;
22472250
public get spoiler(): boolean;
22482251
public setDescription(description: string): this;
22492252
public setFile(attachment: BufferResolvable | Stream, name?: string): this;
22502253
public setName(name: string): this;
2254+
public setTitle(title: string): this;
2255+
public setWaveform(waveform: string): this;
2256+
public setDuration(duration: number): this;
22512257
public setSpoiler(spoiler?: boolean): this;
22522258
public toJSON(): unknown;
22532259
public static from(other: JSONEncodable<AttachmentPayload>): AttachmentBuilder;
@@ -4827,7 +4833,10 @@ export interface BaseApplicationCommandData {
48274833

48284834
export interface AttachmentData {
48294835
description?: string;
4836+
duration?: number;
48304837
name?: string;
4838+
title?: string;
4839+
waveform?: string;
48314840
}
48324841

48334842
export type CommandOptionDataTypeResolvable = ApplicationCommandOptionType;
@@ -5877,7 +5886,10 @@ export interface FetchThreadsOptions {
58775886
export interface AttachmentPayload {
58785887
attachment: BufferResolvable | Stream;
58795888
description?: string;
5889+
duration?: number;
58805890
name?: string;
5891+
title?: string;
5892+
waveform?: string;
58815893
}
58825894

58835895
export type GlobalSweepFilter<Key, Value> = () =>
@@ -6398,11 +6410,11 @@ export interface InteractionDeferUpdateOptions {
63986410
export interface InteractionReplyOptions extends BaseMessageOptions, MessageOptionsPoll {
63996411
flags?:
64006412
| BitFieldResolvable<
6401-
Extract<MessageFlagsString, 'Ephemeral' | 'IsComponentsV2' | 'SuppressEmbeds' | 'SuppressNotifications'>,
6402-
| MessageFlags.Ephemeral
6403-
| MessageFlags.IsComponentsV2
6404-
| MessageFlags.SuppressEmbeds
6405-
| MessageFlags.SuppressNotifications
6413+
Extract<
6414+
MessageFlagsString,
6415+
'Ephemeral' | 'IsComponentsV2' | 'IsVoiceMessage' | 'SuppressEmbeds' | 'SuppressNotifications'
6416+
>,
6417+
MessageFlags.Ephemeral | MessageFlags.IsComponentsV2 | MessageFlags.IsVoiceMessage | MessageFlags.SuppressEmbeds | MessageFlags.SuppressNotifications
64066418
>
64076419
| undefined;
64086420
tts?: boolean;
@@ -6577,8 +6589,8 @@ export interface MessageOptionsPoll {
65776589
export interface MessageOptionsFlags {
65786590
flags?:
65796591
| BitFieldResolvable<
6580-
Extract<MessageFlagsString, 'IsComponentsV2' | 'SuppressEmbeds' | 'SuppressNotifications'>,
6581-
MessageFlags.IsComponentsV2 | MessageFlags.SuppressEmbeds | MessageFlags.SuppressNotifications
6592+
Extract<MessageFlagsString, 'IsComponentsV2' | 'IsVoiceMessage' | 'SuppressEmbeds' | 'SuppressNotifications'>,
6593+
MessageFlags.IsComponentsV2 | MessageFlags.IsVoiceMessage | MessageFlags.SuppressEmbeds | MessageFlags.SuppressNotifications
65826594
>
65836595
| undefined;
65846596
}

packages/discord.js/typings/index.test-d.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3000,3 +3000,23 @@ await guildScheduledEventManager.edit(snowflake, { recurrenceRule: null });
30003000
byMonth: [GuildScheduledEventRecurrenceRuleMonth.May],
30013001
});
30023002
}
3003+
3004+
await textChannel.send({
3005+
files: [
3006+
new AttachmentBuilder('https://example.com/voice-message.ogg')
3007+
.setDuration(2)
3008+
.setWaveform('AFUqPDw3Eg2hh4+gopOYj4xthU4='),
3009+
],
3010+
flags: MessageFlags.IsVoiceMessage,
3011+
});
3012+
3013+
await textChannel.send({
3014+
files: [
3015+
{
3016+
attachment: 'https://example.com/voice-message.ogg',
3017+
duration: 2,
3018+
waveform: 'AFUqPDw3Eg2hh4+gopOYj4xthU4=',
3019+
},
3020+
],
3021+
flags: MessageFlags.IsVoiceMessage,
3022+
});

0 commit comments

Comments
 (0)