Skip to content
This repository was archived by the owner on Feb 6, 2025. It is now read-only.

Commit 6195dd9

Browse files
committed
Replace old handler with SlashCommandBuilder and amongst other improvements
1 parent c339c00 commit 6195dd9

29 files changed

Lines changed: 558 additions & 802 deletions

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

.eslintrc.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
module.exports = {
2+
root: true,
3+
extends: 'eslint:recommended',
4+
env: {
5+
node: true,
6+
es6: true,
7+
},
8+
parserOptions: {
9+
ecmaVersion: 2021,
10+
},
11+
rules: {
12+
'arrow-spacing': ['warn', { 'before': true, 'after': true }],
13+
'brace-style': ['error', 'stroustrup', { 'allowSingleLine': true }],
14+
'comma-dangle': ['error', 'always-multiline'],
15+
'comma-spacing': 'error',
16+
'comma-style': 'error',
17+
'curly': ['error', 'multi-line', 'consistent'],
18+
'dot-location': ['error', 'property'],
19+
'handle-callback-err': 'off',
20+
'indent': ['error', 'tab'],
21+
'keyword-spacing': 'error',
22+
'max-nested-callbacks': ['error', { 'max': 4 }],
23+
'max-statements-per-line': ['error', { 'max': 2 }],
24+
'no-console': 'off',
25+
'no-empty-function': 'error',
26+
'no-floating-decimal': 'error',
27+
'no-inline-comments': 'error',
28+
'no-lonely-if': 'error',
29+
'no-multi-spaces': 'error',
30+
'no-multiple-empty-lines': ['error', { 'max': 2, 'maxEOF': 1, 'maxBOF': 0 }],
31+
'no-shadow': ['error', { 'allow': ['err', 'resolve', 'reject'] }],
32+
'no-trailing-spaces': ['error'],
33+
'no-var': 'error',
34+
'object-curly-spacing': ['error', 'always'],
35+
'prefer-const': 'error',
36+
'quotes': ['error', 'single'],
37+
'semi': ['error', 'always'],
38+
'space-before-blocks': 'error',
39+
'space-before-function-paren': ['error', {
40+
'anonymous': 'never',
41+
'named': 'never',
42+
'asyncArrow': 'always',
43+
}],
44+
'space-in-parens': 'error',
45+
'space-infix-ops': 'error',
46+
'space-unary-ops': 'error',
47+
'spaced-comment': 'error',
48+
'yoda': 'error',
49+
},
50+
};

.github/dependabot.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: npm
4+
directory: "/"
5+
schedule:
6+
interval: daily
7+
time: "00:00"
8+
timezone: America/Los_Angeles
9+
versioning-strategy: increase

.github/workflows/node.js.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2-
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3-
41
name: Node.js CI
52

63
on:
@@ -17,7 +14,6 @@ jobs:
1714
strategy:
1815
matrix:
1916
node-version: [16.x]
20-
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
2117

2218
steps:
2319
- uses: actions/checkout@v2

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2021 Nate
3+
Copyright (c) 2022 Nate
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
# Discord Command Handler
2-
A Discord.js Command Handler example using Slash Commands and Context Menus.
2+
A Discord.js Command Class Handler example using Slash Commands and Context Menus.
33

44
## Features
55
- 🖱 Using Classes
6-
- 👀 Examples for Top Level, Sub Commands and Sub Command Groups
7-
- 🔐 Examples for Permissions
8-
- 👍 Automated Command Creation System
96
- ✅ Easy to setup
107
- 💻 Stable and 99.9% Bug Free
118

@@ -40,31 +37,24 @@ node index
4037
```
4138

4239
## Usage
43-
### Commands
44-
This bot is designed to create and handle application commands automatically on start-up (using the `ready` event) which means you do not need to keep manually `set`ting and deploying commands.
45-
> There is a `clear` command which can let you clear all of the commands easily.
4640

47-
48-
Also, the bot will only create commands for the server, so if you want to have application commands created globally; Replace the following line in `handler/Command.js`:
49-
50-
```js
51-
this.client.guilds.cache.get(YOUR_SERVER_ID).create(cmd);
41+
To create commands, you need to run the following command in the console:
42+
```bash
43+
npm run deploy
5244
```
53-
with
5445

55-
```js
56-
this.client.application.commands.create(cmd);
57-
```
58-
> NOTE: You may need to wait an hour for the commands to create. 200 Global Command Creations per day is the limit.
46+
These will create a new set of commands in the server.
47+
48+
> NOTE: You may need to wait an hour for the commands to create. 200 Command Creates per day is the limit.
5949
6050
**Command Folder Structure:**
61-
- `context` folder contains the Context Menu commands. Change the `type` property to either `USER` or `MESSAGE` to specify the type of context menu. **`description`** must be `null` (using `contextDescription` instead) and `options` must have an empty array `[]`.
62-
- `general` and other folders are slash commands. The `CHAT_INPUT` type must be used to specify the slash command.
51+
- `context` folder contains the Context Menu commands.
52+
- `general` and other folders are slash commands.
6353

