move commands to separate module

This commit is contained in:
JOLIMAITRE Matthieu 2024-05-01 17:17:32 +02:00
parent ba1479acbe
commit a3178942af
2 changed files with 189 additions and 183 deletions

View file

@ -1,18 +1,12 @@
#!/bin/env -S deno run -A --unstable-kv
import {
AutocompleteInteraction,
ChatInputCommandInteraction,
Client,
EmbedBuilder,
SlashCommandBuilder,
TextChannel,
} from "npm:discord.js";
import { Client } from "npm:discord.js";
import { Storage } from "./lib/storage.ts";
import { _1d, _1min, Channel, channel, collect, days_to_ms, log_from, trimmed } from "./lib/utils.ts";
import { channel, log_from } from "./lib/utils.ts";
import { update_loop } from "./lib/board.ts";
import { notification_loop } from "./lib/notification.ts";
import { declare_commands, handle_autocomplete, handle_command } from "./lib/commands/commands.ts";
const log = log_from(import.meta);
@ -46,7 +40,7 @@ async function main() {
await bot.login(token);
log("Logged in as", bot.user?.username);
const commands = build_api_commands(subjects);
const commands = declare_commands(subjects);
if (debug_server !== undefined) {
for (const command of commands) command.setName("dbg-" + command.name);
await bot.application?.commands.set(commands, debug_server);
@ -62,177 +56,4 @@ async function main() {
log("Oki.");
}
function build_api_commands(subjects: Set<string>) {
const subjects_as_choices = [...subjects.values()].map((name) => ({ name, value: name }));
const devoir_command = new SlashCommandBuilder()
.setName("devoir")
.setDescription("Manipuler les devoirs à effectuer.")
.addSubcommand((command) =>
command.setName("ajouter")
.setDescription("Ajouter un nouveau devoir à effectuer.")
.addStringOption((option) =>
option.setName("matière")
.setDescription("Matière du devoir à effectuer.")
.addChoices(...subjects_as_choices)
.setRequired(true)
)
.addNumberOption((option) =>
option.setName("jours")
.setMinValue(0)
.setDescription("Nombre de jours avant la date du rendu.")
.setRequired(true)
)
.addStringOption((option) =>
option.setName("description")
.setDescription("Description du devoir à effectuer.")
.setRequired(true)
)
).addSubcommand((command) =>
command.setName("retirer")
.setDescription("Retirer un devoir.")
.addStringOption((option) =>
option.setName("devoir")
.setDescription("Devoir à retirer.")
.setAutocomplete(true)
.setRequired(true)
)
).addSubcommand((command) =>
command.setName("éditer")
.setDescription("Éditer un devoir.")
.addStringOption((option) =>
option.setName("devoir")
.setDescription("Devoir à éditer.")
.setAutocomplete(true)
.setRequired(true)
)
.addStringOption((option) =>
option.setName("matière")
.setDescription("Nouvelle matière.")
.addChoices(...subjects_as_choices)
.setRequired(false)
)
.addNumberOption((option) =>
option.setName("jours")
.setMinValue(0)
.setDescription("Nouveau nombre de jours avant la date du rendu.")
.setRequired(false)
)
.addStringOption((option) =>
option.setName("description")
.setDescription("Nouvelle description.")
.setRequired(false)
)
);
const adm_command = new SlashCommandBuilder().setName("adm")
.setDescription("Commandes d'administration.")
.addSubcommand((command) =>
command.setName("ajouter-feed")
.setDescription("Ajoute un salon comme feed de notifications.")
.addChannelOption((option) =>
option.setName("salon")
.setDescription("Salon du nouveau feed.")
.setRequired(true)
)
);
return [devoir_command, adm_command];
}
async function handle_command(
interaction: ChatInputCommandInteraction,
storage: Storage,
update_display: Channel,
) {
log("Received command", interaction.commandName);
if (interaction.commandName === "devoir") {
const subcommand = interaction.options.getSubcommand(true);
if (subcommand === "ajouter") {
const subject = interaction.options.getString("matière", true);
const days = interaction.options.getNumber("jours", true);
const description = interaction.options.getString("description", true);
const date = Date.now() + days_to_ms(days);
const { id } = await storage.devoirs.add({ date, description, subject });
const embed = new EmbedBuilder()
.setTitle("`🌟` Ajouté")
.setDescription(`Nouveau devoir ajouté avec succès.`)
.setFooter({ text: `(devoir id:${id})` });
await interaction.reply({ embeds: [embed], ephemeral: true });
update_display.send();
return;
}
if (subcommand === "retirer") {
const id = interaction.options.getString("devoir", true);
await storage.devoirs.delete({ id });
const embed = new EmbedBuilder()
.setTitle("`🗑️` Retiré")
.setDescription(`Devoir supprimé avec succès.`)
.setFooter({ text: `(devoir id:${id})` });
await interaction.reply({ embeds: [embed], ephemeral: true });
update_display.send();
return;
}
if (subcommand === "éditer") {
const id = interaction.options.getString("devoir", true);
const subject = interaction.options.getString("matière", false);
if (subject !== null) storage.devoirs.update({ id }, (d) => d.subject = subject);
const description = interaction.options.getString("description", false);
if (description !== null) storage.devoirs.update({ id }, (d) => d.description = description);
const days = interaction.options.getNumber("jours", false);
if (days !== null) storage.devoirs.update({ id }, (d) => d.date = Date.now() + days_to_ms(days));
const embed = new EmbedBuilder()
.setTitle("`🔧` Édité")
.setDescription(`Devoir mis à jour avec succès.`)
.setFooter({ text: `(devoir id:${id})` });
await interaction.reply({ embeds: [embed], ephemeral: true });
update_display.send();
return;
}
return log("Unknown devoir sub command", subcommand);
}
if (interaction.commandName === "adm") {
const subcommand = interaction.options.getSubcommand(true);
if (subcommand === "ajouter-feed") {
const channel = interaction.options.getChannel("salon", true);
const is_text_channel = channel instanceof TextChannel;
if (!is_text_channel) {
await interaction.reply("Channel must be text.");
return;
}
const board_message = await channel.send("[board]");
const feed_id = await storage.feeds.add({
channel_id: channel.id,
board_message_id: board_message.id,
notification_ids: new Set(),
});
await interaction.reply("Added feed " + feed_id.id);
}
return log("Unknown adm sub command", subcommand);
}
log("Unknown command", interaction.commandName);
}
async function handle_autocomplete(interaction: AutocompleteInteraction, storage: Storage) {
log("Auto completing.");
if (interaction.commandName === "devoir") {
const subcommand = interaction.options.getSubcommand(true);
if (subcommand === "retirer") {
const devoirs = await collect(storage.devoirs.list());
const mapped = devoirs.map(([{ id }, value]) => ({
name: trimmed(`[${value.subject}] ${value.description}`, 100),
value: id,
}));
return await interaction.respond(mapped);
}
if (subcommand === "éditer") {
const devoirs = await collect(storage.devoirs.list());
const mapped = devoirs.map(([{ id }, value]) => ({
name: trimmed(`[${value.subject}] ${value.description}`, 100),
value: id,
}));
return await interaction.respond(mapped);
}
return log("Unknown devoir sub command", subcommand);
}
log("Unknown command", interaction.commandName);
}
if (import.meta.main) await main();

View file

@ -0,0 +1,185 @@
import {
AutocompleteInteraction,
ChatInputCommandInteraction,
EmbedBuilder,
SlashCommandBuilder,
TextChannel,
} from "npm:discord.js";
import { Storage } from "../storage.ts";
import { _1d, _1min, Channel, collect, days_to_ms, log_from, trimmed } from "../utils.ts";
const log = log_from(import.meta);
export function declare_commands(subjects: Set<string>) {
const subjects_as_choices = [...subjects.values()].map((name) => ({ name, value: name }));
const devoir_command = new SlashCommandBuilder()
.setName("devoir")
.setDescription("Manipuler les devoirs à effectuer.")
.addSubcommand((command) =>
command.setName("ajouter")
.setDescription("Ajouter un nouveau devoir à effectuer.")
.addStringOption((option) =>
option.setName("matière")
.setDescription("Matière du devoir à effectuer.")
.addChoices(...subjects_as_choices)
.setRequired(true)
)
.addNumberOption((option) =>
option.setName("jours")
.setMinValue(0)
.setDescription("Nombre de jours avant la date du rendu.")
.setRequired(true)
)
.addStringOption((option) =>
option.setName("description")
.setDescription("Description du devoir à effectuer.")
.setRequired(true)
)
).addSubcommand((command) =>
command.setName("retirer")
.setDescription("Retirer un devoir.")
.addStringOption((option) =>
option.setName("devoir")
.setDescription("Devoir à retirer.")
.setAutocomplete(true)
.setRequired(true)
)
).addSubcommand((command) =>
command.setName("éditer")
.setDescription("Éditer un devoir.")
.addStringOption((option) =>
option.setName("devoir")
.setDescription("Devoir à éditer.")
.setAutocomplete(true)
.setRequired(true)
)
.addStringOption((option) =>
option.setName("matière")
.setDescription("Nouvelle matière.")
.addChoices(...subjects_as_choices)
.setRequired(false)
)
.addNumberOption((option) =>
option.setName("jours")
.setMinValue(0)
.setDescription("Nouveau nombre de jours avant la date du rendu.")
.setRequired(false)
)
.addStringOption((option) =>
option.setName("description")
.setDescription("Nouvelle description.")
.setRequired(false)
)
);
const adm_command = new SlashCommandBuilder().setName("adm")
.setDescription("Commandes d'administration.")
.addSubcommand((command) =>
command.setName("ajouter-feed")
.setDescription("Ajoute un salon comme feed de notifications.")
.addChannelOption((option) =>
option.setName("salon")
.setDescription("Salon du nouveau feed.")
.setRequired(true)
)
);
return [devoir_command, adm_command];
}
export async function handle_command(
interaction: ChatInputCommandInteraction,
storage: Storage,
update_display: Channel,
) {
log("Received command", interaction.commandName);
if (interaction.commandName === "devoir") {
const subcommand = interaction.options.getSubcommand(true);
if (subcommand === "ajouter") {
const subject = interaction.options.getString("matière", true);
const days = interaction.options.getNumber("jours", true);
const description = interaction.options.getString("description", true);
const date = Date.now() + days_to_ms(days);
const { id } = await storage.devoirs.add({ date, description, subject });
const embed = new EmbedBuilder()
.setTitle("`🌟` Ajouté")
.setDescription(`Nouveau devoir ajouté avec succès.`)
.setFooter({ text: `(devoir id:${id})` });
await interaction.reply({ embeds: [embed], ephemeral: true });
update_display.send();
return;
}
if (subcommand === "retirer") {
const id = interaction.options.getString("devoir", true);
await storage.devoirs.delete({ id });
const embed = new EmbedBuilder()
.setTitle("`🗑️` Retiré")
.setDescription(`Devoir supprimé avec succès.`)
.setFooter({ text: `(devoir id:${id})` });
await interaction.reply({ embeds: [embed], ephemeral: true });
update_display.send();
return;
}
if (subcommand === "éditer") {
const id = interaction.options.getString("devoir", true);
const subject = interaction.options.getString("matière", false);
if (subject !== null) storage.devoirs.update({ id }, (d) => d.subject = subject);
const description = interaction.options.getString("description", false);
if (description !== null) storage.devoirs.update({ id }, (d) => d.description = description);
const days = interaction.options.getNumber("jours", false);
if (days !== null) storage.devoirs.update({ id }, (d) => d.date = Date.now() + days_to_ms(days));
const embed = new EmbedBuilder()
.setTitle("`🔧` Édité")
.setDescription(`Devoir mis à jour avec succès.`)
.setFooter({ text: `(devoir id:${id})` });
await interaction.reply({ embeds: [embed], ephemeral: true });
update_display.send();
return;
}
return log("Unknown devoir sub command", subcommand);
}
if (interaction.commandName === "adm") {
const subcommand = interaction.options.getSubcommand(true);
if (subcommand === "ajouter-feed") {
const channel = interaction.options.getChannel("salon", true);
const is_text_channel = channel instanceof TextChannel;
if (!is_text_channel) {
await interaction.reply("Channel must be text.");
return;
}
const board_message = await channel.send("[board]");
const feed_id = await storage.feeds.add({
channel_id: channel.id,
board_message_id: board_message.id,
notification_ids: new Set(),
});
await interaction.reply("Added feed " + feed_id.id);
}
return log("Unknown adm sub command", subcommand);
}
log("Unknown command", interaction.commandName);
}
export async function handle_autocomplete(interaction: AutocompleteInteraction, storage: Storage) {
log("Auto completing.");
if (interaction.commandName === "devoir") {
const subcommand = interaction.options.getSubcommand(true);
if (subcommand === "retirer") {
const devoirs = await collect(storage.devoirs.list());
const mapped = devoirs.map(([{ id }, value]) => ({
name: trimmed(`[${value.subject}] ${value.description}`, 100),
value: id,
}));
return await interaction.respond(mapped);
}
if (subcommand === "éditer") {
const devoirs = await collect(storage.devoirs.list());
const mapped = devoirs.map(([{ id }, value]) => ({
name: trimmed(`[${value.subject}] ${value.description}`, 100),
value: id,
}));
return await interaction.respond(mapped);
}
return log("Unknown devoir sub command", subcommand);
}
log("Unknown command", interaction.commandName);
}