move commands to separate module
This commit is contained in:
parent
ba1479acbe
commit
a3178942af
2 changed files with 189 additions and 183 deletions
187
src/bot.ts
187
src/bot.ts
|
@ -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();
|
||||
|
|
185
src/lib/commands/commands.ts
Normal file
185
src/lib/commands/commands.ts
Normal 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);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue