diff --git a/README.md b/README.md index cbc2bb0e..10a10461 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ client.on('ready', () => { client.on('message', msg => { if (msg.content === 'ping') { - msg.reply('pong'); + msg.channel.send('pong'); } }); diff --git a/docs/examples/avatars.js b/docs/examples/avatars.js index acb13d3a..6687033d 100644 --- a/docs/examples/avatars.js +++ b/docs/examples/avatars.js @@ -23,7 +23,7 @@ client.on('message', message => { // If the message is "what is my avatar" if (message.content === 'what is my avatar') { // Send the user's avatar URL - message.reply(message.author.displayAvatarURL()); + message.channel.send(message.author.displayAvatarURL()); } }); diff --git a/docs/examples/moderation.md b/docs/examples/moderation.md index 63c665c4..9d2ea032 100644 --- a/docs/examples/moderation.md +++ b/docs/examples/moderation.md @@ -45,23 +45,23 @@ client.on('message', message => { .kick('Optional reason that will display in the audit logs') .then(() => { // We let the message author know we were able to kick the person - message.reply(`Successfully kicked ${user.tag}`); + message.channel.send(`Successfully kicked ${user.tag}`); }) .catch(err => { // An error happened // This is generally due to the bot not being able to kick the member, // either due to missing permissions or role hierarchy - message.reply('I was unable to kick the member'); + message.channel.send('I was unable to kick the member'); // Log the error console.error(err); }); } else { // The mentioned user isn't in this guild - message.reply("That user isn't in this guild!"); + message.channel.send("That user isn't in this guild!"); } // Otherwise, if no user was mentioned } else { - message.reply("You didn't mention the user to kick!"); + message.channel.send("You didn't mention the user to kick!"); } } }); @@ -121,23 +121,23 @@ client.on('message', message => { }) .then(() => { // We let the message author know we were able to ban the person - message.reply(`Successfully banned ${user.tag}`); + message.channel.send(`Successfully banned ${user.tag}`); }) .catch(err => { // An error happened // This is generally due to the bot not being able to ban the member, // either due to missing permissions or role hierarchy - message.reply('I was unable to ban the member'); + message.channel.send('I was unable to ban the member'); // Log the error console.error(err); }); } else { // The mentioned user isn't in this guild - message.reply("That user isn't in this guild!"); + message.channel.send("That user isn't in this guild!"); } } else { // Otherwise, if no user was mentioned - message.reply("You didn't mention the user to ban!"); + message.channel.send("You didn't mention the user to ban!"); } } }); diff --git a/docs/general/welcome.md b/docs/general/welcome.md index 2d639c6a..58d36129 100644 --- a/docs/general/welcome.md +++ b/docs/general/welcome.md @@ -68,7 +68,7 @@ client.on('ready', () => { client.on('message', msg => { if (msg.content === 'ping') { - msg.reply('pong'); + msg.channel.send('pong'); } }); diff --git a/docs/topics/voice.md b/docs/topics/voice.md index cb20dd5c..8da93676 100644 --- a/docs/topics/voice.md +++ b/docs/topics/voice.md @@ -37,7 +37,7 @@ client.on('message', async message => { if (message.member.voice.channel) { const connection = await message.member.voice.channel.join(); } else { - message.reply('You need to join a voice channel first!'); + message.channel.send('You need to join a voice channel first!'); } } }); diff --git a/src/structures/APIMessage.js b/src/structures/APIMessage.js index bb884ccd..04bc7210 100644 --- a/src/structures/APIMessage.js +++ b/src/structures/APIMessage.js @@ -79,8 +79,6 @@ class APIMessage { * @returns {?(string|string[])} */ makeContent() { - const GuildMember = require('./GuildMember'); - let content; if (this.options.content === null) { content = ''; @@ -110,25 +108,14 @@ class APIMessage { const isCode = typeof this.options.code !== 'undefined' && this.options.code !== false; const splitOptions = isSplit ? { ...this.options.split } : undefined; - let mentionPart = ''; - if (this.options.reply && !this.isUser && this.target.type !== 'dm') { - const id = this.target.client.users.resolveID(this.options.reply); - mentionPart = `<@${this.options.reply instanceof GuildMember && this.options.reply.nickname ? '!' : ''}${id}>, `; - if (isSplit) { - splitOptions.prepend = `${mentionPart}${splitOptions.prepend || ''}`; - } - } - - if (content || mentionPart) { + if (content) { if (isCode) { const codeName = typeof this.options.code === 'string' ? this.options.code : ''; - content = `${mentionPart}\`\`\`${codeName}\n${Util.cleanCodeBlockContent(content)}\n\`\`\``; + content = `\`\`\`${codeName}\n${Util.cleanCodeBlockContent(content)}\n\`\`\``; if (isSplit) { splitOptions.prepend = `${splitOptions.prepend || ''}\`\`\`${codeName}\n`; splitOptions.append = `\n\`\`\`${splitOptions.append || ''}`; } - } else if (mentionPart) { - content = `${mentionPart}${content}`; } if (isSplit) { @@ -182,21 +169,6 @@ class APIMessage { typeof this.options.allowedMentions === 'undefined' ? this.target.client.options.allowedMentions : this.options.allowedMentions; - if (this.options.reply) { - const id = this.target.client.users.resolveID(this.options.reply); - if (allowedMentions) { - // Clone the object as not to alter the ClientOptions object - allowedMentions = Util.cloneObject(allowedMentions); - const parsed = allowedMentions.parse && allowedMentions.parse.includes('users'); - // Check if the mention won't be parsed, and isn't supplied in `users` - if (!parsed && !(allowedMentions.users && allowedMentions.users.includes(id))) { - if (!allowedMentions.users) allowedMentions.users = []; - allowedMentions.users.push(id); - } - } else { - allowedMentions = { users: [id] }; - } - } let message_reference; if (this.options.inlineReplyTo) { diff --git a/src/structures/Emoji.js b/src/structures/Emoji.js index 0214ea80..86119d30 100644 --- a/src/structures/Emoji.js +++ b/src/structures/Emoji.js @@ -82,7 +82,7 @@ class Emoji extends Base { * @example * // Send a custom emoji from a guild: * const emoji = guild.emojis.cache.first(); - * msg.reply(`Hello! ${emoji}`); + * msg.channel.send(`Hello! ${emoji}`); * @example * // Send the emoji used in a reaction to the channel the reaction is part of * reaction.message.channel.send(`The emoji used was: ${reaction.emoji}`); diff --git a/src/structures/Message.js b/src/structures/Message.js index 2d28d944..c2fe1b1a 100644 --- a/src/structures/Message.js +++ b/src/structures/Message.js @@ -574,37 +574,18 @@ class Message extends Base { } /** - * Replies to the message. + * Send an inline reply to this message. * @param {StringResolvable|APIMessage} [content=''] The content for the message - * @param {MessageOptions|MessageAdditions} [options={}] The options to provide + * @param {MessageOptions|MessageAdditions} [options] The additional options to provide + * @param {MessageResolvable} [options.replyTo=this] The message to reply to * @returns {Promise} - * @example - * // Reply to a message - * message.reply('Hey, I\'m a reply!') - * .then(() => console.log(`Sent a reply to ${message.author.username}`)) - * .catch(console.error); */ reply(content, options) { - return this.channel.send( - content instanceof APIMessage - ? content - : APIMessage.transformOptions(content, options, { reply: this.member || this.author }), - ); - } - - /** - * Send an inline reply to this message. - * @param {StringResolvable|APIMessage} [content=''] The content for the message - * @param {MessageOptions|MessageAdditions} [options={inlineReplyTo:this}] - * The additional options to provide - * @returns {Promise} - */ - inlineReply(content, options) { return this.channel.send( content instanceof APIMessage ? content : APIMessage.transformOptions(content, options, { - inlineReplyTo: this, + replyTo: this, }), ); } diff --git a/src/structures/interfaces/TextBasedChannel.js b/src/structures/interfaces/TextBasedChannel.js index df8fe67b..ec9dffe7 100644 --- a/src/structures/interfaces/TextBasedChannel.js +++ b/src/structures/interfaces/TextBasedChannel.js @@ -65,8 +65,7 @@ class TextBasedChannel { * @property {string|boolean} [code] Language for optional codeblock formatting to apply * @property {boolean|SplitOptions} [split=false] Whether or not the message should be split into multiple messages if * it exceeds the character limit. If an object is provided, these are the options for splitting the message - * @property {UserResolvable} [reply] User to reply to (prefixes the message with a mention, except in DMs) - * @property {MessageResolvable|MessageReplyReference} [inlineReplyTo] The message to reply to + * @property {MessageResolvable} [replyTo] The message to reply to * (must be in the same channel) */ @@ -78,13 +77,6 @@ class TextBasedChannel { * @property {Snowflake[]} [roles] Snowflakes of Roles to be parsed as mentions */ - /** - * Options provided to control parsing of mentions by Discord - * @typedef {Object} MessageReplyReference - * @property {Snowflake} [messageID] Snowflakes of Users to be parsed as mentions - * @property {Snowflake} [channelID] Snowflakes of Roles to be parsed as mentions - */ - /** * Types of mentions to enable in MessageMentionOptions. * - `roles` diff --git a/test/disableMentions.js b/test/disableMentions.js index 97077e20..0521d34c 100644 --- a/test/disableMentions.js +++ b/test/disableMentions.js @@ -36,9 +36,9 @@ client.on('message', message => { // Clean content and log each character console.log(Util.cleanContent(args.join(' '), message).split('')); - if (command === 'test1') message.reply(tests[0]); - else if (command === 'test2') message.reply(tests[1]); - else if (command === 'test3') message.reply(tests[2]); + if (command === 'test1') message.channel.send(tests[0]); + else if (command === 'test2') message.channel.send(tests[1]); + else if (command === 'test3') message.channel.send(tests[2]); }); client.login(token).catch(console.error); diff --git a/test/random.js b/test/random.js index 77112883..11d869ed 100644 --- a/test/random.js +++ b/test/random.js @@ -134,7 +134,7 @@ client.on('message', message => { } message.channel.send('last one...').then(m => { const diff = Date.now() - start; - m.reply(`Each message took ${diff / 21}ms to send`); + m.channel.send(`Each message took ${diff / 21}ms to send`); }); } @@ -205,7 +205,7 @@ client.on('message', msg => { .join() .then(conn => { con = conn; - msg.reply('done'); + msg.channel.send('done'); const s = ytdl(song, { filter: 'audioonly' }, { passes: 3 }); s.on('error', e => console.log(`e w stream 2 ${e}`)); disp = conn.playStream(s); diff --git a/test/sendtest.js b/test/sendtest.js index 186e1c23..691c4e24 100644 --- a/test/sendtest.js +++ b/test/sendtest.js @@ -32,7 +32,6 @@ const tests = [ m => m.channel.send(fill('x'), { split: true }), m => m.channel.send(fill('1'), { code: 'js', split: true }), - m => m.channel.send(fill('x'), { reply: m.author, code: 'js', split: true }), m => m.channel.send(fill('xyz '), { split: { char: ' ' } }), m => m.channel.send('x', { embed: { description: 'a' } }), @@ -99,7 +98,6 @@ const tests = [ async m => m.channel.send({ files: [await read(fileA)] }), async m => m.channel.send(fill('x'), { - reply: m.author, code: 'js', split: true, embed: embed().setImage('attachment://zero.png'), @@ -111,7 +109,6 @@ const tests = [ m => m.channel.send({ files: [{ attachment: readStream(fileA) }] }), async m => m.channel.send(fill('xyz '), { - reply: m.author, code: 'js', split: { char: ' ', prepend: 'hello! ', append: '!!!' }, embed: embed().setImage('attachment://zero.png'), diff --git a/test/tester1000.js b/test/tester1000.js index 471860b3..077b996b 100644 --- a/test/tester1000.js +++ b/test/tester1000.js @@ -31,16 +31,13 @@ const commands = { } message.channel.send(res, { code: 'js' }); }, - ping: message => message.reply('pong'), + ping: message => message.channel.send('pong'), }; client.on('message', message => { if (!message.content.startsWith(prefix) || message.author.bot) return; - message.content = message.content - .replace(prefix, '') - .trim() - .split(' '); + message.content = message.content.replace(prefix, '').trim().split(' '); const command = message.content.shift(); message.content = message.content.join(' '); diff --git a/test/voice.js b/test/voice.js index 37d2669a..1775f280 100644 --- a/test/voice.js +++ b/test/voice.js @@ -43,20 +43,15 @@ client.on('message', m => { conn.receiver.createStream(m.author, true).on('data', b => console.log(b.toString())); conn.player.on('error', (...e) => console.log('player', ...e)); if (!connections.has(m.guild.id)) connections.set(m.guild.id, { conn, queue: [] }); - m.reply('ok!'); + m.channel.send('ok!'); conn.play(ytdl('https://www.youtube.com/watch?v=_XXOSf0s2nk', { filter: 'audioonly' }, { passes: 3 })); }); } else { - m.reply('Specify a voice channel!'); + m.channel.send('Specify a voice channel!'); } } else if (m.content.startsWith('#eval') && m.author.id === '66564597481480192') { try { - const com = eval( - m.content - .split(' ') - .slice(1) - .join(' '), - ); + const com = eval(m.content.split(' ').slice(1).join(' ')); m.channel.send(com, { code: true }); } catch (e) { console.log(e); diff --git a/test/webhooktest.js b/test/webhooktest.js index f73c693f..3691dd8d 100644 --- a/test/webhooktest.js +++ b/test/webhooktest.js @@ -32,7 +32,6 @@ const tests = [ (m, hook) => hook.send(fill('x'), { split: true }), (m, hook) => hook.send(fill('1'), { code: 'js', split: true }), - (m, hook) => hook.send(fill('x'), { reply: m.author, code: 'js', split: true }), (m, hook) => hook.send(fill('xyz '), { split: { char: ' ' } }), (m, hook) => hook.send({ embeds: [{ description: 'a' }] }), @@ -96,7 +95,6 @@ const tests = [ async (m, hook) => hook.send({ files: [await read(fileA)] }), async (m, hook) => hook.send(fill('x'), { - reply: m.author, code: 'js', split: true, embeds: [embed().setImage('attachment://zero.png')], @@ -108,7 +106,6 @@ const tests = [ (m, hook) => hook.send({ files: [{ attachment: readStream(fileA) }] }), async (m, hook) => hook.send(fill('xyz '), { - reply: m.author, code: 'js', split: { char: ' ', prepend: 'hello! ', append: '!!!' }, embeds: [embed().setImage('attachment://zero.png')], diff --git a/typings/index.d.ts b/typings/index.d.ts index 63e6d66d..001a0871 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1028,20 +1028,6 @@ declare module 'discord.js' { public fetch(force?: boolean): Promise; public pin(options?: { reason?: string }): Promise; public react(emoji: EmojiIdentifierResolvable): Promise; - public reply( - content: APIMessageContentResolvable | (MessageOptions & { split?: false }) | MessageAdditions, - ): Promise; - public reply(options: MessageOptions & { split: true | SplitOptions }): Promise; - public reply(options: MessageOptions | APIMessage): Promise; - public reply( - content: StringResolvable, - options: (MessageOptions & { split?: false }) | MessageAdditions, - ): Promise; - public reply( - content: StringResolvable, - options: MessageOptions & { split: true | SplitOptions }, - ): Promise; - public reply(content: StringResolvable, options: MessageOptions): Promise; public suppressEmbeds(suppress?: boolean): Promise; public toJSON(): object; public toString(): string; @@ -1532,6 +1518,8 @@ declare module 'discord.js' { public fetchWebhooks(): Promise>; } + type TextBasedChannelResolvable = TextChannel | NewsChannel | DMChannel | Snowflake; + export class User extends PartialTextBasedChannel(Base) { constructor(client: Client, data: object); public avatar: string | null; @@ -2830,8 +2818,7 @@ declare module 'discord.js' { files?: (FileOptions | BufferResolvable | Stream | MessageAttachment)[]; code?: string | boolean; split?: boolean | SplitOptions; - reply?: UserResolvable; - inlineReplyTo?: MessageResolvable | MessageReplyReference; + replyTo?: MessageResolvable; } type MessageReactionResolvable = MessageReaction | Snowflake; @@ -2842,12 +2829,7 @@ declare module 'discord.js' { messageID: string | null; } - interface MessageReplyReference { - channelID: Snowflake; - messageID: Snowflake; - } - - type MessageResolvable = Message | Snowflake; + type MessageResolvable = Message | { id: Snowflake; channel: TextBasedChannelResolvable }; type MessageTarget = TextChannel | NewsChannel | DMChannel | User | GuildMember | Webhook | WebhookClient;