Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to DJS v13, slash commands #105

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e035e44
Start working on updating for djs v13
dsevillamartin Aug 6, 2021
659ea2f
wip
dsevillamartin Sep 26, 2021
a014c96
more wip, properly register commands & owner command perms, make ping…
dsevillamartin Dec 25, 2021
167d42a
discord: commands > update reload
dsevillamartin Feb 8, 2022
9b28bac
discord: commands > update stats
dsevillamartin Feb 8, 2022
0d51744
discord: modules > update UnhandledError
dsevillamartin Feb 8, 2022
31f165f
discord: commands > change reload - use choices for option
dsevillamartin Feb 10, 2022
269c254
discord: commands > update clean
dsevillamartin Feb 10, 2022
6153db5
discord: commands > change reload - fix some error handling
dsevillamartin Feb 10, 2022
0dbc348
discord: commands > update init
dsevillamartin Feb 10, 2022
f8d369c
discord: commands > update remove
dsevillamartin Feb 11, 2022
ac26b7b
discord: modules > fix RunCommand guild logic
dsevillamartin Feb 11, 2022
ca8366e
discord: commands > update initorg
dsevillamartin Apr 11, 2022
ddd2e30
discord: commands > update removeorg
dsevillamartin Apr 11, 2022
16a0bb2
discord: commands > fix initorg
dsevillamartin Apr 11, 2022
7a3d65c
discord: commands > update github issue
dsevillamartin May 21, 2022
0cb9a9d
discord: commands > update github pr
dsevillamartin May 21, 2022
c229063
discord: commands > update search
dsevillamartin May 30, 2022
3189451
discord: commands > remove help
dsevillamartin Jun 1, 2022
be3b89d
discord: commands > update invite
dsevillamartin Jun 1, 2022
c1657fd
discord: commands > update org
dsevillamartin Jun 1, 2022
2dc0d55
discord: commands > update update
dsevillamartin Jun 2, 2022
2d997ed
discord: update command registering code & allow for few message-only…
dsevillamartin Jun 2, 2022
151c003
discord: commands > update conf
dsevillamartin Aug 13, 2022
767c9f6
discord: commands > create deploy
dsevillamartin Aug 13, 2022
e1b3c11
discord: commands > mark repo actions as guild only
dsevillamartin Aug 13, 2022
b06f959
discord: commands > revert update back to non-slash command
dsevillamartin Aug 13, 2022
d3aa452
discord: add DISCORD_OWNER_ID env
dsevillamartin Aug 13, 2022
0e10008
discord: remove debug log
dsevillamartin Aug 13, 2022
69138a9
add WEB_HOST env for easy domain switching
dsevillamartin Aug 14, 2022
fde2d35
Update @YappyBots/addons commit
dsevillamartin Aug 14, 2022
3be119d
fix: remove prefix (unused) references
dsevillamartin Feb 20, 2023
3b83c58
fix(discord): clean up registering slash commands
dsevillamartin Feb 20, 2023
9ca45d0
fix(discord): slash command perms & choice issues with newer API
dsevillamartin Mar 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
WEB_IP=
WEB_PORT=
WEB_HOST=

DISCORD_TOKEN=
DISCORD_OWNER_ID=
DISCORD_OWNER_SERVER=
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
DISCORD_CHANNEL_LOGGING=
DISCORD_PREFIX=

