discord.js 15.0.0-dev.1739664801-e3e3c212b → 15.0.0-dev.1740096733-0e7bdb072

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "discord.js",
4
- "version": "15.0.0-dev.1739664801-e3e3c212b",
4
+ "version": "15.0.0-dev.1740096733-0e7bdb072",
5
5
  "description": "A powerful library for interacting with the Discord API",
6
6
  "main": "./src/index.js",
7
7
  "types": "./typings/index.d.ts",
@@ -63,8 +63,8 @@
63
63
  "@discordjs/collection": "^2.1.1",
64
64
  "@discordjs/formatters": "^0.5.0",
65
65
  "@discordjs/util": "^1.1.1",
66
- "@discordjs/rest": "^2.4.0",
67
- "@discordjs/ws": "^2.0.0"
66
+ "@discordjs/ws": "^2.0.0",
67
+ "@discordjs/rest": "^2.4.0"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@favware/cliff-jumper": "^4.1.0",
@@ -81,9 +81,9 @@
81
81
  "tslint": "6.1.3",
82
82
  "turbo": "^2.3.3",
83
83
  "typescript": "~5.5.4",
84
- "@discordjs/docgen": "^0.12.1",
84
+ "@discordjs/api-extractor": "^7.38.1",
85
85
  "@discordjs/scripts": "^0.1.0",
86
- "@discordjs/api-extractor": "^7.38.1"
86
+ "@discordjs/docgen": "^0.12.1"
87
87
  },
88
88
  "engines": {
89
89
  "node": ">=22.12.0"
@@ -1,13 +1,17 @@
1
1
  'use strict';
2
2
 
3
3
  const process = require('node:process');
4
+ const { lazy } = require('@discordjs/util');
4
5
  const { Routes } = require('discord-api-types/v10');
5
6
  const { CachedManager } = require('./CachedManager.js');
6
7
  const { BaseChannel } = require('../structures/BaseChannel.js');
8
+ const { MessagePayload } = require('../structures/MessagePayload.js');
7
9
  const { createChannel } = require('../util/Channels.js');
8
10
  const { ThreadChannelTypes } = require('../util/Constants.js');
9
11
  const { Events } = require('../util/Events.js');
10
12
 
13
+ const getMessage = lazy(() => require('../structures/Message.js').Message);
14
+
11
15
  let cacheWarningEmitted = false;
12
16
 
13
17
  /**
@@ -123,6 +127,52 @@ class ChannelManager extends CachedManager {
123
127
  const data = await this.client.rest.get(Routes.channel(id));
124
128
  return this._add(data, null, { cache, allowUnknownGuild });
125
129
  }
130
+
131
+ /**
132
+ * Creates a message in a channel.
133
+ * @param {TextChannelResolvable} channel The channel to send the message to
134
+ * @param {string|MessagePayload|MessageCreateOptions} options The options to provide
135
+ * @returns {Promise<Message>}
136
+ * @example
137
+ * // Send a basic message
138
+ * client.channels.createMessage(channel, 'hello!')
139
+ * .then(message => console.log(`Sent message: ${message.content}`))
140
+ * .catch(console.error);
141
+ * @example
142
+ * // Send a remote file
143
+ * client.channels.createMessage(channel, {
144
+ * files: ['https://github.com/discordjs.png']
145
+ * })
146
+ * .then(console.log)
147
+ * .catch(console.error);
148
+ * @example
149
+ * // Send a local file
150
+ * client.channels.createMessage(channel, {
151
+ * files: [{
152
+ * attachment: 'entire/path/to/file.jpg',
153
+ * name: 'file.jpg',
154
+ * description: 'A description of the file'
155
+ * }]
156
+ * })
157
+ * .then(console.log)
158
+ * .catch(console.error);
159
+ */
160
+ async createMessage(channel, options) {
161
+ let messagePayload;
162
+
163
+ if (options instanceof MessagePayload) {
164
+ messagePayload = options.resolveBody();
165
+ } else {
166
+ messagePayload = MessagePayload.create(this, options).resolveBody();
167
+ }
168
+
169
+ const resolvedChannelId = this.resolveId(channel);
170
+ const resolvedChannel = this.resolve(channel);
171
+ const { body, files } = await messagePayload.resolveFiles();
172
+ const data = await this.client.rest.post(Routes.channelMessages(resolvedChannelId), { body, files });
173
+
174
+ return resolvedChannel?.messages._add(data) ?? new (getMessage())(this.client, data);
175
+ }
126
176
  }
127
177
 
128
178
  exports.ChannelManager = ChannelManager;
@@ -191,6 +191,6 @@ class BaseGuildTextChannel extends GuildChannel {
191
191
  setNSFW() {}
192
192
  }
193
193
 
