discord-buttons-react
Version:
A package which allow you to use buttons as reactions
282 lines (213 loc) • 11.3 kB
JavaScript
const { Structures, MessageEmbed } = require("discord.js");
const { resolveString } = require('discord.js').Util;
const db = require('quick.db');
let createEnum = (keys) => {
const obj = {};
for (const [index, key] of keys.entries()) {
if (key === null) continue;
obj[key] = index;
obj[index] = key;
}
return obj;
}
let MessageButtonStyles = createEnum([null, 'blurple', 'grey', 'green', 'red', 'url']);
let MessageButtonStylesAliases = createEnum([null, 'PRIMARY', 'SECONDARY', 'SUCCESS', 'DESTRUCTIVE', 'LINK']);
let resolveStyle = (style) => {
if (!style || style === undefined || style === null) throw new TypeError('NO_BUTTON_STYLE: Please provide button style');
if (style === 'gray') style = 'grey';
if ((!MessageButtonStyles[style]
||
MessageButtonStyles[style] === undefined
||
MessageButtonStyles[style] === null)
&&
(!MessageButtonStylesAliases[style]
||
MessageButtonStylesAliases[style] === undefined
||
MessageButtonStylesAliases[style] === null)) throw new TypeError('INVALID_BUTTON_STYLE: An invalid button styles was provided');
return typeof style === 'string' ? MessageButtonStyles[style] : style;
}
let randomID = () => {
let s4 = () => {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + '-' + s4() + '-' + s4();
}
let getButtonsFromComponents = (components) => {
const buttonsArray = [];
for (const ActionRow of components) {
for (const btn of ActionRow.components) {
buttonsArray.push(btn)
};
};
return buttonsArray;
}
let isEmoji = (string) => {
var regex = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g;
return regex.test(string)
}
class ReactionButton {
constructor(data = {}) {
//super({ type: 'BUTTON' });
this.setup(data);
}
setup(data) {
this.style = 'style' in data ? resolveStyle(data.style) : null;
this.emoji = 'emoji' in data ? data.emoji : undefined;
return this;
}
setStyle(style) {
style = resolveStyle(style);
if (style != "url") this.style = style
else (style = "gray")
return this;
}
setEmoji(emoji) {
if (isEmoji(resolveString(emoji)) === true) this.emoji = { name: resolveString(emoji) }
else if (emoji.id) this.emoji = { id: emoji.id }
else if (resolveString(emoji).length > 0) this.emoji = { id: resolveString(emoji) }
else this.emoji = { name: null, id: null };
return this;
}
toJSON() {
return {
style: this.style,
emoji: this.emoji,
}
}
}
module.exports = (client) => {
const { MessageButton, MessageActionRow } = require("discord-buttons");
client.on("clickButton", async button => {
let user = await button.clicker.user;
if (!db.get(`discord-buttons-react.${button.message.id}.${button.id}`)) return;
button.defer();
if (db.get(`discord-buttons-react.${button.message.id}`)[button.id]["clickers"].includes(user.id)) {
// editer le message avec le bouton -1
const buttonList = getButtonsFromComponents(button.message.components);
let indexClickedButton = buttonList.findIndex(btn => btn.custom_id == button.id);
let clickedButton = buttonList[indexClickedButton];
let newBtn = new MessageButton()
.setStyle(clickedButton.style)
.setLabel((parseInt(clickedButton.label, 10)-1).toString())
.setEmoji(clickedButton.emoji.id || clickedButton.emoji.name)
.setID(clickedButton.custom_id)
buttonList[indexClickedButton] = newBtn;
const buttonsRoleRow1 = [];
const buttonsRoleRow2 = [];
const buttonsRoleRow3 = [];
const buttonsRoleRow4 = [];
const buttonsRoleRow5 = [];
let i = 0;
for(let btn of buttonList) {
i++
if (i <=5) buttonsRoleRow1.push(btn)
else if (i>5 && i<=10) buttonsRoleRow2.push(btn)
else if (i>10 && i<=15) buttonsRoleRow3.push(btn)
else if (i>15 && i<=20) buttonsRoleRow4.push(btn)
else if (i>20 && i<=25) buttonsRoleRow5.push(btn)
else return;
};
const ListeRows = [];
if (buttonsRoleRow1.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow1));
if (buttonsRoleRow2.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow2));
if (buttonsRoleRow3.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow3));
if (buttonsRoleRow4.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow4));
if (buttonsRoleRow5.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow5));
button.message.edit(button.message.content, { components: ListeRows });
let clickerArray = db.get(`discord-buttons-react.${button.message.id}`)[button.id]["clickers"];
let index = clickerArray.indexOf(user.id);
if (index > -1) {
clickerArray.splice(index, 1);
};
db.set(`discord-buttons-react.${button.message.id}.${button.id}.clickers`, clickerArray);
client.emit('messageButtonReactionRemove', { clicker: button.clicker, message: button.message, reactionEmoji: clickedButton.emoji.name||clickedButton.emoji.id });
}
else {
db.push(`discord-buttons-react.${button.message.id}.${button.id}.clickers`, user.id);
const buttonList = getButtonsFromComponents(button.message.components);
let indexClickedButton = buttonList.findIndex(btn => btn.custom_id == button.id);
let clickedButton = buttonList[indexClickedButton];
let newBtn = new MessageButton()
.setStyle(clickedButton.style)
.setLabel((parseInt(clickedButton.label, 10)+1).toString())
.setEmoji(clickedButton.emoji.id || clickedButton.emoji.name)
.setID(clickedButton.custom_id)
buttonList[indexClickedButton] = newBtn;
const buttonsRoleRow1 = [];
const buttonsRoleRow2 = [];
const buttonsRoleRow3 = [];
const buttonsRoleRow4 = [];
const buttonsRoleRow5 = [];
let i = 0;
for(let btn of buttonList) {
i++
if (i <=5) buttonsRoleRow1.push(btn)
else if (i>5 && i<=10) buttonsRoleRow2.push(btn)
else if (i>10 && i<=15) buttonsRoleRow3.push(btn)
else if (i>15 && i<=20) buttonsRoleRow4.push(btn)
else if (i>20 && i<=25) buttonsRoleRow5.push(btn)
else return;
};
const ListeRows = [];
if (buttonsRoleRow1.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow1));
if (buttonsRoleRow2.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow2));
if (buttonsRoleRow3.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow3));
if (buttonsRoleRow4.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow4));
if (buttonsRoleRow5.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow5));
button.message.edit(button.message.content, { components: ListeRows });
client.emit('messageButtonReactionAdd', { clicker: button.clicker, message: button.message, reactionEmoji: clickedButton.emoji.name||clickedButton.emoji.id });
}
});
class TextChannel extends Structures.get("TextChannel") {
async createMessageReactionButton(content, ReactionButtons) {
const buttonsRoleRow1 = [];
const buttonsRoleRow2 = [];
const buttonsRoleRow3 = [];
const buttonsRoleRow4 = [];
const buttonsRoleRow5 = [];
const listID = [];
let i = 0;
for(let btn of ReactionButtons) {
i++
let ID = randomID();
listID.push(ID)
let bouton = new MessageButton().setStyle(btn.style).setID(ID)
if (btn.emoji) bouton.setEmoji(btn.emoji.name || btn.emoji.id);
bouton.setLabel("0");
if (!btn.label && !btn.emoji) throw new TypeError('DISCORD-BUTTONS-REACT: You must provide emoji and/or label');
if (i <=5) buttonsRoleRow1.push(bouton)
else if (i>5 && i<=10) buttonsRoleRow2.push(bouton)
else if (i>10 && i<=15) buttonsRoleRow3.push(bouton)
else if (i>15 && i<=20) buttonsRoleRow4.push(bouton)
else if (i>20 && i<=25) buttonsRoleRow5.push(bouton)
else return;
};
const ListeRows = [];
if (buttonsRoleRow1.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow1));
if (buttonsRoleRow2.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow2));
if (buttonsRoleRow3.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow3));
if (buttonsRoleRow4.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow4));
if (buttonsRoleRow5.length) ListeRows.push(new MessageActionRow().addComponents(buttonsRoleRow5));
let message;
if (content instanceof MessageEmbed) message = await this.send({ embed: content, components: ListeRows })
else message = await this.send(content, { components: ListeRows });
let listIDObject = {};
for (const Id of listID) {
listIDObject[Id] = {
active: true,
clickers: []
};
};
db.set(`discord-buttons-react.${message.id}`, listIDObject);
};
};
Structures.extend("TextChannel", () => TextChannel);
return {
ReactionButton: ReactionButton
};
};
module.exports.ReactionButton = ReactionButton;