GITHUB_TOKEN=
BDPW_KEY=
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
.DS_Store
node_modules
yarn.lock
.env
.vscode
db/*.sqlite

yalc.lock
.yalc
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Join our Discord server at https://discord.gg/HHqndMG

### Commands

Prefixes are `G! ` (with space), custom prefix set up, or mention the bot.
You can use the following commands through Discord Slash Commands.

__**Util**__:
- `help` - a help command... yeah :P
Expand Down
139 changes: 88 additions & 51 deletions lib/Discord/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ const Discord = require('discord.js');
const DiscordClient = Discord.Client;
const fs = require('fs');
const Log = require('../Util/Log');
const Guild = require('../Models/Guild');

const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v10');

const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN);

/**
* @typedef {external:ClientOptions} ClientOptions
Expand Down Expand Up @@ -72,6 +76,7 @@ class Client extends DiscordClient {
this.addCommand(require(`./Commands/${f}`), f);
} catch (error) {
this.emit('error', `Command | ${f}`, error);
Log.error(error);
}
});
return this;
Expand Down Expand Up @@ -177,50 +182,42 @@ class Client extends DiscordClient {
* @param {Message} msg
* @return {Client}
*/
async runCommand(msg) {
if (msg.author.equals(this.user) || msg.author.bot) return;
const serverConf = msg.guild && (await Guild.find(msg.guild.id));

if (
!msg.mentions.has(this.user)
)
return;
async runCommand(interaction) {
if (!interaction.isCommand()) return;

const content = this.getMsgContent(msg);
const command = content.split(' ')[0].toLowerCase();
const args = content.split(' ').slice(1);

const middleware = this.middleware
.array()
.sort((a, b) => b.priority - a.priority);
const middleware = Array.from(this.middleware.values()).sort(
(a, b) => b.priority - a.priority
);
let i = 0;

const handleErr = (err, currentMiddleware) =>
middleware[middleware.length - 1].run(
msg,
args,
const handleErr = (err, currentMiddleware) => {
Log.error(err);

return middleware[middleware.length - 1].run(
interaction,
next,
currentMiddleware,
err
);
};

const next = (err) => {
const currentMiddleware = middleware[i] || middleware[i - 1];
const nextMiddleware = middleware[i++];
if (err) return handleErr(err, currentMiddleware);
if (nextMiddleware) {
try {
const thisMiddleware = nextMiddleware.run(msg, args, next, command);
const thisMiddleware = nextMiddleware.run(interaction, next);
if (
thisMiddleware.catch &&
thisMiddleware?.catch &&
typeof thisMiddleware.catch === 'function'
) {
thisMiddleware.catch((e) =>
handleErr(e, nextMiddleware || currentMiddleware)
);
}
} catch (e) {
handleErr(err, nextMiddleware || currentMiddleware);
handleErr(e, nextMiddleware || currentMiddleware);
}
}
};
Expand All @@ -230,28 +227,40 @@ class Client extends DiscordClient {
return this;
}

commandError(msg, cmd, err) {
async runCommandMessage(msg) {
if (msg.author?.id !== this.config.owner) return;

if (!msg.mentions.has(this.user)) return;

const content = this.getMsgContent(msg);
const command = content.split(' ')[0].toLowerCase();
const args = content.split(' ').slice(1);

const cmd =
this.commands.get(command) ||
this.commands.get(this.aliases.get(command));

if (!cmd?.conf?.msgTrigger) return;

try {
let commandRun = cmd.run(msg, args);
if (commandRun && commandRun.catch) {
commandRun.catch((e) => cmd.commandError(msg, e));
}
} catch (e) {
cmd.commandError(msg, e);
}
}

commandError(interaction, cmd, err) {
this.emit('error', err);
return msg.channel
.send([
return interaction.reply(
[
`❌ An unexpected error occurred when trying to run command \`${cmd.help.name}\``,
`\`${err}\``,
])
.catch(() => {
if (err && typeof err === 'object' && err.response)
err = err.response
? err.response.body || err.response.text
: err.stack;
if (err && typeof err === 'object' && err.content)
err = `Discord - ${err.content ? err.content[0] : err.message}`;
if (err && typeof err === 'object' && err.code && err.message)
err = err.message;

msg.author.send([
`❌ An unexpected error occurred when trying to run command \`${cmd.help.name}\` in ${msg.channel}`,
`\`${err}\``,
]);
});
].join('\n'),
{ ephemeral: true }
);
}

/**
Expand All @@ -262,21 +271,20 @@ class Client extends DiscordClient {
getMsgContent(message) {
const { content, mentions } = message;

return (
(mentions.users.size &&
mentions.users.first().equals(this.user) &&
content.split(' ').slice(1).join(' ')) ||
content
);
return content.replace(new RegExp(`^<@!?${this.user.id}>\\s*`), '');
}

permissions(msg) {
permissions(interaction) {
/* This function should resolve to an ELEVATION level which
is then sent to the command handler for verification*/
let permlvl = 0;

if (msg.member && msg.member.hasPermission(`ADMINISTRATOR`)) permlvl = 1;
if (this.config.owner === msg.author.id) permlvl = 2;
if (
interaction.memberPermissions &&
interaction.memberPermissions.has(Discord.Permissions.FLAGS.ADMINISTRATOR)
)
permlvl = 1;
if (this.config.owner === interaction.user.id) permlvl = 2;

return permlvl;
}
Expand Down Expand Up @@ -307,6 +315,35 @@ class Client extends DiscordClient {
}
return embed;
}

registerCommands(env = process.env.NODE_ENV) {
const commands = this.commands.filter((cmd) => !cmd.conf.msgTrigger);
const globalCommands = commands.filter((cmd) => cmd.conf.permLevel !== 2);
const ownerCommands = commands.filter((cmd) => cmd.conf.permLevel === 2);

const isDev = env !== 'production';

const ownerCommandsRoute = Routes.applicationGuildCommands(
String(process.env.DISCORD_CLIENT_ID),
process.env.DISCORD_OWNER_SERVER
);
const globalCommandsRoute = Routes.applicationCommands(
String(process.env.DISCORD_CLIENT_ID)
);

Log.verbose(`Registering ${ownerCommands.size} owner commands @ ${ownerCommandsRoute}`);
Log.verbose(`Registering ${globalCommands.size} global commands @ ${isDev ? ownerCommandsRoute : globalCommandsRoute}`);

return Promise.all([
rest.put(ownerCommandsRoute, {
body: ownerCommands.map((cmd) => cmd.getSlashCommand()),
}),

rest.put(isDev ? ownerCommandsRoute : globalCommandsRoute, {
body: globalCommands.map((cmd) => cmd.getSlashCommand()),
}),
]);
}
}

module.exports = Client;
17 changes: 10 additions & 7 deletions lib/Discord/Commands/Announce.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class AnnounceCommand extends Command {
};
this.setConf({
permLevel: 2,
msgTrigger: true,
});
}
async run(msg, args) {
Expand All @@ -19,12 +20,14 @@ class AnnounceCommand extends Command {
.filter((e, i, o) => o.indexOf(e) === i);
let messagedOwners = [];
let message = await msg.channel.send({
embed: {
title: 'Announce',
color: 0xfb5432,
description: 'Announcing message....',
timestamp: new Date(),
},
embeds: [
{
title: 'Announce',
color: 0xfb5432,
description: 'Announcing message....',
timestamp: new Date(),
},
],
});
for (let owner of owners) {
if (!owner) return;
Expand All @@ -38,7 +41,7 @@ class AnnounceCommand extends Command {
)
.setDescription([`\u200B`, announcement, `\u200B`].join('\n'))
.setTimestamp();
await owner.send({ embed });
await owner.send({ embeds: [embed] });
}
// await message.delete();
return message.edit({
Expand Down
53 changes: 36 additions & 17 deletions lib/Discord/Commands/Clean.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const { CommandInteraction } = require('discord.js');
const Command = require('../Command');

class CleanCommand extends Command {
Expand All @@ -6,7 +7,8 @@ class CleanCommand extends Command {

this.props.help = {
name: 'clean',
description: 'clean the messages of the bot found in the number provided',
description:
'Clean 10 messages (by default) sent by the bot, found in the last 50 messages in the channel.',
usage: 'clean [number=10]',
examples: ['clean', 'clean 14'],
};
Expand All @@ -16,22 +18,39 @@ class CleanCommand extends Command {
});
}

run(msg, args) {
let messageCount = args[0] && !isNaN(args[0]) ? Number(args[0]) : 10;

return msg.channel.messages
.fetch({
limit: 50,
})
.then((messages) => {
let msgs = messages.filter((e) => e.author.equals(this.bot.user));
let i = 1;
for (let [, message] of msgs) {
if (i > messageCount) break;
message.delete();
i++;
}
});
getSlashCommand() {
return super
.getSlashCommand()
.addIntegerOption((option) =>
option
.setName('count')
.setDescription('The number of messages to clean.')
.setMinValue(1)
);
}

/**
*
* @param {CommandInteraction} interaction
*/
async run(interaction) {
const messageCount = interaction.options.getInteger('count') || 10;

await interaction.deferReply({ ephemeral: true });

const messages = await interaction.channel.messages.fetch({
limit: 50,
});

const msgs = messages.filter((e) => e.author.equals(this.bot.user));
let i = 0;
for (let [, message] of msgs) {
if (i >= messageCount) break;
message.delete();
i++;
}

await interaction.editReply(`Done. Deleted ${i} messages`);
}
}

Expand Down
Loading