56 |
57 |
58 |
132 |
--------------------------------------------------------------------------------
/guide/README.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | If you're reading this, it probably means you want to learn how to make a bot with discord.js. Awesome! You've come to the right place.
4 | This guide will teach you things such as:
5 | - How to get a bot [up and running](/preparations/) from scratch;
6 | - How to properly [create](/creating-your-bot/), [organize](/creating-your-bot/command-handling.md), and expand on your commands;
7 | - In-depth explanations and examples regarding popular topics (e.g. [reactions](/popular-topics/reactions.md), [embeds](/popular-topics/embeds.md), [canvas](/popular-topics/canvas.md));
8 | - Working with databases (e.g. [sequelize](/sequelize/) and [keyv](/keyv/));
9 | - Getting started with [sharding](/sharding/);
10 | - And much more.
11 |
12 | This guide will also cover subjects like common errors and how to solve them, keeping your code clean, setting up a proper development environment, etc.
13 | Sounds good? Great! Let's get started, then.
14 |
15 | ## Before you begin...
16 |
17 | Alright, making a bot is cool and all, but there are some prerequisites to it. To create a bot with discord.js, you should have a fairly decent grasp of JavaScript itself.
18 | While you _can_ make a bot with very little JavaScript and programming knowledge, trying to do so without understanding the language first will only hinder you. You may get stuck on many uncomplicated issues, struggle with solutions to incredibly easy problems, and all-in-all end up frustrated. Sounds pretty annoying.
19 |
20 | If you don't know JavaScript but would like to learn about it, here are a few links to help get you started:
21 |
22 | * [Eloquent JavaScript, a free online book](http://eloquentjavascript.net/)
23 | * [JavaScript.info, a modern javascript tutorial](https://javascript.info/)
24 | * [Codecademy's interactive JavaScript course](https://www.codecademy.com/learn/introduction-to-javascript)
25 | * [Nodeschool, for both JavaScript and Node.js lessons](https://nodeschool.io/)
26 | * [MDN's JavaScript guide and full documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
27 | * [Google, your best friend](https://google.com)
28 |
29 | Take your pick, learn some JavaScript, and once you feel like you're confident enough to make a bot, come back and get started!
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/guide/additional-features/cooldowns.md:
--------------------------------------------------------------------------------
1 | # Cooldowns
2 |
3 | Spam is something you generally want to avoid, especially if one of your commands require calls to other APIs or takes a bit of time to build/send.
4 |
5 | ::: tip
6 | This section assumes you followed the [Command Handling](/creating-your-bot/command-handling.md) part.
7 | :::
8 |
9 | First, add a cooldown property to your command. This will determine how long the user would have to wait (in seconds) before using the command again.
10 |
11 | ```js {4}
12 | const { SlashCommandBuilder } = require('discord.js');
13 |
14 | module.exports = {
15 | cooldown: 5,
16 | data: new SlashCommandBuilder()
17 | .setName('ping')
18 | .setDescription('Replies with Pong!'),
19 | async execute(interaction) {
20 | // ...
21 | },
22 | };
23 | ```
24 |
25 | In your main file, initialize a [Collection](/additional-info/collections.md) to store cooldowns of commands:
26 |
27 | ```js
28 | client.cooldowns = new Collection();
29 | ```
30 |
31 | The key will be the command names, and the values will be Collections associating the user's id (key) to the last time (value) this user used this command. Overall the logical path to get a user's last usage of a command will be `cooldowns > command > user > timestamp`.
32 |
33 | In your `InteractionCreate` event, add the following code:
34 |
35 | ```js {1,3-5,7-10,12-14}
36 | const { cooldowns } = interaction.client;
37 |
38 | if (!cooldowns.has(command.data.name)) {
39 | cooldowns.set(command.data.name, new Collection());
40 | }
41 |
42 | const now = Date.now();
43 | const timestamps = cooldowns.get(command.data.name);
44 | const defaultCooldownDuration = 3;
45 | const cooldownAmount = (command.cooldown ?? defaultCooldownDuration) * 1_000;
46 |
47 | if (timestamps.has(interaction.user.id)) {
48 | // ...
49 | }
50 |
51 | try {
52 | // ...
53 | } catch (error) {
54 | // ...
55 | }
56 | ```
57 |
58 | You check if the `cooldowns` Collection already has an entry for the command being used. If this is not the case, you can add a new entry, where the value is initialized as an empty Collection. Next, create the following variables:
59 |
60 | 1. `now`: The current timestamp.
61 | 2. `timestamps`: A reference to the Collection of user ids and timestamp key/value pairs for the triggered command.
62 | 3. `cooldownAmount`: The specified cooldown for the command, converted to milliseconds for straightforward calculation. If none is specified, this defaults to three seconds.
63 |
64 | If the user has already used this command in this session, get the timestamp, calculate the expiration time, and inform the user of the amount of time they need to wait before using this command again. Note the use of the `return` statement here, causing the code below this snippet to execute only if the user has not used this command in this session or the wait has already expired.
65 |
66 | Continuing with your current setup, this is the complete `if` statement:
67 |
68 | ```js {2-7}
69 | if (timestamps.has(interaction.user.id)) {
70 | const expirationTime = timestamps.get(interaction.user.id) + cooldownAmount;
71 |
72 | if (now < expirationTime) {
73 | const expiredTimestamp = Math.round(expirationTime / 1_000);
74 | return interaction.reply({ content: `Please wait, you are on a cooldown for \`${command.data.name}\`. You can use it again .`, flags: MessageFlags.Ephemeral });
75 | }
76 | }
77 | ```
78 |
79 | Since the `timestamps` Collection has the user's id as the key, you can use the `get()` method on it to get the value and sum it up with the `cooldownAmount` variable to get the correct expiration timestamp and further check to see if it's expired or not.
80 |
81 | The previous user check serves as a precaution in case the user leaves the guild. You can now use the `setTimeout` method, which will allow you to execute a function after a specified amount of time and remove the timeout.
82 |
83 | ```js {5-6}
84 | if (timestamps.has(interaction.user.id)) {
85 | // ...
86 | }
87 |
88 | timestamps.set(interaction.user.id, now);
89 | setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount);
90 | ```
91 |
92 | This line causes the entry for the user under the specified command to be deleted after the command's cooldown time has expired for them.
93 |
94 | ## Resulting code
95 |
96 |
--------------------------------------------------------------------------------
/guide/additional-features/reloading-commands.md:
--------------------------------------------------------------------------------
1 | # Reloading Commands
2 |
3 | When writing your commands, you may find it tedious to restart your bot every time for testing the smallest changes. With a command handler, you can eliminate this issue and reload your commands while your bot is running.
4 |
5 | ::: warning
6 | ESM does not support require and clearing import cache. You can use [hot-esm](https://www.npmjs.com/package/hot-esm) to import files without cache. Windows support is experimental per [this issue](https://github.com/vinsonchuong/hot-esm/issues/33).
7 | :::
8 |
9 | ::: tip
10 | This section assumes you followed the [Command Handling](/creating-your-bot/command-handling.md) part.
11 | :::
12 |
13 | ::: warning
14 | The reload command ideally should not be used by every user. You should deploy it as a guild command in a private guild.
15 | :::
16 |
17 | ```js
18 | const { SlashCommandBuilder } = require('discord.js');
19 |
20 | module.exports = {
21 | data: new SlashCommandBuilder()
22 | .setName('reload')
23 | .setDescription('Reloads a command.')
24 | .addStringOption(option =>
25 | option.setName('command')
26 | .setDescription('The command to reload.')
27 | .setRequired(true)),
28 | async execute(interaction) {
29 | // ...
30 | },
31 | };
32 | ```
33 |
34 | First off, you need to check if the command you want to reload exists. You can do this check similarly to getting a command.
35 |
36 | ```js {4-9}
37 | module.exports = {
38 | // ...
39 | async execute(interaction) {
40 | const commandName = interaction.options.getString('command', true).toLowerCase();
41 | const command = interaction.client.commands.get(commandName);
42 |
43 | if (!command) {
44 | return interaction.reply(`There is no command with name \`${commandName}\`!`);
45 | }
46 | },
47 | };
48 | ```
49 |
50 | To build the correct file path, you will need the file name. You can use `command.data.name` for doing that.
51 |
52 | In theory, all there is to do is delete the previous command from `client.commands` and require the file again. In practice, you cannot do this easily as `require()` caches the file. If you were to require it again, you would load the previously cached file without any changes. You first need to delete the file from `require.cache`, and only then should you require and set the command file to `client.commands`:
53 |
54 | ```js {1,4-6}
55 | delete require.cache[require.resolve(`./${command.data.name}.js`)];
56 |
57 | try {
58 | const newCommand = require(`./${command.data.name}.js`);
59 | interaction.client.commands.set(newCommand.data.name, newCommand);
60 | await interaction.reply(`Command \`${newCommand.data.name}\` was reloaded!`);
61 | } catch (error) {
62 | console.error(error);
63 | await interaction.reply(`There was an error while reloading a command \`${command.data.name}\`:\n\`${error.message}\``);
64 | }
65 | ```
66 |
67 | The snippet above uses a `try...catch` block to load the command file and add it to `client.commands`. In case of an error, it will log the full error to the console and notify the user about it with the error's message component `error.message`. Note that you never actually delete the command from the commands Collection and instead overwrite it. This behavior prevents you from deleting a command and ending up with no command at all after a failed `require()` call, as each use of the reload command checks that Collection again.
68 |
69 | ## Resulting code
70 |
71 |
72 |
--------------------------------------------------------------------------------
/guide/additional-info/collections.md:
--------------------------------------------------------------------------------
1 | # Collections
2 |
3 | discord.js comes with a utility class known as `Collection`.
4 | It extends JavaScript's native `Map` class, so it has all the `Map` features and more!
5 |
6 | ::: warning
7 | If you're not familiar with `Map`, read [MDN's page on it](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) before continuing. You should be familiar with `Array` [methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) as well. We will also use some ES6 features, so read up [here](/additional-info/es6-syntax.md) if you do not know what they are.
8 | :::
9 |
10 | A `Map` allows for an association between unique keys and their values.
11 | For example, how can you transform every value or filter the entries in a `Map` easily?
12 | This is the point of the `Collection` class!
13 |
14 | ## Array-like Methods
15 |
16 | Many of the methods on `Collection` correspond to their namesake in `Array`. One of them is `find`:
17 |
18 | ```js
19 | // Assume we have an array of users and a collection of the same users.
20 | array.find(u => u.discriminator === '1000');
21 | collection.find(u => u.discriminator === '1000');
22 | ```
23 |
24 | The interface of the callback function is very similar between the two.
25 | For arrays, callbacks usually pass the parameters `(value, index, array)`, where `value` is the value iterated to,
26 | `index` is the current index, and `array` is the array. For collections, you would have `(value, key, collection)`.
27 | Here, `value` is the same, but `key` is the key of the value, and `collection` is the collection itself instead.
28 |
29 | Methods that follow this philosophy of staying close to the `Array` interface are as follows:
30 |
31 | - `find`
32 | - `filter` - Note that this returns a `Collection` rather than an `Array`.
33 | - `map` - Yet this returns an `Array` of values instead of a `Collection`!
34 | - `every`
35 | - `some`
36 | - `reduce`
37 | - `concat`
38 | - `sort`
39 |
40 | ## Converting to Array
41 |
42 | Since `Collection` extends `Map`, it is an [iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols), and can be converted to an `Array` through either `Array.from()` or spread syntax (`...collection`).
43 |
44 | ```js
45 | // For values.
46 | Array.from(collection.values());
47 | [...collection.values()];
48 |
49 | // For keys.
50 | Array.from(collection.keys());
51 | [...collection.keys()];
52 |
53 | // For [key, value] pairs.
54 | Array.from(collection);
55 | [...collection];
56 | ```
57 |
58 | ::: warning
59 | Many people convert Collections to Arrays way too much! This can lead to unnecessary and confusing code. Before you use `Array.from()` or similar, ask yourself if whatever you are trying to do can't be done with the given `Map` or `Collection` methods or with a for-of loop.
60 | :::
61 |
62 | ## Extra Utilities
63 |
64 | Some methods are not from `Array` and are instead entirely new to standard JavaScript.
65 |
66 | ```js
67 | // A random value.
68 | collection.random();
69 |
70 | // The first value.
71 | collection.first();
72 |
73 | // The first 5 values.
74 | collection.first(5);
75 |
76 | // Similar to `first`, but from the end.
77 | collection.last();
78 | collection.last(2);
79 |
80 | // Removes anything that meets the condition from the collection.
81 | // Sort of like `filter`, but in-place.
82 | collection.sweep(user => user.username === 'Bob');
83 | ```
84 |
85 | A more complicated method is `partition`, which splits a single Collection into two new Collections based on the provided function.
86 | You can think of it as two `filter`s, but done at the same time:
87 |
88 | ```js
89 | // `bots` is a Collection of users where their `bot` property was true.
90 | // `humans` is a Collection where the property was false instead!
91 | const [bots, humans] = collection.partition(u => u.bot);
92 |
93 | // Both return true.
94 | bots.every(b => b.bot);
95 | humans.every(h => !h.bot);
96 | ```
97 |
--------------------------------------------------------------------------------
/guide/additional-info/images/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/additional-info/images/search.png
--------------------------------------------------------------------------------
/guide/additional-info/images/send.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/additional-info/images/send.png
--------------------------------------------------------------------------------
/guide/additional-info/notation.md:
--------------------------------------------------------------------------------
1 | # Understanding notation
2 |
3 | Throughout the discord.js docs and when asking for help on the official server, you will run into many different kinds of notations. To help you understand the texts that you read, we will be going over some standard notations.
4 |
5 | ::: tip
6 | Always keep in mind that notation is not always rigorous. There will be typos, misunderstandings, or contexts that will cause notation to differ from the usual meanings.
7 | :::
8 |
9 | ## Classes
10 |
11 | Some common notations refer to a class or the properties, methods, or events of a class. There are many variations on these notations, and they are very flexible depending on the person, so use your best judgment when reading them.
12 |
13 | The notation `` means an instance of the `Class` class. For example, a snippet like `.reply('Hello')` is asking you to replace `` with some value that is an instance of `BaseInteraction`, e.g. `interaction.reply('Hello')`. It could also just be a placeholder, e.g., `` would mean a placeholder for some ID.
14 |
15 | The notation `Class#foo` can refer to the `foo` property, method, or event of the `Class` class. Which one the writer meant needs to be determined from context. For example:
16 |
17 | - `BaseInteraction#user` means that you should refer to the `user` property on a `BaseInteraction`.
18 | - `TextChannel#send` means that you should refer to the `send` method on a `TextChannel`.
19 | - `Client#interactionCreate` means that you should refer to the `interactionCreate` event on a `Client`.
20 |
21 | ::: tip
22 | Remember that this notation is not valid JavaScript; it is a shorthand to refer to a specific piece of code.
23 | :::
24 |
25 | Sometimes, the notation is extended, which can help you determine which one the writer meant. For example, `TextChannel#send(options)` is definitely a method of `TextChannel`, since it uses function notation. `Client#event:messageCreate` is an event since it says it is an event.
26 |
27 | The vital thing to take away from this notation is that the `#` symbol signifies that the property, method, or event can only be accessed through an instance of the class. Unfortunately, many abuse this notation, e.g., `#send` or `Util#resolveColor`. `` is already an instance, so this makes no sense, and `resolveColor` is a static method–you should write it as `Util.resolveColor`. Always refer back to the docs if you are confused.
28 |
29 | As an example, the documentation's search feature uses this notation.
30 |
31 | 
32 |
33 | Notice the use of the `.` operator for the static method, `Role.comparePositions` and the `#` notation for the method, `Role#comparePositionsTo`.
34 |
35 | ## Types
36 |
37 | In the discord.js docs, there are type signatures everywhere, such as in properties, parameters, or return values. If you do not come from a statically typed language, you may not know what specific notations mean.
38 |
39 | The symbol `*` means any type. For example, methods that return `*` mean that they can return anything, and a parameter of type `*` can be anything.
40 |
41 | The symbol `?` means that the type is nullable. You can see it before or after the type (e.g. `?T` or `T?`). This symbol means that the value can be of the type `T` or `null`. An example is `GuildMember#nickname`; its type is `?string` since a member may or may not have a nickname.
42 |
43 | The expression `T[]` means an array of `T`. You can sometimes see multiple brackets `[]`, indicating that the array is multi-dimensional, e.g., `string[][]`.
44 |
45 | The expression `...T` signifies a rest parameter of type `T`. This means that the function can take any amount of arguments, and all those arguments must be of the type `T`.
46 |
47 | The operator `|`, which can read as "or", creates a union type, e.g. `A|B|C`. Simply, it means the value can be of any one of the types given.
48 |
49 | The angle brackets `<>` are used for generic types or parameterized types, signifying a type that uses another type(s). The notation looks like `A` where `A` is the type and `B` is a type parameter. If this is hard to follow, it is enough to keep in mind that whenever you see `A`, you can think of an `A` containing `B`. Examples:
50 |
51 | - `Array` means an array of strings.
52 | - `Promise` means a `Promise` that contains a `User`.
53 | - `Array>` would be an array of `Promise`s, each containing a `User` or a `GuildMember`.
54 | - `Collection` would be a `Collection`, containing key-value pairs where the keys are `Snowflake`s, and the values are `User`s.
55 |
56 | 
57 |
58 | In this piece of the docs, you can see two type signatures, `string`, `MessagePayload`, or `MessageOptions`, and `Promise<(Message|Array)>`. The meaning of the word "or" here is the same as `|`.
59 |
--------------------------------------------------------------------------------
/guide/creating-your-bot/main-file.md:
--------------------------------------------------------------------------------
1 | # Creating the main file
2 |
3 | ::: tip
4 | This page assumes you've already prepared the [configuration files](/creating-your-bot/#creating-configuration-files) from the previous page. We're using the `config.json` approach, however feel free to substitute your own!
5 | :::
6 |
7 | Open your code editor and create a new file. We suggest that you save the file as `index.js`, but you may name it whatever you wish.
8 |
9 | Here's the base code to get you started:
10 |
11 | ```js
12 | // Require the necessary discord.js classes
13 | const { Client, Events, GatewayIntentBits } = require('discord.js');
14 | const { token } = require('./config.json');
15 |
16 | // Create a new client instance
17 | const client = new Client({ intents: [GatewayIntentBits.Guilds] });
18 |
19 | // When the client is ready, run this code (only once).
20 | // The distinction between `client: Client` and `readyClient: Client` is important for TypeScript developers.
21 | // It makes some properties non-nullable.
22 | client.once(Events.ClientReady, readyClient => {
23 | console.log(`Ready! Logged in as ${readyClient.user.tag}`);
24 | });
25 |
26 | // Log in to Discord with your client's token
27 | client.login(token);
28 | ```
29 |
30 | This is how you create a client instance for your Discord bot and log in to Discord. The `GatewayIntentBits.Guilds` intents option is necessary for the discord.js client to work as you expect it to, as it ensures that the caches for guilds, channels, and roles are populated and available for internal use.
31 |
32 | ::: tip
33 | The term "guild" is used by the Discord API and in discord.js to refer to a Discord server.
34 | :::
35 |
36 | Intents also define which events Discord should send to your bot, and you may wish to enable more than just the minimum. You can read more about the other intents on the [Intents topic](/popular-topics/intents).
37 |
38 | ## Running your application
39 |
40 | Open your terminal and run `node index.js` to start the process. If you see "Ready!" after a few seconds, you're good to go! The next step is to start adding [slash commands](/creating-your-bot/slash-commands.md) to develop your bot's functionality.
41 |
42 | ::: tip
43 | You can open your `package.json` file and edit the `"main": "index.js"` field to point to your main file. You can then run `node .` in your terminal to start the process!
44 |
45 | After closing the process with `Ctrl + C`, you can press the up arrow on your keyboard to bring up the latest commands you've run. Pressing up and then enter after closing the process is a quick way to start it up again.
46 | :::
47 |
48 | #### Resulting code
49 |
50 |
--------------------------------------------------------------------------------
/guide/images/branding/banner-blurple-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/images/branding/banner-blurple-small.png
--------------------------------------------------------------------------------
/guide/images/branding/banner-blurple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/images/branding/banner-blurple.png
--------------------------------------------------------------------------------
/guide/images/branding/banner-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/images/branding/banner-small.png
--------------------------------------------------------------------------------
/guide/images/branding/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/images/branding/banner.png
--------------------------------------------------------------------------------
/guide/images/branding/logo-blurple-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/images/branding/logo-blurple-favicon.png
--------------------------------------------------------------------------------
/guide/images/branding/logo-blurple-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/images/branding/logo-blurple-small.png
--------------------------------------------------------------------------------
/guide/images/branding/logo-blurple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/images/branding/logo-blurple.png
--------------------------------------------------------------------------------
/guide/images/branding/logo-favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/images/branding/logo-favicon.png
--------------------------------------------------------------------------------
/guide/images/branding/logo-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/images/branding/logo-small.png
--------------------------------------------------------------------------------
/guide/images/branding/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/images/branding/logo.png
--------------------------------------------------------------------------------
/guide/improving-dev-environment/pm2.md:
--------------------------------------------------------------------------------
1 | # Managing your bot process with PM2
2 |
3 | PM2 is a process manager. It manages your applications' states, so you can start, stop, restart, and delete processes. It offers features such as monitoring running processes and setting up a "start with operating system" (be that Windows, Linux, or Mac) so your processes start when you boot your system.
4 |
5 | ## Installation
6 |
7 | You can install PM2 via the following command:
8 |
9 | :::: code-group
10 | ::: code-group-item npm
11 | ```sh:no-line-numbers
12 | npm install --global pm2
13 | ```
14 | :::
15 | ::: code-group-item yarn
16 | ```sh:no-line-numbers
17 | yarn global add pm2
18 | ```
19 | :::
20 | ::: code-group-item pnpm
21 | ```sh:no-line-numbers
22 | pnpm add --global pm2
23 | ```
24 | :::
25 | ::: code-group-item bun
26 | ```sh:no-line-numbers
27 | bun add --global pm2
28 | ```
29 | :::
30 | ::::
31 |
32 | ## Starting your app
33 |
34 | After you install PM2, the easiest way you can start your app is by going to the directory your bot is in and then run the following:
35 |
36 | ```sh:no-line-numbers
37 | pm2 start your-app-name.js
38 | ```
39 |
40 | ### Additional notes
41 |
42 | The `pm2 start` script allows for more optional command-line arguments.
43 |
44 | - `--name`: This allows you to set the name of your process when listing it up with `pm2 list` or `pm2 monit`:
45 |
46 | ```sh:no-line-numbers
47 | pm2 start your-app-name.js --name "Some cool name"
48 | ```
49 |
50 | - `--watch`: This option will automatically restart your process as soon as a file change is detected, which can be useful for development environments:
51 |
52 | ```bash
53 | pm2 start your-app-name.js --watch
54 | ```
55 |
56 | ::: tip
57 | The `pm2 start` command can take more optional parameters, but only these two are relevant. If you want to see all the parameters available, you can check the documentation of pm2 [here](https://pm2.keymetrics.io/docs/usage/pm2-doc-single-page/).
58 | :::
59 |
60 | Once the process launches with pm2, you can run `pm2 monit` to monitor all console outputs from the processes started by pm2. This accounts for any `console.log()` in your code or outputted errors.
61 |
62 | In a similar fashion to how you start the process, running `pm2 stop` will stop the current process without removing it from PM2's interface:
63 |
64 | ```sh:no-line-numbers
65 | pm2 stop your-app-name.js
66 | ```
67 |
68 | ## Setting up booting with your system
69 |
70 | Perhaps one of the more useful features of PM2 is being able to boot up with your Operating System. This feature will ensure that your bot processes will always be started after an (unexpected) reboot (e.g., after a power outage).
71 |
72 | The initial steps differ per OS. In this guide, we'll cover those for Windows and Linux/macOS.
73 |
74 | ### Initial steps for Windows
75 |
76 | It is recommended to use `pm2-installer`. Follow the steps over at their [`GitHub`](https://github.com/jessety/pm2-installer).
77 |
78 | ### Initial steps for Linux/macOS
79 |
80 | You'll need a start script, which you can get by running the following command:
81 |
82 | ```sh:no-line-numbers
83 | # Detects the available init system, generates the config, and enables startup system
84 | pm2 startup
85 | ```
86 |
87 | Or, if you want to specify your machine manually, select one of the options with the command:
88 |
89 | ```sh:no-line-numbers
90 | pm2 startup [ubuntu | ubuntu14 | ubuntu12 | centos | centos6 | arch | oracle | amazon | macos | darwin | freesd | systemd | systemv | upstart | launchd | rcd | openrc]
91 | ```
92 |
93 | The output of running one of the commands listed above will output a command for you to run with all environment variables and options configured.
94 |
95 | **Example output for an Ubuntu user:**
96 |
97 | ```sh:no-line-numbers
98 | [PM2] You have to run this command as root. Execute the following command:
99 | sudo su -c "env PATH=$PATH:/home/user/.nvm/versions/node/v8.9/bin pm2 startup ubuntu -u user --hp /home/user
100 | ```
101 |
102 | After running that command, you can continue to the next step.
103 |
104 | ### Saving the current process list
105 |
106 | To save the current process list so it will automatically get started after a restart, run the following command:
107 |
108 | ```sh:no-line-numbers
109 | pm2 save
110 | ```
111 |
112 | To disable this, you can run the following command:
113 |
114 | ```sh:no-line-numbers
115 | pm2 unstartup
116 | ```
117 |
--------------------------------------------------------------------------------
/guide/interactions/context-menus.md:
--------------------------------------------------------------------------------
1 | # Context Menus
2 |
3 | Context Menus are application commands which appear when right clicking or tapping a user or a message, in the Apps submenu.
4 |
5 | ::: tip
6 | This page is a follow-up to the [slash commands](/slash-commands/advanced-creation.md) section. Please carefully read those pages first so that you can understand the methods used in this section.
7 | :::
8 |
9 | ## Registering context menu commands
10 |
11 | To create a context menu command, use the class. You can then set the type of the context menu (user or message) using the `setType()` method.
12 |
13 | ```js
14 | const { ContextMenuCommandBuilder, ApplicationCommandType } = require('discord.js');
15 |
16 | const data = new ContextMenuCommandBuilder()
17 | .setName('User Information')
18 | .setType(ApplicationCommandType.User);
19 | ```
20 |
21 | ## Receiving context menu command interactions
22 |
23 | Context menus commands, just like slash commands, are received via an interaction. You can check if a given interaction is a context menu by invoking the `isContextMenuCommand()` method, or the `isMessageContextMenuCommand()` and `isUserContextMenuCommand()` methods to check for the specific type of context menu interaction:
24 |
25 | ```js {2}
26 | client.on(Events.InteractionCreate, interaction => {
27 | if (!interaction.isUserContextMenuCommand()) return;
28 | console.log(interaction);
29 | });
30 | ```
31 |
32 | ## Extracting data from context menus
33 |
34 | For user context menus, you can get the targeted user by accessing the `targetUser` or `targetMember` property from the .
35 |
36 | For message context menus, you can get the targeted message by accessing the `targetMessage` property from the .
37 |
38 | ```js {4}
39 | client.on(Events.InteractionCreate, interaction => {
40 | if (!interaction.isUserContextMenuCommand()) return;
41 | // Get the User's username from context menu
42 | const { username } = interaction.targetUser;
43 | console.log(username);
44 | });
45 | ```
46 |
47 | ## Notes
48 |
49 | - Context menu commands cannot have subcommands or any options.
50 | - Responding to context menu commands functions the same as slash commands. Refer to our [slash command responses](/slash-commands/response-methods) guide for more information.
51 | - Context menu command permissions also function the same as slash commands. Refer to our [slash command permissions](/slash-commands/permissions) guide for more information.
52 |
--------------------------------------------------------------------------------
/guide/interactions/images/modal-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/interactions/images/modal-example.png
--------------------------------------------------------------------------------
/guide/interactions/images/selectephem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/interactions/images/selectephem.png
--------------------------------------------------------------------------------
/guide/message-components/action-rows.md:
--------------------------------------------------------------------------------
1 | # Action rows
2 |
3 | With the components API, you can create interactive message components to enhance the functionality of your slash commands. To get started with this, the first component type you'll need to understand is the action row. To send any type of component, it **must** be placed in an action row.
4 |
5 | Action rows are a fairly simple form of layout component. A message may contain up to five rows, each of which has a "width" of five units. This can be thought of as a flexible 5x5 grid. A button will consume one unit of width in a row, while a select menu will consume the whole five units of width. At this time, these are the only types of components that can be sent in a message.
6 |
7 | :::warning
8 | The "width units" referred to are not fixed - the actual width of each individual button will be dynamic based on its label contents.
9 | :::
10 |
11 | ## Building action rows
12 |
13 | To create an action row, use the class and the method to add buttons or a select menu.
14 |
15 | ```js
16 | const row = new ActionRowBuilder()
17 | .addComponents(component);
18 | ```
19 |
20 | ::: warning
21 | If you're using TypeScript, you'll need to specify the type of components your action row holds. This can be done by specifying the component builder you will add to it using a generic parameter in .
22 |
23 | ```diff
24 | - new ActionRowBuilder()
25 | + new ActionRowBuilder()
26 | ```
27 | :::
28 |
29 | ## Sending action rows
30 |
31 | Once one or many components are inside your row(s), send them in the `components` property of your (extends ).
32 |
33 | ```js {4}
34 | const row = new ActionRowBuilder()
35 | .addComponents(component);
36 |
37 | await interaction.reply({ components: [row] });
38 | ```
39 |
40 | To learn how to create the buttons and select menus that will go inside your row, including more detailed examples on how you might use them, continue on to the other pages in this section.
41 |
--------------------------------------------------------------------------------
/guide/message-components/images/select.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/message-components/images/select.png
--------------------------------------------------------------------------------
/guide/miscellaneous/cache-customization.md:
--------------------------------------------------------------------------------
1 | # Cache customization
2 |
3 | Sometimes, you would like to be able to customize discord.js's caching behavior in order to reduce memory usage.
4 | To this end, discord.js provides you with two ways to do so:
5 |
6 | 1. Limiting the size of caches.
7 | 2. Periodically removing old items from caches.
8 |
9 | ::: danger
10 | Customization of caching behavior is an advanced topic.
11 | It is very easy to introduce errors if your custom cache is not working as expected.
12 | :::
13 |
14 | ## Limiting caches
15 |
16 | When creating a new , you can limit the size of caches, which are specific to certain managers, using the `makeCache` option. Generally speaking, almost all your customizations can be done via the helper functions from the class.
17 |
18 | Below is the default settings, which will limit message caches.
19 |
20 | ```js
21 | const { Client, Options } = require('discord.js');
22 |
23 | const client = new Client({
24 | makeCache: Options.cacheWithLimits(Options.DefaultMakeCacheSettings),
25 | });
26 | ```
27 |
28 | To change the cache behaviors for a type of manager, add it on top of the default settings. For example, you can make caches for reactions limited to 0 items i.e. the client won't cache reactions at all:
29 |
30 | ```js
31 | const client = new Client({
32 | makeCache: Options.cacheWithLimits({
33 | ...Options.DefaultMakeCacheSettings,
34 | ReactionManager: 0,
35 | }),
36 | });
37 | ```
38 |
39 | ::: danger
40 | As noted in the documentation, customizing `GuildManager`, `ChannelManager`, `GuildChannelManager`, `RoleManager`, or `PermissionOverwriteManager` is unsupported! Functionality will break with any kind of customization.
41 | :::
42 |
43 | We can further customize this by passing options to , a special kind of collection that limits the number of items. In the example below, the client is configured so that:
44 |
45 | 1. Only 200 guild members maximum may be cached per `GuildMemberManager` (essentially, per guild).
46 | 2. We never remove a member if it is the client. This is especially important, so that the client can function correctly in guilds.
47 |
48 | ```js
49 | const client = new Client({
50 | makeCache: Options.cacheWithLimits({
51 | ...Options.DefaultMakeCacheSettings,
52 | ReactionManager: 0,
53 | GuildMemberManager: {
54 | maxSize: 200,
55 | keepOverLimit: member => member.id === member.client.user.id,
56 | },
57 | }),
58 | });
59 | ```
60 |
61 | ## Sweeping caches
62 |
63 | In addition to limiting caches, you can also periodically sweep and remove old items from caches. When creating a new , you can customize the `sweepers` option.
64 |
65 | Below is the default settings, which will occasionally sweep threads.
66 |
67 | ```js
68 | const { Client, Options } = require('discord.js');
69 |
70 | const client = new Client({
71 | sweepers: Options.DefaultSweeperSettings,
72 | });
73 | ```
74 |
75 | To change the sweep behavior, you specify the type of cache to sweep () and the options for sweeping (). If the type of cache has a lifetime associated with it, such as invites, messages, or threads, then you can set the `lifetime` option to sweep items older than specified. Otherwise, you can set the `filter` option for any type of cache, which will select the items to sweep.
76 |
77 | ```js
78 | const client = new Client({
79 | sweepers: {
80 | ...Options.DefaultSweeperSettings,
81 | messages: {
82 | interval: 3_600, // Every hour.
83 | lifetime: 1_800, // Remove messages older than 30 minutes.
84 | },
85 | users: {
86 | interval: 3_600, // Every hour.
87 | filter: () => user => user.bot && user.id !== user.client.user.id, // Remove all bots.
88 | },
89 | },
90 | });
91 | ```
92 |
93 | ::: tip
94 | Take a look at the documentation for which types of cache you can sweep.
95 | Also look to see exactly what lifetime means for invites, messages, and threads!
96 | :::
97 |
--------------------------------------------------------------------------------
/guide/miscellaneous/images/chalk-red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/miscellaneous/images/chalk-red.png
--------------------------------------------------------------------------------
/guide/miscellaneous/images/chalk-ugly.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/miscellaneous/images/chalk-ugly.png
--------------------------------------------------------------------------------
/guide/miscellaneous/images/winston.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/miscellaneous/images/winston.png
--------------------------------------------------------------------------------
/guide/oauth2/images/add-redirects.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/oauth2/images/add-redirects.png
--------------------------------------------------------------------------------
/guide/oauth2/images/authorize-app-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/oauth2/images/authorize-app-page.png
--------------------------------------------------------------------------------
/guide/oauth2/images/generate-url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/oauth2/images/generate-url.png
--------------------------------------------------------------------------------
/guide/oauth2/images/oauth2-app-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/oauth2/images/oauth2-app-page.png
--------------------------------------------------------------------------------
/guide/popular-topics/audit-logs.md:
--------------------------------------------------------------------------------
1 | # Working with Audit Logs
2 |
3 | ## A Quick Background
4 |
5 | Audit logs are an excellent moderation tool offered by Discord to know what happened in a server and usually by whom. Making use of audit logs requires the `ViewAuditLog` permission. Audit logs may be fetched on a server, or they may be received via the gateway event `guildAuditLogEntryCreate` which requires the `GuildModeration` intent.
6 |
7 | There are quite a few cases where you may use audit logs. This guide will limit itself to the most common use cases. Feel free to consult the [relevant Discord API page](https://discord.com/developers/docs/resources/audit-log) for more information.
8 |
9 | Keep in mind that these examples explore a straightforward case and are by no means exhaustive. Their purpose is to teach you how audit logs work, and expansion of these examples is likely needed to suit your specific use case.
10 |
11 | ## Fetching Audit Logs
12 |
13 | Let's start by glancing at the method and how to work with it. Like many discord.js methods, it returns a [`Promise`](/additional-info/async-await.md) containing the object. This object has one property, `entries`, which holds a [`Collection`](/additional-info/collections.md) of objects, and consequently, the information you want to retrieve.
14 |
15 | Here is the most basic fetch to look at some entries.
16 |
17 | ```js
18 | const fetchedLogs = await guild.fetchAuditLogs();
19 | const firstEntry = fetchedLogs.entries.first();
20 | ```
21 |
22 | Simple, right? Now, let's look at utilizing its options:
23 |
24 | ```js
25 | const { AuditLogEvent } = require('discord.js');
26 |
27 | const fetchedLogs = await guild.fetchAuditLogs({
28 | type: AuditLogEvent.InviteCreate,
29 | limit: 1,
30 | });
31 |
32 | const firstEntry = fetchedLogs.entries.first();
33 | ```
34 |
35 | This will return the first entry where an invite was created. You used `limit: 1` here to specify only one entry.
36 |
37 | ## Receiving Audit Logs
38 |
39 | Audit logs may be received via the gateway event `guildAuditLogEntryCreate`. This is the best way to receive audit logs if you want to monitor them. As soon as a message is deleted, or an invite or emoji is created, your application will receive an instance of this event. A common use case is to find out _who_ did the action that caused the audit log event to happen.
40 |
41 | ### Who deleted a message?
42 |
43 | One of the most common use cases for audit logs is understanding who deleted a message in a Discord server. If a user deleted another user's message, you can find out who did that as soon as you receive the corresponding audit log event.
44 |
45 | ```js
46 | const { AuditLogEvent, Events } = require('discord.js');
47 |
48 | client.on(Events.GuildAuditLogEntryCreate, async auditLog => {
49 | // Define your variables.
50 | // The extra information here will be the channel.
51 | const { action, extra: channel, executorId, targetId } = auditLog;
52 |
53 | // Check only for deleted messages.
54 | if (action !== AuditLogEvent.MessageDelete) return;
55 |
56 | // Ensure the executor is cached.
57 | const executor = await client.users.fetch(executorId);
58 |
59 | // Ensure the author whose message was deleted is cached.
60 | const target = await client.users.fetch(targetId);
61 |
62 | // Log the output.
63 | console.log(`A message by ${target.tag} was deleted by ${executor.tag} in ${channel}.`);
64 | });
65 | ```
66 |
67 | With this, you now have a very simple logger telling you who deleted a message authored by another person.
68 |
69 | ### Who kicked a user?
70 |
71 | This is very similar to the example above.
72 |
73 | ```js
74 | const { AuditLogEvent, Events } = require('discord.js');
75 |
76 | client.on(Events.GuildAuditLogEntryCreate, async auditLog => {
77 | // Define your variables.
78 | const { action, executorId, targetId } = auditLog;
79 |
80 | // Check only for kicked users.
81 | if (action !== AuditLogEvent.MemberKick) return;
82 |
83 | // Ensure the executor is cached.
84 | const executor = await client.users.fetch(executorId);
85 |
86 | // Ensure the kicked guild member is cached.
87 | const kickedUser = await client.users.fetch(targetId);
88 |
89 | // Now you can log the output!
90 | console.log(`${kickedUser.tag} was kicked by ${executor.tag}.`);
91 | });
92 | ```
93 |
94 | If you want to check who banned a user, it's the same example as above except the `action` should be `AuditLogEvent.MemberBanAdd`. You can check the rest of the types over at the [discord-api-types documentation](https://discord-api-types.dev/api/discord-api-types-v10/enum/AuditLogEvent).
95 |
--------------------------------------------------------------------------------
/guide/popular-topics/formatters.md:
--------------------------------------------------------------------------------
1 | # Formatters
2 |
3 | discord.js provides the package which contains a variety of utilities you can use when writing your Discord bot.
4 |
5 | ## Basic Markdown
6 |
7 | These functions format strings into all the different Markdown styles supported by Discord.
8 |
9 | ```js
10 | const { blockQuote, bold, italic, quote, spoiler, strikethrough, underline, subtext } = require('discord.js');
11 | const string = 'Hello!';
12 |
13 | const boldString = bold(string);
14 | const italicString = italic(string);
15 | const strikethroughString = strikethrough(string);
16 | const underlineString = underline(string);
17 | const spoilerString = spoiler(string);
18 | const quoteString = quote(string);
19 | const blockquoteString = blockQuote(string);
20 | const subtextString = subtext(string);
21 | ```
22 |
23 | ## Links
24 |
25 | There are also two functions to format hyperlinks. `hyperlink()` will format the URL into a masked markdown link, and `hideLinkEmbed()` will wrap the URL in `<>`, preventing it from embedding.
26 |
27 | ```js
28 | const { hyperlink, hideLinkEmbed } = require('discord.js');
29 | const url = 'https://discord.js.org/';
30 |
31 | const link = hyperlink('discord.js', url);
32 | const hiddenEmbed = hideLinkEmbed(url);
33 | ```
34 |
35 | ## Code blocks
36 |
37 | You can use `inlineCode()` and `codeBlock()` to turn a string into an inline code block or a regular code block with or without syntax highlighting.
38 |
39 | ```js
40 | const { inlineCode, codeBlock } = require('discord.js');
41 | const jsString = 'const value = true;';
42 |
43 | const inline = inlineCode(jsString);
44 | const codeblock = codeBlock(jsString);
45 | const highlighted = codeBlock('js', jsString);
46 | ```
47 |
48 | ## Timestamps
49 |
50 | With `time()`, you can format Unix timestamps and dates into a Discord time string.
51 |
52 | ```js
53 | const { time, TimestampStyles } = require('discord.js');
54 | const date = new Date();
55 |
56 | const timeString = time(date);
57 | const relative = time(date, TimestampStyles.RelativeTime);
58 | ```
59 |
60 | ## Mentions
61 |
62 | `userMention()`, `channelMention()`, and `roleMention()` all exist to format Snowflakes into mentions.
63 |
64 | ```js
65 | const { channelMention, roleMention, userMention } = require('discord.js');
66 | const id = '123456789012345678';
67 |
68 | const channel = channelMention(id);
69 | const role = roleMention(id);
70 | const user = userMention(id);
71 | ```
72 |
--------------------------------------------------------------------------------
/guide/popular-topics/images/canvas-add-name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/canvas-add-name.png
--------------------------------------------------------------------------------
/guide/popular-topics/images/canvas-after-text-wrap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/canvas-after-text-wrap.png
--------------------------------------------------------------------------------
/guide/popular-topics/images/canvas-before-text-wrap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/canvas-before-text-wrap.png
--------------------------------------------------------------------------------
/guide/popular-topics/images/canvas-circle-avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/canvas-circle-avatar.png
--------------------------------------------------------------------------------
/guide/popular-topics/images/canvas-final-result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/canvas-final-result.png
--------------------------------------------------------------------------------
/guide/popular-topics/images/canvas-plain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/canvas-plain.png
--------------------------------------------------------------------------------
/guide/popular-topics/images/canvas-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/canvas-preview.png
--------------------------------------------------------------------------------
/guide/popular-topics/images/canvas-square-avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/canvas-square-avatar.png
--------------------------------------------------------------------------------
/guide/popular-topics/images/canvas-stretched-avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/canvas-stretched-avatar.png
--------------------------------------------------------------------------------
/guide/popular-topics/images/canvas.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/canvas.jpg
--------------------------------------------------------------------------------
/guide/popular-topics/images/creating-webhooks-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/creating-webhooks-1.png
--------------------------------------------------------------------------------
/guide/popular-topics/images/creating-webhooks-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/creating-webhooks-2.png
--------------------------------------------------------------------------------
/guide/popular-topics/images/creating-webhooks-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/creating-webhooks-3.png
--------------------------------------------------------------------------------
/guide/popular-topics/images/wallpaper.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/popular-topics/images/wallpaper.jpg
--------------------------------------------------------------------------------
/guide/popular-topics/partials.md:
--------------------------------------------------------------------------------
1 | # Partial Structures
2 |
3 | Partial Structures were introduced to the library in version 12 and are optionally received whenever there is insufficient data to emit the client event with a fully intact discord.js structure. They are (as the name suggests) incomplete, and you cannot expect them to have any information besides their ID. All other properties and methods on this object should be considered invalid and defunct. Before this feature, discord.js client events would not emit if one of the necessary structures could not be built with sufficient data to guarantee a fully functional structure. If you do not opt into partials, this is still the case.
4 |
5 | One example leveraging partials is the handling of reactions on uncached messages, which is explained on [this page](/popular-topics/reactions.md#listening-for-reactions-on-old-messages).
6 |
7 | Prior you had to either handle the undocumented `raw` event or fetch the respective messages on startup. The first approach was prone to errors and unexpected internal behavior. The second was not fully fail-proof either, as the messages could still be uncached if cache size was exceeded in busy channels.
8 |
9 | ## Enabling Partials
10 |
11 | As we said earlier, partials do not have all the information necessary to make them fully functional discord.js structures, so it would not be a good idea to enable the functionality by default. Users should know how to handle them before opting into this feature.
12 |
13 | You choose which structures you want to emit as partials as client options when instantiating your bot client. Available structures are: `User`, `Channel` (only DM channels can be uncached, server channels will always be available), `GuildMember`, `Message`, `Reaction`, `GuildScheduledEvent` and `ThreadMember`.
14 |
15 | ```js
16 | const { Client, Partials } = require('discord.js');
17 |
18 | const client = new Client({ partials: [Partials.Message, Partials.Channel, Partials.Reaction] });
19 | ```
20 |
21 | ::: warning
22 | Make sure you enable all partials you need for your use case! If you miss one, the event does not get emitted.
23 | :::
24 |
25 | ::: warning
26 | Partial structures are enabled globally. You cannot make them work for only a specific event or cache, and you very likely need to adapt other parts of your code that are accessing data from the relevant caches. All caches holding the respective structure type might return partials as well!
27 | :::
28 |
29 | ## Handling Partial data
30 |
31 | All structures you can choose to use partials for have a new property, fittingly called `.partial`, indicating if it is a fully functional or partial instance of its class. The value is `true` if partial, `false` if fully functional.
32 |
33 | ::: warning
34 | Partial data is only ever guaranteed to contain an ID! Do not assume any property or method to work when dealing with a partial structure!
35 | :::
36 |
37 | ```js
38 | if (message.partial) {
39 | console.log('The message is partial.');
40 | } else {
41 | console.log('The message is not partial.');
42 | }
43 | ```
44 |
45 | ## Obtaining the full structure
46 |
47 | Along with `.partial` to check if the structure you call it on is partial or not, the library also introduced a `.fetch()` method to retrieve the missing data from the API and complete the structure. The method returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) you need to handle. After the Promise resolves (and with it, the missing data arrived), you can use the structure as you would before.
48 |
49 | ```js {2-8,10}
50 | if (message.partial) {
51 | message.fetch()
52 | .then(fullMessage => {
53 | console.log(fullMessage.content);
54 | })
55 | .catch(error => {
56 | console.log('Something went wrong when fetching the message: ', error);
57 | });
58 | } else {
59 | console.log(message.content);
60 | }
61 | ```
62 |
63 | ::: warning
64 | You cannot fetch deleted data from the API. For message deletions, `messageDelete` will only emit with the ID, which you cannot use to fetch the complete message containing content, author, or other information, as it is already inaccessible by the time you receive the event.
65 | :::
66 |
--------------------------------------------------------------------------------
/guide/preparations/README.md:
--------------------------------------------------------------------------------
1 | # Installing Node.js and discord.js
2 |
3 | ## Installing Node.js
4 |
5 | To use discord.js, you'll need to install the latest LTS version of [Node.js](https://nodejs.org/).
6 |
7 | ::: tip
8 | To check if you already have Node installed on your machine \(e.g., if you're using a VPS\), run `node -v` in your terminal. It is recommended to use the latest LTS version of Node.
9 | :::
10 |
11 | On Windows, it's as simple as installing any other program. Download the latest version from [the Node.js website](https://nodejs.org/), open the downloaded file, and follow the steps from the installer.
12 |
13 | On macOS, either:
14 |
15 | - Download the latest version from [the Node.js website](https://nodejs.org/), open the package installer, and follow the instructions
16 | - Use a package manager like [Homebrew](https://brew.sh/) with the command `brew install node`
17 |
18 | On Linux, you can consult [this page](https://nodejs.org/en/download/package-manager/) to determine how you should install Node.
19 |
20 | ## Preparing the essentials
21 |
22 | To use discord.js, you'll need to install it via npm \(Node's package manager\). npm comes with every Node installation, so you don't have to worry about installing that. However, before you install anything, you should set up a new project folder.
23 |
24 | Navigate to a suitable place on your machine and create a new folder named `discord-bot` (or whatever you want). Next you'll need to open your terminal.
25 |
26 | ### Opening the terminal
27 |
28 | ::: tip
29 | If you use [Visual Studio Code](https://code.visualstudio.com/), you can press Ctrl + ` (backtick) to open its integrated terminal.
30 | :::
31 |
32 | On Windows, either:
33 |
34 | - `Shift + Right-click` inside your project directory and choose the "Open command window here" option
35 | - Press `Win + R` and run `cmd.exe`, and then `cd` into your project directory
36 |
37 | On macOS, either:
38 | - Open Launchpad or Spotlight and search for "Terminal"
39 | - In your "Applications" folder, under "Utilities", open the Terminal app
40 |
41 | On Linux, you can quickly open the terminal with `Ctrl + Alt + T`.
42 |
43 | With the terminal open, run the `node -v` command to make sure you've successfully installed Node.js.
44 |
45 | ### Initiating a project folder
46 |
47 | :::: code-group
48 | ::: code-group-item npm
49 | ```sh:no-line-numbers
50 | npm init
51 | ```
52 | :::
53 | ::: code-group-item yarn
54 | ```sh:no-line-numbers
55 | yarn init
56 | ```
57 | :::
58 | ::: code-group-item pnpm
59 | ```sh:no-line-numbers
60 | pnpm init
61 | ```
62 | :::
63 | ::: code-group-item bun
64 | ```sh:no-line-numbers
65 | bun init
66 | ```
67 | :::
68 | ::::
69 |
70 | This is the next command you'll be running. This command creates a `package.json` file for you, which will keep track of the dependencies your project uses, as well as other info.
71 |
72 | This command will ask you a sequence of questions–you should fill them out as you see fit. If you're not sure of something or want to skip it as a whole, leave it blank and press enter.
73 |
74 | ::: tip
75 | To get started quickly, you can run the following command to have it fill out everything for you.
76 |
77 |
78 |
79 |
80 | ```sh:no-line-numbers
81 | npm init -y
82 | ```
83 |
84 |
85 |
86 |
87 | ```sh:no-line-numbers
88 | yarn init -y
89 | ```
90 |
91 |
92 |
93 |
94 | ```sh:no-line-numbers
95 | pnpm init
96 | ```
97 |
98 |
99 |
100 |
101 | ```sh:no-line-numbers
102 | bun init -y
103 | ```
104 |
105 |
106 |
107 | :::
108 |
109 | Once you're done with that, you're ready to install discord.js!
110 |
111 | ## Installing discord.js
112 |
113 | Now that you've installed Node.js and know how to open your console and run commands, you can finally install discord.js! Run the following command in your terminal:
114 |
115 | :::: code-group
116 | ::: code-group-item npm
117 | ```sh:no-line-numbers
118 | npm install discord.js
119 | ```
120 | :::
121 | ::: code-group-item yarn
122 | ```sh:no-line-numbers
123 | yarn add discord.js
124 | ```
125 | :::
126 | ::: code-group-item pnpm
127 | ```sh:no-line-numbers
128 | pnpm add discord.js
129 | ```
130 | :::
131 | ::: code-group-item bun
132 | ```sh:no-line-numbers
133 | bun add discord.js
134 | ```
135 | :::
136 | ::::
137 |
138 | And that's it! With all the necessities installed, you're almost ready to start coding your bot.
139 |
140 | ## Installing a linter
141 |
142 | While you are coding, it's possible to run into numerous syntax errors or code in an inconsistent style. You should [install a linter](/preparations/setting-up-a-linter.md) to ease these troubles. While code editors generally can point out syntax errors, linters coerce your code into a specific style as defined by the configuration. While this is not required, it is advised.
143 |
--------------------------------------------------------------------------------
/guide/preparations/adding-your-bot-to-servers.md:
--------------------------------------------------------------------------------
1 | # Adding your bot to servers
2 |
3 | After you [set up a bot application](/preparations/setting-up-a-bot-application.md), you'll notice that it's not in any servers yet. So how does that work?
4 |
5 | Before you're able to see your bot in your own (or other) servers, you'll need to add it by creating and using a unique invite link using your bot application's client id.
6 |
7 | ## Bot invite links
8 |
9 | The basic version of one such link looks like this:
10 |
11 | ```:no-line-numbers
12 | https://discord.com/api/oauth2/authorize?client_id=123456789012345678&permissions=0&scope=bot%20applications.commands
13 | ```
14 |
15 | The structure of the URL is quite simple:
16 |
17 | * `https://discord.com/api/oauth2/authorize` is Discord's standard structure for authorizing an OAuth2 application (such as your bot application) for entry to a Discord server.
18 | * `client_id=...` is to specify _which_ application you want to authorize. You'll need to replace this part with your client's id to create a valid invite link.
19 | * `permissions=...` describes what permissions your bot will have on the server you are adding it to.
20 | * `scope=bot%20applications.commands` specifies that you want to add this application as a Discord bot, with the ability to create slash commands.
21 |
22 | ::: warning
23 | If you get an error message saying "Bot requires a code grant", head over to your application's settings and disable the "Require OAuth2 Code Grant" option. You shouldn't enable this option unless you know why you need to.
24 | :::
25 |
26 | ## Creating and using your invite link
27 |
28 | To create an invite link, head back to the [My Apps](https://discord.com/developers/applications/me) page under the "Applications" section, click on your bot application, and open the OAuth2 page.
29 |
30 | In the sidebar, you'll find the OAuth2 URL generator. Select the `bot` and `applications.commands` options. Once you select the `bot` option, a list of permissions will appear, allowing you to configure the permissions your bot needs.
31 |
32 | Grab the link via the "Copy" button and enter it in your browser. You should see something like this (with your bot's username and avatar):
33 |
34 | 
35 |
36 | Choose the server you want to add it to and click "Authorize". Do note that you'll need the "Manage Server" permission on a server to add your bot there. This should then present you a nice confirmation message:
37 |
38 | 
39 |
40 | Congratulations! You've successfully added your bot to your Discord server. It should show up in your server's member list somewhat like this:
41 |
42 | 
43 |
--------------------------------------------------------------------------------
/guide/preparations/images/bot-auth-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/preparations/images/bot-auth-page.png
--------------------------------------------------------------------------------
/guide/preparations/images/bot-authorized.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/preparations/images/bot-authorized.png
--------------------------------------------------------------------------------
/guide/preparations/images/bot-in-memberlist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/preparations/images/bot-in-memberlist.png
--------------------------------------------------------------------------------
/guide/preparations/images/create-app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/preparations/images/create-app.png
--------------------------------------------------------------------------------
/guide/preparations/images/created-bot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/preparations/images/created-bot.png
--------------------------------------------------------------------------------
/guide/preparations/setting-up-a-bot-application.md:
--------------------------------------------------------------------------------
1 | # Setting up a bot application
2 |
3 | ## Creating your bot
4 |
5 | Now that you've installed Node, discord.js, and hopefully a linter, you're almost ready to start coding! The next step you need to take is setting up an actual Discord bot application via Discord's website.
6 |
7 | It's effortless to create one. The steps you need to take are as follows:
8 |
9 | 1. Open the [Discord developer portal](https://discord.com/developers/applications) and log into your account.
10 | 2. Click on the "New Application" button.
11 | 3. Enter a name and confirm the pop-up window by clicking the "Create" button.
12 |
13 | You should see a page like this:
14 |
15 | 
16 |
17 | You can edit your application's name, description, and avatar here. Once you've done that, then congratulations—you're now the proud owner of a shiny new Discord bot! You're not entirely done, though.
18 |
19 | ## Your bot's token
20 |
21 | ::: danger
22 | This section is critical, so pay close attention. It explains what your bot token is, as well as the security aspects of it.
23 | :::
24 |
25 | After creating a bot user, you'll see a section like this:
26 |
27 | 
28 |
29 | In this panel, you can give your bot a snazzy avatar, set its username, and make it public or private. Your bot's token will be revealed when you press the "Reset Token" button and confirm. When we ask you to paste your bot's token somewhere, this is the value that you need to put in. If you happen to lose your bot's token at some point, you need to come back to this page and reset your bot's token again which will reveal the new token, invalidating all old ones.
30 |
31 | ### What is a token, anyway?
32 |
33 | A token is essentially your bot's password; it's what your bot uses to login to Discord. With that said, **it is vital that you do not ever share this token with anybody, purposely or accidentally**. If someone does manage to get a hold of your bot's token, they can use your bot as if it were theirs—this means they can perform malicious acts with it.
34 |
35 | Tokens look like this: `NzkyNzE1NDU0MTk2MDg4ODQy.X-hvzA.Ovy4MCQywSkoMRRclStW4xAYK7I` (don't worry, we immediately reset this token before even posting it here!). If it's any shorter and looks more like this: `kxbsDRU5UfAaiO7ar9GFMHSlmTwYaIYn`, you copied your client secret instead. Make sure to copy the token if you want your bot to work!
36 |
37 | ### Token leak scenario
38 |
39 | Let's imagine that you have a bot on over 1,000 servers, and it took you many, many months of coding and patience to get it on that amount. Your bot's token gets leaked somewhere, and now someone else has it. That person can:
40 |
41 | * Spam every server your bot is on;
42 | * DM spam as many users as possible;
43 | * Delete as many channels as possible;
44 | * Kick or ban as many server members as possible;
45 | * Make your bot leave all of the servers it has joined;
46 |
47 | All that and much, much more. Sounds pretty terrible, right? So make sure to keep your bot's token as safe as possible!
48 |
49 | In the [initial files](/creating-your-bot/) page of the guide, we cover how to safely store your bot's token in a configuration file.
50 |
51 | ::: danger
52 | If your bot token has been compromised by committing it to a public repository, posting it in discord.js support etc. or otherwise see your bot's token in danger, return to this page and press "Reset Token". This will invalidate all old tokens belonging to your bot. Keep in mind that you will need to update your bot's token where you used it before.
53 | :::
54 |
--------------------------------------------------------------------------------
/guide/requesting-more-content.md:
--------------------------------------------------------------------------------
1 | # Requesting more content
2 |
3 | Since this guide is made specifically for the discord.js community, we want to be sure to provide the most relevant and up-to-date content. We will, of course, make additions to the current pages and add new ones as we see fit, but fulfilling requests is how we know we're providing content you all want the most.
4 |
5 | Requests may be as simple as "add an example to the [frequently asked questions](/popular-topics/faq.html) page", or as elaborate as "add a page regarding [sharding](/sharding/)". We'll do our best to fulfill all requests, as long as they're reasonable.
6 |
7 | To make a request, simply head over to [the repo's issue tracker](https://github.com/discordjs/guide/issues) and [create a new issue](https://github.com/discordjs/guide/issues/new)! Title it appropriately, and let us know exactly what you mean inside the issue description. Make sure that you've looked around the site before making a request; what you want to request might already exist!
8 |
9 | ::: tip
10 | Remember that you can always [fork the repo](https://github.com/discordjs/guide) and [make a pull request](https://github.com/discordjs/guide/pulls) if you want to add anything to the guide yourself!
11 | :::
12 |
--------------------------------------------------------------------------------
/guide/sharding/additional-information.md:
--------------------------------------------------------------------------------
1 | # Additional information
2 |
3 | ::: tip
4 | This page is a follow-up and bases its code on [the previous page](/sharding/).
5 | :::
6 |
7 | Here are some extra topics covered about sharding that might have raised concerns.
8 |
9 | ## Legend
10 |
11 | * `manager` is an instance of `ShardingManager`, e.g. `const manager = new ShardingManager(file, options);`
12 | * `client.shard` refers to the current shard.
13 |
14 | ## Shard messages
15 |
16 | For shards to communicate, they have to send messages to one another, as they each have another process. You must wait for each shard to finish spawning before you can listen to their events, otherwise `ShardingManager#shards` will be an empty `Collection`. You can listen for these messages on the individual shards by adding the following lines in your `index.js` file:
17 |
18 | ```js
19 | manager.spawn()
20 | .then(shards => {
21 | shards.forEach(shard => {
22 | shard.on('message', message => {
23 | console.log(`Shard[${shard.id}] : ${message._eval} : ${message._result}`);
24 | });
25 | });
26 | })
27 | .catch(console.error);
28 | ```
29 |
30 | As the property names imply, the `_eval` property is what the shard is attempting to evaluate, and the `_result` property is the output of said evaluation. However, these properties are only guaranteed if a _shard_ is sending a message. There will also be an `_error` property, should the evaluation have thrown an error.
31 |
32 | You can also send messages via `process.send('hello')`, which would not contain the same information. This is why the `.message` property's type is declared as `*` in the documentation.
33 |
34 | ## Specific shards
35 |
36 | There might be times where you want to target a specific shard. An example would be to kill a specific shard that isn't working as intended. You can achieve this by taking the following snippet (in a command, preferably):
37 |
38 | ::: tip
39 | In discord.js v13, `Client#shard` can hold multiple ids. If you use the default sharding manager, the `.ids` array will only have one entry.
40 | :::
41 |
42 | ```js
43 | client.shard.broadcastEval(c => {
44 | if (c.shard.ids.includes(0)) process.exit();
45 | });
46 | ```
47 |
48 | If you're using something like [PM2](http://pm2.keymetrics.io/) or [Forever](https://github.com/foreverjs/forever), this is an easy way to restart a specific shard. Remember, sends a message to **all** shards, so you have to check if it's on the shard you want.
49 |
50 | ## `ShardingManager#shardArgs` and `ShardingManager#execArgv`
51 |
52 | Consider the following example of creating a new `ShardingManager` instance:
53 |
54 | ```js
55 | const manager = new ShardingManager('./bot.js', {
56 | execArgv: ['--trace-warnings'],
57 | shardArgs: ['--ansi', '--color'],
58 | token: 'your-token-goes-here',
59 | });
60 | ```
61 |
62 | The `execArgv` property is what you would usually pass to Node without sharding, e.g.:
63 |
64 | ```sh:no-line-numbers
65 | node --trace-warnings bot.js
66 | ```
67 |
68 | You can find a list of command-line options for Node [here](https://nodejs.org/api/cli.html).
69 |
70 | The `shardArgs` property is what you would usually pass to your bot without sharding, e.g.:
71 |
72 | ```sh:no-line-numbers
73 | node bot.js --ansi --color
74 | ```
75 |
76 | You can access them later as usual via `process.argv`, which contains an array of executables, your main file, and the command-line arguments used to execute the script.
77 |
78 | ## Eval arguments
79 |
80 | There may come the point where you will want to pass arguments from the outer scope into a `.broadcastEval()` call.
81 |
82 | ```js
83 | function funcName(c, { arg }) {
84 | // ...
85 | }
86 |
87 | client.shard.broadcastEval(funcName, { context: { arg: 'arg' } });
88 | ```
89 |
90 | The `BroadcastEvalOptions` typedef was introduced in discord.js v13 as the second parameter in `.broadcastEval()`. It accepts two properties: `shard` and `context`. The `context` property will be sent as the second argument to your function.
91 |
92 | In this small snippet, an argument is passed to the `funcName` function through this parameter.
93 | The function will receive the arguments as an object as the second parameter.
94 |
95 | ::: warning
96 | The `context` option only accepts properties which are JSON-serializable. This means you cannot pass complex data types in the context directly.
97 | For example, if you sent a `User` instance, the function would receive the raw data object.
98 | :::
99 |
--------------------------------------------------------------------------------
/guide/slash-commands/deleting-commands.md:
--------------------------------------------------------------------------------
1 | # Deleting commands
2 |
3 | ::: tip
4 | This page is a follow-up to [command deployment](/creating-your-bot/command-deployment.md). To delete commands, you need to register them in the first place.
5 | :::
6 |
7 | You may have decided that you don't need a command anymore and don't want your users to be confused when they encounter a removed command.
8 |
9 | ## Deleting specific commands
10 |
11 | To delete a specific command, you will need its id. Head to **Server Settings -> Integrations -> Bots and Apps** and choose your bot. Then, right click a command and click **Copy ID**.
12 |
13 | ::: tip
14 | You need to have [Developer Mode](https://support.discord.com/hc/articles/206346498) enabled for this to show up!
15 | :::
16 |
17 | 
18 |
19 | 
20 |
21 | Edit your `deploy-commands.js` as shown below, or put it into its own file to clearly discern it from the deploy workflow:
22 |
23 | ```js {9-17}
24 | const { REST, Routes } = require('discord.js');
25 | const { clientId, guildId, token } = require('./config.json');
26 |
27 | const rest = new REST().setToken(token);
28 |
29 | // ...
30 |
31 | // for guild-based commands
32 | rest.delete(Routes.applicationGuildCommand(clientId, guildId, 'commandId'))
33 | .then(() => console.log('Successfully deleted guild command'))
34 | .catch(console.error);
35 |
36 | // for global commands
37 | rest.delete(Routes.applicationCommand(clientId, 'commandId'))
38 | .then(() => console.log('Successfully deleted application command'))
39 | .catch(console.error);
40 | ```
41 |
42 | Where `'commandId'` is the id of the command you want to delete. Run your deploy script and it will delete the command.
43 |
44 | ## Deleting all commands
45 |
46 | To delete all commands in the respective scope (one guild, all global commands) you can pass an empty array when setting commands.
47 |
48 | ```js {9-18}
49 | const { REST, Routes } = require('discord.js');
50 | const { clientId, guildId, token } = require('./config.json');
51 |
52 | const rest = new REST().setToken(token);
53 |
54 | // ...
55 |
56 | // for guild-based commands
57 | rest.put(Routes.applicationGuildCommands(clientId, guildId), { body: [] })
58 | .then(() => console.log('Successfully deleted all guild commands.'))
59 | .catch(console.error);
60 |
61 | // for global commands
62 | rest.put(Routes.applicationCommands(clientId), { body: [] })
63 | .then(() => console.log('Successfully deleted all application commands.'))
64 | .catch(console.error);
65 | ```
66 |
67 | Discord's API doesn't currently provide an easy way to delete guild-based commands that occur on multiple guilds from all places at once. Each will need a call of the above endpoint, while specifying the respective guild and command id. Note, that the same command will have a different id, if deployed to a different guild!
68 |
--------------------------------------------------------------------------------
/guide/slash-commands/images/bots-and-apps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/slash-commands/images/bots-and-apps.png
--------------------------------------------------------------------------------
/guide/slash-commands/images/commands-copy-id.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/discordjs/guide/1fa24806d4e0c24095f3b2cf21fa746d2fc66d50/guide/slash-commands/images/commands-copy-id.png
--------------------------------------------------------------------------------
/guide/slash-commands/permissions.md:
--------------------------------------------------------------------------------
1 | # Slash command permissions
2 |
3 | Slash commands have their own permissions system. This system allows you to set the default level of permissions required for a user to execute a command when it is first deployed or your bot is added to a new server.
4 |
5 | The slash command permissions for guilds are defaults only and can be altered by guild administrators, allowing them to configure access however best suits their moderation and server roles. Your code should not try to enforce its own permission management, as this can result in a conflict between the server-configured permissions and your bot's code.
6 |
7 | ::: warning
8 | It is not possible to prevent users with Administrator permissions from using any commands deployed globally or specifically to their guild. Think twice before creating "dev-only" commands such as `eval`.
9 | :::
10 |
11 | ## Member permissions
12 |
13 | You can use to set the default permissions required for a member to run the command. Setting it to `0` will prohibit anyone in a guild from using the command unless a specific overwrite is configured or the user has the Administrator permission flag.
14 |
15 | For this, we'll introduce two common and simple moderation commands: `ban` and `kick`. For a ban command, a sensible default is to ensure that users already have the Discord permission `BanMembers` in order to use it.
16 |
17 | ```js {11}
18 | const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js');
19 |
20 | const data = new SlashCommandBuilder()
21 | .setName('ban')
22 | .setDescription('Select a member and ban them.')
23 | .addUserOption(option =>
24 | option
25 | .setName('target')
26 | .setDescription('The member to ban')
27 | .setRequired(true))
28 | .setDefaultMemberPermissions(PermissionFlagsBits.BanMembers);
29 | ```
30 |
31 | For a kick command however, we can allow members with the `KickMembers` permission to execute the command, so we'll list that flag here.
32 |
33 | ::: tip
34 | You can require the user to have all of multiple permissions by merging them with the `|` bitwise OR operator (for example `PermissionFlagsBits.BanMembers | PermissionFlagsBits.KickMembers`).
35 | You cannot require any of multiple permissions. Discord evaluates against the combined permission bitfield!
36 |
37 | If you want to learn more about the `|` bitwise OR operator you can check the [Wikipedia](https://en.wikipedia.org/wiki/Bitwise_operation#OR) and [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_OR) articles on the topic.
38 | :::
39 |
40 | ```js {11}
41 | const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js');
42 |
43 | const data = new SlashCommandBuilder()
44 | .setName('kick')
45 | .setDescription('Select a member and kick them.')
46 | .addUserOption(option =>
47 | option
48 | .setName('target')
49 | .setDescription('The member to kick')
50 | .setRequired(true))
51 | .setDefaultMemberPermissions(PermissionFlagsBits.KickMembers);
52 | ```
53 |
54 | In reality, you'll probably want to have an additional confirmation step before a ban actually executes. Check out the [button components section](/message-components/buttons) of the guide to see how to add confirmation buttons to your command responses, and listen to button clicks.
55 |
56 | ## Contexts
57 |
58 | By default, globally-deployed commands are also available for use in DMs. You can pass in [InteractionContextType](https://discord-api-types.dev/api/discord-api-types-v10/enum/InteractionContextType) to the `setContexts` method of the builder to restrict the command to only be available in guilds or DMs.
59 |
60 | It doesn't make much sense for your `ban` command to be available in DMs, so you can add `setContexts(InteractionContextType.Guild)` to the builder so that it is only available in guilds:
61 |
62 | ```js {11-12}
63 | const { InteractionContextType, PermissionFlagsBits, SlashCommandBuilder } = require('discord.js');
64 |
65 | const data = new SlashCommandBuilder()
66 | .setName('ban')
67 | .setDescription('Select a member and ban them.')
68 | .addUserOption(option =>
69 | option
70 | .setName('target')
71 | .setDescription('The member to ban')
72 | .setRequired(true))
73 | .setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
74 | .setContexts(InteractionContextType.Guild);
75 | ```
76 |
77 | And that's all you need to know on slash command permissions and contexts!
78 |
--------------------------------------------------------------------------------
/guide/voice/life-cycles.md:
--------------------------------------------------------------------------------
1 | # Life cycles
2 |
3 | Two of the main components that you'll interact with when using `@discordjs/voice` are:
4 |
5 | - **VoiceConnection** – maintains a network connection to a Discord voice server
6 | - **AudioPlayer** – plays audio resources across a voice connection
7 |
8 | Both voice connections and audio players are _stateful_, and you can subscribe to changes in their state as they progress through their respective life cycles.
9 |
10 | It's important to listen for state change events, as they will likely require you to take some action. For example, a voice connection entering the `Disconnected` state will probably require you to attempt to reconnect it.
11 |
12 | Their individual life cycles with descriptions of their states are documented on their respective pages.
13 |
14 | Listening to changes in the life cycles of voice connections and audio players can be done in two ways:
15 |
16 | ## Subscribing to individual events
17 |
18 | ```js
19 | const { VoiceConnectionStatus, AudioPlayerStatus } = require('@discordjs/voice');
20 |
21 | connection.on(VoiceConnectionStatus.Ready, (oldState, newState) => {
22 | console.log('Connection is in the Ready state!');
23 | });
24 |
25 | player.on(AudioPlayerStatus.Playing, (oldState, newState) => {
26 | console.log('Audio player is in the Playing state!');
27 | });
28 | ```
29 |
30 | :::tip
31 | One advantage of listening for transitions to individual states is that it becomes a lot easier to write sequential logic. This is made easy using our [state transition helper](https://github.com/discordjs/discord.js/blob/main/packages/voice/src/util/entersState.ts). An example is shown below.
32 |
33 | ```js
34 | const { AudioPlayerStatus, entersState } = require('@discordjs/voice');
35 |
36 | async function start() {
37 | player.play(resource);
38 | try {
39 | await entersState(player, AudioPlayerStatus.Playing, 5_000);
40 | // The player has entered the Playing state within 5 seconds
41 | console.log('Playback has started!');
42 | } catch (error) {
43 | // The player has not entered the Playing state and either:
44 | // 1) The 'error' event has been emitted and should be handled
45 | // 2) 5 seconds have passed
46 | console.error(error);
47 | }
48 | }
49 |
50 | void start();
51 | ```
52 | :::
53 |
54 | ## Subscribing to all state transitions
55 |
56 | If you would prefer to keep a single event listener for all possible state transitions, then you can also listen to the `stateChange` event:
57 |
58 | ```js
59 | connection.on('stateChange', (oldState, newState) => {
60 | console.log(`Connection transitioned from ${oldState.status} to ${newState.status}`);
61 | });
62 |
63 | player.on('stateChange', (oldState, newState) => {
64 | console.log(`Audio player transitioned from ${oldState.status} to ${newState.status}`);
65 | });
66 | ```
67 |
--------------------------------------------------------------------------------
/guide/whats-new.md:
--------------------------------------------------------------------------------
1 |
12 |
13 | # What's new
14 |
15 |
16 |
17 |
18 | upgrade
23 |
24 | discord.js v14 has released and the guide has been updated!
25 |
26 |
27 |
28 |
29 | This includes additions and changes made in Discord, such as slash commands and message components.
30 |
31 |
32 |
33 | ## Site
34 |
35 | - Upgraded to [VuePress v2](https://v2.vuepress.vuejs.org/)
36 | - New theme made to match the [discord.js documentation site](https://discord.js.org/)
37 | - Discord message components upgraded to [@discord-message-components/vue](https://github.com/Danktuary/discord-message-components/blob/main/packages/vue/README.md)
38 | - Many fixes in code blocks, grammar, consistency, etc.
39 |
40 | ## Pages
41 |
42 | All content has been updated to use discord.js v14 syntax. The v13 version of the guide can be found at [https://v13.discordjs.guide/](https://v13.discordjs.guide/).
43 |
44 | ### New
45 |
46 | - [Updating from v13 to v14](/additional-info/changes-in-v14.md): A list of the changes from discord.js v13 to v14
47 | - [Slash commands](/slash-commands/advanced-creation.md): Registering, replying to slash commands and permissions
48 | - [Buttons](/message-components/buttons): Building, sending, and receiving buttons
49 | - [Select menus](/message-components/select-menus): Building, sending, and receiving select menus
50 | - [Threads](/popular-topics/threads.md): Creating and managing threads
51 | - [Formatters](/popular-topics/formatters.md): A collection of formatters to use with your bot
52 |
53 | ### Updated
54 |
55 | - Commando: Replaced with [Sapphire](https://sapphirejs.dev/docs/Guide/getting-started/getting-started-with-sapphire)
56 | - [Voice](/voice/): Rewritten to use the [`@discordjs/voice`](https://github.com/discordjs/discord.js/tree/main/packages/voice) package
57 | - [Command handling](/creating-your-bot/command-handling.md/): Updated to use slash commands
58 | - Obsolete sections removed
59 | - `client.on('message')` snippets updated to `client.on('interactionCreate')`
60 | - [Message content will become a new privileged intent on August 31, 2022](https://support-dev.discord.com/hc/articles/6207308062871)
61 |
62 |
63 |
64 | Thank you to all of those that contributed to the development of discord.js and the guide!
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [[headers]]
2 | for = "/*"
3 | [headers.values]
4 | Permissions-Policy = "interest-cohort=()"
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "discord.js-guide",
3 | "description": "Imagine a guide... that explores the many possibilities for your discord.js bot.",
4 | "version": "3.0.0",
5 | "private": true,
6 | "scripts": {
7 | "lint": "eslint . --ext js,md,vue",
8 | "dev": "vuepress dev guide",
9 | "build": "NODE_ENV=production vuepress build guide"
10 | },
11 | "repository": "https://github.com/discordjs/guide.git",
12 | "keywords": [
13 | "discord",
14 | "bot",
15 | "guide",
16 | "tutorial",
17 | "javascript",
18 | "node"
19 | ],
20 | "author": "Sanctuary ",
21 | "contributors": [
22 | "dragonfire535 ",
23 | "Drahcirius",
24 | "Lewdcario",
25 | "Souji "
26 | ],
27 | "license": "MIT",
28 | "bugs": {
29 | "url": "https://github.com/discordjs/guide/issues"
30 | },
31 | "homepage": "https://discordjs.guide",
32 | "devDependencies": {
33 | "@vuepress/plugin-docsearch": "^2.0.0-beta.24",
34 | "@vuepress/plugin-google-analytics": "^2.0.0-beta.24",
35 | "eslint": "^7.18.0",
36 | "eslint-config-sora": "^3.1.0",
37 | "eslint-plugin-markdown": "^1.0.0",
38 | "eslint-plugin-vue": "^7.5.0",
39 | "@babel/eslint-parser": "^7.17.0",
40 | "vuepress-vite": "^2.0.0-beta.24"
41 | },
42 | "dependencies": {
43 | "@discord-message-components/vue": "^0.2.1"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------