6454
### Permissions
65-
Using the `defaultPermission` boolean in your command file, this will determine the permissions for both the Slash and Context Menu commands when the bot starts up (through the `ready` event). The bot may require another restart for it to work properly (even after commands are created).
55+
Using the `setdefaultPermission` boolean in your command file, this will determine the permissions for both the Slash and Context Menu commands when the bot starts up (through the `ready` event). The bot may require another restart for it to work properly (even after commands are created).
6656

67-
> Read more about Application Command Permissions [here](https://discordjs.guide/interactions/slash-command-permissions.html)!
57+
> Read more about Slash Command Permissions [here](https://discordjs.guide/creating-your-bot/command-handling.html#command-handling)!
6858
6959
**Examples:**
7060
```js
@@ -95,10 +85,10 @@ await r.permissions.set({ permissions });
9585
- `false`: Means that the command will only be available to be select users and roles.
9686

9787
## 📚 Guides
98-
- [Registering Slash Commands](https://discordjs.guide/interactions/registering-slash-commands.html)
99-
- [Replying to Slash Commands](https://discordjs.guide/interactions/replying-to-slash-commands.html)
100-
- [Slash Command Permissions](https://discordjs.guide/interactions/slash-command-permissions.html.html)
101-
- [Handling Commands](https://discordjs.guide/command-handling/#individual-command-files)
88+
- [Creating commands](https://discordjs.guide/creating-your-bot/creating-commands.html)
89+
- [Replying to Slash Commands](https://discordjs.guide/interactions/slash-commands.html#replying-to-slash-commands)
90+
- [Slash Command Permissions](https://discordjs.guide/interactions/slash-commands.html#slash-command-permissions)
91+
- [Handling Commands](https://discordjs.guide/creating-your-bot/command-handling.html#command-handling)
10292

10393
## 👋 Support
10494
If you have found an issue with using this command handler example or have any suggestions? Feel free to join the [NTM Discord Server](https://discord.gg/G2rb53z), send an [issue](https://github.com/NTMNathan/djs-command-handler/issues) or [pull request](https://github.com/NTMNathan/djs-command-handler/pulls). We'll be happy to help and take a look!

index.js renamed to bot.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
const Client = require("./structures/Client");
2-
require("dotenv").config();
1+
const Client = require('./structures/Client');
2+
require('dotenv').config();
33

44
const client = new Client();
55
client.login();

commands/context/avatar.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const Command = require('../../structures/CommandClass');
2+
3+
const { MessageEmbed } = require('discord.js');
4+
const { ContextMenuCommandBuilder } = require('@discordjs/builders');
5+
const { ApplicationCommandType } = require('discord-api-types/v9');
6+
7+
module.exports = class Avatar extends Command {
8+
constructor(client) {
9+
super(client, {
10+
data: new ContextMenuCommandBuilder()
11+
.setName('Avatar')
12+
.setType(ApplicationCommandType.User)
13+
.setDefaultPermission(true),
14+
contextDescription: 'Fetches the avatar of a user.',
15+
usage: 'Avatar',
16+
category: 'Context',
17+
permissions: ['Use Application Commands', 'Send Messages', 'Embed Links'],
18+
});
19+
}
20+
async run(client, interaction) {
21+
const user = client.users.cache.get(interaction.targetId);
22+
23+
const embed = new MessageEmbed()
24+
.setTitle(`**${user.username}'s Avatar**`)
25+
.setColor(client.config.embedColor)
26+
.setImage(user.displayAvatarURL({ dynamic: true, size: 2048 }));
27+
28+
await interaction.reply({ embeds: [embed] });
29+
}
30+
};

commands/context/hello.js

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
1-
const Command = require("../../structures/CommandClass");
1+
const Command = require('../../structures/CommandClass');
2+
3+
const { ContextMenuCommandBuilder } = require('@discordjs/builders');
4+
const { ApplicationCommandType } = require('discord-api-types/v9');
25

36
module.exports = class Hello extends Command {
4-
constructor(client) {
5-
super(client, {
6-
name: "Hello",
7-
type: "MESSAGE",
8-
defaultPermission: true,
9-
contextDescription: "Sends a message that greets you, with a present!",
10-
category: "Context",
11-
permissions: ["Use Application Commands", "Send Messages", "Embed Links"]
12-
});
13-
}
14-
async run(client, interaction) {
15-
await interaction.reply({ content: `Hello ${interaction.user}! Here, you should have a slice of vanilla cake 😊🍰` });
16-
}
7+
constructor(client) {
8+
super(client, {
9+
data: new ContextMenuCommandBuilder()
10+
.setName('Hello')
11+
.setType(ApplicationCommandType.Message)
12+
.setDefaultPermission(true),
13+
contextDescription: 'Sends a message that greets you, with a present!',
14+
usage: 'Hello',
15+
category: 'Context',
16+
permissions: ['Use Application Commands', 'Send Messages', 'Embed Links'],
17+
});
18+
}
19+
async run(client, interaction) {
20+
await interaction.reply({ content: `Hello ${interaction.user}! Here, you should have a slice of vanilla cake 😊🍰` });
21+
}
1722
};

