mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
feat!: create forwards and add ChannelManager#createMessage() (#10559)
BREAKING CHANGE: `MessageCreateOptions` no longer accepts `forward` or `reply`. Use `messageReference` instead. --------- Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
This commit is contained in:
@@ -1,13 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
const process = require('node:process');
|
||||
const { lazy } = require('@discordjs/util');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const { CachedManager } = require('./CachedManager.js');
|
||||
const { BaseChannel } = require('../structures/BaseChannel.js');
|
||||
const { MessagePayload } = require('../structures/MessagePayload.js');
|
||||
const { createChannel } = require('../util/Channels.js');
|
||||
const { ThreadChannelTypes } = require('../util/Constants.js');
|
||||
const { Events } = require('../util/Events.js');
|
||||
|
||||
const getMessage = lazy(() => require('../structures/Message.js').Message);
|
||||
|
||||
let cacheWarningEmitted = false;
|
||||
|
||||
/**
|
||||
@@ -123,6 +127,52 @@ class ChannelManager extends CachedManager {
|
||||
const data = await this.client.rest.get(Routes.channel(id));
|
||||
return this._add(data, null, { cache, allowUnknownGuild });
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a message in a channel.
|
||||
* @param {TextChannelResolvable} channel The channel to send the message to
|
||||
* @param {string|MessagePayload|MessageCreateOptions} options The options to provide
|
||||
* @returns {Promise<Message>}
|
||||
* @example
|
||||
* // Send a basic message
|
||||
* client.channels.createMessage(channel, 'hello!')
|
||||
* .then(message => console.log(`Sent message: ${message.content}`))
|
||||
* .catch(console.error);
|
||||
* @example
|
||||
* // Send a remote file
|
||||
* client.channels.createMessage(channel, {
|
||||
* files: ['https://github.com/discordjs.png']
|
||||
* })
|
||||
* .then(console.log)
|
||||
* .catch(console.error);
|
||||
* @example
|
||||
* // Send a local file
|
||||
* client.channels.createMessage(channel, {
|
||||
* files: [{
|
||||
* attachment: 'entire/path/to/file.jpg',
|
||||
* name: 'file.jpg',
|
||||
* description: 'A description of the file'
|
||||
* }]
|
||||
* })
|
||||
* .then(console.log)
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async createMessage(channel, options) {
|
||||
let messagePayload;
|
||||
|
||||
if (options instanceof MessagePayload) {
|
||||
messagePayload = options.resolveBody();
|
||||
} else {
|
||||
messagePayload = MessagePayload.create(this, options).resolveBody();
|
||||
}
|
||||
|
||||
const resolvedChannelId = this.resolveId(channel);
|
||||
const resolvedChannel = this.resolve(channel);
|
||||
const { body, files } = await messagePayload.resolveFiles();
|
||||
const data = await this.client.rest.post(Routes.channelMessages(resolvedChannelId), { body, files });
|
||||
|
||||
return resolvedChannel?.messages._add(data) ?? new (getMessage())(this.client, data);
|
||||
}
|
||||
}
|
||||
|
||||
exports.ChannelManager = ChannelManager;
|
||||
|
||||
@@ -191,6 +191,6 @@ class BaseGuildTextChannel extends GuildChannel {
|
||||
setNSFW() {}
|
||||
}
|
||||
|
||||
TextBasedChannel.applyToClass(BaseGuildTextChannel, true);
|
||||
TextBasedChannel.applyToClass(BaseGuildTextChannel);
|
||||
|
||||
exports.BaseGuildTextChannel = BaseGuildTextChannel;
|
||||
|
||||
@@ -229,6 +229,6 @@ class BaseGuildVoiceChannel extends GuildChannel {
|
||||
setNSFW() {}
|
||||
}
|
||||
|
||||
TextBasedChannel.applyToClass(BaseGuildVoiceChannel, true, ['lastPinAt']);
|
||||
TextBasedChannel.applyToClass(BaseGuildVoiceChannel, ['lastPinAt']);
|
||||
|
||||
exports.BaseGuildVoiceChannel = BaseGuildVoiceChannel;
|
||||
|
||||
@@ -118,7 +118,7 @@ class DMChannel extends BaseChannel {
|
||||
// Doesn't work on DM channels; setNSFW() {}
|
||||
}
|
||||
|
||||
TextBasedChannel.applyToClass(DMChannel, true, [
|
||||
TextBasedChannel.applyToClass(DMChannel, [
|
||||
'bulkDelete',
|
||||
'fetchWebhooks',
|
||||
'createWebhook',
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
const { PermissionFlagsBits } = require('discord-api-types/v10');
|
||||
const { Base } = require('./Base.js');
|
||||
const { VoiceState } = require('./VoiceState.js');
|
||||
const { TextBasedChannel } = require('./interfaces/TextBasedChannel.js');
|
||||
const { DiscordjsError, ErrorCodes } = require('../errors/index.js');
|
||||
const { GuildMemberRoleManager } = require('../managers/GuildMemberRoleManager.js');
|
||||
const { GuildMemberFlagsBitField } = require('../util/GuildMemberFlagsBitField.js');
|
||||
@@ -11,7 +10,6 @@ const { PermissionsBitField } = require('../util/PermissionsBitField.js');
|
||||
|
||||
/**
|
||||
* Represents a member of a guild on Discord.
|
||||
* @implements {TextBasedChannel}
|
||||
* @extends {Base}
|
||||
*/
|
||||
class GuildMember extends Base {
|
||||
@@ -476,6 +474,22 @@ class GuildMember extends Base {
|
||||
return this.guild.members.fetch({ user: this.id, cache: true, force });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to this user.
|
||||
* @param {string|MessagePayload|MessageCreateOptions} options The options to provide
|
||||
* @returns {Promise<Message>}
|
||||
* @example
|
||||
* // Send a direct message
|
||||
* guildMember.send('Hello!')
|
||||
* .then(message => console.log(`Sent message: ${message.content} to ${guildMember.displayName}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async send(options) {
|
||||
const dmChannel = await this.createDM();
|
||||
|
||||
return this.client.channels.createMessage(dmChannel, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this guild member equals another guild member. It compares all properties, so for most
|
||||
* comparison it is advisable to just compare `member.id === member2.id` as it is significantly faster
|
||||
@@ -527,20 +541,4 @@ class GuildMember extends Base {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to this user.
|
||||
* @method send
|
||||
* @memberof GuildMember
|
||||
* @instance
|
||||
* @param {string|MessagePayload|MessageCreateOptions} options The options to provide
|
||||
* @returns {Promise<Message>}
|
||||
* @example
|
||||
* // Send a direct message
|
||||
* guildMember.send('Hello!')
|
||||
* .then(message => console.log(`Sent message: ${message.content} to ${guildMember.displayName}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
|
||||
TextBasedChannel.applyToClass(GuildMember);
|
||||
|
||||
exports.GuildMember = GuildMember;
|
||||
|
||||
@@ -8,6 +8,7 @@ const {
|
||||
ChannelType,
|
||||
MessageType,
|
||||
MessageFlags,
|
||||
MessageReferenceType,
|
||||
PermissionFlagsBits,
|
||||
} = require('discord-api-types/v10');
|
||||
const { Attachment } = require('./Attachment.js');
|
||||
@@ -680,7 +681,11 @@ class Message extends Base {
|
||||
* @readonly
|
||||
*/
|
||||
get editable() {
|
||||
const precheck = Boolean(this.author.id === this.client.user.id && (!this.guild || this.channel?.viewable));
|
||||
const precheck = Boolean(
|
||||
this.author.id === this.client.user.id &&
|
||||
(!this.guild || this.channel?.viewable) &&
|
||||
this.reference?.type !== MessageReferenceType.Forward,
|
||||
);
|
||||
|
||||
// Regardless of permissions thread messages cannot be edited if
|
||||
// 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 {
|
||||
* .then(() => console.log(`Replied to message "${message.content}"`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async reply(options) {
|
||||
if (!this.channel) throw new DiscordjsError(ErrorCodes.ChannelNotCached);
|
||||
reply(options) {
|
||||
let data;
|
||||
|
||||
if (options instanceof MessagePayload) {
|
||||
data = options;
|
||||
} else {
|
||||
data = MessagePayload.create(this, options, {
|
||||
reply: {
|
||||
messageReference: this,
|
||||
messageReference: {
|
||||
messageId: this.id,
|
||||
channelId: this.channelId,
|
||||
guildId: this.guildId ?? undefined,
|
||||
type: MessageReferenceType.Default,
|
||||
failIfNotExists: options?.failIfNotExists ?? this.client.options.failIfNotExists,
|
||||
},
|
||||
});
|
||||
}
|
||||
return this.channel.send(data);
|
||||
return this.client.channels.createMessage(this.channelId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards this message.
|
||||
* @param {TextChannelResolvable} channel The channel to forward this message to.
|
||||
* @returns {Promise<Message>}
|
||||
*/
|
||||
forward(channel) {
|
||||
return this.client.channels.createMessage(channel, {
|
||||
messageReference: {
|
||||
messageId: this.id,
|
||||
channelId: this.channelId,
|
||||
guildId: this.guildId ?? undefined,
|
||||
type: MessageReferenceType.Forward,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -151,7 +151,7 @@ class MessagePayload {
|
||||
if (
|
||||
// eslint-disable-next-line eqeqeq
|
||||
this.options.flags != null ||
|
||||
(this.isMessage && this.options.reply === undefined) ||
|
||||
(this.isMessage && this.options.messageReference === undefined) ||
|
||||
this.isMessageManager
|
||||
) {
|
||||
flags = new MessageFlagsBitField(this.options.flags).bitfield;
|
||||
@@ -168,13 +168,16 @@ class MessagePayload {
|
||||
}
|
||||
|
||||
let message_reference;
|
||||
if (typeof this.options.reply === 'object') {
|
||||
const reference = this.options.reply.messageReference;
|
||||
const message_id = this.isMessage ? (reference.id ?? reference) : this.target.messages.resolveId(reference);
|
||||
if (message_id) {
|
||||
if (this.options.messageReference) {
|
||||
const reference = this.options.messageReference;
|
||||
|
||||
if (reference.messageId) {
|
||||
message_reference = {
|
||||
message_id,
|
||||
fail_if_not_exists: this.options.reply.failIfNotExists ?? this.target.client.options.failIfNotExists,
|
||||
message_id: reference.messageId,
|
||||
channel_id: reference.channelId,
|
||||
guild_id: reference.guildId,
|
||||
type: reference.type,
|
||||
fail_if_not_exists: reference.failIfNotExists ?? this.target.client.options.failIfNotExists,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -292,7 +295,7 @@ exports.MessagePayload = MessagePayload;
|
||||
|
||||
/**
|
||||
* A target for a message.
|
||||
* @typedef {TextBasedChannels|User|GuildMember|Webhook|WebhookClient|BaseInteraction|InteractionWebhook|
|
||||
* @typedef {TextBasedChannels|ChannelManager|Webhook|WebhookClient|BaseInteraction|InteractionWebhook|
|
||||
* Message|MessageManager} MessageTarget
|
||||
*/
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ class PartialGroupDMChannel extends BaseChannel {
|
||||
awaitMessageComponent() {}
|
||||
}
|
||||
|
||||
TextBasedChannel.applyToClass(PartialGroupDMChannel, true, [
|
||||
TextBasedChannel.applyToClass(PartialGroupDMChannel, [
|
||||
'bulkDelete',
|
||||
'send',
|
||||
'sendTyping',
|
||||
|
||||
@@ -598,6 +598,6 @@ class ThreadChannel extends BaseChannel {
|
||||
// Doesn't work on Thread channels; setNSFW() {}
|
||||
}
|
||||
|
||||
TextBasedChannel.applyToClass(ThreadChannel, true, ['fetchWebhooks', 'setRateLimitPerUser', 'setNSFW']);
|
||||
TextBasedChannel.applyToClass(ThreadChannel, ['fetchWebhooks', 'setRateLimitPerUser', 'setNSFW']);
|
||||
|
||||
exports.ThreadChannel = ThreadChannel;
|
||||
|
||||
@@ -234,7 +234,7 @@ class ThreadOnlyChannel extends GuildChannel {
|
||||
setRateLimitPerUser() {}
|
||||
}
|
||||
|
||||
TextBasedChannel.applyToClass(ThreadOnlyChannel, true, [
|
||||
TextBasedChannel.applyToClass(ThreadOnlyChannel, [
|
||||
'send',
|
||||
'lastMessage',
|
||||
'lastPinAt',
|
||||
|
||||
@@ -4,12 +4,10 @@ const { userMention } = require('@discordjs/formatters');
|
||||
const { calculateUserDefaultAvatarIndex } = require('@discordjs/rest');
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const { Base } = require('./Base.js');
|
||||
const { TextBasedChannel } = require('./interfaces/TextBasedChannel.js');
|
||||
const { UserFlagsBitField } = require('../util/UserFlagsBitField.js');
|
||||
|
||||
/**
|
||||
* Represents a user on Discord.
|
||||
* @implements {TextBasedChannel}
|
||||
* @extends {Base}
|
||||
*/
|
||||
class User extends Base {
|
||||
@@ -277,6 +275,22 @@ class User extends Base {
|
||||
return this.client.users.deleteDM(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to this user.
|
||||
* @param {string|MessagePayload|MessageCreateOptions} options The options to provide
|
||||
* @returns {Promise<Message>}
|
||||
* @example
|
||||
* // Send a direct message
|
||||
* user.send('Hello!')
|
||||
* .then(message => console.log(`Sent message: ${message.content} to ${user.tag}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async send(options) {
|
||||
const dmChannel = await this.createDM();
|
||||
|
||||
return this.client.channels.createMessage(dmChannel, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user is equal to another.
|
||||
* It compares id, username, discriminator, avatar, banner, accent color, and bot flags.
|
||||
@@ -361,20 +375,4 @@ class User extends Base {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to this user.
|
||||
* @method send
|
||||
* @memberof User
|
||||
* @instance
|
||||
* @param {string|MessagePayload|MessageCreateOptions} options The options to provide
|
||||
* @returns {Promise<Message>}
|
||||
* @example
|
||||
* // Send a direct message
|
||||
* user.send('Hello!')
|
||||
* .then(message => console.log(`Sent message: ${message.content} to ${user.tag}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
|
||||
TextBasedChannel.applyToClass(User);
|
||||
|
||||
exports.User = User;
|
||||
|
||||
@@ -172,7 +172,7 @@ class Webhook {
|
||||
* @example
|
||||
* // Send a remote file
|
||||
* webhook.send({
|
||||
* files: ['https://cdn.discordapp.com/icons/222078108977594368/6e1019b3179d71046e463a75915e7244.png?size=2048']
|
||||
* files: ['https://github.com/discordjs.png']
|
||||
* })
|
||||
* .then(console.log)
|
||||
* .catch(console.error);
|
||||
|
||||
@@ -7,7 +7,6 @@ const { DiscordjsTypeError, DiscordjsError, ErrorCodes } = require('../../errors
|
||||
const { MaxBulkDeletableMessageAge } = require('../../util/Constants.js');
|
||||
const { InteractionCollector } = require('../InteractionCollector.js');
|
||||
const { MessageCollector } = require('../MessageCollector.js');
|
||||
const { MessagePayload } = require('../MessagePayload.js');
|
||||
|
||||
/**
|
||||
* Interface for classes that have text-channel-like features.
|
||||
@@ -88,14 +87,6 @@ class TextBasedChannel {
|
||||
* @property {PollData} [poll] The poll to send with the message
|
||||
*/
|
||||
|
||||
/**
|
||||
* Options for sending a message with a reply.
|
||||
* @typedef {Object} ReplyOptions
|
||||
* @property {MessageResolvable} messageReference The message to reply to (must be in the same channel and not system)
|
||||
* @property {boolean} [failIfNotExists=this.client.options.failIfNotExists] Whether to error if the referenced
|
||||
* message does not exist (creates a standard message in this case when false)
|
||||
*/
|
||||
|
||||
/**
|
||||
* The options for sending a message.
|
||||
* @typedef {BaseMessageOptionsWithPoll} BaseMessageCreateOptions
|
||||
@@ -110,10 +101,16 @@ class TextBasedChannel {
|
||||
* <info>Only `MessageFlags.SuppressEmbeds` and `MessageFlags.SuppressNotifications` can be set.</info>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {MessageReference} MessageReferenceOptions
|
||||
* @property {boolean} [failIfNotExists=this.client.options.failIfNotExists] Whether to error if the
|
||||
* referenced message doesn't exist instead of sending as a normal (non-reply) message
|
||||
*/
|
||||
|
||||
/**
|
||||
* The options for sending a message.
|
||||
* @typedef {BaseMessageCreateOptions} MessageCreateOptions
|
||||
* @property {ReplyOptions} [reply] The options for replying to a message
|
||||
* @property {MessageReferenceOptions} [messageReference] The options for a reference to a message
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -145,7 +142,7 @@ class TextBasedChannel {
|
||||
* @example
|
||||
* // Send a remote file
|
||||
* channel.send({
|
||||
* files: ['https://cdn.discordapp.com/icons/222078108977594368/6e1019b3179d71046e463a75915e7244.png?size=2048']
|
||||
* files: ['https://github.com/discordjs.png']
|
||||
* })
|
||||
* .then(console.log)
|
||||
* .catch(console.error);
|
||||
@@ -161,27 +158,8 @@ class TextBasedChannel {
|
||||
* .then(console.log)
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async send(options) {
|
||||
const { User } = require('../User.js');
|
||||
const { GuildMember } = require('../GuildMember.js');
|
||||
|
||||
if (this instanceof User || this instanceof GuildMember) {
|
||||
const dm = await this.createDM();
|
||||
return dm.send(options);
|
||||
}
|
||||
|
||||
let messagePayload;
|
||||
|
||||
if (options instanceof MessagePayload) {
|
||||
messagePayload = options.resolveBody();
|
||||
} else {
|
||||
messagePayload = MessagePayload.create(this, options).resolveBody();
|
||||
}
|
||||
|
||||
const { body, files } = await messagePayload.resolveFiles();
|
||||
const d = await this.client.rest.post(Routes.channelMessages(this.id), { body, files });
|
||||
|
||||
return this.messages.cache.get(d.id) ?? this.messages._add(d);
|
||||
send(options) {
|
||||
return this.client.channels.createMessage(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -386,24 +364,23 @@ class TextBasedChannel {
|
||||
return this.edit({ nsfw, reason });
|
||||
}
|
||||
|
||||
static applyToClass(structure, full = false, ignore = []) {
|
||||
const props = ['send'];
|
||||
if (full) {
|
||||
props.push(
|
||||
'lastMessage',
|
||||
'lastPinAt',
|
||||
'bulkDelete',
|
||||
'sendTyping',
|
||||
'createMessageCollector',
|
||||
'awaitMessages',
|
||||
'createMessageComponentCollector',
|
||||
'awaitMessageComponent',
|
||||
'fetchWebhooks',
|
||||
'createWebhook',
|
||||
'setRateLimitPerUser',
|
||||
'setNSFW',
|
||||
);
|
||||
}
|
||||
static applyToClass(structure, ignore = []) {
|
||||
const props = [
|
||||
'lastMessage',
|
||||
'lastPinAt',
|
||||
'bulkDelete',
|
||||
'sendTyping',
|
||||
'createMessageCollector',
|
||||
'awaitMessages',
|
||||
'createMessageComponentCollector',
|
||||
'awaitMessageComponent',
|
||||
'fetchWebhooks',
|
||||
'createWebhook',
|
||||
'setRateLimitPerUser',
|
||||
'setNSFW',
|
||||
'send',
|
||||
];
|
||||
|
||||
for (const prop of props) {
|
||||
if (ignore.includes(prop)) continue;
|
||||
Object.defineProperty(
|
||||
|
||||
42
packages/discord.js/typings/index.d.ts
vendored
42
packages/discord.js/typings/index.d.ts
vendored
@@ -2175,6 +2175,9 @@ export class Message<InGuild extends boolean = boolean> extends Base {
|
||||
public reply(
|
||||
options: string | MessagePayload | MessageReplyOptions,
|
||||
): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
|
||||
public forward(
|
||||
channel: Exclude<TextBasedChannelResolvable, PartialGroupDMChannel>,
|
||||
): Promise<OmitPartialGroupDMChannel<Message>>;
|
||||
public resolveComponent(customId: string): MessageActionRowComponent | null;
|
||||
public startThread(options: StartThreadOptions): Promise<PublicThreadChannel<false>>;
|
||||
public suppressEmbeds(suppress?: boolean): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
|
||||
@@ -4026,6 +4029,10 @@ export class CategoryChannelChildManager extends DataManager<Snowflake, Category
|
||||
|
||||
export class ChannelManager extends CachedManager<Snowflake, Channel, ChannelResolvable> {
|
||||
private constructor(client: Client<true>, iterable: Iterable<RawChannelData>);
|
||||
public createMessage(
|
||||
channel: Exclude<TextBasedChannelResolvable, PartialGroupDMChannel>,
|
||||
options: string | MessagePayload | MessageCreateOptions,
|
||||
): Promise<OmitPartialGroupDMChannel<Message>>;
|
||||
public fetch(id: Snowflake, options?: FetchChannelOptions): Promise<Channel | null>;
|
||||
}
|
||||
|
||||
@@ -6332,7 +6339,7 @@ export interface MessageCreateOptions extends BaseMessageOptionsWithPoll {
|
||||
tts?: boolean;
|
||||
nonce?: string | number;
|
||||
enforceNonce?: boolean;
|
||||
reply?: ReplyOptions;
|
||||
messageReference?: MessageReferenceOptions;
|
||||
stickers?: readonly StickerResolvable[];
|
||||
flags?:
|
||||
| BitFieldResolvable<
|
||||
@@ -6365,6 +6372,10 @@ export interface MessageReference {
|
||||
type: MessageReferenceType;
|
||||
}
|
||||
|
||||
export interface MessageReferenceOptions extends MessageReference {
|
||||
failIfNotExists?: boolean;
|
||||
}
|
||||
|
||||
export type MessageResolvable = Message | Snowflake;
|
||||
|
||||
export interface BaseSelectMenuComponentData extends BaseComponentData {
|
||||
@@ -6437,15 +6448,14 @@ export interface TextInputComponentData extends BaseComponentData {
|
||||
}
|
||||
|
||||
export type MessageTarget =
|
||||
| ChannelManager
|
||||
| Interaction
|
||||
| InteractionWebhook
|
||||
| TextBasedChannel
|
||||
| User
|
||||
| GuildMember
|
||||
| Webhook<WebhookType.Incoming>
|
||||
| WebhookClient
|
||||
| Message
|
||||
| MessageManager;
|
||||
| MessageManager
|
||||
| TextBasedChannel
|
||||
| Webhook<WebhookType.Incoming>
|
||||
| WebhookClient;
|
||||
|
||||
export interface MultipleShardRespawnOptions {
|
||||
shardDelay?: number;
|
||||
@@ -6609,12 +6619,7 @@ export interface ReactionCollectorOptions extends CollectorOptions<[MessageReact
|
||||
maxUsers?: number;
|
||||
}
|
||||
|
||||
export interface ReplyOptions {
|
||||
messageReference: MessageResolvable;
|
||||
failIfNotExists?: boolean;
|
||||
}
|
||||
|
||||
export interface MessageReplyOptions extends Omit<MessageCreateOptions, 'reply'> {
|
||||
export interface MessageReplyOptions extends Omit<MessageCreateOptions, 'messageReference'> {
|
||||
failIfNotExists?: boolean;
|
||||
}
|
||||
|
||||
@@ -6783,26 +6788,26 @@ export type Channel =
|
||||
|
||||
export type TextBasedChannel = Exclude<Extract<Channel, { type: TextChannelType }>, ForumChannel | MediaChannel>;
|
||||
|
||||
export type SendableChannels = Extract<Channel, { send: (...args: any[]) => any }>;
|
||||
|
||||
export type TextBasedChannels = TextBasedChannel;
|
||||
|
||||
export type TextBasedChannelTypes = TextBasedChannel['type'];
|
||||
|
||||
export type GuildTextBasedChannelTypes = Exclude<TextBasedChannelTypes, ChannelType.DM | ChannelType.GroupDM>;
|
||||
|
||||
export type SendableChannelTypes = SendableChannels['type'];
|
||||
|
||||
export type VoiceBasedChannel = Extract<Channel, { bitrate: number }>;
|
||||
|
||||
export type GuildBasedChannel = Extract<Channel, { guild: Guild }>;
|
||||
|
||||
export type SendableChannels = Extract<Channel, { send: (...args: any[]) => any }>;
|
||||
|
||||
export type CategoryChildChannel = Exclude<Extract<Channel, { parent: CategoryChannel | null }>, CategoryChannel>;
|
||||
|
||||
export type NonThreadGuildBasedChannel = Exclude<GuildBasedChannel, AnyThreadChannel>;
|
||||
|
||||
export type GuildTextBasedChannel = Extract<GuildBasedChannel, TextBasedChannel>;
|
||||
|
||||
export type SendableChannelTypes = SendableChannels['type'];
|
||||
|
||||
export type TextChannelResolvable = Snowflake | TextChannel;
|
||||
|
||||
export type TextBasedChannelResolvable = Snowflake | TextBasedChannel;
|
||||
@@ -6893,7 +6898,8 @@ export interface WebhookFetchMessageOptions {
|
||||
threadId?: Snowflake;
|
||||
}
|
||||
|
||||
export interface WebhookMessageCreateOptions extends Omit<MessageCreateOptions, 'nonce' | 'reply' | 'stickers'> {
|
||||
export interface WebhookMessageCreateOptions
|
||||
extends Omit<MessageCreateOptions, 'nonce' | 'messageReference' | 'stickers'> {
|
||||
username?: string;
|
||||
avatarURL?: string;
|
||||
threadId?: Snowflake;
|
||||
|
||||
@@ -432,12 +432,20 @@ client.on('messageCreate', async message => {
|
||||
assertIsMessage(channel.send({}));
|
||||
assertIsMessage(channel.send({ embeds: [] }));
|
||||
|
||||
assertIsMessage(client.channels.createMessage(channel, 'string'));
|
||||
assertIsMessage(client.channels.createMessage(channel, {}));
|
||||
assertIsMessage(client.channels.createMessage(channel, { embeds: [] }));
|
||||
|
||||
const attachment = new AttachmentBuilder('file.png');
|
||||
const embed = new EmbedBuilder();
|
||||
assertIsMessage(channel.send({ files: [attachment] }));
|
||||
assertIsMessage(channel.send({ embeds: [embed] }));
|
||||
assertIsMessage(channel.send({ embeds: [embed], files: [attachment] }));
|
||||
|
||||
assertIsMessage(client.channels.createMessage(channel, { files: [attachment] }));
|
||||
assertIsMessage(client.channels.createMessage(channel, { embeds: [embed] }));
|
||||
assertIsMessage(client.channels.createMessage(channel, { embeds: [embed], files: [attachment] }));
|
||||
|
||||
if (message.inGuild()) {
|
||||
expectAssignable<Message<true>>(message);
|
||||
const component = await message.awaitMessageComponent({ componentType: ComponentType.Button });
|
||||
@@ -467,8 +475,13 @@ client.on('messageCreate', async message => {
|
||||
// @ts-expect-error
|
||||
channel.send();
|
||||
// @ts-expect-error
|
||||
client.channels.createMessage();
|
||||
// @ts-expect-error
|
||||
channel.send({ another: 'property' });
|
||||
|
||||
// @ts-expect-error
|
||||
client.channels.createMessage({ another: 'property' });
|
||||
// @ts-expect-error
|
||||
client.channels.createMessage('string');
|
||||
// Check collector creations.
|
||||
|
||||
// Verify that buttons interactions are inferred.
|
||||
@@ -647,7 +660,7 @@ client.on('messageCreate', async message => {
|
||||
|
||||
const embedData = { description: 'test', color: 0xff0000 };
|
||||
|
||||
channel.send({
|
||||
client.channels.createMessage(channel, {
|
||||
components: [row, rawButtonsRow, buttonsRow, rawStringSelectMenuRow, stringSelectRow],
|
||||
embeds: [embed, embedData],
|
||||
});
|
||||
@@ -1334,7 +1347,7 @@ client.on('guildCreate', async g => {
|
||||
],
|
||||
});
|
||||
|
||||
channel.send({ components: [row, row2] });
|
||||
client.channels.createMessage(channel, { components: [row, row2] });
|
||||
}
|
||||
|
||||
channel.setName('foo').then(updatedChannel => {
|
||||
@@ -2704,7 +2717,7 @@ declare const sku: SKU;
|
||||
});
|
||||
}
|
||||
|
||||
await textChannel.send({
|
||||
await client.channels.createMessage('123', {
|
||||
poll: {
|
||||
question: {
|
||||
text: 'Question',
|
||||
|
||||
Reference in New Issue
Block a user