Init.
This commit is contained in:
commit
c872cad278
11 changed files with 1052 additions and 0 deletions
111
src/bot.ts
Normal file
111
src/bot.ts
Normal file
|
@ -0,0 +1,111 @@
|
|||
import {
|
||||
CacheType,
|
||||
Client,
|
||||
EmbedBuilder,
|
||||
GatewayIntentBits,
|
||||
Interaction,
|
||||
REST,
|
||||
Routes,
|
||||
SlashCommandBuilder,
|
||||
SlashCommandStringOption,
|
||||
} from "npm:discord.js@14.14.1";
|
||||
import { channel, log_from, SimpleResult, split_promise } from "./utils.ts";
|
||||
const log = (...args: unknown[]) => log_from(import.meta.url, ...args);
|
||||
|
||||
export class EpitlsBot {
|
||||
bot;
|
||||
token;
|
||||
rest;
|
||||
assoc_channel;
|
||||
|
||||
constructor(bot_token: string) {
|
||||
this.token = bot_token;
|
||||
const intents = [GatewayIntentBits.Guilds];
|
||||
this.bot = new Client({ intents });
|
||||
this.bot.on("interactionCreate", (interaction) => this.handle_interaction(interaction));
|
||||
this.rest = new REST().setToken(bot_token);
|
||||
this.assoc_channel = channel<
|
||||
{ cri_login: string; discord_user_id: string; callback: (success: SimpleResult) => void }
|
||||
>();
|
||||
}
|
||||
|
||||
async start() {
|
||||
const { promise, resolver } = split_promise<void>();
|
||||
this.bot.on("ready", () => resolver());
|
||||
this.bot.login(this.token);
|
||||
await promise;
|
||||
await this.register_commands();
|
||||
}
|
||||
|
||||
private async register_commands() {
|
||||
const cmd = new SlashCommandBuilder()
|
||||
.setName("associate")
|
||||
.setDescription("Associates a cri account to your discord account.")
|
||||
.addStringOption(
|
||||
new SlashCommandStringOption()
|
||||
.setName("cri_email")
|
||||
.setDescription("claude.nougaro@epita.fr")
|
||||
.setRequired(true),
|
||||
).toJSON();
|
||||
|
||||
for (const guild_id of this.bot.guilds.cache.keys()) {
|
||||
await this.rest.put(
|
||||
Routes.applicationGuildCommands(this.bot.application!.id, guild_id),
|
||||
{ body: [cmd] },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async handle_interaction(interaction: Interaction<CacheType>) {
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
if (interaction.commandName != "associate") return;
|
||||
const email = interaction.options.getString("cri_email")!;
|
||||
if (!email.endsWith("@epita.fr")) {
|
||||
await interaction.reply(message_command_response_error("invalid cri email " + email));
|
||||
return;
|
||||
}
|
||||
const [cri_login] = email.split("@epita.fr");
|
||||
const discord_user_id = interaction.user.id;
|
||||
const { promise, resolver } = split_promise<SimpleResult>();
|
||||
|
||||
this.assoc_channel.send({ cri_login, discord_user_id, callback: resolver });
|
||||
await interaction.reply(message_command_response_sending_email(email));
|
||||
const result = await promise;
|
||||
if (result === true) interaction.editReply(message_command_response_success());
|
||||
else interaction.editReply(message_command_response_error(result));
|
||||
}
|
||||
|
||||
async assign_role(user_id: string, guild_id: string, role_id: string) {
|
||||
const guild = await this.bot.guilds.fetch(guild_id);
|
||||
const member = await guild.members.fetch({ user: user_id });
|
||||
const role = await guild.roles.fetch(role_id);
|
||||
if (role === null) return console.error("Role", role_id, "not found in guild", guild_id);
|
||||
member.roles.add(role_id);
|
||||
log(`Assigned role '${role.name}' to user '${member.displayName}'.`);
|
||||
}
|
||||
|
||||
async *receive_associations() {
|
||||
while (true) yield await this.assoc_channel.receive();
|
||||
}
|
||||
}
|
||||
|
||||
function message_command_response_sending_email(email: string) {
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle("`🟡`| Verification")
|
||||
.setDescription(`Sending a verification link to your email \`${email}\`.`);
|
||||
return { embeds: [embed] };
|
||||
}
|
||||
|
||||
function message_command_response_error(msg: string) {
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle("`❌`| Verification")
|
||||
.setDescription(`An error occured\n\`${msg}\``);
|
||||
return { embeds: [embed] };
|
||||
}
|
||||
|
||||
function message_command_response_success() {
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle("`✅`| Verification")
|
||||
.setDescription("Your email was associated with this account.");
|
||||
return { embeds: [embed] };
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue