diff --git a/.gitignore b/.gitignore index 4182a6b..812f9ff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ dist node_modules -config.json +config.toml diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/config.exemple.json b/config.exemple.json deleted file mode 100644 index ec5b9cd..0000000 --- a/config.exemple.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "token": "" -} diff --git a/config.exemple.toml b/config.exemple.toml new file mode 100644 index 0000000..e69de29 diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..22ce99d --- /dev/null +++ b/config.toml @@ -0,0 +1,77 @@ +token = "OTQyNDIwNjMwMjY2MDg1NDQ3.GoU3vp.2cT7Q7eFEqELfgQQzYJW0Kuss0FNc2WQT68KW0" + +[roles_picker.lang] +name = "lang" +message = "What languages do you speak?" +placeholder = "Add/Remove languages roles" + + [[roles_picker.lang.roles]] + name = "Français" + description = "Bonjour!" + role = "990751069011337246" + emoji = "🇫🇷" + + [[roles_picker.lang.roles]] + name = "English" + description = "Hello!" + role = "990751113626128446" + emoji = "🇺🇸" + + [[roles_picker.lang.roles]] + name = "中文" + description = "你好!" + role = "990751145049853953" + emoji = "🇨🇳" + +[roles_picker.color] +name = "color" +message = "Choose your favorite color" +placeholder = "Add/Remove color roles" + + [[roles_picker.color.roles]] + name = "Green" + description = "Green but not realy green" + role = 990751069011337246 + emoji = ":green_circle:" + + [[roles_picker.color.roles]] + name = "EELV (French politic party)" + description = "Europe Écologie Les Verts" + role = 990751113626128446 + emoji = ":evergreen_tree:" + + [[roles_picker.color.roles]] + name = "Purple" + description = "The Best Color" + role = 990751145049853953 + emoji = ":purple_circle:" + + [[roles_picker.color.roles]] + name = "Yellow" + description = "Disgusting color on light theme" + role = 990751145049853953 + emoji = ":yellow_circle:" + + [[roles_picker.color.roles]] + name = "Orange" + description = "Borring color" + role = 990751145049853953 + emoji = ":orange_circle:" + + [[roles_picker.color.roles]] + name = "Red" + description = "Too much iment" + role = 990751145049853953 + emoji = ":red_circle:" + + +[roles_picker.game] +name = "game" +message = "Which game do you play?" +placeholder = "Add/Remove gaming roles" + + [[roles_picker.game.roles]] + name = "Minecraft" + description = "Would you rather fight a hundred chicken_sized zombies or ten zombie_sized chickens?" + role = 990751069011337246 + emoji = "" diff --git a/package.json b/package.json index 882915a..98e2222 100644 --- a/package.json +++ b/package.json @@ -6,14 +6,15 @@ "license": "AGPL-3.0-only", "dependencies": { "discord.js": "^13.8.1", - "sheweny": "^3.4.3" + "sheweny": "^3.4.3", + "toml": "^3.0.0" }, "devDependencies": { "ts-node-dev": "^1.1.8", "typescript": "^4.5.4" }, "scripts": { - "build": "tsc", - "dev": "tsc && node dist/index.js" + "build": "rm -rf dist/ && tsc", + "dev": "yarn build && cp config.toml dist/config.toml && node dist/index.js" } } diff --git a/src/commands/create-role-picker.ts b/src/commands/create-role-picker.ts new file mode 100644 index 0000000..338cca2 --- /dev/null +++ b/src/commands/create-role-picker.ts @@ -0,0 +1,61 @@ +import {Command} from "sheweny"; +import type {ShewenyClient} from "sheweny"; +import {CommandInteraction, MessageActionRow, MessageSelectMenu} from "discord.js"; +import {Container} from "../container"; +import {Config} from "../config"; + +export class CreateRolePickerCommand extends Command { + constructor(client: ShewenyClient) { + const configuration = Container.container.get("config") + const rolePicker = configuration.roles_picker + const pickers = Object.keys(rolePicker) + + super(client, { + name: "create-role-picker", + description: "Send a role picker", + type: "SLASH_COMMAND", + category: "Tests", + options: [{ + name: "picker", + description: "name of the role picker", + type: "STRING", + required: true, + choices: pickers.map((name) => ({ + name: name, + value: name + })), + }] + }); + } + + execute(interaction: CommandInteraction) { + const pickerName = interaction.options.get("picker")?.value + if (typeof pickerName != "string") { + throw new Error("plop") + } + + const configuration = Container.container.get("config") + const rolePicker = configuration.roles_picker[pickerName] + + const role = rolePicker.roles + + const row = new MessageActionRow().addComponents( + new MessageSelectMenu() + .setMinValues(0) + .setMaxValues(role.length) + .setCustomId(`interaction-poc-${rolePicker.name}`) + .setPlaceholder(rolePicker.placeholder) + .addOptions( + role.map(({name, description, role, emoji}) => ({ + label: name, + description: description, + value: role, + emoji: emoji + }))) + ); + + interaction.channel?.send({content: rolePicker.message, components: [row]}) + + interaction.reply({content: "Command execute successfully :ok_hand:", ephemeral: true}) + } +} diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..7403b92 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,18 @@ +export interface Config { + token: string + roles_picker: Record +} + +interface RolePicker { + name: string, + message: string, + placeholder: string, + roles: Role[] +} + +interface Role { + name: string + description: string, + role: string, + emoji: string +} diff --git a/src/container.ts b/src/container.ts new file mode 100644 index 0000000..7acd5d1 --- /dev/null +++ b/src/container.ts @@ -0,0 +1,13 @@ +export class Container { + static container: Container + + instance: Record = [] + + set(key: string, value: T) { + this.instance[key] = value + } + + get(key: string): T { + return this.instance[key] + } +} diff --git a/src/index.ts b/src/index.ts index 11acb45..e8055d6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,21 +1,31 @@ import { ShewenyClient } from "sheweny"; -import { token } from "../config.json" +import {Container} from "./container"; +import {Config} from "./config"; +import * as TOML from "toml"; +import * as fs from "fs"; + +const configurationFile = fs.readFileSync("./config.toml").toString() +const configuration = TOML.parse(configurationFile) as Config + +const container = new Container() +container.set("config", configuration) +Container.container = container const client = new ShewenyClient({ - intents: ["GUILDS", "GUILD_MESSAGES"], - admins: ["611468402263064577"], - // managers: { - // commands: { - // directory: "./commands", - // prefix: "!", - // loadAll: true, - // autoRegisterApplicationCommands: true, - // }, - // events: { - // directory: "./events", - // loadAll: true, - // }, - // }, + intents: ["GUILDS", "GUILD_MEMBERS", "GUILD_MESSAGES"], + managers: { + commands: { + directory: "./commands", + guildId: "805896397873872906", + prefix: "!", + loadAll: true, + autoRegisterApplicationCommands: true, + }, + selectMenus: { + directory: "./interactions/select-menus", + loadAll: true + }, + }, }); -client.login(token) +client.login(configuration.token) diff --git a/src/interactions/select-menus/roles.ts b/src/interactions/select-menus/roles.ts new file mode 100644 index 0000000..1b6e5e6 --- /dev/null +++ b/src/interactions/select-menus/roles.ts @@ -0,0 +1,38 @@ +import {SelectMenu} from "sheweny"; +import type {ShewenyClient} from "sheweny"; +import type {SelectMenuInteraction} from "discord.js"; +import {GuildMemberRoleManager} from "discord.js"; +import {Container} from "../../container"; +import {Config} from "../../config"; + +export class Roles extends SelectMenu { + constructor(client: ShewenyClient) { + super(client, ["interaction-poc-lang"]); + } + + execute(selectMenu: SelectMenuInteraction) { + const memberRoles = selectMenu.member?.roles + const response: string[] = [] + + const container = Container.container + const config = container.get("config") + const picker = selectMenu.customId.split("-") + const roles = config.roles_picker[picker[picker.length - 1]].roles + + if (!(memberRoles instanceof GuildMemberRoleManager)) { + throw new Error("plop") + } + + roles.forEach(role => { + if (memberRoles.cache.has(role.role) && !selectMenu.values.includes(role.role)) { + memberRoles.remove(role.role) + response.push(`❌ Role ${role.name} remove`) + } else if (!memberRoles.cache.has(role.role) && selectMenu.values.includes(role.role)) { + memberRoles.add(role.role) + response.push(`✅ Role ${role.name} added`) + } + }) + + selectMenu.reply({content: response.join("\n"), ephemeral: true}) + } +} diff --git a/yarn.lock b/yarn.lock index d72bf70..a3df137 100644 --- a/yarn.lock +++ b/yarn.lock @@ -434,6 +434,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +toml@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" + integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"