Skip to content

Commit

Permalink
feat: interactions (#5448)
Browse files Browse the repository at this point in the history
Co-authored-by: izexi <43889168+izexi@users.noreply.github.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Advaith <advaithj1@gmail.com>
Co-authored-by: Shiaupiau <stu43005@gmail.com>
Co-authored-by: monbrey <rsm999@uowmail.edu.au>
Co-authored-by: Tiemen <ThaTiemsz@users.noreply.github.com>
Co-authored-by: Carter <carter@elhnet.net>
  • Loading branch information
8 people committed May 7, 2021
1 parent af00ec8 commit f7643f7
Show file tree
Hide file tree
Showing 24 changed files with 1,340 additions and 35 deletions.
52 changes: 52 additions & 0 deletions docs/examples/commands.md
@@ -0,0 +1,52 @@
# Slash Commands

In this example, you'll get to know how to create commands and listen to incoming interactions.

## Creating a Command

First off, we need to create a command so that users can use it. We will create an `echo` command which simply returns what the user inputted. Note that global commands can take up to an hour to appear in the client, so if you want to test a new command, you should create it for one guild first.

```js
// The data for our command
const commandData = {
name: 'echo',
description: 'Replies with your input!',
options: [{
name: 'input',
type: 'STRING',
description: 'The input which should be echoed back',
required: true,
}],
};

client.once('ready', () => {
// Creating a global command
client.application.commands.create(commandData);

// Creating a guild-specific command
client.guilds.cache.get('id').commands.create(commandData);
});
```

And that's it! As soon as your client is ready, it will register the `echo` command.

## Handling Commands

Now let's implement a simple handler for it:

```js
client.on('interaction', interaction => {
// If the interaction isn't a slash command, return
if (!interaction.isCommand()) return;

// Check if it is the correct command
if (interaction.commandName === 'echo') {
// Get the input of the user
const input = interaction.options[0].value;
// Reply to the command
interaction.reply(input);
}
});
```

The `interaction` event will get emitted every time the client receives an interaction. Only our own slash commands trigger this event, so there is no need to implement a check for commands that belong to other bots.
2 changes: 2 additions & 0 deletions docs/index.yml
Expand Up @@ -28,3 +28,5 @@
path: moderation.md
- name: Webhook
path: webhook.js
- name: Slash Commands
path: commands.md
5 changes: 5 additions & 0 deletions esm/discord.mjs
Expand Up @@ -28,8 +28,10 @@ export const {
UserFlags,
Util,
version,
ApplicationCommandManager,
BaseGuildEmojiManager,
ChannelManager,
GuildApplicationCommandManager,
GuildChannelManager,
GuildEmojiManager,
GuildEmojiRoleManager,
Expand All @@ -49,6 +51,7 @@ export const {
resolveString,
splitMessage,
Application,
ApplicationCommand,
Base,
Activity,
APIMessage,
Expand All @@ -59,6 +62,7 @@ export const {
ClientApplication,
ClientUser,
Collector,
CommandInteraction,
DMChannel,
Emoji,
Guild,
Expand All @@ -70,6 +74,7 @@ export const {
GuildTemplate,
Integration,
IntegrationApplication,
Interaction,
Invite,
Message,
MessageAttachment,
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -59,7 +59,7 @@
"@types/node": "^12.12.6",
"@types/ws": "^7.2.7",
"cross-env": "^7.0.2",
"discord-api-types": "^0.18.0",
"discord-api-types": "^0.18.1",
"discord.js-docgen": "git+https://github.com/discordjs/docgen.git",
"dtslint": "^4.0.4",
"eslint": "^7.11.0",
Expand Down
23 changes: 23 additions & 0 deletions src/client/websocket/handlers/INTERACTION_CREATE.js
@@ -0,0 +1,23 @@
'use strict';

const { Events, InteractionTypes } = require('../../../util/Constants');
let Structures;

module.exports = (client, { d: data }) => {
if (data.type === InteractionTypes.APPLICATION_COMMAND) {
if (!Structures) Structures = require('../../../util/Structures');
const CommandInteraction = Structures.get('CommandInteraction');

const interaction = new CommandInteraction(client, data);

/**
* Emitted when an interaction is created.
* @event Client#interaction
* @param {Interaction} interaction The interaction which was created
*/
client.emit(Events.INTERACTION_CREATE, interaction);
return;
}

client.emit(Events.DEBUG, `[INTERACTION] Received interaction with unknown type: ${data.type}`);
};
2 changes: 2 additions & 0 deletions src/errors/Messages.js
Expand Up @@ -110,6 +110,8 @@ const Messages = {
FETCH_GROUP_DM_CHANNEL: "Bots don't have access to Group DM Channels and cannot fetch them",

MEMBER_FETCH_NONCE_LENGTH: 'Nonce length must not exceed 32 characters.',

INTERACTION_ALREADY_REPLIED: 'This interaction has already been deferred or replied to.',
};

for (const [name, message] of Object.entries(Messages)) register(name, message);
5 changes: 5 additions & 0 deletions src/index.js
Expand Up @@ -33,8 +33,10 @@ module.exports = {
version: require('../package.json').version,

// Managers
ApplicationCommandManager: require('./managers/ApplicationCommandManager'),
BaseGuildEmojiManager: require('./managers/BaseGuildEmojiManager'),
ChannelManager: require('./managers/ChannelManager'),
GuildApplicationCommandManager: require('./managers/GuildApplicationCommandManager'),
GuildChannelManager: require('./managers/GuildChannelManager'),
GuildEmojiManager: require('./managers/GuildEmojiManager'),
GuildEmojiRoleManager: require('./managers/GuildEmojiRoleManager'),
Expand All @@ -58,6 +60,7 @@ module.exports = {

// Structures
Application: require('./structures/interfaces/Application'),
ApplicationCommand: require('./structures/ApplicationCommand'),
Base: require('./structures/Base'),
Activity: require('./structures/Presence').Activity,
APIMessage: require('./structures/APIMessage'),
Expand All @@ -71,6 +74,7 @@ module.exports = {
return require('./structures/ClientUser');
},
Collector: require('./structures/interfaces/Collector'),
CommandInteraction: require('./structures/CommandInteraction'),
DMChannel: require('./structures/DMChannel'),
Emoji: require('./structures/Emoji'),
Guild: require('./structures/Guild'),
Expand All @@ -82,6 +86,7 @@ module.exports = {
GuildTemplate: require('./structures/GuildTemplate'),
Integration: require('./structures/Integration'),
IntegrationApplication: require('./structures/IntegrationApplication'),
Interaction: require('./structures/Interaction'),
Invite: require('./structures/Invite'),
Message: require('./structures/Message'),
MessageAttachment: require('./structures/MessageAttachment'),
Expand Down

0 comments on commit f7643f7

Please sign in to comment.