commands/context/userinfo.js

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,56 @@
1-
const Command = require("../../structures/CommandClass");
1+
const Command = require('../../structures/CommandClass');
22

3-
const { MessageEmbed } = require("discord.js");
4-
const { stripIndents } = require("common-tags");
3+
const { MessageEmbed } = require('discord.js');
4+
const { ContextMenuCommandBuilder } = require('@discordjs/builders');
5+
const { ApplicationCommandType } = require('discord-api-types/v9');
6+
const { stripIndents } = require('common-tags');
57

68
module.exports = class UserInfo extends Command {
7-
constructor(client) {
8-
super(client, {
9-
name: "User Info",
10-
type: "USER",
11-
defaultPermission: true,
12-
contextDescription: "Returns information about a user.",
13-
category: "Context",
14-
cooldown: 5,
15-
enabled: true,
16-
staffOnly: false,
17-
permissions: ["Use Application Commands", "Send Messages", "Embed Links"]
18-
});
19-
}
20-
async run(client, interaction) {
21-
const member = interaction.guild.members.cache.get(interaction.targetId);
9+
constructor(client) {
10+
super(client, {
11+
data: new ContextMenuCommandBuilder()
12+
.setName('User Info')
13+
.setType(ApplicationCommandType.User)
14+
.setDefaultPermission(true),
15+
contextDescription: 'Returns information about a user.',
16+
usage: 'User Info',
17+
category: 'Context',
18+
permissions: ['Use Application Commands', 'Send Messages', 'Embed Links'],
19+
});
20+
}
21+
async run(client, interaction) {
22+
const member = interaction.guild.members.cache.get(interaction.targetId);
2223

23-
const embed = new MessageEmbed()
24-
.setTitle(`**${member.user.username}#${member.user.discriminator}**`)
25-
.setColor(client.config.embedColor)
26-
.setThumbnail(member.user.displayAvatarURL({ dynamic: true, size: 2048 }))
27-
.addFields(
28-
{
29-
name: "👤 Account Info",
30-
value: stripIndents`
24+
const embed = new MessageEmbed()
25+
.setTitle(`**${member.user.username}#${member.user.discriminator}**`)
26+
.setColor(client.config.embedColor)
27+
.setThumbnail(member.user.displayAvatarURL({ dynamic: true, size: 2048 }))
28+
.addFields(
29+
{
30+
name: '👤 Account Info',
31+
value: stripIndents`
3132
**ID:** ${member.user.id}
32-
**Bot:** ${member.user.bot ? "Yes" : "No"}
33+
**Bot:** ${member.user.bot ? 'Yes' : 'No'}
3334
**Created:** <t:${Math.floor(member.user.createdTimestamp / 1000)}:d>
3435
`,
35-
inline: true
36-
},
37-
{
38-
name: "📋 Member Info",
39-
value: stripIndents`
36+
inline: true,
37+
},
38+
{
39+
name: '📋 Member Info',
40+
value: stripIndents`
4041
**Joined Server:** <t:${Math.floor(member.joinedTimestamp / 1000)}:R>
41-
**Nickname:** ${member.nickname || `None`}
42-
**Hoist Role:** ${member.roles.hoist ? member.roles.hoist.name : "None"}
42+
**Nickname:** ${member.nickname || 'None'}
43+
**Hoist Role:** ${member.roles.hoist ? member.roles.hoist.name : 'None'}
4344
`,
44-
inline: true
45-
},
46-
{
47-
name: `📝 Roles [${member.roles.cache.size - 1}]`,
48-
value: member.roles.cache.size ? member.roles.cache.map(roles => `**${roles}**`).slice(0, -1).join(" ") : "None",
49-
inline: false
50-
}
51-
);
45+
inline: true,
46+
},
47+
{
48+
name: `📝 Roles [${member.roles.cache.size - 1}]`,
49+
value: member.roles.cache.size ? member.roles.cache.map(roles => `**${roles}**`).slice(0, -1).join(' ') : 'None',
50+
inline: false,
51+
},
52+
);
5253

53-
interaction.reply({ embeds: [embed] });
54-
}
54+
await interaction.reply({ embeds: [embed] });
55+
}
5556
};

0 commit comments

Comments
 (0)