command + select menu for role picker

This commit is contained in:
Aymeric GUERACAGUE 2022-06-30 13:44:54 +02:00
parent 19b9c3df43
commit 0ec999a4ed
Signed by: Superkooka
GPG Key ID: F78F2B172E894865
12 changed files with 243 additions and 23 deletions

2
.gitignore vendored
View File

@ -1,4 +1,4 @@
dist
node_modules
config.json
config.toml

0
README.md Normal file
View File

View File

@ -1,3 +0,0 @@
{
"token": ""
}

0
config.exemple.toml Normal file
View File

77
config.toml Normal file
View File

@ -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 = ""

View File

@ -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"
}
}

View File

@ -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>("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>("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})
}
}

18
src/config.ts Normal file
View File

@ -0,0 +1,18 @@
export interface Config {
token: string
roles_picker: Record<string, RolePicker>
}
interface RolePicker {
name: string,
message: string,
placeholder: string,
roles: Role[]
}
interface Role {
name: string
description: string,
role: string,
emoji: string
}

13
src/container.ts Normal file
View File

@ -0,0 +1,13 @@
export class Container {
static container: Container
instance: Record<string, any> = []
set<T>(key: string, value: T) {
this.instance[key] = value
}
get<T>(key: string): T {
return this.instance[key]
}
}

View File

@ -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)

View File

@ -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>("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})
}
}

View File

@ -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"