Skip to content

Commit

Permalink
Discord Slash Command Support
Browse files Browse the repository at this point in the history
- Added support for Discord slash commands.
- Updated the `Command` class to generate slash command data based on command parameters.
- Implemented slash command registration in the `DiscordController`.
- Modified command handlers to support both message-based and interaction-based (slash command) invocations.
- Adjusted command responses to utilize ephemeral messages and embeds when appropriate.
- Updated the `HoyoLab` module to include nickname and code information in redemption responses.
  • Loading branch information
torikushiii committed Jul 9, 2024
1 parent c42e7d8 commit aa70cff
Show file tree
Hide file tree
Showing 8 changed files with 367 additions and 34 deletions.
57 changes: 57 additions & 0 deletions classes/command.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const { SlashCommandBuilder, Message } = require("discord.js");

module.exports = class Command extends require("./template.js") {
name;
description = null;
Expand Down Expand Up @@ -64,6 +66,54 @@ module.exports = class Command extends require("./template.js") {
return this.code(...args);
}

getSlashCommandData () {
if (!this.params || this.params.length === 0) {
return new SlashCommandBuilder()
.setName(this.name)
.setDescription(this.description ?? "No description provided");
}

const builder = new SlashCommandBuilder()
.setName(this.name)
.setDescription(this.description ?? "No description provided");

for (const param of this.params) {
let option;

/* eslint-disable implicit-arrow-linebreak */
switch (param.type) {
case "string":
option = builder.addStringOption(opt =>
opt.setName(param.name)
.setDescription(param.description)
.addChoices(param.choices ?? [])
.setRequired(param.required ?? false)
);
break;
case "integer":
option = builder.addIntegerOption(opt =>
opt.setName(param.name)
.setDescription(param.description)
.setRequired(param.required ?? false)
);
break;
case "boolean":
option = builder.addBooleanOption(opt =>
opt.setName(param.name)
.setDescription(param.description)
.setRequired(param.required ?? false)
);
break;
default:
console.warn(`Unsupported parameter type: ${param.type} for ${this.name}`);
continue;
}
/* eslint-enable implicit-arrow-linebreak */
}

return builder;
}

static async initialize () {
return this;
}
Expand Down Expand Up @@ -133,6 +183,7 @@ module.exports = class Command extends require("./template.js") {
const appendOptions = { ...options };
const contextOptions = {
platform: options.platform,
interaction: options.interaction,
invocation: identifier,
user: userData,
channel: channelData,
Expand All @@ -149,6 +200,12 @@ module.exports = class Command extends require("./template.js") {
let execution;
try {
execution = await command.code(contextOptions, ...args);
if (execution instanceof Message) {
return;
}
if (execution?.reply === undefined) {
return;
}
}
catch (e) {
const logObject = {
Expand Down
72 changes: 65 additions & 7 deletions commands/expedition/index.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,77 @@
module.exports = {
name: "expedition",
description: "Check the status of your expedition.",
params: null,
params: [
{
name: "game",
description: "The game you want to check expeditions for.",
type: "string",
choices: [
{ name: "Genshin Impact", value: "genshin" },
{ name: "Honkai: Star Rail", value: "starrail" }
],
required: true
}
],
run: (async function expedition (context, game) {
const validGames = app.HoyoLab.supportedGames({ blacklist: "honkai" });
const { interaction } = context;
const supportedGames = app.HoyoLab.supportedGames({ blacklist: "honkai" });

if (supportedGames.length === 0) {
if (interaction) {
return await interaction.reply({
content: "There are no accounts available for checking expeditions.",
ephemeral: true
});
}

return {
success: false,
reply: "There are no accounts available for checking expeditions."
};
}

if (!game) {
if (interaction) {
return await interaction.reply({
content: "Please specify a game.",
ephemeral: true
});
}

return {
success: false,
reply: `Please specify a game. Valid games are: ${validGames.join(", ")}`
reply: `Please specify a game. Supported games are: ${supportedGames.join(", ")}`
};
}
if (!validGames.includes(game.toLowerCase())) {
if (!supportedGames.includes(game.toLowerCase())) {
if (interaction) {
return await interaction.reply({
content: "You don't have any accounts for that game.",
ephemeral: true
});
}

return {
success: false,
reply: `Invalid game. Valid games are: ${validGames.join(", ")}`
reply: `Invalid game. Supported games are: ${supportedGames.join(", ")}`
};
}

game = game.toLowerCase();

const accounts = app.HoyoLab.getActiveAccounts({ whitelist: game });
if (accounts.length === 0) {
if (interaction) {
return await interaction.reply({
content: "You don't have any accounts for this game.",
ephemeral: true
});
}

return {
success: false,
reply: `No accounts found for that type of game`
reply: "You don't have any accounts for this game."
};
}

Expand All @@ -48,6 +96,13 @@ module.exports = {
}

if (data.length === 0) {
if (interaction) {
return await interaction.reply({
content: "No expedition data found for this type of account.",
ephemeral: true
});
}

return {
success: false,
reply: "No expedition data found for this type of account"
Expand All @@ -74,7 +129,10 @@ module.exports = {
timestamp: new Date()
}];

await context.channel.send({ embeds });
await interaction.reply({
embeds,
ephemeral: true
});
}

return;
Expand Down
65 changes: 56 additions & 9 deletions commands/notes/index.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,95 @@
module.exports = {
name: "notes",
description: "Check your HoyoLab notes.",
params: null,
params: [
{
name: "game",
description: "The game you want to check notes for.",
type: "string",
choices: [
{ name: "Genshin Impact", value: "genshin" },
{ name: "Honkai: Star Rail", value: "starrail" },
{ name: "Zenless Zone Zero", value: "nap" }
],
required: true
}
],
run: (async function notes (context, game) {
const validGames = app.HoyoLab.supportedGames({ blacklist: "honkai" });
const { interaction } = context;
const supportedGames = app.HoyoLab.supportedGames({ blacklist: "honkai" });

if (supportedGames.length === 0) {
if (interaction) {
return await interaction.reply({
content: "There are no accounts available for checking notes.",
ephemeral: true
});
}

return {
success: false,
reply: "There are no accounts available for checking notes."
};
}

if (!game) {
if (interaction) {
return await interaction.reply({
content: "Please specify a game.",
ephemeral: true
});
}

return {
success: false,
reply: `Please specify a game. Valid games are: ${validGames.join(", ")}`
reply: `Please specify a game. Supported games are: ${supportedGames.join(", ")}`
};
}

if (game === "zenless" || game === "zzz") {
game = "nap";
}

if (!validGames.includes(game.toLowerCase())) {
if (!supportedGames.includes(game.toLowerCase())) {
if (interaction) {
return await interaction.reply({
content: "You don't have any accounts for that game.",
ephemeral: true
});
}

return {
success: false,
reply: `Invalid game. Valid games are: ${validGames.join(", ")}`
reply: `Invalid game specified. Supported games are: ${supportedGames.join(", ")}`
};
}

game = game.toLowerCase();

const accounts = app.HoyoLab.getActiveAccounts({ whitelist: game });
if (accounts.length === 0) {
if (interaction) {
return await interaction.reply({
content: "You don't have any accounts for that game.",
ephemeral: true
});
}

return {
success: false,
reply: "No accounts found for that type of game"
reply: "You don't have any accounts for that game."
};
}

for (const account of accounts) {
const { stamina, expedition } = account;
if (stamina.check === false && expedition.check === false) {
await context.channel.send(`${account.nickname} - Notes disabled for this account.`);
continue;
}

const platform = app.HoyoLab.get(game);
const notes = await platform.notes(account);
if (notes.success === false) {
await context.channel.send(`${account.nickname} - Failed to fetch notes, check the logs for more information.`);
continue;
}

Expand Down Expand Up @@ -138,7 +185,7 @@ module.exports = {
);
}

await context.channel.send({ embeds });
await interaction.reply({ embeds, ephemeral: true });
}
else if (context.platform.id === 2) {
const { data } = notes;
Expand Down
Loading

0 comments on commit aa70cff

Please sign in to comment.