# Updating from v11 to v12
discord.js v12 has been formally released after a long time in development, meaning it's time to update from v11 to get new features for your bots! However, with those new features come many changes to the library that will break code written for v11. This guide will serve as a handy reference for updating your code, covering the most commonly-used methods that have changed, new topics such as partials and internal sharding. It also includes a comprehensive list of the method and property changes at the end.
TIP
This guide has two versions! Make sure to select v12 (stable) in the header bar's drop-down selection to get code snippets and explanations for the new version across the guide.
# Before You Start
v12 requires Node 12.x or higher, so make sure you're up-to-date. To check your Node version, use node -v in your terminal or command prompt, and if it's not high enough, update it! There are many resources online to help you with this step based on your host system.
Once you got Node up-to-date, you can install v12 by running npm install discord.js in your terminal or command prompt for text-only use or npm install discord.js @discordjs/opus for voice support.
You can check your discord.js version with npm list discord.js. Should it still show v11.x, uninstall (npm uninstall discord.js) and re-install discord.js and make sure the entry in your package.json does not prevent a major version update. Please refer to the npm documentation (opens new window) for this.
# Commonly Used Methods That Changed
- All section headers are named in the following convention:
Class#methodOrProperty. - The use of parenthesis designates optional inclusion. For example,
TextChannel#fetch(Pinned)Message(s)means that this section will include changes forTextChannel#fetchPinnedMessages,TextChannel#fetchMessages, andTextChannel#fetchMessage. - The use of asterisks designates a wildcard. For example,
TextChannel#send***means that this section will include changes forTextChannel#sendMessage,TextChannel#sendFile,TextChannel#sendEmbed, and so forth.
WARNING
clientOptions.disableEveryone was removed and replaced with clientOptions.disableMentions!
- const client = new Discord.Client({ disableEveryone: true });
+ const client = new Discord.Client({ disableMentions: 'everyone' });
# Managers/ Cache
v12 introduces the concept of managers; you will no longer be able to directly use collection methods such as Collection#get on data structures like Client#users. You will now have to directly ask for cache on a manager before trying to use collection methods. Any method called directly on a manager will call the API, such as GuildMemberManager#fetch and MessageManager#delete.
- client.users.get('123456789012345678');
+ client.users.cache.get('123456789012345678');
- channel.messages.get('123456789012345678');
+ channel.messages.cache.get('123456789012345678');
- guild.members.get('123456789012345678');
+ guild.members.cache.get('123456789012345678');
# Collection
# Collection#exists
collection.exists() was removed entirely, collection.some() should be used to check if an element exists in the collection that satisfies the provided value.
- client.users.exists('username', 'Bob');
+ client.users.cache.some(user => user.username === 'Bob');
# Collection#filterArray
collection.filterArray() was removed entirely, as it was just a helper method for collection.filter().array() and most of the time, converting a collection to an array is an unnecessary step.
# Collection#find
collection.find('property', value) was removed entirely, and collection.find() only accepts a function in v12.
- client.users.find('username', 'Bob');
+ client.users.cache.find(user => user.username === 'Bob');
# Collection#findAll
collection.findAll() was removed entirely as it just duplicated collection.filterArray()'s results.
# Fetch
Some methods that retrieve uncached data have changed, transformed in the shape of a Manager.
- client.fetchUser('123456789012345678');
+ client.users.fetch('123456789012345678');
- guild.fetchMember('123456789012345678');
+ guild.members.fetch('123456789012345678');
- guild.fetchMembers();
+ guild.members.fetch();
- textChannel.fetchMessage('123456789012345678');
+ textChannel.messages.fetch('123456789012345678');
- textChannel.fetchMessages({ limit: 10 });
+ textChannel.messages.fetch({ limit: 10 });
- textChannel.fetchPinnedMessages();
+ textChannel.messages.fetchPinned();
# Send
All the .send***() methods have been removed in favor of one general .send() method.
- channel.sendMessage('Hey!');
+ channel.send('Hey!');
- channel.sendEmbed(embedVariable);
+ channel.send(embedVariable);
+ channel.send({ embed: embedVariable });
channel.send(embedVariable) will only work if that variable is an instance of the MessageEmbed class; object literals won't give you the expected result unless your embed data is inside an embed key.
- channel.sendCode('js', 'const version = 11;');
+ channel.send('const version = 12;', { code: 'js' });
- channel.sendFile('./file.png');
- channel.sendFiles(['./file-one.png', './file-two.png']);
+ channel.send({
+ files: [{
+ attachment: 'entire/path/to/file.jpg',
+ name: 'file.jpg'
+ }]
+ });
+ channel.send({
+ files: ['https://cdn.discordapp.com/icons/222078108977594368/6e1019b3179d71046e463a75915e7244.png']
+ });
# Roles
The GuildMember.roles Collection has changed to a Manager, meaning the associated methods for interacting with a member's roles have too. They're no longer on the GuildMember object itself, but instead now on the GuildMemberRoleManager. The Manager holds API methods and cache for the roles in GuildMemberRoleManager#cache, a plain Collection.
- guildMember.addRole('123456789012345678');
- guildMember.addRoles(['123456789012345678', '098765432109876543']);
+ guildMember.roles.add('123456789012345678');
+ guildMember.roles.add(['123456789012345678', '098765432109876543']);
- guildMember.removeRole('123456789012345678');
- guildMember.removeRoles(['123456789012345678', '098765432109876543']);
+ guildMember.roles.remove('123456789012345678');
+ guildMember.roles.remove(['123456789012345678', '098765432109876543']);
- guildMember.setRoles(['123456789012345678', '098765432109876543']);
+ guildMember.roles.set(['123456789012345678', '098765432109876543']);
- guildMember.roles.get('123456789012345678');
+ guildMember.roles.cache.get('123456789012345678');
Also, the GuildMember properties related to roles have moved to the GuildMemberRoleManager.
- guildMember.colorRole;
+ guildMember.roles.color;
- guildMember.highestRole;
+ guildMember.roles.highest;
- guildMember.hoistRole;
+ guildMember.roles.hoist;
# Ban and Unban
The method to ban members and users has moved to the GuildMemberManager.
- guild.ban('123456789012345678');
+ guild.members.ban('123456789012345678');
- guild.unban('123456789012345678');
+ guild.members.unban('123456789012345678');
# Image URLs
Some image-related properties like user.avatarURL are now methods in v12 so that you can apply some options to them, e.g., to affect their display size.
- user.avatarURL;
+ user.avatarURL();
- user.displayAvatarURL;
+ user.displayAvatarURL();
- guild.iconURL;
+ guild.iconURL();
- guild.splashURL;
+ guild.splashURL();
# Dynamic File type
Version 12 now allows you to set the file type for images dynamically. If you provide the dynamic option, you will receive a .gif URL if the image is animated; otherwise, it will fall back to the specified format or its default .webp.
user.avatarURL({ format: 'png', dynamic: true, size: 1024 });
# RichEmbed Constructor
The RichEmbed constructor was removed, and now the MessageEmbed constructor is used. It is mostly the same to use. The only differences are removing richEmbed.attachFile (messageEmbed.attachFiles accepts a single file as a parameter as well) and richEmbed.addBlankField and the addition of messageEmbed.addFields.
# String Concatenation
v12 has changed how discord.js objects behave when being cast to a string. If added to a string, structures will display their id whenever possible (due to the internal method valueOf changing according to its specification). When calling toString explicitly, the structure is cast via the String constructor or supplied as a value in template expressions (which internally calls toString). The mention format <@id> is displayed, which Discord resolves to a proper mention if the structure is in the viewing client's cache (in v11, both toString and valueOf showed the same behavior as toString does now).
- channel.send(userObject + ' has joined!')
+ channel.send(`${userObject} has joined!`)
# User Account-Only Methods
All user account-only methods have been removed, as they are no longer publicly accessible from the API.
# Voice
v12 has a new voice system that improves stability but also comes with some changes to playing audio:
# Applies to VoiceConnection and VoiceBroadcast
- connection.playFile('file.mp3')
+ connection.play('file.mp3')
- connection.playStream(stream)
+ connection.play(stream)
- connection.playArbitraryInput(input)
+ connection.play(input)
- connection.playBroadcast(broadcast)
+ connection.play(broadcast)
- connection.playOpusStream(stream)
+ connection.play(stream, { type: 'opus' })
- connection.playConvertedStream(stream)
+ connection.play(stream, { type: 'converted' })
You can now also play Ogg Opus files or WebM Opus files directly without the need for FFmpeg in v12:
connection.play(fs.createReadStream('file.ogg'), { type: 'ogg/opus' });
connection.play(fs.createReadStream('file.webm'), { type: 'webm/opus' });
It is also possible to define initial values for plp, fec, and bitrate when playing a stream. Minus bitrate, these are new configurable options in v12 that can help when playing audio on unstable network connections.
- connection.playStream(stream).setBitrate(96)
+ connection.play(stream, { bitrate: 96 })
If you don't want to alter a stream's volume while you're playing it, you can disable volume to improve performance. You cannot revert this option during playback.
connection.play(stream, { volume: false });
The internal voice system in v12 now uses streams where possible, and as such, StreamDispatcher itself is now a WritableStream. It also comes with new changes:
- dispatcher.end()
+ dispatcher.destroy()
- dispatcher.on('end', handler)
+ dispatcher.on('finish', handler)
You can manually control how many audio packets should queue before playing audio for more consistent playback using the highWaterMark option (defaults to 12)
connection.play(stream, { highWaterMark: 512 });
If you're frequently pausing/resuming an audio stream, you can enable playing silence packets while paused to prevent audio glitches on the Discord client
// Passing true plays silence
dispatcher.pause(true);
# Broadcasts
Broadcasts themselves now contain a BroadcastDispatcher that shares a similar interface to the StreamDispatcher and can be used to control the playback of an audio stream.
- client.createVoiceBroadcast()
+ client.voice.createBroadcast()
- broadcast.dispatchers
+ broadcast.subscribers
# Breaking Changes and Deletions
The section headers for breaking changes will be named after the v11 classes/methods/properties and will be in alphabetical order so that you can easily find what you need. We have named the section headers for additions after the v12 classes/methods/properties to appropriately reflect their current syntax.
"Difference" code blocks will be used to display the old methods vs. the newer ones—the red being removals and the green being its replacement. Some bits may have more than one version of being handled. Additions will use regular JavaScript syntax code blocks.
WARNING
While this list was carefully crafted, it may be incomplete! If you notice pieces of missing or inaccurate data, we encourage you to submit a pull request (opens new window)!
- Activity (additions)
- ActivityFlags (additions)
- APIMessage (additions)
- Base (additions)
- BaseClient (additions)
- BitField (additions)
- BroadcastDispatcher (additions)
- Channel (changed send/fetch to TextChannel) (additions)
- ClientApplication (additions)
- Client (changes) (additions)
- ClientOptions (changes) (additions)
- ClientUser (changes)
- Collection (changes)
- Collector (changes) (additions)
- CollectorOptions (additions)
- DMChannel (changes) (additions)
- Emoji (changes)
- EvaluatedPermissions (changes)
- Game (changes)
- GroupDMChannel (changes)
- Guild (changes) (additions)
- GuildChannel (changes) (additions)
- GuildMember (changes)
- HTTPError (additions)
- Invite (changes)
- Message (changes) (additions)
- MessageAttachment (changes) (additions)
- MessageCollectorOptions (changes)
- MessageEmbed (changes) (additions)
- MessageMentions (changes)
- MessageReaction (changes)
- OAuth2Application (changes)
- PartialGuild (changes)
- PartialGuildChannel (changes)
- Permissions (changes) (additions)
- Presence (changes) (additions)
- ReactionCollector (additions)
- ReactionEmoji (changes)
- RichEmbed (changes)
- RichPresenceAssets (changes)
- Role (changes)
- Shard (changes)
- ShardClientUtil (changes)
- ShardingManager (changes)
- StreamDispatcher (changes)
- TextChannel (changes) (additions)
- User (changes) (additions)
- Util (changes)
- VoiceBroadcast (changes) (additions)
- VoiceChannel (additions)
- VoiceConnection (changes)
- VoiceReceiver (changes) (additions)
- VoiceRegion (changes)
- VoiceState (additions)
- VolumeInterface (changes)
- Webhook (changes) (additions)
- WebhookClient (changes)
- WebSocketManager (additions)
- WebsocketOptions (additions)
- WebSocketShard (additions)
# Dependencies
# Snekfetch
The snekfetch dependency was replaced with node-fetch. snekfetch was deprecated by its developer and is no longer maintained.
# Attachment
The Attachment class was removed in favor of the MessageAttachment class.
# Client
# Client#fetchUser
client.fetchUser() was removed and transformed in the shape of a Manager.
- client.fetchUser('123456789012345678');
+ client.users.fetch('123456789012345678');
# Client#broadcasts
client.broadcasts was removed and is now in the ClientVoiceManager class.
- client.broadcasts;
+ client.voice.broadcasts;
# Client#browser
client.browser has been changed to be an internal constant and is no longer available publicly.
# Client#channels
client.channels has been changed from a Collection to a Manager.
# Client#clientUserGuildSettingsUpdate
The client.clientUserGuildSettingsUpdate event was removed entirely, along with all other user account-only properties and methods.
# Client#clientUserSettingsUpdate
The client.clientUserSettingsUpdate event was removed entirely, along with all other user account-only properties and methods.
# Client#destroy
The client.destroy() method no longer returns a Promise.
# Client#disconnect
The client.disconnect event was removed in favor of the client.shardDisconnect event to use internal sharding.
- client.on('disconnect', event => {});
+ client.on('shardDisconnect', (event, shardID) => {});
# Client#emojis
client.emojis has changed from a Collection to a Manager.
# Client#guildMemberSpeaking
The speaking parameter has changed from a boolean value to a read-only Speaking class.
# Client#guilds
client.guilds has changed from a Collection to a Manager.
# Client#ping
client.ping has moved to the WebSocketManager under client.ws.ping
- client.ping
+ client.ws.ping
# Client#pings
client.pings has been moved to the WebSocketShard class to use internal sharding. The Client class has a Collection of WebSocketShards available via client.ws.shards; alternatively, the WebSocketShard can be found as a property of other structures, e.g. guild.shard.
- client.pings;
+ guild.shard.ping;
# Client#presences
client.presences was removed to reduce extraneous getters.
# Client#presenceUpdate
The client.presenceUpdate has been changed and now passes the old and new Presence rather than the GuildMember.
- client.on('presenceUpdate', (oldMember, newMember) =>
+ client.on('presenceUpdate', (oldPresence, newPresence) =>
# Client#reconnecting
The client.reconnecting event was removed in favor of the client.shardReconnecting event to use internal sharding.
- client.on('reconnecting', () => console.log('Successfully reconnected.'));
+ client.on('shardReconnecting', id => console.log(`Shard with ID ${id} reconnected.`));
# Client#resume
The client.resume event was removed in favor of the client.shardResume event to use internal sharding.
- client.on('resume', replayed => console.log(`Resumed connection and replayed ${replayed} events.`));
+ client.on('shardResume', (shardID, replayed) => console.log(`Shard ID ${shardID} resumed connection and replayed ${replayed} events.`));
# Client#status
The client.status property was removed and moved to the WebSocketManager class and is no longer a getter.
- client.status;
+ client.ws.status;
# Client#syncGuilds
client.syncGuilds() was removed entirely, along with all other user account-only properties and methods.
# Client#typingStop
The client.typingStop event was removed entirely, as it was an event created by the library and not an actual Discord WebSocket event.
# Client#userNoteUpdate
The client.userNoteUpdate event was removed entirely, along with all other user account-only properties and methods.
# Client#users
client.users has been changed from a Collection to a Manager.
# Client#voiceConnections
client.voiceConnections was removed and moved to the ClientVoiceManager class and is no longer a getter.
- client.voiceConnections;
+ client.voice.connections;
# Client#voiceStateUpdate
The client.voiceStateUpdate event now emits oldState and newState representing the VoiceState of the member before and after the update instead of the member itself.
- client.on('voiceStateUpdate', (oldMember, newMember) => console.log(oldMember));
+ client.on('voiceStateUpdate', (oldState, newState) => console.log(oldState));
# ClientOptions
Several changes were made to the ClientOptions object located in client#options.
# ClientOptions#apiRequestMethod
clientOptions.apiRequestMethod has been made sequential and is used internally.
# ClientOptions#shardId
clientOptions.shardId has been changed to clientOptions.shards and now also accepts an array of numbers.
- options.shardId: 1
+ options.shards: [1, 2, 3]
# ClientOptions#shards
clientOptions.shards was removed and is functionally equivalent to clientOptions.shardCount on v12.
# ClientOptions#sync
clientOptions.sync was removed entirely, along with all other user account-only properties and methods.
# ClientOptions#disabledEvents
clientOptions.disabledEvents was removed in favor of using intents. Please refer to our more detailed article about this topic
# ClientUser
# ClientUser#acceptInvite
clientUser.acceptInvite() was removed entirely, along with all other user account-only properties and methods.
# ClientUser#addFriend
clientUser.addFriend() was removed entirely, along with all other user account-only properties and methods.
# ClientUser#avatarURL
clientUser.avatarURL is now a method, as opposed to a property. If you provide the dynamic option, you will receive a .gif URL if the image is animated; otherwise, it will fall back to the specified format or its default .webp.
- clientUser.avatarURL;
+ clientUser.avatarURL();
+ clientUser.avatarURL({ dynamic: true, format: 'png', size: 1024 });
# ClientUser#block
clientUser.block() was removed entirely, along with all other user account-only properties and methods.
# ClientUser#blocked
clientUser.blocked was removed entirely, along with all other user account-only properties and methods.
# ClientUser#createGuild
clientUser.createGuild() was removed and transformed in the shape of a Manager. Also, the second and third parameters in clientUser.createGuild() have been changed/removed, leaving it with a total of two parameters. The region and icon parameters from v11 merged into an object as the second parameter.
- clientUser.createGuild('New server', 'us-east', './path/to/file.png');
+ client.guilds.create('New server', { region: 'us-east', icon: './path/to/file.png' });
# ClientUser#displayAvatarURL
clientUser.displayAvatarURL is now a method, as opposed to a property. It also allows you to determine the file format and size to return. If you provide the dynamic option, you will receive a .gif URL if the image is animated; otherwise, it will fall back to the specified format or its default .webp.
- clientUser.displayAvatarURL;
+ clientUser.displayAvatarURL();
+ clientUser.displayAvatarURL({ format: 'png', dynamic: true, size: 1024 });
# ClientUser#email
clientUser.email was removed entirely, along with all other user account-only properties and methods.
# ClientUser#fetchMentions
clientUser.fetchMentions() was removed entirely, along with all other user account-only properties and methods.
# ClientUser#fetchProfile
clientUser.fetchProfile() was removed entirely, along with all other user account-only properties and methods.
# ClientUser#friends
clientUser.friends was removed entirely, along with all other user account-only properties and methods.
# ClientUser#guildSettings
clientUser.guildSettings was removed entirely, along with all other user account-only properties and methods.
# ClientUser#mfaEnabled
clientUser.mfaEnabled was removed entirely, along with all other user account-only properties and methods.
# ClientUser#mobile
clientUser.mobile was removed entirely, along with all other user account-only properties and methods.
# ClientUser#note
clientUser.note was removed entirely, along with all other user account-only properties and methods.
# ClientUser#notes
clientUser.notes was removed entirely, along with all other user account-only properties and methods.
# ClientUser#premium
clientUser.premium was removed entirely, along with all other user account-only properties and methods.
# ClientUser#removeFriend
clientUser.removeFriend() was removed entirely, along with all other user account-only properties and methods.
# ClientUser#send***
Just like the TextChannel#send*** methods, all the .send***() methods have been removed in favor of one general .send() method. Read through the TextChannel#send*** section for more information.
# ClientUser#setGame
clientUser.setGame() has changed to clientUser.setActivity(). The second parameter is no longer for providing a streaming URL but rather an object that allows you to provide the URL and activity type.
- clientUser.setGame('with my bot friends!');
+ clientUser.setActivity('with my bot friends!');
- clientUser.setGame('with my bot friends!', 'https://twitch.tv/your/stream/here');
+ clientUser.setActivity('with my bot friends!', { url: 'https://twitch.tv/your/stream/here', type: 'STREAMING' });
# ClientUser#setNote
clientUser.setNote() was removed entirely, along with all other user account-only properties and methods.
# ClientUser#setPassword
clientUser.setPassword() was removed entirely, along with all other user account-only properties and methods.
# ClientUser#settings
clientUser.settings was removed entirely, along with all other user account-only properties and methods.
# ClientUser#unblock
clientUser.unblock() was removed entirely, along with all other user account-only properties and methods.
# ClientUserChannelOverride
The ClientUserChannelOverride class was removed entirely, along with all other user account-only properties and methods.
# ClientUserGuildSettings
The ClientUserGuildSettings class was removed entirely, along with all other user account-only properties and methods.
# ClientUserSettings
The ClientUserSettings class was removed entirely, along with all other user account-only properties and methods.
# ClientUserChannelOverride
The ClientUserChannelOverride class was removed entirely.
# ClientUserGuildSettings
The ClientUserGuildSettings class was removed entirely.
# ClientUserSettings
The ClientUserSettings class was removed entirely.
# Collection
# Collection#find/findKey
Both methods will now return undefined if nothing is found.
# Collection#deleteAll
collection.deleteAll() was removed in favor of map's default clear() method.
- roles.deleteAll();
+ roles.clear();
# Collection#exists
collection.exists() was removed entirely in favor of collection.some()
- client.users.exists('username', 'Bob');
+ client.users.cache.some(user => user.username === 'Bob');
# Collection#filterArray
collection.filterArray() was removed completely.
# Collection#findAll
collection.findAll() was removed completely as the same functionality can be obtained through collection.filter().
# Collection#first/firstKey/last/lastKey/random/randomKey
The amount parameter of these methods now allows a negative number, which will start the query from the end of the collection.
# Collection#tap
collection.tap runs a specific function over the collection instead of mimicking <array>.forEach(), this functionality was moved to collection.each().
# Collector
# Collector#cleanup
collector.cleanup() was removed entirely.
# Collector#handle
collector.handle() has been changed to collector.handleCollect().
# Collector#postCheck
collector.postCheck() has been changed to collector.checkEnd().
# DMChannel
# DMChannel#acknowledge
dmChannel.acknowledge() was removed entirely, along with all other user account-only properties and methods.
# DMChannel#createCollector
dmChannel.createCollector() was removed in favor of dmChannel.createMessageCollector().
TIP
Note that the behavior of collector options has changed! See this section for more details!
# DMChannel#fetch(Pinned)Message(s)
dmChannel.fetchMessage(s) has been transformed in the shape of a Manager. See the TextChannel#fetch(Pinned)Message(s) section for more information.
# DMChannel#search
dmChannel.search() was removed entirely, along with all other user account-only properties and methods.
# DMChannel#send***
Just like the TextChannel#send*** methods, all the .send***() methods have been removed in favor of one general .send() method. Read through the TextChannel#send*** section for more information.
# Emoji
Emoji now extends Base and represents either a GuildEmoji or ReactionEmoji. Some of the specific properties have moved to their respective object instead of everything on the base Emoji object.
# Emoji#***RestrictedRole(s)
The helper methods to add and remove a role or roles from the roles allowed to use the emoji are now set via the GuildEmojiRoleManager.
- emoji.addRestrictedRole('123456789012345678');
- emoji.addRestrictedRoles(['123456789012345678', '098765432109876543']);
- emoji.removeRestrictedRole('1234567890123345678');
- emoji.removedRestrictedRoles(['123456789012345678', '098765432109876543']);
+ emoji.roles.add('123456789012345678');
+ emoji.roles.remove('123456789012345678');
+ emoji.roles.set(['123456789012345678', '098765432109876543']);
# Emoji#deletable
emoji.deletable has been moved to guildEmoji.deletable.
# Emoji#fetchAuthor
emoji.fetchAuthor() has been moved to guildEmoji.fetchAuthor().
# Emoji#guild
emoji.guild has been moved to guildEmoji.guild.
# Emoji#setName
emoji.setName() has been moved to guildEmoji.setName().
# EvaluatedPermissions
evaluatedPermissions was removed entirely; see the Permissions page.
# Game
The Game class was removed in favor of the Activity class to be consistent with the API. It is also an array of multiple Activities since a user can have multiple.
- user.presence.game
+ user.presence.activities
# GroupDMChannel
The GroupDMChannel class was deprecated from the Discord API. While it's still available through Gamebridge for now, that will also be removed in the future. In addition, group DM's has always been unreliable and hacky to work with a bot.
# Guild
# Guild#acknowledge
guild.acknowledge() was removed entirely, along with all other user account-only properties and methods.
# Guild#allowDMs
guild.allowDMs() was removed entirely, along with all other user account-only properties and methods.
# Guild#ban
guild.ban() has moved to the GuildMemberManager. In addition, the second parameter in guild.members.ban() has changed. The options parameter no longer accepts a number nor a string.
- guild.ban(user, 7);
+ guild.members.ban(user, { days: 7 });
- guild.ban(user, 'Too much trolling');
+ guild.members.ban(user, { reason: 'Too much trolling' });
# Guild#Channels
guild.channels is now a Manager instead of a Collection.
# Guild#createChannel
guild.createChannel() has transformed in the shape of a Manager. The second, third, and fourth parameters in guild.createChannel() were changed/removed, leaving it with a total of two parameters; the second one is an object with all of the options available in ChannelData.
- guild.createChannel('new-channel', 'text', permissionOverwriteArray, 'New channel added for fun!');
+ guild.channels.create('new-channel', { type: 'text', permissionOverwrites: permissionOverwriteArray, reason: 'New channel added for fun!' });
# Guild#createEmoji
guild.createEmoji() has been transformed in the shape of a Manager. The third and fourth parameters in guild.createEmoji() were changed/removed, leaving it with a total of three parameters. The roles and reason parameters from v11 merged into an object as the third parameter.
- guild.createEmoji('./path/to/file.png', 'NewEmoji', collectionOfRoles, 'New emoji added for fun!');
+ guild.emojis.create('./path/to/file.png', 'NewEmoji', { roles: collectionOfRoles, reason: 'New emoji added for fun!' });
# Guild#createRole
guild.createRole() has transformed in the shape of a Manager. The first and second parameters in guild.createRole() were changed/removed, leaving it with a total of one parameter. The data and reason parameters from v11 have moved into an object as the first parameter.
- guild.createRole(roleData, 'New staff role!');
+ guild.roles.create({ data: roleData, reason: 'New staff role!' });
# Guild#deleteEmoji
Guild.deleteEmoji() was removed and transformed in the shape of a Manager. Note the possible use of resolve() as a broader alternative to get().
- guild.deleteEmoji('123456789012345678');
+ guild.emojis.resolve('123456789012345678').delete();
# Guild#defaultChannel
Unfortunately, "default" channels don't exist in Discord anymore, and as such, the guild.defaultChannel property was removed with no alternative.
Q: "I previously had a welcome message system (or something similar) set up using that property. What can I do now?"
A: There are a few ways to tackle this. Using the example of a welcome message system, you can:
- Set up a database table to store the channel ID in a column when someone uses a
!welcome-channel #channel-namecommand, for example. Then inside theguildMemberAddevent, useclient.channels.cache.get('id')and send a message to that channel. This is the most reliable method and gives server staff freedom to rename the channel as they please. - Make a new command that creates a
welcome-messageschannel, useguild.channels.cache.find(channel => channel.name === 'welcome-messages'), and send a message to that channel. This method will work fine in most cases but will break if someone on that server decides to rename the channel. This may also give you unexpected results due to Discord allowing multiple channels to have the same name.
TIP
Not sure how to set up a database? Check out this page!
# Guild#defaultRole
guild.defaultRole has been moved to the RoleManager and renamed to use the less confusing "everyone" terminology.
- guild.defaultRole
+ guild.roles.everyone
# Guild#emojis
guild.emojis has been transformed in the shape of a Manager.
# Guild#fetchBans
guild.fetchBans() will return a Collection of objects in v12, whereas v11 would return a Collection of User objects.
- guild.fetchBans().then(bans => console.log(`${bans.first().tag} was banned`));
+ guild.fetchBans().then(bans => console.log(`${bans.first().user.tag} was banned because '${bans.first().reason}'`));
# Guild#fetchMember(s)
guild.fetchMember() and guild.fetchMembers() were both removed and transformed in the shape of Managers. In addition, guild.members.fetch() will return a Collection of GuildMember objects in v12, whereas v11 would return a Guild object.
- guild.fetchMember('123456789012345678');
+ guild.members.fetch('123456789012345678');
- guild.fetchMembers();
+ guild.members.fetch();
# Guild#iconURL
guild.iconURL is now a method, as opposed to a property. It also allows you to determine the file format and size to return. If you provide the dynamic option, you will receive a .gif URL if the image is animated; otherwise, it will fall back to the specified format or its default .webp if none is provided.
- guild.iconURL;
+ guild.iconURL();
+ guild.iconURL({ format: 'png', dynamic: true, size: 1024 });
# Guild#messageNotifications
guild.messageNotifications was removed entirely, along with all other user account-only properties and methods.
# Guild#mobilePush
guild.mobilePush was removed entirely, along with all other user account-only properties and methods.
# Guild#muted
guild.muted was removed entirely, along with all other user account-only properties and methods.
# Guild#position
guild.position was removed entirely, along with all other user account-only properties and methods.
# Guild#presences
guild.presences is now a Manager instead of a Collection.
# Guild#pruneMembers
guild.pruneMembers() has transformed in the shape of a Manager. The first, second, and third parameters in the method were changed/removed, leaving it with a total of one parameter. The days, dry, and reason parameters from v11 have merged into an object as the first parameter.
- guild.pruneMembers(7, true, 'Scheduled pruning');
+ guild.members.prune({ days: 7, dry: true, reason: 'Scheduled pruning' });
# Guild#roles
guild.roles is now a Manager instead of a Collection.
# Guild#search
guild.search() was removed entirely, along with all other user account-only properties and methods.
# Guild#setChannelPosition
guild.setChannelPosition() was removed entirely. As an alternative, you can use channel.setPosition(), or guild.setChannelPositions(), which accepts the same form of data as guild.setChannelPosition but inside an array.
- guild.setChannelPosition({ channel: '123456789012345678', position: 1 });
+ guild.setChannelPositions([{ channel: '123456789012345678', position: 1 }]);
+ channel.setPosition(1);
# Guild#setPosition
guild.setPosition() was removed entirely, along with all other user account-only properties and methods.
# Guild#setRolePosition
guild.setRolePosition() was removed entirely as an extraneous helper method. As an alternative, you can use role.setPosition().
- guild.setRolePosition({ role: '123456789012345678', position: 1 });
+ role.setPosition(1);
# Guild#splashURL
guild.splashURL is now a method, as opposed to a property. It also allows you to determine the file format and size to return.
- guild.splashURL;
+ guild.splashURL();
+ guild.splashURL({ format: 'png', size: 1024 });
# Guild#suppressEveryone
guild.suppressEveryone was removed entirely, along with all other user account-only properties and methods.
# Guild#sync
guild.sync() was removed entirely, along with all other user account-only properties and methods.
# Guild#unban
guild.unban() has been transformed in the shape of a Manager and is now a method on GuildMemberManager. It also now optionally accepts a string as a second parameter for reason.
- guild.unban('123456789012345678');
+ guild.members.unban('123456789012345678', 'Ban appealed.');
# Guild#verificationLevel
guild.verificationLevel now returns one of "NONE", "LOW", "MEDIUM", "HIGH", "VERY_HIGH" instead of the corresponding number.
# GuildChannel
A channel's properties relating to its position have been renamed. guildChannel.calculatedPosition is now guildChannel.position. guildChannel.position is now more clearly named guildChannel.rawPosition to denote that it's directly from the API without any sorting.
- channel.calculatedPosition;
+ channel.position;
- channel.position;
+ channel.rawPosition;
# GuildChannel#clone
The first, second, third, and fourth parameters in channel.clone() have been changed/removed, leaving it with a total of one parameter. The name, withPermissions, withTopic, and reason parameters from v11 have merged into an object as the first parameter. Several other parameters have also merged with the options object.
# GuildChannel#createInvite
The second parameter in channel.createInvite() was removed, leaving it with one parameter. The reason parameter from v11 has merged into an object as the first parameter.
- channel.createInvite({ temporary: true }, 'Just testing');
+ channel.createInvite({ temporary: true, reason: 'Just testing' });
# GuildChannel#members
guildChannel.members was removed from guildChannel.members and added to textChannel.members and voiceChannel.members.
# GuildChannel#messageNotifications
guildChannel.messageNotifications was removed entirely, along with all other user account-only properties.
# GuildChannel#muted
guildChannel.muted was removed entirely, along with all other user account-only properties.
# GuildChannel#overwritePermissions
guildChannel.overwritePermissions has been changed to act as replacement for guildChannel.replacePermissionOverwrites.
The old functionality is moved to guildChannel.updateOverwrite and guildChannel.createOverwrite
- message.channel.overwritePermissions(message.author, {
- SEND_MESSAGES: false
- })
+ message.channel.createOverwrite(message.author, {
+ SEND_MESSAGES: false
+ })
# GuildChannel#***Permissions
guildChannel.memberPermissions and guildChannel.rolePermissions are now private.
# GuildChannel#replacePermissionOverwrites
guildChannel.replacePermissionOverwrites has been renamed to guildChannel.overwritePermissions. Overwrites and reason are no longer a part of the options object; they are now method arguments.
- channel.replacePermissionOverwrites({
- overwrites: [
- {
- id: message.author.id,
- denied: ['VIEW_CHANNEL'],
- },
- ],
- reason: 'Needed to change permissions'
- });
+ channel.overwritePermissions([
+ {
+ id: message.author.id,
+ deny: ['VIEW_CHANNEL'],
+ },
+ ], 'Needed to change permissions');
# GuildChannel#setPosition
The second parameter in channel.setPosition() has been changed. The relative parameter from v11 has merged into an object.
- channel.setPosition(10, true);
+ channel.setPosition(10, { relative: true, reason: 'Basic organization' });
# GuildMember
# GuildMember***Role(s)
All of the methods to modify a member's roles have moved to the GuildMemberRoleManager.
- guildMember.addRole('123456789012345678');
- guildMember.addRoles(['123456789012345678', '098765432109876543']);
+ guildMember.roles.add('123456789012345678');
+ guildMember.roles.add(['123456789012345678', '098765432109876543']);
- guildMember.removeRole('123456789012345678');
- guildMember.removeRoles(['123456789012345678', '098765432109876543']);
+ guildMember.roles.remove('123456789012345678');
+ guildMember.roles.remove(['123456789012345678', '098765432109876543']);
- guildMember.setRoles(['123456789012345678', '098765432109876543']);
+ guildMember.roles.set(['123456789012345678', '098765432109876543']);
# GuildMember#ban
guildMember.ban() has been transformed in the shape of a Manager and is now a method on GuildMemberManager. The second parameter has changed from a string or an object to only an object. The reason and days parameters are keys in the options object.
- member.ban(user, 7);
+ guild.members.ban(user, { days: 7 });
- member.ban(user, 'Too much trolling');
+ guild.members.ban(user, { reason: 'Too much trolling' });
# GuildMember#***Role
guildMember.colorRole, guildMember.highestRole and guildMember.hoistRole have all been moved to the GuildMemberRoleManager.
- guildMember.colorRole;
+ guildMember.roles.color;
- guildMember.highestRole;
+ guildMember.roles.highest;
- guildMember.hoistRole;
+ guildMember.roles.hoist;
# GuildMember#***deaf
guildMember.deaf, guildMember.selfDeaf and guildMember.serverDeaf have all been moved to the VoiceState class.
- guildMember.deaf;
+ guildMember.voice.deaf;
- guildMember.selfDeaf;
+ guildMember.voice.selfDeaf;
- guildMember.serverDeaf;
+ guildMember.voice.serverDeaf;
# GuildMember#hasPermission
The explicit parameter was removed entirely. The checkAdmin and checkOwner parameters have merged into a single options object with those values as keys.
- guildMember.hasPermission('MANAGE_MESSAGES', true, false, false);
+ guildMember.hasPermission('MANAGE_MESSAGES', { checkAdmin: false, checkOwner: false });
# GuildMember#hasPermissions
guildMember.hasPermissions() was removed in favor of guildMember.hasPermission().
- guildMember.hasPermissions(['MANAGE_MESSAGES', 'MANAGE_ROLES']);
+ guildMember.hasPermission(['MANAGE_MESSAGES', 'MANAGE_ROLES']);
# GuildMember#lastMessage
The guildMember.lastMessage property is now read-only.
# GuildMember#missingPermissions
guildMember.missingPermissions was removed entirely.
# GuildMember#***mute
guildMember.mute, guildMember.selfMute and guildMember.serverMute have all been moved to the VoiceState class.
- guildMember.mute;
+ guildMember.voice.mute;
- guildMember.selfMute;
+ guildMember.voice.selfMute;
- guildMember.serverMute;
+ guildMember.voice.serverMute;
# GuildMember#roles
guildMember.roles is now a Manager instead of a Collection.
# GuildMember#send***
Just like the textChannel#send*** methods, all the .send***() methods have been removed in favor of one general .send() method. Read through the textChannel#send*** section for more information.
# GuildMember#set***
Along with the rest of the voice-related methods and properties, the methods for moving, muting, and deafening a member have moved to the VoiceState class.
- guildMember.setDeaf(true);
+ guildMember.voice.setDeaf(true);
- guildMember.setMute(true);
+ guildMember.voice.setMute(true);
- guildMember.setVoiceChannel('123456789012345678');
+ guildMember.voice.setChannel('123456789012345678');
- guildMember.setVoiceChannel(null);
+ guildMember.voice.kick();
# GuildMember#speaking
guildMember.speaking has been moved to the VoiceState class.
- guildMember.speaking;
+ guildMember.voice.speaking;
# GuildMember#voice***
guildMember.voiceChannel, guildMember.voiceChannelID and guildMember.voiceSessionID have all been moved to the VoiceState class, which is read-only.
- guildMember.voiceChannel;
+ guildMember.voice.channel;
- guildMember.voiceChannelID;
+ guildMember.voice.channelID;
- guildMember.voiceSessionID;
+ guildMember.voice.sessionID;
# Invite
# Invite#***ChannelCount
invite.textChannelCount and invite.voiceChannelCount have both been removed entirely.
# Message
# Message#acknowledge
message.acknowledge() was removed entirely, along with all other user account-only properties and methods.
# Message#clearReactions
message.clearReactions() has been transformed in the shape of a Manager.
- message.clearReactions();
+ message.reactions.removeAll();
# Message#delete
The first parameter in message.delete() has been changed. The timeout parameter from v11 have merged into an object as the first parameter. Also, there is now another optional key in the object, reason.
- message.delete(5000);
+ message.delete({ timeout: 5000, reason: 'It had to be done.' });
# Message#editCode
In the same sense that the channel.sendCode() method was removed, message.editCode() has also been removed entirely.
- message.editCode('js', 'const version = 11;');
+ message.edit('const version = 12;', { code: 'js' });
# Message#hit
message.hit was removed entirely, as it was used for user-account only searches.
# Message#is(Member)Mentioned
message.isMentioned() and message.isMemberMentioned() have been removed in favor of message.mentions.has().
- message.isMentioned('123456789012345678');
- message.isMemberMentioned('123456789012345678');
+ message.mentions.has('123456789012345678');
# Message#member
message.member is now read-only.
# MessageAttachment
The MessageAttachment class constructor parameters have changed to reflect that Attachment was removed and rolled into MessageAttachment.
# MessageAttachment#client
attachment.client was removed entirely so an attachment can be constructed without needing the full client.
# MessageAttachment#filename
attachment.filename has been renamed to attachment.name.
# MessageAttachment#filesize
attachment.filesize has been renamed to attachment.size.
# MessageCollector
See the Collector section for most changes to MessageCollector, such as the new dispose method and event. Changes to the MessageCollector constructor, in particular, are as follows:
# MessageCollector#channel
A GroupDMChannel is no longer able to be used for a collector, only DMChannel and TextChannel.
# MessageCollector#message
The messageCollector.message event was removed in favor of the generic collector.on event.
# MessageCollectorOptions
# MessageCollectorOptions#max(Matches)
The max and maxMatches properties of the MessageCollector class were renamed and repurposed.
- `max`: The maximum amount of messages to process.
+ `maxProcessed`: The maximum amount of messages to process.
- `maxMatches`: The maximum amount of messages to collect.
+ `max`: The maximum amount of messages to collect.
# MessageEmbed
MessageEmbed now encompasses both the received embeds in a message and the constructor–the RichEmbed constructor was removed in favor of MessageEmbed.
# MessageEmbed#addBlankField
messageEmbed.addBlankField() was removed entirely. To add a blank field, use messageEmbed.addField('\u200b', '\u200b').
# MessageEmbed#attachFiles
RichEmbed.attachFile() was removed in favor of MessageEmbed.attachFiles() method, which works for one or more files.
# MessageEmbed#client
messageEmbed.client was removed entirely, so a new embed can be constructed without needing the full client.
# MessageEmbed#message
messageEmbed.message was removed entirely, so a new embed can be constructed without needing the full client.
# MessageMentions
# MessageMentions#has
mentions.has() has been added, replacing message.isMentioned() and message.isMemberMentioned(). It has two paramets: the first is data representing a User, GuildMember, Role, or GuildChannel and an optional options object.
- message.isMentioned('123456789012345678');
- message.isMemberMentioned('123456789012345678');
+ message.mentions.has('123456789012345678');
+ message.mentions.has('123456789012345678', { ignoreDirect: true, ignoreRoles: true, ignoreEveryone: true });
# MessageReaction
# MessageReaction#fetchUsers
messageReaction.fetchUsers() has been transformed in the shape of a Manager. Also, the first parameter was removed in favor of an object.
- reaction.fetchUsers(50);
+ reaction.users.fetch({ limit: 50 });
# MessageReaction#remove
messageReaction.remove() has been transformed in the shape of a Manager.
- reaction.remove();
+ reaction.users.remove();
# OAuth2Application
The OAuth2Application class is now named ClientApplication.
# OAuth2Application#bot
application.bot was removed entirely.
# OAuth2Application#flags
application.flags was removed entirely.
# OAuth2Application#iconURL
application.iconURL is now a method, as opposed to a property. It also allows you to determine the file format and size to return.
- application.iconURL;
+ application.iconURL();
+ application.iconURL({ format: 'png', size: 1024 });
# OAuth2Application#redirectURLs
application.redirectURLs was removed entirely.
# OAuth2Application#reset
application.reset() was removed entirely, as it was an endpoint for user accounts.
# OAuth2Application#rpcApplicationState
application.rpcApplicationState was removed entirely.
# OAuth2Application#secret
application.secret was removed entirely.
# PartialGuild(Channel)
The PartialGuild and PartialGuildChannel classes for use with invites have been removed entirely.
# Permissions
# Permissions#_member
permissions._member was removed entirely.
# Permissions#flags
The following permission flags have been renamed:
READ_MESSAGES->VIEW_CHANNELEXTERNAL_EMOJIS->USE_EXTERNAL_EMOJISMANAGE_ROLES_OR_PERMISSIONS->MANAGE_ROLES
# Permissions#hasPermission(s)
permissions.hasPermission() and permissions.hasPermissions() have been removed entirely in favor of permissions.has(). This change reduces extraneous helper methods.
# Permissions#missingPermissions
permissions.missingPermissions() has been renamed to permissions.missing() and also refactored. The second parameter in v11 was named explicit, described as "Whether to require the user to explicitly have the exact permissions", defaulting to false. However, the second parameter in v11 is named checkAdmin, described as "Whether to allow the administrator permission to override", defaulting to true.
- permissions.missingPermissions(['MANAGE_SERVER']);
+ permissions.missing(['MANAGE_SERVER']);
# Permissions#raw
permissions.raw was removed in favor of permissions.bitfield.
- permissions.raw;
+ permissions.bitfield;
# Permissions#resolve
permissions.resolve() was removed entirely.
# Presence
# Presence#game
presence.game was removed in favor of the Activity class. It is now an array of Activities.
- presence.game;
+ presence.activities;
# RichEmbed
The RichEmbed class was removed in favor of the MessageEmbed class.
# RichEmbed#attachFile
RichEmbed.attachFile() was removed in favor of MessageEmbed.attachFiles().
- new RichEmbed().attachFile('attachment://file-namme.png');
+ new MessageEmbed().attachFiles(['attachment://file-namme.png']);
- new RichEmbed().attachFile({ attachment: './file-name.png' });
+ new MessageEmbed().attachFiles([{ attachment: './file-name.png' }]);
- new RichEmbed().attachFile(new Attachment('./file-name.png'));
+ new MessageEmbed().attachFiles([new MessageAttachment('./file-name.png')]);
# RichPresenceAssets
# RichPresenceAssets#***ImageURL
Both properties relating to the rich presence's image URL have changed to be a method instead of a property. It also allows you to determine the file format and size to return.
- asset.smallImageURL;
- asset.largeImageURL;
+ asset.smallImageURL();
+ asset.largeImageURL({ format: 'png', size: 1024 });
# Role
The properties of a role relating to its position have been renamed. role.calculatedPosition is now role.position. role.position is now more clearly named role.rawPosition to denote that it's directly from the API without any sorting.
- role.calculatedPosition;
+ role.position;
- role.position;
+ role.rawPosition;
# Role#hasPermission(s)
role.hasPermission() and role.hasPermissions() have been removed in favor of permissions.has().
- role.hasPermission('MANAGE_MESSAGES');
+ role.permissions.has('MANAGE_MESSAGES');
- role.hasPermissions(['MANAGE_MESSAGES', 'MANAGE_SERVER']);
+ role.permissions.has(['MANAGE_MESSAGES', 'MANAGE_SERVER']);
# Role#serialize
role.serialize() was removed as an extraneous helper method.
- role.serialize();
+ role.permissions.serialize();
# Role#setPosition
The optional second parameter of the role.setPosition() method has changed to an object; its keys are relative (a boolean) and reason (a string).
- role.setPosition(3, true);
+ role.setPosition(3, { relative: true, reason: 'Needed to be higher.' });
# Shard
The death and spawn events for a shard can also include a Worker in addition to the ChildProcess that was exited or spawned.
# Shard#args
shard.args is now a property of the shard and was removed as a parameter from the constructor.
# Shard#respawn
shard.respawn now takes a second, optional parameter spawnTimeout, how long to wait in milliseconds until the shard's Client becomes ready.
# Shard#spawn
The parameters used in v11 have been removed and replaced with a single, optional parameter, spawnTimeout.
# ShardClientUtil
A new mode parameter is available in the constructor to make use of workers introduced in Node v10.5.0.
# ShardClientUtil#id
shardClientUtil.id was removed and replaced with shardClientUtil.ids, an array of shard IDs of the current client.
# ShardClientUtil#singleton
shardCLientUtil now has a second parameter, mode, to specify whether it's a process or worker.
# ShardingManager
# ShardingManger#_spawn
The private method shardingManager._spawn() was removed entirely.
# ShardingManager#createShard
The id parameter is now optional and defaults to this.shards.size.
# ShardingManager#launch
The shardingManager.launch event was removed entirely and replaced with the shardingManager.shardCreate event.
# ShardingManager#message
The shardingManager.message event was removed from this class and is now on the Shard class.
# ShardingManager#respawnAll
The waitForReady parameter was renamed to spawnTimeout, and the currentShardIndex parameter was removed entirely.
# ShardingManager#spawn
A third, optional parameter, spawnTimeout, was added, specifying how long to wait in milliseconds to wait until the Client is ready; the default is 30000.
# StreamDispatcher
StreamDispatcher now extends WritableStream from Node, you can see the docs here (opens new window).
# StreamDispatcher#destroyed
streamDispatcher.destroyed was removed entirely.
# StreamDispatcher#end
The end event was removed. Please use the native finish event as documented here (opens new window).
The end method is now inherited from WritableStream as documented here (opens new window).
# StreamDispatcher#passes
streamDispatcher.passes was removed entirely.
# StreamDispatcher#pause
The streamDispatcher.pause method now takes an optional parameter silence to specify whether to play silence while paused to prevent audio glitches. Its value is a boolean and defaults to false.
- dispatcher.pause();
+ dispatcher.pause(true);
# StreamDispatcher#stream
The streamDispatcher.stream property was removed and replaced with streamDispatcher.broadcast, which is the broadcast controlling the stream (if any).
# StreamDispatcher#time
The streamDispatcher.time property has been renamed to streamDispatcher.streamTime.
# TextChannel
# TextChannel#acknowledge
textChannel.acknowledge() was removed entirely, along with all other user account-only methods and properties.
# Textchannel#awaitMessages
TIP
The behavior of collector options has changed! See this section for more details!
# TextChannel#***position
See the GuildChannel section for changes to positions.
# TextChannel#clone
All parameters have been removed and reconfigured into a single object.
- channel.clone(undefined, true, false, 'Needed a clone');
+ channel.clone({ name: undefined, reason: 'Needed a clone' });
# TextChannel#createCollector
textChannel.createCollector() was removed entirely in favor of textChannel.createMessageCollector().
See this section for changes to the MessageCollector class.
- channel.createCollector(filterFunction, { maxMatches: 2, max: 10, time: 15000 });
+ channel.createMessageCollector(filterFunction, { max: 2, maxProcessed: 10, time: 15000 });
TIP
Note that the behavior of collector options has changed! See this section for more details!
# TextChannel#createWebhook
The second and third parameters in textChannel.createWebhook() have been changed/removed, leaving it with a total of two parameters. The avatar and reason parameters from v11 have merged into an object as the second parameter.
- channel.createWebhook('Snek', 'https://i.imgur.com/mI8XcpG.jpg', 'Needed a cool new Webhook');
+ channel.createWebhook('Snek', { avatar: 'https://i.imgur.com/mI8XcpG.jpg', reason: 'Needed a cool new Webhook' });
# TextChannel#memberPermissions
This method is now private.
# TextChannel#rolePermissions
This method is now private.
# TextChannel#search
This method was removed, along with all other user account-only methods.
# TextChannel#send***
All the .send***() methods have been removed in favor of one general .send() method.
- channel.sendMessage('Hey!');
+ channel.send('Hey!');
- channel.sendEmbed(embedVariable);
+ channel.send(embedVariable);
+ channel.send({ embed: embedVariable });
WARNING
channel.send(embedVariable) will only work if that variable is an instance of the MessageEmbed class; object literals won't give you the expected result unless your embed data is inside an embed key.
- channel.sendCode('js', 'const version = 11;');
+ channel.send('const version = 12;', { code: 'js' });
- channel.sendFile('./file.png');
- channel.sendFiles(['./file-one.png', './file-two.png']);
+ channel.send({
+ files: [{
+ attachment: 'entire/path/to/file.jpg',
+ name: 'file.jpg',
+ }]
+ channel.send({
+ files: ['https://cdn.discordapp.com/icons/222078108977594368/6e1019b3179d71046e463a75915e7244.png']
+ });
- channel.sendFiles(['./file-one.png', './file-two.png']);
+ channel.send({ files: [{ attachment: './file-one.png' }, { attachment: './file-two.png' }] });
+ channel.send({ files: [new MessageAttachment('./file-one.png'), new MessageAttachment('./file-two.png')] });
# TextChannel#fetch(Pinned)Message(s)
channel.fetchMessage(), channel.fetchMessages(), and channel.fetchPinnedMessages() were all removed and transformed in the shape of Managers.
- channel.fetchMessage('123456789012345678');
+ channel.messages.fetch('123456789012345678');
- channel.fetchMessages({ limit: 100 });
+ channel.messages.fetch({ limit: 100 });
- channel.fetchPinnedMessages();
+ channel.messages.fetchPinned();
# User
# User#addFriend
user.addFriend() was removed entirely, along with all other user account-only methods.
# User#avatarURL
user.avatarURL is now a method, as opposed to a property. It also allows you to determine the file format and size to return. If you provide the dynamic option, you will receive a .gif URL if the image is animated; otherwise, it will fall back to the specified format or its default .webp.
- user.avatarURL;
+ user.avatarURL();
+ user.avatarURL({ format: 'png', dynamic: true, size: 1024 });
# User#block
user.block() was removed entirely, along with all other user account-only methods.
# User#displayAvatarURL
user.displayAvatarURL is now a method, as opposed to a property. It also allows you to determine the file format and size to return. If you provide the dynamic option, you will receive a .gif URL if the image is animated; otherwise, it will fall back to the specified format or its default .webp.
- user.displayAvatarURL;
+ user.displayAvatarURL();
+ user.displayAvatarURL({ format: 'png', dynamic: true, size: 1024 });
# User#fetchProfile
user.fetchProfile() was removed entirely, along with all other user account-only methods.
# User#note
user.note was removed entirely, along with all other user account-only methods.
# User#removeFriend
user.removeFriend() was removed entirely, along with all other user account-only methods.
# User#setNote
user.setNote() was removed entirely, along with all other user account-only methods.
# User#send***
Just like the textChannel#send*** methods, all the .send***() methods have been removed in favor of one general .send() method. Read through the textChannel#send*** section for more information.
# User#unblock
user.unblock() was removed entirely, along with all other user account-only methods.
# UserConnection
The UserConnection class was removed entirely, along with all other user account-only properties.
# UserProfile
The UserProfile class was removed entirely, along with all other user account-only properties.
# VoiceBroadcast
VoiceBroadcast now implements PlayInterface instead of VolumeInterface.
# VoiceBroadcast#currentTranscoder
This property was removed entirely.
# VoiceBroadcast#destroy
This method was removed entirely.
# VoiceBroadcast#dispatchers
This property has been renamed to subscribers and is no longer read-only.
- broadcast.dispatchers;
+ broadcast.subscribers;
# VoiceBroadcast#end
This event was removed from the VoiceBroadcast class and is implemented from the WritableStream class from Node, which BroadcastDispatcher implements.
# VoiceBroadcast#error
This event has moved from the VoiceBroadcast class to the BroadcastDispatcher class.
# VoiceBroadcast#pause
This method has moved from the VoiceBroadcast class to the BroadcastDispatcher class.
# VoiceBroadcast#play***
All .play***() methods have been removed and transformed into a single .play() method.
# VoiceBroadcast#prism
This property was removed entirely.
# VoiceBroadcast#resume
This method has moved from the VoiceBroadcast class to the BroadcastDispatcher class.
# VoiceBroadcast#warn
This event was removed entirely.
# VoiceConnection
The VoiceConnection class is now accessible via the respective VoiceState class.
- guild.voiceConnection;
+ guild.voice.connection;
- member.voiceConnection;
+ member.voice.connection;
The VoiceConnection class also implements the new PlayInterface class in addition to extending EventEmitter from Node.
# VoiceConnection#createReceiver
voiceconnection.createReceiver() was removed, there is now a single receiver that be accessed from voiceConnection.receiver
# VoiceConnection#play***
All connection.play***() methods have been removed in favor of one, flexible .play() method.
# VoiceConnection#prism
This property was removed entirely.
# VoiceConnection#receivers
This property was removed entirely.
# VoiceConnection#sendVoiceStateUpdate
This method was removed entirely.
# VoiceConnection#set***
Both connection.setSessionID() and connection.setTokenAndEndpoint() have been removed entirely.
# VoiceReceiver
# VoiceReceiver#create***Stream
Both the receiver.createOpusStream() and receiver.createPCMStream() methods have been condensed into one method, receiver.createStream(), which also optionally accepts a ReceiveStreamOptions object for the stream.
- receiver.createOpusStream('123456789012345678');
- receiver.createPCMStream('123456789012345678');
+ receiver.createStream('123456789012345678', { mode: 'opus', end: 'silence' });
# VoiceReceiver#destroy
This method was removed entirely; refer to StreamDispatcher#destroy for documentation.
# VoiceReceiver#destroyed
This property was removed entirely.
# VoiceReceiver#opus
This event was removed entirely.
# VoiceReceiver#pcm
This event was removed entirely.
# VoiceReceiver#recreate
This method was removed entirely.
# VoiceReceiver#voiceConnection
This property was removed entirely.
# VoiceReceiver#warn
This event was removed entirely; use the receiver.debug event instead.
# VoiceRegion
# VoiceRegion#sampleHostname
This property was removed entirely.
# Webhook
# Webhook#avatarURL
webhook.avatarURL is now a method, as opposed to a property. It also allows you to determine the file format and size to return. If you provide the dynamic option, you will receive a .gif URL if the image is animated; otherwise, it will fall back to the specified format or its default .webp.
- webhook.avatarURL;
+ webhook.avatarURL();
+ webhook.avatarURL({ format: 'png', dynamic: true, size: 1024 });
# Webhook#send***
Just like the TextChannel#send*** methods, all the .send***() methods have been removed in favor of one general .send() method. Read through the TextChannel#send*** section for more information.
# WebhookClient
The WebhookClient class now extends BaseClient, and implements Webhook instead of just extending Webhook, so many methods and properties are documented there, as opposed to on the client.
# Additions
WARNING
Remember to add examples for the additions.
# Activity
# ActivityFlags
# ActivityOptions
These are options for setting an Activity.
# APIMessage
# Base
# BaseClient
# BitField
# BroadcastDispatcher
# CategoryChannel
# CategoryChannel#members
Similar to TextChannel#members and VoiceChannel#members, CategoryChannel#members returns a Collection of GuildMembers who can see the category, mapped by their ID.
# Channel
# Channel#toString
channel.toString() was moved from GuildChannel to Channel.
# Channel#type
channel.type now may also return unknown.
# Client
# Client#clearImmediate
# Client#guildIntegrationsUpdate
# Client#invalidated
# Client#setImmediate
# Client#webhookUpdate
# ClientApplication
This is not a new class; it was formerly called OAuth2Application in v11. Changes and deletions to methods and properties are covered above (link needed). Additions are as follow:
# ClientApplication#cover(Image)
ClientApplication.cover and its associated method ClientApplication.coverImage() return the URL to the application's cover image, with optional modifiers if applied in the method.
ClientApplication.coverImage({ width: 1024, height: 1024 });
# ClientApplication#fetchAssets
ClientApplication.fetchAssets() returns a Promise that resolves into an array of ClientAsset objects, each of which contains id, name and type keys.
# ClientOptions
# ClientOptions#disableEveryone
clientOptions.disableEveryone was removed and replaced with clientOptions.disableMentions. The former was a best-effort approach to escape the everyone mention before sending it off to discord. The API has since introduced a way to deal with this properly on their end, which we use in version 12 through clientOptions.disableMentions.
- const client = new Discord.Client({ disableEveryone: true });
+ const client = new Discord.Client({ disableMentions: 'everyone' });
# ClientOptions#partials
clientOptions.partials was added to allow for partial structures–see the Partials section of the guide for more details.
# ClientOptions#retry
clientOptions.retry has been added to allow a maximum amount of reconnect attempts on 5XX errors.
# ClientOptions#presence
clientOptions.presence has been added to specify presence data to set upon login.
# ClientVoiceManager
# Collector
# Collector#(handle)Dispose
collector.handleDispose and collector.dispose() have been added to remove an element from the collection.
# CollectorOptions
# CollectorOptions#dispose
collectorOptions.dispose has been added to allow deleted data to be removed from the collection.
# Manager
The Manager class was added to store various data types. Uses include
- RoleManager
- UserManager
- GuildManager
- ChannelManager
- MessageManager
- PresenceManager
- ReactionManager
- GuildEmojiManager
- GuildMemberManager
- GuildChannelManager
- ReactionUserManager
- GuildEmojiRoleManager
- GuildMemberRoleManager
# DiscordAPIError
# DiscordAPIError#httpStatus
The DiscordAPIError#httpStatus has been added with the 4xx status code that the error returns. See the MDN docs (opens new window) for more details.
# DMChannel
# DMChannel#lastMessage
The message object of the last message in the channel, if one was sent. It is a read-only property.
# DMChannel#lastPin***
Two properties have been added, dmChannel#lastPinAt (read-only) and dmChannel#lastPinStamp, which returns the Date and timestamp, respectively, of the last pinned message if one is present.
# Guild
# Guild#createIntegration
guild.createIntegration() has been added.
# Guild#fetchEmbed
guild.fetchEmbed has been added.
# Guild#fetchIntegrations
guild.fetchIntegrations() has been added.
# Guild#fetchVanityCode
guild.fetchVanityCode() has been added.
# Guild#setEmbed
guild.setEmbed() has been added.
# Guild#shard(ID)
guild.shard (read-only) and guild.shardID have been added, representing the shard's information.
# GuildAuditLogs
# GuildAuditLogs#Actions
auditLogs.Actions() has been added (static method).
# GuildAuditLogs#Targets
auditLogs.Targets() has been added (static method).
# GuildChannel
# GuildChannel#createOverwrite
Creates or updates an existing overwrite for a user or role. The second parameter is a PermissionOverwriteOption object; the third optional parameter is reason, a string.
channel.createOverwrite(message.author, {
SEND_MESSAGES: false,
});
# GuildChannel#permissionsLocked
guildChannel.permissionsLocked is a boolean value representing if the permissionOverwrites of the channel match its parent's permissionOverwrites.
# GuildChannel#updateOverwrite
Creates or updates an existing overwrite for a user or role. The second parameter is a PermissionOverwriteOption object; the third optional parameter is reason, a string.
channel.updateOverwrite(message.author, {
SEND_MESSAGES: false,
});
# GuildChannel#viewable
guildChannel.viewable is a boolean value representing whether the channel is visible to the client user.
# HTTPError
# Integration
# Message
# Message#activity
message.activity has been added.
# Message#application
message.application has been added.
# Message.url
message.url has been added to provide a URL to jump to the message.
# MessageAttachment
# MessageAttachment#setAttachment
attachment.setAttachment() has been added.
# MessageAttachment#setFile
attachment.setFile() has been added.
# MessageAttachment#setName
attachment.setName() has been added.
# MessageEmbed
# MessageEmbed#addFields
MessageEmbed.addFields has been added to add multiple fields at once (note: Fields have to be passed as EmbedFieldData)
# MessageEmbed#files
MessageEmbed.files has been added as an array of files in the MessageEmbed.
# MessageEmbed#length
MessageEmbed.length has been added. It returns a number equal to all field names and values, the title, description, footer, and author name.
# Permissions
# Permissions#flags
PRIORITY_SPEAKER has been added.
# PlayInterface
This is a new class to play audio over VoiceConnection's and VoiceBroadcast's.
# Presence
# Presence#clientStatus
The new presence.clientStatus property returns an object with three keys: web, mobile and desktop; their values are a PresenceStatus string. This property allows you to check which client the member or user is using to access Discord.
# Presence#guild
presence.guild has been added as a helper property to represent the Guild the presence belongs to, if applicable.
# Presence#member
presence.member is a read-only property representing the GuildMember the presence belongs to, if applicable.
# Presence#user(ID)
presence.user (read-only) and presence.userID are properties representing a User and its ID that the presence belongs to. The former can be null if the User is not cached.
# ReactionCollector
# ReactionCollector#empty
reactionCollector.empty() was added to remove all collected reactions from the collector.
# ReactionCollector#key
# ReactionCollector#remove
The new remove event emits when a collected reaction is un-reacted if the dispose option is set to true.
# Shard
# Shard#_evals
The private property _evals was added to map ongoing Promises for calls to shard.eval().
# Shard#_fetches
The private property _fetches was added to map ongoing Promises for calls to shard.fetchClientValues().
# Shard#worker
# ShardClientUtil
# ShardClientUtil#client
# ShardClientUtil#parentPort
The message port for the primary process, if the mode of the ShardClientUtil is worker.
# ShardClientUtil#respawnAll
shardClientUtil.respawnAll() will request a respawn of all shards. It has three parameters, all of which are optional: shardDelay, how long to wait in milliseconds between each shard; respawnDelay, how long to wait between killing the shard's process or worker and restarting it; and spawnTimeout, how long to wait in milliseconds for a shard to become ready before moving to the next shard.
# Speaking
The Speaking class has been added as a data structure to interact with the bit fields present when a GuildMember is speaking or in the VoiceConnection#speaking event.
# StreamDispatcher
# StreamDispatcher#bitrateEditable
# StreamDispatcher#paused***
Two new properties have been added, pausedSince and pausedTime, to represent the timestamp when the stream was paused and how long it's been paused for in milliseconds, respectively.
# StreamDispatcher#set***
Several new methods have been added to adjust various aspects of the stream. Methods marked with a * denote that they're usable only with a compatible Opus stream.
setFEC()* - whether to forward error correction or not if using a compatible Opus streamsetPLP()* - sets the expected packet loss percentage if using a compatible Opus streamsetVolume()- sets the volume relative to the input streamsetVolumeDecibels()- sets the volume in decibelssetVolumeLogarithmic()- sets the volume so that a perceived value of0.5is half the perceived volume, etc.
# StreamDispatcher#volumeChange
This new event emits when a volume change in the stream is detected.
dispatcher.on('volumeChange', (oldVolume, newVolume) => {
console.log(`Volume changed from ${oldVolume} to ${newVolume}.`);
});
# TextChannel
# TextChannel#lastPinTimestamp
TextChannel.lastPinTimestamp was added.
# TextChannel#lastPinAt
TextChannel.lastPinAt was added.
# User
# User#lastMessageChannelID
# User#locale
user.locale has been added.
# Util
# Util#cleanContent
This new method converts all mentions to their equivalent text.
# Util#discordSort
This new method sorts a Collection by Discord's position and ID.
# Util#flatten
This new method flattens any object. Any Collections in the object will be converted to an array of keys.
# Util#resolveColor
This new method resolves a ColorResolvable into a color number.
# Util#resolveString
This new method resolves a StringResolvable into a string.
# Util#Constants
# Constant.Colors
WHITE and YELLOW have been added as values.
# VoiceBroadcast
# VoiceBroadcast#dispatcher
This new property represents the primary dispatcher (if any) that controls everything played by subscribed dispatchers.
# VoiceChannel
# VoiceChannel#editable
This new property returns a boolean value whether the client can edit the VoiceChannel or not, e.g., any change to the channel besides moving it via channel.setPosition(). It differs from channel.manageable in that it also checks if the client has the CONNECT permissions for that particular channel.
# VoiceReceiver
# VoiceReceiver#debug
This new event emits on a warning and will emit either with an Error object or string, depending on what causes it to emit.
# VoiceState
# VolumeInterface
# VolumeInterface#volumeEditable
This new property returns a boolean value whether the client can edit the stream's volume.
# Webhook
# Webhook#url
This new property returns a string representing the URL of the webhook and is read-only.
# WebSocketManager
This new class represents the manager of the WebSocket connection for the client.
# WebSocketOptions
# WebSocketOptions#intents
This new parameter adds support for Intents, controlling which events you receive from Discord. Please refer to our more detailed article about this topic
# WebSocketShard
This new class represents a Shard's WebSocket connection.