adds renaming and rule for historical participation

This commit is contained in:
Matthieu Jolimaitre 2024-02-05 19:17:34 +01:00
parent fb141abd05
commit 09e05c5c53
5 changed files with 114 additions and 36 deletions

View file

@ -4,16 +4,18 @@ import {
Client,
EmbedBuilder,
GatewayIntentBits,
Guild,
Interaction,
REST,
Routes,
SlashCommandBooleanOption,
SlashCommandBuilder,
SlashCommandRoleOption,
SlashCommandStringOption,
SlashCommandSubcommandBuilder,
} from "npm:discord.js@14.14.1";
import { channel, log_from, SimpleResult, split_promise } from "./utils.ts";
import { RuleSet } from "./rules.ts";
import { SlashCommandSubcommandBuilder } from "npm:discord.js@14.14.1";
import { SlashCommandRoleOption } from "npm:discord.js@14.14.1";
import { channel, log_from, SimpleResult, split_promise, try_ } from "./utils.ts";
const log = log_from(import.meta.url);
/**
@ -54,15 +56,34 @@ export class EpitlsBot {
* Assigns a discord role to a discord user.
*/
public async assign_role(user_id: string, guild_id: string, role_id: string) {
const guild = await this.bot.guilds.fetch(guild_id);
const member = await this.try_fetch_member(guild, user_id);
if (member === undefined) return;
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 to user '${member.displayName}' role '${role.name}'.`);
}
public async update_user_name(user_id: string, must_contain: string, default_suffix: string) {
for (const guild of this.bot.guilds.cache.values()) {
const user = await this.try_fetch_member(guild, user_id);
if (user === undefined) continue;
const name = user.displayName;
if (to_comparable(name).includes(to_comparable(must_contain))) continue;
const DISCORD_MAX_NAME_LENGTH = 35;
const generated_name_prefix = name.slice(0, DISCORD_MAX_NAME_LENGTH - default_suffix.length);
const generated_name = generated_name_prefix + default_suffix;
log(`Setting name of '${name}' to '${generated_name}'.`);
await try_(async () => await user.setNickname(generated_name));
}
}
private async try_fetch_member(guild: Guild, user_id: string) {
try {
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}'.`);
return await guild.members.fetch({ user: user_id });
} catch (_) {
//
return undefined;
}
}
@ -124,6 +145,12 @@ export class EpitlsBot {
.setName("role")
.setDescription("Role à assigner.")
.setRequired(true),
)
.addBooleanOption(
new SlashCommandBooleanOption()
.setName("incl_historical")
.setDescription("Assigner le rôle aux membres qui ont été membre du groupe, mais qui ne le sont plus.")
.setRequired(true),
),
)
.addSubcommand(
@ -185,10 +212,10 @@ export class EpitlsBot {
return;
}
const rules = [] as GuildRule[];
for (const { group_id, role_id } of this.rules.roles_for_guild(guild_id)) {
for (const { group_id, role_id, include_historical } of this.rules.roles_for_guild(guild_id)) {
const role = await interaction.guild!.roles.fetch(role_id);
const role_name = role?.name ?? "<DELETED>";
rules.push({ group_id, role_name });
rules.push({ group_id, role_name, include_historical });
}
await interaction.reply(message_command_response_rule_list_success(rules));
}
@ -203,11 +230,12 @@ export class EpitlsBot {
}
const group_id = interaction.options.getString("group", true);
const role = interaction.options.getRole("role", true);
const include_historical = interaction.options.getBoolean("incl_historical", true);
// TODO : test if role exists
const role_id = role.id;
const role_name = role.name;
await this.rules.append_rule(group_id, { guild_id, role_id });
await interaction.reply(message_command_response_rule_add_success({ group_id, role_name }));
await this.rules.append_rule(group_id, { guild_id, role_id }, include_historical);
await interaction.reply(message_command_response_rule_add_success({ group_id, role_name, include_historical }));
}
private async handle_command_rule_remove(interaction: ChatInputCommandInteraction<CacheType>) {
@ -221,10 +249,10 @@ export class EpitlsBot {
const group_id = interaction.options.getString("group", true);
const removed = await this.rules.remove_rules(group_id, guild_id);
const rules = [] as GuildRule[];
for (const { group_id, target_role: { role_id } } of removed) {
for (const { group_id, target_role: { role_id }, include_historical } of removed) {
const role = await interaction.guild!.roles.fetch(role_id);
const role_name = role?.name ?? "<DELETED>";
rules.push({ group_id, role_name });
rules.push({ group_id, role_name, include_historical });
}
await interaction.reply(message_command_response_rule_remove_success(rules));
}
@ -262,13 +290,12 @@ function message_command_response_list_error(msg: string) {
return { embeds: [embed] };
}
type GuildRule = { group_id: string; role_name: string };
type GuildRule = { group_id: string; role_name: string; include_historical: boolean };
function message_command_response_rule_list_success(rules: GuildRule[]) {
const rule_list = rules.map((r) => `- \`${r.group_id}\`\`@${r.role_name}\``).join("\n");
const embed = new EmbedBuilder()
.setTitle("`📚️`| Liste des règles")
.setDescription(`Règles d'associations groupe / rôle.
${rule_list}
${rules.map(display_rule).join("\n")}
`);
return { embeds: [embed] };
}
@ -277,17 +304,28 @@ function message_command_response_rule_add_success(rule: GuildRule) {
const embed = new EmbedBuilder()
.setTitle("`✅`| Règle ajouté")
.setDescription(`Règle d'association ajoutée :
- \`${rule.group_id}\`\`@${rule.role_name}\`
${display_rule(rule)}
`);
return { embeds: [embed] };
}
function message_command_response_rule_remove_success(rules: GuildRule[]) {
const rule_list = rules.map((r) => `- \`${r.group_id}\`\`@${r.role_name}\``).join("\n");
const embed = new EmbedBuilder()
.setTitle("`✅`| Règle ajouté")
.setDescription(`Règle d'association retirées :
${rule_list}
${rules.map(display_rule).join("\n")}
`);
return { embeds: [embed] };
}
function to_comparable(input: string) {
return input
.toLowerCase()
.normalize("NFD") // normalize accents
.replace(/\p{Diacritic}/gu, ""); // remotes accents
}
function display_rule(rule: GuildRule) {
if (rule.include_historical) return `- \`${rule.group_id}\` [H] → \`@${rule.role_name}\``;
else return `- \`${rule.group_id}\`\`@${rule.role_name}\``;
}