This repository was archived by the owner on Oct 5, 2025. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
feat: Sapphire guide #711
Closed
Closed
feat: Sapphire guide #711
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
5173008
feat: Sapphire guide
kyranet ac23447
refactor: applied suggestions
kyranet 471f6c7
docs: add most of `args`, finished `first-command`
kyranet 2539446
refactor: use code groups
kyranet 3c3685f
docs: requested changes I
kyranet bae4d38
docs: requested changes II
kyranet 4ac3968
docs: requested changes III
kyranet ac7c622
docs: added built-in arguments
kyranet bfd6d43
docs: requested changes IV
kyranet aab0601
docs: requested changes V
kyranet e6774cd
docs: requested changes V
kyranet ebe3859
docs: added listener guides and more on args
kyranet File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| const { Command } = require('@sapphire/framework'); | ||
|
|
||
| module.exports = class AddCommand extends Command { | ||
| constructor(context) { | ||
| super(context, { | ||
| description: 'Adds two numbers', | ||
| }); | ||
| } | ||
|
|
||
| async run(message, args) { | ||
| const a = await args.pick('number'); | ||
| const b = await args.pick('number'); | ||
| return message.channel.send(`The result is... ${a + b}!`); | ||
| } | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import { Command } from '@sapphire/framework'; | ||
|
|
||
| export class AddCommand extends Command { | ||
| constructor(context) { | ||
| super(context, { | ||
| description: 'Adds two numbers', | ||
| }); | ||
| } | ||
|
|
||
| async run(message, args) { | ||
| const a = await args.pick('number'); | ||
| const b = await args.pick('number'); | ||
| return message.channel.send(`The result is... ${a + b}!`); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| const { Command } = require('@sapphire/framework'); | ||
|
|
||
| module.exports = class BanCommand extends Command { | ||
| constructor(context) { | ||
| super(context, { | ||
| description: 'Bans up to 5 members with optionally a reason', | ||
| }); | ||
| } | ||
|
|
||
| async run(message, args) { | ||
| const members = await args.repeat('member', { times: 5 }); | ||
| const reason = args.finished ? null : args.rest('string'); | ||
|
|
||
| // De-duplicate members: | ||
| for (const member of new Set(members)) { | ||
| await member.ban({ reason }); | ||
| } | ||
|
|
||
| await message.channel.send('Done!'); | ||
| } | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| import { Command } from '@sapphire/framework'; | ||
|
|
||
| export class BanCommand extends Command { | ||
| constructor(context) { | ||
| super(context, { | ||
| description: 'Bans up to 5 members with optionally a reason', | ||
| }); | ||
| } | ||
|
|
||
| async run(message, args) { | ||
| const members = await args.repeat('member', { times: 5 }); | ||
| const reason = args.finished ? null : args.rest('string'); | ||
|
|
||
| // De-duplicate members: | ||
| for (const member of new Set(members)) { | ||
| await member.ban({ reason }); | ||
| } | ||
|
|
||
| await message.channel.send('Done!'); | ||
| } | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| const { Command } = require('@sapphire/framework'); | ||
|
|
||
| module.exports = class MaxCommand extends Command { | ||
| constructor(context) { | ||
| super(context, { | ||
| description: 'Gets the maximum between a number of numbers', | ||
| }); | ||
| } | ||
|
|
||
| async run(message, args) { | ||
| const numbers = await args.repeat('number'); | ||
| return message.channel.send(`The highest number is ${Math.max(...numbers)}!`); | ||
| } | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| import { Command } from '@sapphire/framework'; | ||
|
|
||
| export class MaxCommand extends Command { | ||
| constructor(context) { | ||
| super(context, { | ||
| description: 'Gets the maximum between a number of numbers', | ||
| }); | ||
| } | ||
|
|
||
| async run(message, args) { | ||
| const numbers = await args.repeat('number'); | ||
| return message.channel.send(`The highest number is ${Math.max(...numbers)}!`); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| const { Command } = require('@sapphire/framework'); | ||
|
|
||
| module.exports = class PowCommand extends Command { | ||
| constructor(context) { | ||
| super(context, { | ||
| description: 'Calculates the exponent of a number with an exponent', | ||
| }); | ||
| } | ||
|
|
||
| async run(message, args) { | ||
| const base = await args.pick('number'); | ||
| const exponent = args.finished ? 2 : await args.pick('number'); | ||
| return message.channel.send(`The result is... ${Math.pow(base, exponent)}!`); | ||
| } | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import { Command } from '@sapphire/framework'; | ||
|
|
||
| export class PowCommand extends Command { | ||
| constructor(context) { | ||
| super(context, { | ||
| description: 'Calculates the exponent of a number with an exponent', | ||
| }); | ||
| } | ||
|
|
||
| async run(message, args) { | ||
| const base = await args.pick('number'); | ||
| const exponent = args.finished ? 2 : await args.pick('number'); | ||
| return message.channel.send(`The result is... ${Math.pow(base, exponent)}!`); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| const { Command } = require('@sapphire/framework'); | ||
|
|
||
| module.exports = class PingCommand extends Command { | ||
| constructor(context) { | ||
| super(context, { | ||
| aliases: ['pong'], | ||
| description: 'Tests the latency.', | ||
| }); | ||
| } | ||
|
|
||
| async run(message) { | ||
| const response = await message.channel.send('Ping...'); | ||
| const latency = response.createdTimestamp - message.createdTimestamp; | ||
| await response.edit(`Pong! Took me ${latency}ms.`); | ||
| } | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import { Command } from '@sapphire/framework'; | ||
|
|
||
| export class PingCommand extends Command { | ||
| constructor(context) { | ||
| super(context, { | ||
| aliases: ['pong'], | ||
| description: 'Tests the latency.', | ||
| }); | ||
| } | ||
|
|
||
| async run(message) { | ||
| const response = await message.channel.send('Ping...'); | ||
| const latency = response.createdTimestamp - message.createdTimestamp; | ||
| await response.edit(`Pong! Took me ${latency}ms.`); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| const { SapphireClient } = require('@sapphire/framework'); | ||
|
|
||
| const client = new SapphireClient({ intents: ['GUILDS', 'GUILD_MESSAGES'] }); | ||
|
|
||
| client.login('your-token-goes-here'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| import { SapphireClient } from '@sapphire/framework'; | ||
|
|
||
| const client = new SapphireClient({ intents: ['GUILDS', 'GUILD_MESSAGES'] }); | ||
|
|
||
| client.login('your-token-goes-here'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| # Getting started with Sapphire | ||
|
|
||
| When installing the Sapphire Framework, you need to install both discord.js and the framework. You can do this by running the following command: | ||
|
|
||
| ```sh-session | ||
| npm install discord.js @sapphire/framework | ||
| ``` | ||
|
|
||
| ::: warning | ||
| You need at least Node.js version 14.0 to use Sapphire. | ||
| ::: | ||
|
|
||
| ## Creating an index.js file | ||
|
|
||
| While it doesn't have to be called `index.js`, this file is the main file for your bot, which will handle the bot's setup and login. You can also place it inside a folder, such as `src`. | ||
|
|
||
| ::: warning | ||
| Make sure that the `main` property in your `package.json` points to the right path, such as `index.js` or `src/index.js`. | ||
| ::: | ||
|
|
||
| To begin, require `@sapphire/framework` and create a new `SapphireClient`. This is where you can customize Sapphire's behavior, as well as discord.js'. The Sapphire client extends discord.js', so everything from `Client` is available in `SapphireClient`! | ||
|
|
||
| :::: code-group | ||
| ::: code-group-item CommonJS | ||
| ```js | ||
| const { SapphireClient } = require('@sapphire/framework'); | ||
|
|
||
| const client = new SapphireClient({ intents: ['GUILDS', 'GUILD_MESSAGES'] }); | ||
|
|
||
| client.login('your-token-goes-here'); | ||
| ``` | ||
| ::: | ||
| ::: code-group-item ESM | ||
| ```js | ||
| import { SapphireClient } from '@sapphire/framework'; | ||
kyranet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| const client = new SapphireClient({ intents: ['GUILDS', 'GUILD_MESSAGES'] }); | ||
|
|
||
| client.login('your-token-goes-here'); | ||
| ``` | ||
| ::: | ||
| :::: | ||
|
|
||
|
|
||
| Sapphire uses mention prefix (`@bot command`), but you can optionally define a default prefix (or prefixes) with the `defaultPrefix` option, as well as `regexPrefix` if you are familiar with regexes. | ||
|
|
||
| There is also the advanced option `baseUserDirectory`, which allows you to define the base directory for Sapphire to scan. By default, Sapphire will register this as the directory where your `main` file is at, joined by the store's name. As such, if the root directory is `src`, it will register `src/commands` as one of the command directories. | ||
|
|
||
|
|
||
| ::: danger | ||
| You should use environment variables or a `config.json` for your token instead of passing it directly! | ||
kyranet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| You can read more about why you should [here](/preparations/setting-up-a-bot-application.html#keeping-your-token-safe). | ||
| ::: | ||
|
|
||
| And that's it for your `index.js` file! In the end, your file structure should look like this, along with whatever `.gitignore` or `config.json` files you may have: | ||
|
|
||
| ```:no-line-numbers | ||
| node_modules/ | ||
| src/ | ||
| └── index.js | ||
| package-lock.json | ||
| package.json | ||
| ``` | ||
|
|
||
| ## Resulting code | ||
|
|
||
| <ResultingCode /> | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.