194
- TextBasedChannel.applyToClass(BaseGuildTextChannel, true);
194
+ TextBasedChannel.applyToClass(BaseGuildTextChannel);
195
195
 
196
196
  exports.BaseGuildTextChannel = BaseGuildTextChannel;
@@ -229,6 +229,6 @@ class BaseGuildVoiceChannel extends GuildChannel {
229
229
  setNSFW() {}
230
230
  }
231
231
 
232
- TextBasedChannel.applyToClass(BaseGuildVoiceChannel, true, ['lastPinAt']);
232
+ TextBasedChannel.applyToClass(BaseGuildVoiceChannel, ['lastPinAt']);
233
233
 
234
234
  exports.BaseGuildVoiceChannel = BaseGuildVoiceChannel;
@@ -118,7 +118,7 @@ class DMChannel extends BaseChannel {
118
118
  // Doesn't work on DM channels; setNSFW() {}
119
119
  }
120
120
 
121
- TextBasedChannel.applyToClass(DMChannel, true, [
121
+ TextBasedChannel.applyToClass(DMChannel, [
122
122
  'bulkDelete',
123
123
  'fetchWebhooks',
124
124
  'createWebhook',
@@ -3,7 +3,6 @@
3
3
  const { PermissionFlagsBits } = require('discord-api-types/v10');
4
4
  const { Base } = require('./Base.js');
5
5
  const { VoiceState } = require('./VoiceState.js');
6
- const { TextBasedChannel } = require('./interfaces/TextBasedChannel.js');
7
6
  const { DiscordjsError, ErrorCodes } = require('../errors/index.js');
8
7
  const { GuildMemberRoleManager } = require('../managers/GuildMemberRoleManager.js');
9
8
  const { GuildMemberFlagsBitField } = require('../util/GuildMemberFlagsBitField.js');
@@ -11,7 +10,6 @@ const { PermissionsBitField } = require('../util/PermissionsBitField.js');
11
10
 
12
11
  /**
13
12
  * Represents a member of a guild on Discord.
14
- * @implements {TextBasedChannel}
15
13
  * @extends {Base}
16
14
  */
17
15
  class GuildMember extends Base {
@@ -476,6 +474,22 @@ class GuildMember extends Base {
476
474
  return this.guild.members.fetch({ user: this.id, cache: true, force });
477
475
  }
478
476
 
477
+ /**
478
+ * Sends a message to this user.
479
+ * @param {string|MessagePayload|MessageCreateOptions} options The options to provide
480
+ * @returns {Promise<Message>}
481
+ * @example
482
+ * // Send a direct message
483
+ * guildMember.send('Hello!')
484
+ * .then(message => console.log(`Sent message: ${message.content} to ${guildMember.displayName}`))
485
+ * .catch(console.error);
486
+ */
487
+ async send(options) {
488
+ const dmChannel = await this.createDM();
489
+
490
+ return this.client.channels.createMessage(dmChannel, options);
491
+ }
492
+
479
493
  /**
480
494
  * Whether this guild member equals another guild member. It compares all properties, so for most
481
495
  * comparison it is advisable to just compare `member.id === member2.id` as it is significantly faster
@@ -527,20 +541,4 @@ class GuildMember extends Base {
527
541
  }
528
542
  }
529
543
 
530
- /**
531
- * Sends a message to this user.
532
- * @method send
533
- * @memberof GuildMember
534
- * @instance
535
- * @param {string|MessagePayload|MessageCreateOptions} options The options to provide
536
- * @returns {Promise<Message>}
537
- * @example
538
- * // Send a direct message
539
- * guildMember.send('Hello!')
540
- * .then(message => console.log(`Sent message: ${message.content} to ${guildMember.displayName}`))
541
- * .catch(console.error);
542
- */
543
-
544
- TextBasedChannel.applyToClass(GuildMember);
545
-
546
544
  exports.GuildMember = GuildMember;
@@ -8,6 +8,7 @@ const {
8
8
  ChannelType,
9
9
  MessageType,
10
10
  MessageFlags,
11
+ MessageReferenceType,
11
12
  PermissionFlagsBits,
12
13
  } = require('discord-api-types/v10');
13
14
  const { Attachment } = require('./Attachment.js');
@@ -680,7 +681,11 @@ class Message extends Base {
680
681
  * @readonly
681
682
  */
682
683
  get editable() {
683
- const precheck = Boolean(this.author.id === this.client.user.id && (!this.guild || this.channel?.viewable));
684
+ const precheck = Boolean(
685
+ this.author.id === this.client.user.id &&
686
+ (!this.guild || this.channel?.viewable) &&
687
+ this.reference?.type !== MessageReferenceType.Forward,
688
+ );
684
689
 
685
690
  // Regardless of permissions thread messages cannot be edited if
686
691
  // the thread is archived or the thread is locked and the bot does not have permission to manage threads.
@@ -915,21 +920,39 @@ class Message extends Base {
915
920
  * .then(() => console.log(`Replied to message "${message.content}"`))
916
921
  * .catch(console.error);
917
922
  */
918
- async reply(options) {
919
- if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
923
+ reply(options) {
920
924
  let data;
921
925
 
922
926
  if (options instanceof MessagePayload) {
923
927
  data = options;
924
928
  } else {
925
929
  data = MessagePayload.create(this, options, {
926
- reply: {
927
- messageReference: this,
930
+ messageReference: {
931
+ messageId: this.id,
932
+ channelId: this.channelId,
933
+ guildId: this.guildId ?? undefined,
934
+ type: MessageReferenceType.Default,
928
935
  failIfNotExists: options?.failIfNotExists ?? this.client.options.failIfNotExists,
929
936
  },
930
937
  });
931
938
  }
932
- return this.channel.send(data);
939
+ return this.client.channels.createMessage(this.channelId, data);
940
+ }
941
+
942
+ /**
943
+ * Forwards this message.
944
+ * @param {TextChannelResolvable} channel The channel to forward this message to.
945
+ * @returns {Promise<Message>}
946
+ */
947
+ forward(channel) {
948
+ return this.client.channels.createMessage(channel, {
949
+ messageReference: {
950
+ messageId: this.id,
951
+ channelId: this.channelId,
952
+ guildId: this.guildId ?? undefined,
953
+ type: MessageReferenceType.Forward,
954
+ },
955
+ });
933
956
  }
934
957
 
935
958
  /**
@@ -151,7 +151,7 @@ class MessagePayload {
151
151
  if (
152
152
  // eslint-disable-next-line eqeqeq
153
153
  this.options.flags != null ||
154
- (this.isMessage && this.options.reply === undefined) ||
154
+ (this.isMessage && this.options.messageReference === undefined) ||
155
155
  this.isMessageManager
156
156
  ) {
157
157
  flags = new MessageFlagsBitField(this.options.flags).bitfield;
@@ -168,13 +168,16 @@ class MessagePayload {
168
168
  }
169
169
 
170
170
  let message_reference;
171
- if (typeof this.options.reply === 'object') {
172
- const reference = this.options.reply.messageReference;
173
- const message_id = this.isMessage ? (reference.id ?? reference) : this.target.messages.resolveId(reference);
174
- if (message_id) {
171
+ if (this.options.messageReference) {
172
+ const reference = this.options.messageReference;
173
+
174
+ if (reference.messageId) {
175
175
  message_reference = {
176
- message_id,
177
- fail_if_not_exists: this.options.reply.failIfNotExists ?? this.target.client.options.failIfNotExists,
176
+ message_id: reference.messageId,
177
+ channel_id: reference.channelId,
178
+ guild_id: reference.guildId,
179
+ type: reference.type,
180
+ fail_if_not_exists: reference.failIfNotExists ?? this.target.client.options.failIfNotExists,
178
181
  };
179
182
  }
180
183
  }
@@ -292,7 +295,7 @@ exports.MessagePayload = MessagePayload;
292
295
 
293
296
  /**
294
297
  * A target for a message.
295
- * @typedef {TextBasedChannels|User|GuildMember|Webhook|WebhookClient|BaseInteraction|InteractionWebhook|
298
+ * @typedef {TextBasedChannels|ChannelManager|Webhook|WebhookClient|BaseInteraction|InteractionWebhook|
296
299
  * Message|MessageManager} MessageTarget
297
300
  */
298
301
 
@@ -116,7 +116,7 @@ class PartialGroupDMChannel extends BaseChannel {
116
116
  awaitMessageComponent() {}
117
117
  }
118
118
 
119
- TextBasedChannel.applyToClass(PartialGroupDMChannel, true, [
119
+ TextBasedChannel.applyToClass(PartialGroupDMChannel, [
120
120
  'bulkDelete',
121
121
  'send',
122
122
  'sendTyping',
@@ -598,6 +598,6 @@ class ThreadChannel extends BaseChannel {
598
598
  // Doesn't work on Thread channels; setNSFW() {}
599
599
  }
600
600
 
601
- TextBasedChannel.applyToClass(ThreadChannel, true, ['fetchWebhooks', 'setRateLimitPerUser', 'setNSFW']);
601
+ TextBasedChannel.applyToClass(ThreadChannel, ['fetchWebhooks', 'setRateLimitPerUser', 'setNSFW']);
602
602
 
603
603
  exports.ThreadChannel = ThreadChannel;
@@ -234,7 +234,7 @@ class ThreadOnlyChannel extends GuildChannel {
234
234
  setRateLimitPerUser() {}
235
235
  }
236
236
 
237
- TextBasedChannel.applyToClass(ThreadOnlyChannel, true, [
237
+ TextBasedChannel.applyToClass(ThreadOnlyChannel, [
238
238
  'send',
239
239
  'lastMessage',
240
240
  'lastPinAt',
@@ -4,12 +4,10 @@ const { userMention } = require('@discordjs/formatters');
4
4
  const { calculateUserDefaultAvatarIndex } = require('@discordjs/rest');
5
5
  const { DiscordSnowflake } = require('@sapphire/snowflake');
6
6
  const { Base } = require('./Base.js');
7
- const { TextBasedChannel } = require('./interfaces/TextBasedChannel.js');
8
7
  const { UserFlagsBitField } = require('../util/UserFlagsBitField.js');
9
8
 
10
9
  /**
11
10
  * Represents a user on Discord.
12
- * @implements {TextBasedChannel}
13
11
  * @extends {Base}
14
12
  */
15
13
  class User extends Base {
@@ -277,6 +275,22 @@ class User extends Base {
277
275
  return this.client.users.deleteDM(this.id);
278
276
  }
279
277
 
278
+ /**
279
+ * Sends a message to this user.
280
+ * @param {string|MessagePayload|MessageCreateOptions} options The options to provide
281
+ * @returns {Promise<Message>}
282
+ * @example
283
+ * // Send a direct message
284
+ * user.send('Hello!')
285
+ * .then(message => console.log(`Sent message: ${message.content} to ${user.tag}`))
286
+ * .catch(console.error);
287
+ */
288
+ async send(options) {
289
+ const dmChannel = await this.createDM();
290
+
291
+ return this.client.channels.createMessage(dmChannel, options);
292
+ }
293
+
280
294
  /**
281
295
  * Checks if the user is equal to another.
282
296
  * It compares id, username, discriminator, avatar, banner, accent color, and bot flags.
@@ -361,20 +375,4 @@ class User extends Base {
361
375
  }
362
376
  }
363
377
 
364
- /**
365
- * Sends a message to this user.
366
- * @method send
367
- * @memberof User
368
- * @instance
369
- * @param {string|MessagePayload|MessageCreateOptions} options The options to provide
370
- * @returns {Promise<Message>}
371
- * @example
372
- * // Send a direct message
373
- * user.send('Hello!')
374
- * .then(message => console.log(`Sent message: ${message.content} to ${user.tag}`))
375
- * .catch(console.error);
376
- */
377
-
378
- TextBasedChannel.applyToClass(User);
379
-
380
378
  exports.User = User;
@@ -172,7 +172,7 @@ class Webhook {
172
172
  * @example
173
173
  * // Send a remote file
174
174
  * webhook.send({
175
- * files: ['https://cdn.discordapp.com/icons/222078108977594368/6e1019b3179d71046e463a75915e7244.png?size=2048']
175
+ * files: ['https://github.com/discordjs.png']
176
176
  * })
177
177
  * .then(console.log)
178
178
  * .catch(console.error);
@@ -7,7 +7,6 @@ const { DiscordjsTypeError, DiscordjsError, ErrorCodes } = require('../../errors
7
7
  const { MaxBulkDeletableMessageAge } = require('../../util/Constants.js');
8
8
  const { InteractionCollector } = require('../InteractionCollector.js');
9
9
  const { MessageCollector } = require('../MessageCollector.js');
10
- const { MessagePayload } = require('../MessagePayload.js');
11
10
 
12
11
  /**
13
12
  * Interface for classes that have text-channel-like features.
@@ -88,14 +87,6 @@ class TextBasedChannel {
88
87
  * @property {PollData} [poll] The poll to send with the message
89
88
  */
90
89
 
91
- /**
92
- * Options for sending a message with a reply.
93
- * @typedef {Object} ReplyOptions
94
- * @property {MessageResolvable} messageReference The message to reply to (must be in the same channel and not system)
95
- * @property {boolean} [failIfNotExists=this.client.options.failIfNotExists] Whether to error if the referenced
96
- * message does not exist (creates a standard message in this case when false)
97
- */
98
-
99
90
  /**
100
91
  * The options for sending a message.
101
92
  * @typedef {BaseMessageOptionsWithPoll} BaseMessageCreateOptions
@@ -110,10 +101,16 @@ class TextBasedChannel {
110
101
  * <info>Only `MessageFlags.SuppressEmbeds` and `MessageFlags.SuppressNotifications` can be set.</info>
111
102
  */
112
103
 
104
+ /**
105
+ * @typedef {MessageReference} MessageReferenceOptions
106
+ * @property {boolean} [failIfNotExists=this.client.options.failIfNotExists] Whether to error if the
107
+ * referenced message doesn't exist instead of sending as a normal (non-reply) message
108
+ */
109
+
113
110
  /**
114
111
  * The options for sending a message.
115
112
  * @typedef {BaseMessageCreateOptions} MessageCreateOptions
116
- * @property {ReplyOptions} [reply] The options for replying to a message
113
+ * @property {MessageReferenceOptions} [messageReference] The options for a reference to a message
117
114
  */
118
115
 
119
116
  /**
@@ -145,7 +142,7 @@ class TextBasedChannel {
145
142
  * @example
146
143
  * // Send a remote file
147
144
  * channel.send({
148
- * files: ['https://cdn.discordapp.com/icons/222078108977594368/6e1019b3179d71046e463a75915e7244.png?size=2048']
145
+ * files: ['https://github.com/discordjs.png']
149
146
  * })
150
147
  * .then(console.log)
151
148
  * .catch(console.error);
@@ -161,27 +158,8 @@ class TextBasedChannel {
161
158
  * .then(console.log)
162
159
  * .catch(console.error);
163
160
  */
164
- async send(options) {
165
- const { User } = require('../User.js');
166
- const { GuildMember } = require('../GuildMember.js');
167
-
168
- if (this instanceof User || this instanceof GuildMember) {
169
- const dm = await this.createDM();
170
- return dm.send(options);
171
- }
172
-
173
- let messagePayload;
174
-
175
- if (options instanceof MessagePayload) {
176
- messagePayload = options.resolveBody();
177
- } else {
178
- messagePayload = MessagePayload.create(this, options).resolveBody();
179
- }
180
-
181
- const { body, files } = await messagePayload.resolveFiles();
182
- const d = await this.client.rest.post(Routes.channelMessages(this.id), { body, files });
183
-
184
- return this.messages.cache.get(d.id) ?? this.messages._add(d);
161
+ send(options) {
162
+ return this.client.channels.createMessage(this, options);
185
163
  }
186
164
 
187
165
  /**
@@ -386,24 +364,23 @@ class TextBasedChannel {
386
364
  return this.edit({ nsfw, reason });
387
365
  }
388
366
 
389
- static applyToClass(structure, full = false, ignore = []) {
390
- const props = ['send'];
391
- if (full) {
392
- props.push(
393
- 'lastMessage',
394
- 'lastPinAt',
395
- 'bulkDelete',
396
- 'sendTyping',
397
- 'createMessageCollector',
398
- 'awaitMessages',
399
- 'createMessageComponentCollector',
400
- 'awaitMessageComponent',
401
- 'fetchWebhooks',
402
- 'createWebhook',
403
- 'setRateLimitPerUser',
404
- 'setNSFW',
405
- );
406
- }
367
+ static applyToClass(structure, ignore = []) {
368
+ const props = [
369
+ 'lastMessage',
370
+ 'lastPinAt',
371
+ 'bulkDelete',
372
+ 'sendTyping',
373
+ 'createMessageCollector',
374
+ 'awaitMessages',
375
+ 'createMessageComponentCollector',
376
+ 'awaitMessageComponent',
377
+ 'fetchWebhooks',
378
+ 'createWebhook',
379
+ 'setRateLimitPerUser',
380
+ 'setNSFW',
381
+ 'send',
382
+ ];
383
+
407
384
  for (const prop of props) {
408
385
  if (ignore.includes(prop)) continue;
409
386
  Object.defineProperty(
@@ -2175,6 +2175,9 @@ export class Message<InGuild extends boolean = boolean> extends Base {
2175
2175
  public reply(
2176
2176
  options: string | MessagePayload | MessageReplyOptions,
2177
2177
  ): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
2178
+ public forward(
2179
+ channel: Exclude<TextBasedChannelResolvable, PartialGroupDMChannel>,
2180
+ ): Promise<OmitPartialGroupDMChannel<Message>>;
2178
2181
  public resolveComponent(customId: string): MessageActionRowComponent | null;
2179
2182
  public startThread(options: StartThreadOptions): Promise<PublicThreadChannel<false>>;
2180
2183
  public suppressEmbeds(suppress?: boolean): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
@@ -4026,6 +4029,10 @@ export class CategoryChannelChildManager extends DataManager<Snowflake, Category
4026
4029
 
4027
4030
  export class ChannelManager extends CachedManager<Snowflake, Channel, ChannelResolvable> {
4028
4031
  private constructor(client: Client<true>, iterable: Iterable<RawChannelData>);
4032
+ public createMessage(
4033
+ channel: Exclude<TextBasedChannelResolvable, PartialGroupDMChannel>,
4034
+ options: string | MessagePayload | MessageCreateOptions,
4035
+ ): Promise<OmitPartialGroupDMChannel<Message>>;
4029
4036
  public fetch(id: Snowflake, options?: FetchChannelOptions): Promise<Channel | null>;
4030
4037
  }
4031
4038
 
@@ -6332,7 +6339,7 @@ export interface MessageCreateOptions extends BaseMessageOptionsWithPoll {
6332
6339
  tts?: boolean;
6333
6340
  nonce?: string | number;
6334
6341
  enforceNonce?: boolean;
6335
- reply?: ReplyOptions;
6342
+ messageReference?: MessageReferenceOptions;
6336
6343
  stickers?: readonly StickerResolvable[];
6337
6344
  flags?:
6338
6345
  | BitFieldResolvable<
@@ -6365,6 +6372,10 @@ export interface MessageReference {
6365
6372
  type: MessageReferenceType;
6366
6373
  }
6367
6374
 
6375
+ export interface MessageReferenceOptions extends MessageReference {
6376
+ failIfNotExists?: boolean;
6377
+ }
6378
+
6368
6379
  export type MessageResolvable = Message | Snowflake;
6369
6380
 
6370
6381
  export interface BaseSelectMenuComponentData extends BaseComponentData {
@@ -6437,15 +6448,14 @@ export interface TextInputComponentData extends BaseComponentData {
6437
6448
  }
6438
6449
 
6439
6450
  export type MessageTarget =
6451
+ | ChannelManager
6440
6452
  | Interaction
6441
6453
  | InteractionWebhook
6454
+ | Message
6455
+ | MessageManager
6442
6456
  | TextBasedChannel
6443
- | User
6444
- | GuildMember
6445
6457
  | Webhook<WebhookType.Incoming>
6446
- | WebhookClient
6447
- | Message
6448
- | MessageManager;
6458
+ | WebhookClient;
6449
6459
 
6450
6460
  export interface MultipleShardRespawnOptions {
6451
6461
  shardDelay?: number;
@@ -6609,12 +6619,7 @@ export interface ReactionCollectorOptions extends CollectorOptions<[MessageReact
6609
6619
  maxUsers?: number;
6610
6620
  }
6611
6621
 
6612
- export interface ReplyOptions {
6613
- messageReference: MessageResolvable;
6614
- failIfNotExists?: boolean;
6615
- }
6616
-
6617
- export interface MessageReplyOptions extends Omit<MessageCreateOptions, 'reply'> {
6622
+ export interface MessageReplyOptions extends Omit<MessageCreateOptions, 'messageReference'> {
6618
6623
  failIfNotExists?: boolean;
6619
6624
  }
6620
6625
 
@@ -6783,26 +6788,26 @@ export type Channel =
6783
6788
 
6784
6789
  export type TextBasedChannel = Exclude<Extract<Channel, { type: TextChannelType }>, ForumChannel | MediaChannel>;
6785
6790
 
6786
- export type SendableChannels = Extract<Channel, { send: (...args: any[]) => any }>;
6787
-
6788
6791
  export type TextBasedChannels = TextBasedChannel;
6789
6792
 
6790
6793
  export type TextBasedChannelTypes = TextBasedChannel['type'];
6791
6794
 
6792
6795
  export type GuildTextBasedChannelTypes = Exclude<TextBasedChannelTypes, ChannelType.DM | ChannelType.GroupDM>;
6793
6796
 
6794
- export type SendableChannelTypes = SendableChannels['type'];
6795
-
6796
6797
  export type VoiceBasedChannel = Extract<Channel, { bitrate: number }>;
6797
6798
 
6798
6799
  export type GuildBasedChannel = Extract<Channel, { guild: Guild }>;
6799
6800
 
6801
+ export type SendableChannels = Extract<Channel, { send: (...args: any[]) => any }>;
6802
+
6800
6803
  export type CategoryChildChannel = Exclude<Extract<Channel, { parent: CategoryChannel | null }>, CategoryChannel>;
6801
6804
 
6802
6805
  export type NonThreadGuildBasedChannel = Exclude<GuildBasedChannel, AnyThreadChannel>;
6803
6806
 
6804
6807
  export type GuildTextBasedChannel = Extract<GuildBasedChannel, TextBasedChannel>;
6805
6808
 
6809
+ export type SendableChannelTypes = SendableChannels['type'];
6810
+
6806
6811
  export type TextChannelResolvable = Snowflake | TextChannel;
6807
6812
 
6808
6813
  export type TextBasedChannelResolvable = Snowflake | TextBasedChannel;
@@ -6893,7 +6898,8 @@ export interface WebhookFetchMessageOptions {
6893
6898
  threadId?: Snowflake;
6894
6899
  }
6895
6900
 
6896
- export interface WebhookMessageCreateOptions extends Omit<MessageCreateOptions, 'nonce' | 'reply' | 'stickers'> {
6901
+ export interface WebhookMessageCreateOptions
6902
+ extends Omit<MessageCreateOptions, 'nonce' | 'messageReference' | 'stickers'> {
6897
6903
  username?: string;
6898
6904
  avatarURL?: string;
6899
6905
  threadId?: Snowflake;
@@ -2175,6 +2175,9 @@ export class Message<InGuild extends boolean = boolean> extends Base {
2175
2175
  public reply(
2176
2176
  options: string | MessagePayload | MessageReplyOptions,
2177
2177
  ): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
2178
+ public forward(
2179
+ channel: Exclude<TextBasedChannelResolvable, PartialGroupDMChannel>,
2180
+ ): Promise<OmitPartialGroupDMChannel<Message>>;
2178
2181
  public resolveComponent(customId: string): MessageActionRowComponent | null;
2179
2182
  public startThread(options: StartThreadOptions): Promise<PublicThreadChannel<false>>;
2180
2183
  public suppressEmbeds(suppress?: boolean): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
@@ -4026,6 +4029,10 @@ export class CategoryChannelChildManager extends DataManager<Snowflake, Category
4026
4029
 
4027
4030
  export class ChannelManager extends CachedManager<Snowflake, Channel, ChannelResolvable> {
4028
4031
  private constructor(client: Client<true>, iterable: Iterable<RawChannelData>);
4032
+ public createMessage(
4033
+ channel: Exclude<TextBasedChannelResolvable, PartialGroupDMChannel>,
4034
+ options: string | MessagePayload | MessageCreateOptions,
4035
+ ): Promise<OmitPartialGroupDMChannel<Message>>;
4029
4036
  public fetch(id: Snowflake, options?: FetchChannelOptions): Promise<Channel | null>;
4030
4037
  }
4031
4038
 
@@ -6332,7 +6339,7 @@ export interface MessageCreateOptions extends BaseMessageOptionsWithPoll {
6332
6339
  tts?: boolean;
6333
6340
  nonce?: string | number;
6334
6341
  enforceNonce?: boolean;
6335
- reply?: ReplyOptions;
6342
+ messageReference?: MessageReferenceOptions;
6336
6343
  stickers?: readonly StickerResolvable[];
6337
6344
  flags?:
6338
6345
  | BitFieldResolvable<
@@ -6365,6 +6372,10 @@ export interface MessageReference {
6365
6372
  type: MessageReferenceType;
6366
6373
  }
6367
6374
 
6375
+ export interface MessageReferenceOptions extends MessageReference {
6376
+ failIfNotExists?: boolean;
6377
+ }
6378
+
6368
6379
  export type MessageResolvable = Message | Snowflake;
6369
6380
 
6370
6381
  export interface BaseSelectMenuComponentData extends BaseComponentData {
@@ -6437,15 +6448,14 @@ export interface TextInputComponentData extends BaseComponentData {
6437
6448
  }
6438
6449
 
6439
6450
  export type MessageTarget =
6451
+ | ChannelManager
6440
6452
  | Interaction
6441
6453
  | InteractionWebhook
6454
+ | Message
6455
+ | MessageManager
6442
6456
  | TextBasedChannel
6443
- | User
6444
- | GuildMember
6445
6457
  | Webhook<WebhookType.Incoming>
6446
- | WebhookClient
6447
- | Message
6448
- | MessageManager;
6458
+ | WebhookClient;
6449
6459
 
6450
6460
  export interface MultipleShardRespawnOptions {
6451
6461
  shardDelay?: number;
@@ -6609,12 +6619,7 @@ export interface ReactionCollectorOptions extends CollectorOptions<[MessageReact
6609
6619
  maxUsers?: number;
6610
6620
  }
6611
6621
 
6612
- export interface ReplyOptions {
6613
- messageReference: MessageResolvable;
6614
- failIfNotExists?: boolean;
6615
- }
6616
-
6617
- export interface MessageReplyOptions extends Omit<MessageCreateOptions, 'reply'> {
6622
+ export interface MessageReplyOptions extends Omit<MessageCreateOptions, 'messageReference'> {
6618
6623
  failIfNotExists?: boolean;
6619
6624
  }
6620
6625
 
@@ -6783,26 +6788,26 @@ export type Channel =
6783
6788
 
6784
6789
  export type TextBasedChannel = Exclude<Extract<Channel, { type: TextChannelType }>, ForumChannel | MediaChannel>;
6785
6790
 
6786
- export type SendableChannels = Extract<Channel, { send: (...args: any[]) => any }>;
6787
-
6788
6791
  export type TextBasedChannels = TextBasedChannel;
6789
6792
 
6790
6793
  export type TextBasedChannelTypes = TextBasedChannel['type'];
6791
6794
 
6792
6795
  export type GuildTextBasedChannelTypes = Exclude<TextBasedChannelTypes, ChannelType.DM | ChannelType.GroupDM>;
6793
6796
 
6794
- export type SendableChannelTypes = SendableChannels['type'];
6795
-
6796
6797
  export type VoiceBasedChannel = Extract<Channel, { bitrate: number }>;
6797
6798
 
6798
6799
  export type GuildBasedChannel = Extract<Channel, { guild: Guild }>;
6799
6800
 
6801
+ export type SendableChannels = Extract<Channel, { send: (...args: any[]) => any }>;
6802
+
6800
6803
  export type CategoryChildChannel = Exclude<Extract<Channel, { parent: CategoryChannel | null }>, CategoryChannel>;
6801
6804
 
6802
6805
  export type NonThreadGuildBasedChannel = Exclude<GuildBasedChannel, AnyThreadChannel>;
6803
6806
 
6804
6807
  export type GuildTextBasedChannel = Extract<GuildBasedChannel, TextBasedChannel>;
6805
6808
 
6809
+ export type SendableChannelTypes = SendableChannels['type'];
6810
+
6806
6811
  export type TextChannelResolvable = Snowflake | TextChannel;
6807
6812
 
6808
6813
  export type TextBasedChannelResolvable = Snowflake | TextBasedChannel;
@@ -6893,7 +6898,8 @@ export interface WebhookFetchMessageOptions {
6893
6898
  threadId?: Snowflake;
6894
6899
  }
6895
6900
 
6896
- export interface WebhookMessageCreateOptions extends Omit<MessageCreateOptions, 'nonce' | 'reply' | 'stickers'> {
6901
+ export interface WebhookMessageCreateOptions
6902
+ extends Omit<MessageCreateOptions, 'nonce' | 'messageReference' | 'stickers'> {
6897
6903
  username?: string;
6898
6904
  avatarURL?: string;
6899
6905
  threadId?: Snowflake;
@@ -432,12 +432,20 @@ client.on('messageCreate', async message => {
432
432
  assertIsMessage(channel.send({}));
433
433
  assertIsMessage(channel.send({ embeds: [] }));
434
434
 
435
+ assertIsMessage(client.channels.createMessage(channel, 'string'));
436
+ assertIsMessage(client.channels.createMessage(channel, {}));
437
+ assertIsMessage(client.channels.createMessage(channel, { embeds: [] }));
438
+
435
439
  const attachment = new AttachmentBuilder('file.png');
436
440
  const embed = new EmbedBuilder();
437
441
  assertIsMessage(channel.send({ files: [attachment] }));
438
442
  assertIsMessage(channel.send({ embeds: [embed] }));
439
443
  assertIsMessage(channel.send({ embeds: [embed], files: [attachment] }));
440
444
 
445
+ assertIsMessage(client.channels.createMessage(channel, { files: [attachment] }));
446
+ assertIsMessage(client.channels.createMessage(channel, { embeds: [embed] }));
447
+ assertIsMessage(client.channels.createMessage(channel, { embeds: [embed], files: [attachment] }));
448
+
441
449
  if (message.inGuild()) {
442
450
  expectAssignable<Message<true>>(message);
443
451
  const component = await message.awaitMessageComponent({ componentType: ComponentType.Button });
@@ -467,8 +475,13 @@ client.on('messageCreate', async message => {
467
475
  // @ts-expect-error
468
476
  channel.send();
469
477
  // @ts-expect-error
478
+ client.channels.createMessage();
479
+ // @ts-expect-error
470
480
  channel.send({ another: 'property' });
471
-
481
+ // @ts-expect-error
482
+ client.channels.createMessage({ another: 'property' });
483
+ // @ts-expect-error
484
+ client.channels.createMessage('string');
472
485
  // Check collector creations.
473
486
 
474
487
  // Verify that buttons interactions are inferred.
@@ -647,7 +660,7 @@ client.on('messageCreate', async message => {
647
660
 
648
661
  const embedData = { description: 'test', color: 0xff0000 };
649
662
 
650
- channel.send({
663
+ client.channels.createMessage(channel, {
651
664
  components: [row, rawButtonsRow, buttonsRow, rawStringSelectMenuRow, stringSelectRow],
652
665
  embeds: [embed, embedData],
653
666
  });
@@ -1334,7 +1347,7 @@ client.on('guildCreate', async g => {
1334
1347
  ],
1335
1348
  });
1336
1349
 
1337
- channel.send({ components: [row, row2] });
1350
+ client.channels.createMessage(channel, { components: [row, row2] });
1338
1351
  }
1339
1352
 
1340
1353
  channel.setName('foo').then(updatedChannel => {
@@ -2704,7 +2717,7 @@ declare const sku: SKU;
2704
2717
  });
2705
2718
  }
2706
2719
 
2707
- await textChannel.send({
2720
+ await client.channels.createMessage('123', {
2708
2721
  poll: {
2709
2722
  question: {
2710
2723
  text: 'Question',