Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

discord-buttons

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

discord-buttons - npm Package Compare versions

Comparing version 3.2.1 to 4.0.0

.github/FUNDING.yml

13

package.json
{
"name": "discord-buttons",
"version": "3.2.1",
"version": "4.0.0",
"description": "Discord.js buttons",
"main": "src/index.js",
"types": "typings/index.d.ts",
"scripts": {
"format": "prettier --write \"typings/*.ts\" \"src/**/*.js\"",
"version": "npm run format"
},
"funding": {

@@ -26,11 +30,12 @@ "type": "individual",

"type": "git",
"url": "git+https://github.com/AngeloCore/discord-buttons.git"
"url": "git+https://github.com/discord-buttons/discord-buttons.git"
},
"bugs": {
"url": "https://github.com/AngeloCore/discord-buttons/issues"
"url": "https://github.com/discord-buttons/discord-buttons/issues"
},
"homepage": "https://discord-buttons.js.org",
"devDependencies": {
"@types/node": "^15.3.0"
"@types/node": "^15.3.0",
"prettier": "^2.3.2"
}
}

@@ -1,56 +0,92 @@

const { Structures, Client } = require("discord.js");
const { Structures, Client } = require('discord.js');
const MessageComponent = require('./v12/Classes/MessageComponent');
const TextChannel = require('./v12/Classes/TextChannel');
const DMChannel = require('./v12/Classes/DMChannel');
const NewsChannel = require('./v12/Classes/NewsChannel');
const Message = require('./v12/Classes/Message');
const { MessageComponentTypes } = require('./v12/Constants');
var version = require('discord.js').version.split('');
if (version.includes('(')) {
version = version.join('').split('(').pop().split('');
}
version = parseInt(version[0] + version[1]);
module.exports = (client) => {
if (version != 12) {
throw new Error('The discord.js version must be v12 or high');
}
const { Events } = require('discord.js').Constants;
if (!client || !client instanceof Client) throw new Error("INVALID_CLIENT_PROVIDED: The Discord.js Client isn't provided or it's invalid.");
Events.CLICK_BUTTON = 'clickButton';
const message = Structures.get('Message');
if (!message.createButtonCollector || typeof message.createButtonCollector !== 'function') {
Structures.extend('TextChannel', () => TextChannel);
Structures.extend('DMChannel', () => DMChannel);
Structures.extend('NewsChannel', () => NewsChannel);
Structures.extend('Message', () => Message);
}
if (version < 11 || version === 11) {
throw new Error('The discord.js version must be v12 or high');
client.ws.on('INTERACTION_CREATE', (data) => {
if (!data.data.component_type) return;
switch (data.data.component_type) {
case MessageComponentTypes.BUTTON:
client.emit('clickButton', new MessageComponent(client, data));
break;
case MessageComponentTypes.SELECT_MENU:
client.emit('clickMenu', new MessageComponent(client, data, true));
break;
default:
client.emit('debug', `Got unknown interaction component type, ${data.data.component_type}`);
break;
}
});
};
if (!client || !client instanceof Client) throw new Error("INVALID_CLIENT_PROVIDED: The discord.js client is not provided or is invalid...")
module.exports.multipleImport = (...clients) => {
if (version != 12) {
throw new Error('The discord.js version must be v12 or high');
}
const TextChannel = require('./v12/Classes/TextChannel');
const DMChannel = require('./v12/Classes/DMChannel');
const NewsChannel = require('./v12/Classes/NewsChannel');
const message = Structures.get('Message');
if (!message.createButtonCollector || typeof message.createButtonCollector !== 'function') {
Structures.extend('TextChannel', () => TextChannel);
Structures.extend('DMChannel', () => DMChannel);
Structures.extend('NewsChannel', () => NewsChannel);
Structures.extend('Message', () => Message);
}
if (version === 12) {
const Message = require('./v12/Classes/Message');
Structures.extend('Message', () => Message);
} else if (version === 13) {
const Message = require('./v13/Classes/Message');
const CommandInteraction = require('./v13/Classes/CommandInteraction');
Structures.extend('Message', () => Message);
Structures.extend('CommandInteraction', () => CommandInteraction);
}
clients.forEach((client) => {
if (!client || !client instanceof Client) throw new Error("INVALID_CLIENT_PROVIDED: The Discord.js Client isn't provided or it's invalid.");
client.ws.on('INTERACTION_CREATE', (data) => {
if (!data.data.component_type) return;
if (!data.message) return;
switch (data.data.component_type) {
case MessageComponentTypes.BUTTON:
client.emit('clickButton', new MessageComponent(client, data));
break;
if (data.data.component_type) {
const MessageComponent = require('./v12/Classes/clickButton');
const button = new MessageComponent(client, data);
client.emit('clickButton', button);
}
case MessageComponentTypes.SELECT_MENU:
client.emit('clickMenu', new MessageComponent(client, data, true));
break;
default:
client.emit('debug', `Got unknown interaction component type, ${data.data.component_type}`);
break;
}
});
});
};
return;
}
module.exports.MessageButton = require(`./v${version}/Classes/MessageButton`);
module.exports.MessageButton = require(`./v12/Classes/MessageButton`);
module.exports.MessageMenu = require(`./v12/Classes/MessageMenu`);
module.exports.MessageMenuOption = require(`./v12/Classes/MessageMenuOption`);
module.exports.MessageActionRow = require('./v12/Classes/MessageActionRow');
module.exports.ButtonInteraction = require('./v12/Classes/clickButton');
module.exports.Message = require(`./v${version}/Classes/Message`);
module.exports.ButtonCollector = require(`./v${version}/Classes/ButtonCollector`);
module.exports.MessageComponent = require('./v12/Classes/MessageComponent');
module.exports.Message = require(`./v12/Classes/Message`);
module.exports.ButtonCollector = require(`./v12/Classes/ButtonCollector`);
module.exports.MenuCollector = require(`./v12/Classes/MenuCollector`);
module.exports.APIMessage = require('./v12/Classes/APIMessage').APIMessage;

@@ -64,2 +100,2 @@ module.exports.sendAPICallback = require('./v12/Classes/APIMessage').sendAPICallback;

module.exports.Constants = require('./v12/Constants');
version === 13 ? module.exports.CommandInteraction = require('./v13/Classes/CommandInteraction') : null
module.exports.InteractionReply = require(`./v12/Classes/managers/InteractionReply`);

@@ -1,2 +0,2 @@

const { APIMessage: dAPIMessage, MessageEmbed } = require("discord.js");
const { APIMessage: dAPIMessage, MessageEmbed } = require('discord.js');
const Util = require('../Util');

@@ -6,210 +6,308 @@ const { MessageComponentTypes } = require('../Constants.js');

const MessageActionRow = require('./MessageActionRow');
const MessageButton = require('./MessageButton');
const MessageMenu = require('./MessageMenu');
class sendAPICallback extends dAPIMessage {
resolveData() {
resolveData() {
if (this.data) {
return this;
}
if (this.data) {
return this;
}
super.resolveData();
if (typeof (this.options.content) === 'object') {
this.options = this.options.content;
this.options.content = null;
}
if (this.options.content instanceof MessageEmbed) {
this.data.embed = this.options.content;
this.data.embeds.push(this.options.content);
this.data.content = undefined;
}
super.resolveData();
if (this.options.flags) {
this.data.flags = parseInt(this.options.flags);
}
if (this.options.content instanceof MessageEmbed) {
this.data.embed = this.options.content;
this.data.content = null;
}
if (typeof this.options.ephemeral === 'boolean' && this.options.ephemeral === true) {
this.data.flags = 64;
}
if (this.options.flags) {
this.data.flags = parseInt(this.options.flags);
}
let components = [];
let hasActionRow = false;
let hasComponent = false;
if (MessageComponentTypes[this.options.type]) {
hasComponent = true;
if (this.options.type === MessageComponentTypes.ACTION_ROW) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: this.options.components.map((b) =>
BaseMessageComponent.create(b.type === MessageComponentTypes.BUTTON ? Util.resolveButton(b) : Util.resolveMenu(b)),
),
});
hasActionRow = true;
} else if (this.options.type === MessageComponentTypes.BUTTON) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: [BaseMessageComponent.create(Util.resolveButton(this.options))],
});
} else if (this.options.type === MessageComponentTypes.SELECT_MENU) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: [BaseMessageComponent.create(Util.resolveMenu(this.options))],
});
}
}
if (typeof (this.options.ephemeral) === 'boolean' && this.options.ephemeral === true) {
this.data.flags = 64;
}
if (this.options.component) {
hasComponent = true;
if (this.options.component instanceof MessageActionRow) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: this.options.component.components.map((b) =>
BaseMessageComponent.create(b.type === MessageComponentTypes.BUTTON ? Util.resolveButton(b) : Util.resolveMenu(b)),
),
});
} else if (this.options.component instanceof MessageButton) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: [BaseMessageComponent.create(Util.resolveButton(this.options.component))],
});
} else if (this.options.component instanceof MessageMenu) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: [BaseMessageComponent.create(Util.resolveMenu(this.options.component))],
});
}
}
let components = [];
let hasActionRow = false;
if (MessageComponentTypes[this.options.type]) {
if (this.options.type === MessageComponentTypes.ACTION_ROW) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: this.options.components.map(b => BaseMessageComponent.create(Util.resolveButton(b)))
});
hasActionRow = true;
} else {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: [BaseMessageComponent.create(Util.resolveButton(this.options))]
});
}
}
if (this.options.components) {
hasComponent = true;
if (Array.isArray(this.options.components)) {
if (hasActionRow === false) {
components.push(
...this.options.components.map((c) => {
let buttons = [];
if (this.options.component) {
buttons.push(
...c.components.map((b) =>
BaseMessageComponent.create(b.type === MessageComponentTypes.BUTTON ? Util.resolveButton(b) : Util.resolveMenu(b)),
),
);
if (this.options.component instanceof MessageActionRow) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: this.options.component.components.map(b => BaseMessageComponent.create(Util.resolveButton(b)))
});
} else {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: [BaseMessageComponent.create(Util.resolveButton(this.options.component))]
});
}
return {
type: MessageComponentTypes.ACTION_ROW,
components: buttons,
};
}),
);
}
} else {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: this.options.components.components.map((b) =>
BaseMessageComponent.create(b.type === MessageComponentTypes.BUTTON ? Util.resolveButton(b) : Util.resolveMenu(b)),
),
});
}
}
if (this.options.components) {
if (this.options.buttons) {
hasComponent = true;
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: Array.isArray(this.options.buttons)
? this.options.buttons.map((b) => BaseMessageComponent.create(Util.resolveButton(b)))
: [BaseMessageComponent.create(Util.resolveButton(this.options.buttons))],
});
}
if (Array.isArray(this.options.components)) {
if (hasActionRow === false) {
components.push(...this.options.components.map(c => {
let buttons = [];
if (this.options.button) {
hasComponent = true;
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: Array.isArray(this.options.button)
? this.options.button.map((b) => BaseMessageComponent.create(Util.resolveButton(b)))
: [BaseMessageComponent.create(Util.resolveButton(this.options.button))],
});
}
buttons.push(...c.components.map(b => BaseMessageComponent.create(Util.resolveButton(b))));
if (this.options.menus) {
hasComponent = true;
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: Array.isArray(this.options.menus)
? this.options.menus.map((b) => BaseMessageComponent.create(Util.resolveMenu(b)))
: [BaseMessageComponent.create(Util.resolveMenu(this.options.menus))],
});
}
return {
type: MessageComponentTypes.ACTION_ROW,
components: buttons
}
}));
}
} else {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: this.options.components.components.map(b => BaseMessageComponent.create(Util.resolveButton(b)))
})
}
}
if (this.options.menu) {
hasComponent = true;
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: Array.isArray(this.options.menus)
? this.options.menus.map((b) => BaseMessageComponent.create(Util.resolveMenu(b)))
: [BaseMessageComponent.create(Util.resolveMenu(this.options.menus))],
});
}
if (this.options.buttons) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: Array.isArray(this.options.buttons) ? this.options.buttons.map(b => BaseMessageComponent.create(Util.resolveButton(b))) : [BaseMessageComponent.create(Util.resolveButton(this.options.buttons))]
});
}
if (this.options.components === null || this.options.component === null || this.options.buttons === null || this.options.button === null) {
hasComponent = true;
components = [];
}
if (this.options.button) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: Array.isArray(this.options.button) ? this.options.button.map(b => BaseMessageComponent.create(Util.resolveButton(b))) : [BaseMessageComponent.create(Util.resolveButton(this.options.button))]
});
}
if (typeof components.length == 'number') {
if (hasComponent === true) this.data.components = components.length === 0 ? [] : components;
}
if (this.options === null && !this.options === undefined) components = [];
if (typeof components.length == 'number') {
this.data.components = components.length === 0 ? [] : components;
}
return this;
}
return this;
}
}
class APIMessage extends dAPIMessage {
resolveData() {
resolveData() {
if (this.data) {
return this;
}
if (this.data) {
return this;
}
super.resolveData();
if (typeof (this.options.content) === 'object') {
this.options = this.options.content;
this.options.content = null;
}
if (this.options.content instanceof MessageEmbed) {
this.data.embed = this.options.content;
this.data.embeds.push(this.options.content);
this.data.content = undefined;
}
super.resolveData();
let components = [];
let hasActionRow = false;
let hasComponent = false;
if (MessageComponentTypes[this.options.type]) {
hasComponent = true;
if (this.options.type === MessageComponentTypes.ACTION_ROW) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: this.options.components.map((b) =>
BaseMessageComponent.create(b.type === MessageComponentTypes.BUTTON ? Util.resolveButton(b) : Util.resolveMenu(b)),
),
});
hasActionRow = true;
} else if (this.options.type === MessageComponentTypes.BUTTON) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: [BaseMessageComponent.create(Util.resolveButton(this.options))],
});
} else if (this.options.type === MessageComponentTypes.SELECT_MENU) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: [BaseMessageComponent.create(Util.resolveMenu(this.options))],
});
}
}
if (this.options.content instanceof MessageEmbed) {
this.data.embed = this.options.content;
this.data.content = null;
}
if (this.options.component) {
hasComponent = true;
if (this.options.component instanceof MessageActionRow) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: this.options.component.components.map((b) =>
BaseMessageComponent.create(b.type === MessageComponentTypes.BUTTON ? Util.resolveButton(b) : Util.resolveMenu(b)),
),
});
} else if (this.options.component instanceof MessageButton) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: [BaseMessageComponent.create(Util.resolveButton(this.options.component))],
});
} else if (this.options.component instanceof MessageMenu) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: [BaseMessageComponent.create(Util.resolveMenu(this.options.component))],
});
}
}
let components = [];
let hasActionRow = false;
if (MessageComponentTypes[this.options.type]) {
if (this.options.type === MessageComponentTypes.ACTION_ROW) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: this.options.components.map(b => BaseMessageComponent.create(Util.resolveButton(b)))
});
hasActionRow = true;
} else {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: [BaseMessageComponent.create(Util.resolveButton(this.options))]
});
}
}
if (this.options.components) {
hasComponent = true;
if (Array.isArray(this.options.components)) {
if (hasActionRow === false) {
components.push(
...this.options.components.map((c) => {
let buttons = [];
if (this.options.component) {
buttons.push(
...c.components.map((b) =>
BaseMessageComponent.create(b.type === MessageComponentTypes.BUTTON ? Util.resolveButton(b) : Util.resolveMenu(b)),
),
);
if (this.options.component instanceof MessageActionRow) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: this.options.component.components.map(b => BaseMessageComponent.create(Util.resolveButton(b)))
});
} else {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: [BaseMessageComponent.create(Util.resolveButton(this.options.component))]
});
}
return {
type: MessageComponentTypes.ACTION_ROW,
components: buttons,
};
}),
);
}
} else {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: this.options.components.components.map((b) =>
BaseMessageComponent.create(b.type === MessageComponentTypes.BUTTON ? Util.resolveButton(b) : Util.resolveMenu(b)),
),
});
}
}
if (this.options.components) {
if (this.options.buttons) {
hasComponent = true;
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: Array.isArray(this.options.buttons)
? this.options.buttons.map((b) => BaseMessageComponent.create(Util.resolveButton(b)))
: [BaseMessageComponent.create(Util.resolveButton(this.options.buttons))],
});
}
if (Array.isArray(this.options.components)) {
if (hasActionRow === false) {
components.push(...this.options.components.map(c => {
let buttons = [];
if (this.options.button) {
hasComponent = true;
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: Array.isArray(this.options.button)
? this.options.button.map((b) => BaseMessageComponent.create(Util.resolveButton(b)))
: [BaseMessageComponent.create(Util.resolveButton(this.options.button))],
});
}
buttons.push(...c.components.map(b => BaseMessageComponent.create(Util.resolveButton(b))));
if (this.options.menus) {
hasComponent = true;
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: Array.isArray(this.options.menus)
? this.options.menus.map((b) => BaseMessageComponent.create(Util.resolveMenu(b)))
: [BaseMessageComponent.create(Util.resolveMenu(this.options.menus))],
});
}
return {
type: MessageComponentTypes.ACTION_ROW,
components: buttons
}
}));
}
} else {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: this.options.components.components.map(b => BaseMessageComponent.create(Util.resolveButton(b)))
})
}
}
if (this.options.menu) {
hasComponent = true;
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: Array.isArray(this.options.menus)
? this.options.menus.map((b) => BaseMessageComponent.create(Util.resolveMenu(b)))
: [BaseMessageComponent.create(Util.resolveMenu(this.options.menus))],
});
}
if (this.options.buttons) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: Array.isArray(this.options.buttons) ? this.options.buttons.map(b => BaseMessageComponent.create(Util.resolveButton(b))) : [BaseMessageComponent.create(Util.resolveButton(this.options.buttons))]
});
}
if (this.options.components === null || this.options.component === null || this.options.buttons === null || this.options.button === null) {
hasComponent = true;
components = [];
}
if (this.options.button) {
components.push({
type: MessageComponentTypes.ACTION_ROW,
components: Array.isArray(this.options.button) ? this.options.button.map(b => BaseMessageComponent.create(Util.resolveButton(b))) : [BaseMessageComponent.create(Util.resolveButton(this.options.button))]
});
}
if (typeof components.length == 'number') {
if (hasComponent === true) this.data.components = components.length === 0 ? [] : components;
}
if (this.options === null && !this.options === undefined) components = [];
if (typeof components.length == 'number') {
this.data.components = components.length === 0 ? [] : components;
}
return this;
}
return this;
}
}
module.exports = {
sendAPICallback,
APIMessage
}
sendAPICallback,
APIMessage,
};

@@ -1,2 +0,2 @@

const { Collector } = require("discord.js");
const { Collector } = require('discord.js');
const Collection = require('discord.js').Collection;

@@ -88,2 +88,2 @@ const { Events } = require('discord.js').Constants;

module.exports = ButtonCollector;
module.exports = ButtonCollector;

@@ -6,29 +6,27 @@ const DMChannel = require('discord.js').Structures.get('DMChannel');

class ExtendedDMChannel extends DMChannel {
async send(content, options) {
const User = Structures.get('User');
const GuildMember = Structures.get('GuildMember');
async send(content, options) {
const User = Structures.get('User');
const GuildMember = Structures.get('GuildMember');
if (this instanceof User || this instanceof GuildMember) {
return this.createDM().then(dm => dm.send(content, options));
}
if (this instanceof User || this instanceof GuildMember) {
return this.createDM().then((dm) => dm.send(content, options));
}
let apiMessage;
let apiMessage;
if (content instanceof APIMessage) {
apiMessage = content.resolveData();
} else {
apiMessage = APIMessage.create(this, content, options).resolveData();
}
if (content instanceof APIMessage) {
apiMessage = content.resolveData();
} else {
apiMessage = APIMessage.create(this, content, options).resolveData();
}
if (Array.isArray(apiMessage.data.content)) {
return Promise.all(apiMessage.data.content.map(this.send.bind(this)));
}
if (Array.isArray(apiMessage.data.content)) {
return Promise.all(apiMessage.data.content.map(this.send.bind(this)));
}
const { data, files } = await apiMessage.resolveFiles();
return this.client.api.channels[this.id].messages
.post({ data, files })
.then(d => this.client.actions.MessageCreate.handle(d).message);
}
const { data, files } = await apiMessage.resolveFiles();
return this.client.api.channels[this.id].messages.post({ data, files }).then((d) => this.client.actions.MessageCreate.handle(d).message);
}
}
module.exports = ExtendedDMChannel;
module.exports = ExtendedDMChannel;

@@ -5,31 +5,38 @@ const { MessageComponentTypes } = require('../../Constants');

class BaseMessageComponent {
constructor(data) {
this.type = 'type' in data ? resolveType(data.type) : null;
constructor(data) {
this.type = 'type' in data ? resolveType(data.type) : null;
}
static create(data) {
let component;
if (typeof data.type === 'string' && !data.type === 'SELECT_MENU_OPTION') {
type = MessageComponentTypes[type];
}
static create(data) {
let component;
if (typeof (data.type) === 'string') {
type = MessageComponentTypes[type];
}
switch (data.type) {
case MessageComponentTypes.ACTION_ROW: {
const MessageActionRow = require('../MessageActionRow');
component = new MessageActionRow(data);
break;
}
case MessageComponentTypes.BUTTON: {
const MessageButton = require('../MessageButton');
component = new MessageButton(data);
break;
}
default:
throw new SyntaxError('INVALID_TYPE: Invalid MessageComponentType');
}
return component;
switch (data.type) {
case MessageComponentTypes.ACTION_ROW: {
const MessageActionRow = require('../MessageActionRow');
component = new MessageActionRow(data).toJSON();
break;
}
case MessageComponentTypes.BUTTON: {
const MessageButton = require('../MessageButton');
component = new MessageButton(data).toJSON();
break;
}
case MessageComponentTypes.SELECT_MENU: {
const MessageMenu = require('../MessageMenu');
component = new MessageMenu(data).toJSON();
break;
}
case 'SELECT_MENU_OPTION': {
const MessageMenuOption = require('../MessageMenuOption');
component = new MessageMenuOption(data).toJSON();
break;
}
}
return component;
}
}
module.exports = BaseMessageComponent;
module.exports = BaseMessageComponent;

@@ -1,3 +0,4 @@

const Message = require("discord.js").Structures.get('Message');
const Message = require('discord.js').Structures.get('Message');
const ButtonCollector = require('./ButtonCollector');
const MenuCollector = require('./MenuCollector');
const APIMessage = require('./APIMessage').APIMessage;

@@ -7,49 +8,63 @@ const BaseMessageComponent = require('./interfaces/BaseMessageComponent');

class ExtendedMessage extends Message {
_patch(data) {
super._patch(data);
this.components = (data.components || []).map(c => BaseMessageComponent.create(c, this.client));
return this;
_patch(data) {
super._patch(data);
if (data.components && Array.isArray(data.components) && data.components.length > 0) {
this.components = data.components.map((c) => BaseMessageComponent.create(c));
} else {
this.components = [];
}
return this;
}
createButtonCollector(filter, options = {}) {
return new ButtonCollector(this, filter, options);
}
createButtonCollector(filter, options = {}) {
return new ButtonCollector(this, filter, options);
}
awaitButtons(filter, options = {}) {
return new Promise((resolve, reject) => {
const collector = this.createButtonCollector(filter, options);
collector.once('end', (buttons, reason) => {
if (options.errors && options.errors.includes(reason)) {
reject(buttons);
} else {
resolve(buttons);
}
});
})
}
awaitButtons(filter, options = {}) {
return new Promise((resolve, reject) => {
const collector = this.createButtonCollector(filter, options);
collector.once('end', (buttons, reason) => {
if (options.errors && options.errors.includes(reason)) {
reject(buttons);
} else {
resolve(buttons);
}
});
});
}
reply(content, options) {
return this.channel.send(
content instanceof APIMessage
? content
: APIMessage.transformOptions(content, options, { reply: this.member || this.author }),
);
}
createMenuCollector(filter, options = {}) {
return new MenuCollector(this, filter, options);
}
edit(content, options = {}) {
if (this.components.length > 0 && options !== null && options.component === undefined && options.components === undefined) {
options.components = this.components.map(c => BaseMessageComponent.create(c, this.client));
awaitMenus(filter, options = {}) {
return new Promise((resolve, reject) => {
const collector = this.createMenuCollector(filter, options);
collector.once('end', (menus, reason) => {
if (options.errors && options.errors.includes(reason)) {
reject(menus);
} else {
resolve(menus);
}
const { data } =
content instanceof APIMessage ? content.resolveData() : APIMessage.create(this, content, options).resolveData();
return this.client.api.channels[this.channel.id].messages[this.id].patch({ data }).then(d => {
const clone = this._clone();
clone._patch(d);
return clone;
});
}
});
});
}
reply(content, options) {
return this.channel.send(
content instanceof APIMessage ? content : APIMessage.transformOptions(content, options, { reply: this.member || this.author }),
);
}
edit(content, options) {
if (options === null && options !== undefined) options = { components: null };
const { data } = content instanceof APIMessage ? content.resolveData() : APIMessage.create(this, content, options).resolveData();
return this.client.api.channels[this.channel.id].messages[this.id].patch({ data }).then((d) => {
const clone = this._clone();
clone._patch(d);
return clone;
});
}
}
module.exports = ExtendedMessage;
module.exports = ExtendedMessage;

@@ -0,41 +1,60 @@

const MessageButton = require('./MessageButton');
const MessageMenu = require('./MessageMenu');
const { MessageComponentTypes } = require('../Constants');
const BaseMessageComponent = require('./interfaces/BaseMessageComponent');
class MessageActionRow extends BaseMessageComponent {
class MessageActionRow extends BaseMessageComponent {
constructor(data = {}) {
super({ type: 'ACTION_ROW' });
this.setup(data);
}
constructor(data = {}) {
super({ type: 'ACTION_ROW' });
this.setup(data);
setup(data) {
if ('component' in data) {
this.component = BaseMessageComponent.create(component);
}
setup(data) {
if ('component' in data) {
this.component = BaseMessageComponent.create(component, null, true);
}
this.components = [];
if ('components' in data) {
this.components = data.components.map(c => BaseMessageComponent.create(c, null, true));
}
return this;
this.components = [];
if ('components' in data) {
this.components = data.components.map((c) => BaseMessageComponent.create(c));
}
addComponents(...components) {
this.components.push(...components.flat(2).map(c => BaseMessageComponent.create(c, null, true)));
return this;
}
return this;
}
addComponent(component) {
return this.addComponents(component);
}
addComponents(...components) {
this.components.push(...components.flat(Infinity).map((c) => BaseMessageComponent.create(c)));
return this;
}
toJSON() {
return {
components: this.components.map(c => c.toJSON()),
type: MessageComponentTypes[this.type],
};
}
addComponent(component) {
return this.addComponents(component);
}
removeComponents(index, deleteCount, ...components) {
this.components.splice(index, deleteCount, ...components.flat(Infinity).map((c) => BaseMessageComponent.create(c)));
return this;
}
toJSON() {
return {
components: this.components
? this.components.map((c) => {
if (c instanceof MessageButton || c instanceof MessageMenu) {
return c;
} else {
switch (c.type) {
case MessageComponentTypes.BUTTON:
return new MessageButton(c);
case MessageComponentTypes.SELECT_MENU:
return new MessageMenu(c);
}
}
})
: [],
type: MessageComponentTypes[this.type],
};
}
}
module.exports = MessageActionRow;
const { MessageComponentTypes } = require('../Constants.js');
const BaseMessageComponent = require('./interfaces/BaseMessageComponent');
const { resolveString } = require('discord.js').Util;
const { resolveStyle, isEmoji } = require('../Util');
const { resolveStyle } = require('../Util');
class MessageButton extends BaseMessageComponent {
constructor(data = {}) {
super({ type: 'BUTTON' });
this.setup(data);
}
constructor(data = {}) {
super({ type: 'BUTTON' });
this.setup(data);
}
setup(data) {
this.style = 'style' in data ? resolveStyle(data.style) : null;
setup(data) {
this.label = 'label' in data && data.label ? resolveString(data.label) : undefined;
this.style = 'style' in data ? resolveStyle(data.style) : null;
this.disabled = 'disabled' in data ? data.disabled : false;
this.label = ('label' in data && data.label) ? resolveString(data.label) : undefined;
if (data.emoji) this.setEmoji(data.emoji);
this.disabled = 'disabled' in data ? data.disabled : false;
if ('url' in data && data.url) this.url = resolveString(data.url);
else this.url = undefined;
this.emoji = 'emoji' in data ? data.emoji : undefined;
if (('id' in data && data.id) || ('custom_id' in data && data.custom_id)) this.custom_id = data.id || data.custom_id;
else this.custom_id = undefined;
if ('url' in data && data.url)
this.url = resolveString(data.url)
else this.url = undefined;
return this;
}
if (('id' in data && data.id) || ('custom_id' in data && data.custom_id))
this.custom_id = data.id || data.custom_id;
else this.custom_id = undefined
setStyle(style) {
style = resolveStyle(style);
this.style = style;
return this;
}
return this;
}
setLabel(label) {
label = resolveString(label);
this.label = label;
return this;
}
setStyle(style) {
style = resolveStyle(style);
this.style = style;
return this;
}
setDisabled(disabled) {
if (disabled === false) this.disabled = false;
else this.disabled = true;
return this;
}
setLabel(label) {
label = resolveString(label);
this.label = label;
return this;
}
setURL(url) {
this.url = resolveString(url);
return this;
}
setDisabled(disabled = true) {
this.disabled = disabled;
return this;
}
setID(id) {
this.custom_id = resolveString(id);
return this;
}
setURL(url) {
this.url = resolveString(url);
return this;
}
setEmoji(emoji, animated) {
if (!emoji) throw new Error('MISSING_EMOJI: On this option was used `.setEmoji` method without emoji');
setID(id) {
this.custom_id = resolveString(id);
return this;
}
this.emoji = {
id: undefined,
name: undefined,
};
setEmoji(emoji, animated) {
if (!emoji) return this;
if (isEmoji(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 };
if ((animated && typeof (animated) !== 'boolean') || (emoji.animated && typeof (emoji.animated) !== 'boolean')) throw new SyntaxError('The emoji animated option must be boolean');
if (this.emoji && typeof (emoji.animated) === 'boolean') this.emoji.animated = emoji.animated;
if (this.emoji && typeof (animated) === 'boolean') this.emoji.animated = animated;
return this;
}
if (!isNaN(emoji)) this.emoji.id = emoji;
if (!isNaN(emoji.id)) this.emoji.id = emoji.id;
if (emoji.name) this.emoji.name = emoji.name;
toJSON() {
return {
type: MessageComponentTypes.BUTTON,
style: this.style,
label: this.label,
emoji: this.emoji,
disabled: this.disabled,
url: this.url,
custom_id: this.custom_id
}
}
if (!this.emoji.id && !this.emoji.name) this.emoji.name = emoji;
if (typeof animated === 'boolean') this.emoji.animated = animated;
return this;
}
toJSON() {
return {
type: MessageComponentTypes.BUTTON,
style: this.style,
label: this.label,
emoji: this.emoji,
disabled: this.disabled,
url: this.url,
custom_id: this.custom_id,
};
}
}
module.exports = MessageButton;
module.exports = MessageButton;

@@ -6,29 +6,27 @@ const NewsChannel = require('discord.js').Structures.get('NewsChannel');

class ExtendedNewsChannel extends NewsChannel {
async send(content, options) {
const User = Structures.get('User');
const GuildMember = Structures.get('GuildMember');
async send(content, options) {
const User = Structures.get('User');
const GuildMember = Structures.get('GuildMember');
if (this instanceof User || this instanceof GuildMember) {
return this.createDM().then(dm => dm.send(content, options));
}
if (this instanceof User || this instanceof GuildMember) {
return this.createDM().then((dm) => dm.send(content, options));
}
let apiMessage;
let apiMessage;
if (content instanceof APIMessage) {
apiMessage = content.resolveData();
} else {
apiMessage = APIMessage.create(this, content, options).resolveData();
}
if (content instanceof APIMessage) {
apiMessage = content.resolveData();
} else {
apiMessage = APIMessage.create(this, content, options).resolveData();
}
if (Array.isArray(apiMessage.data.content)) {
return Promise.all(apiMessage.data.content.map(this.send.bind(this)));
}
if (Array.isArray(apiMessage.data.content)) {
return Promise.all(apiMessage.data.content.map(this.send.bind(this)));
}
const { data, files } = await apiMessage.resolveFiles();
return this.client.api.channels[this.id].messages
.post({ data, files })
.then(d => this.client.actions.MessageCreate.handle(d).message);
}
const { data, files } = await apiMessage.resolveFiles();
return this.client.api.channels[this.id].messages.post({ data, files }).then((d) => this.client.actions.MessageCreate.handle(d).message);
}
}
module.exports = ExtendedNewsChannel;
module.exports = ExtendedNewsChannel;

@@ -6,29 +6,27 @@ const TextChannel = require('discord.js').Structures.get('TextChannel');

class ExtendedTextChannel extends TextChannel {
async send(content, options) {
const User = Structures.get('User');
const GuildMember = Structures.get('GuildMember');
async send(content, options) {
const User = Structures.get('User');
const GuildMember = Structures.get('GuildMember');
if (this instanceof User || this instanceof GuildMember) {
return this.createDM().then(dm => dm.send(content, options));
}
if (this instanceof User || this instanceof GuildMember) {
return this.createDM().then((dm) => dm.send(content, options));
}
let apiMessage;
let apiMessage;
if (content instanceof APIMessage) {
apiMessage = content.resolveData();
} else {
apiMessage = APIMessage.create(this, content, options).resolveData();
}
if (content instanceof APIMessage) {
apiMessage = content.resolveData();
} else {
apiMessage = APIMessage.create(this, content, options).resolveData();
}
if (Array.isArray(apiMessage.data.content)) {
return Promise.all(apiMessage.data.content.map(this.send.bind(this)));
}
if (Array.isArray(apiMessage.data.content)) {
return Promise.all(apiMessage.data.content.map(this.send.bind(this)));
}
const { data, files } = await apiMessage.resolveFiles();
return this.client.api.channels[this.id].messages
.post({ data, files })
.then(d => this.client.actions.MessageCreate.handle(d).message);
}
const { data, files } = await apiMessage.resolveFiles();
return this.client.api.channels[this.id].messages.post({ data, files }).then((d) => this.client.actions.MessageCreate.handle(d).message);
}
}
module.exports = ExtendedTextChannel;
module.exports = ExtendedTextChannel;

@@ -1,46 +0,57 @@

const { WebhookClient, MessageEmbed } = require('discord.js');
const { MessageEmbed, WebhookClient } = require('discord.js');
const APIMessage = require('./APIMessage').sendAPICallback;
class ExtendedWebhookClient extends WebhookClient {
async editMessage(message, content, options) {
async editMessage(message, content, options) {
if (content ? content.embed : null instanceof MessageEmbed) {
options
? options.embeds && Array.isArray(options.embeds)
? options.embeds.push(content.embed)
: (options.embeds = [content.embed])
: (options = {}) && (options.embeds = [content.embed]);
content = null;
}
if (content ? content.embed : null instanceof MessageEmbed) {
options ? (options.embeds && Array.isArray(options.embeds) ? options.embeds.push(content.embed) : options.embeds = [content.embed]) : (options = {}) && (options.embeds = [content.embed]);
content = null;
}
if (options && options.embed) {
options
? options.embeds && Array.isArray(options.embeds)
? options.embeds.push(options.embed)
: (options.embeds = [options.embed])
: (options = {}) && (options.embeds = [options.embed]);
options.embed = null;
}
if (options && options.embed) {
options ? (options.embeds && Array.isArray(options.embeds) ? options.embeds.push(options.embed) : options.embeds = [options.embed]) : (options = {}) && (options.embeds = [options.embed]);
options.embed = null;
}
let apiMessage;
let apiMessage;
if (content instanceof APIMessage) {
apiMessage = content.resolveData();
} else {
apiMessage = APIMessage.create(this, content, options).resolveData();
}
if (content instanceof APIMessage) {
apiMessage = content.resolveData();
} else {
apiMessage = APIMessage.create(this, content, options).resolveData();
}
const { data, files } = await apiMessage.resolveFiles();
const { data, files } = await apiMessage.resolveFiles();
return this.client.api
.webhooks(this.id, this.token)
.messages(typeof message === 'string' ? message : message.id)
.patch({ data, files });
}
return this.client.api
.webhooks(this.id, this.token)
.messages(typeof message === 'string' ? message : message.id)
.patch({ data, files });
}
async deleteMessage(message) {
await this.client.api
.webhooks(this.id, this.token)
.messages(typeof message === 'string' ? message : message.id)
.delete();
}
async deleteMessage(message) {
await this.client.api
.webhooks(this.id, this.token)
.messages(typeof message === 'string' ? message : message.id)
.delete();
}
async fetchMessage(message, cache = true) {
const data = await this.client.api.webhooks(this.id, this.token).messages(message).get();
return this.client.channels ? (this.client.channels.cache.get(data.channel_id) ? this.client.channels.cache.get(data.channel_id).messages.add(data, cache) : null) : data;
}
async fetchMessage(message, cache = true) {
const data = await this.client.api.webhooks(this.id, this.token).messages(message).get();
return this.client.channels
? this.client.channels.cache.get(data.channel_id)
? this.client.channels.cache.get(data.channel_id).messages.add(data, cache)
: null
: data;
}
}
module.exports = ExtendedWebhookClient;
module.exports = ExtendedWebhookClient;
exports.MessageComponentTypes = createEnum([null, 'ACTION_ROW', 'BUTTON', 'SELECT_MENU']);
exports.MessageButtonStyles = createEnum([null, 'blurple', 'grey', 'green', 'red', 'url']);
exports.MessageButtonStylesAliases = createEnum([null, 'PRIMARY', 'SECONDARY', 'SUCCESS', 'DESTRUCTIVE', 'LINK']);
exports.InteractionReplyTypes = createEnum([
null,
'PONG',
null,
null,
'CHANNEL_MESSAGE_WITH_SOURCE',
'DEFFERED_CHANNEL_MESSAGE_WITH_SOURCE',
'DEFFERED_UPDATE_MESSAGE',
'UPDATE_MESSAGE',
]);
function createEnum(keys) {
const obj = {};
for (const [index, key] of keys.entries()) {
if (key === null) continue;
obj[key] = index;
obj[index] = key;
}
return obj;
}
const obj = {};
for (const [index, key] of keys.entries()) {
if (key === null) continue;
obj[key] = index;
obj[index] = key;
}
return obj;
}
const { MessageButtonStyles, MessageButtonStylesAliases, MessageComponentTypes } = require('./Constants.js');
module.exports = {
resolveStyle(style) {
if (!style || style === undefined || style === null) throw new TypeError('NO_BUTTON_STYLE: Please provide button style');
resolveStyle(style) {
if (!style || style === undefined || style === null) throw new TypeError('NO_BUTTON_STYLE: Please provide button style');
if (style === 'gray') style = 'grey';
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');
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;
},
resolveButton(data) {
return typeof style === 'string' ? MessageButtonStyles[style] : style;
},
resolveButton(data) {
if (data.type !== MessageComponentTypes.BUTTON) throw new TypeError('INVALID_BUTTON_TYPE: Invalid type');
if (data.type !== 2 && data.type !== 3) throw new TypeError('NO_BUTTON_TYPE: Invalid type');
if (!data.style) throw new TypeError('NO_BUTTON_STYLE: Please provide button style');
if (!data.style) throw new TypeError('NO_BUTTON_STYLE: Please provide button style');
if (!data.label && !data.emoji) throw new TypeError('NO_BUTTON_LABEL_AND_EMOJI: Please provide button label and/or emoji');
if (!data.label && !data.emoji) throw new TypeError('NO_BUTTON_LABEL_AND_EMOJI: Please provide button label and/or emoji');
if ('disabled' in data && typeof data.disabled !== 'boolean')
throw new TypeError('BUTTON_DISABLED: The button disabled option must be boolean (true/false)');
if ('disabled' in data && typeof (data.disabled) !== 'boolean') throw new TypeError('BUTTON_DISABLED: The button disabled option must be boolean (true/false)')
if (data.style === MessageButtonStyles['url'] && !data.url) throw new TypeError('NO_BUTTON_URL: You provided url style, you must provide an URL');
if (data.style === MessageButtonStyles['url'] && !data.url) throw new TypeError('NO_BUTTON_URL: You provided url style, you must provide an URL');
if (data.style !== MessageButtonStyles['url'] && data.url)
throw new TypeError('BOTH_URL_CUSTOM_ID: A custom id and url cannot both be specified');
if (data.style !== MessageButtonStyles['url'] && data.url) throw new TypeError('BOTH_URL_CUSTOM_ID: A custom id and url cannot both be specified');
if (data.style === MessageButtonStyles['url'] && data.custom_id)
throw new TypeError('BOTH_URL_CUSTOM_ID: A custom id and url cannot both be specified');
if (data.style === MessageButtonStyles['url'] && data.custom_id) throw new TypeError('BOTH_URL_CUSTOM_ID: A custom id and url cannot both be specified');
if (data.style !== MessageButtonStyles['url'] && !data.custom_id) throw new TypeError('NO_BUTTON_ID: Please provide button id');
if (data.style !== MessageButtonStyles['url'] && !data.custom_id) throw new TypeError('NO_BUTTON_ID: Please provide button id');
if (data.emoji && data.emoji.id && isNaN(data.emoji.id)) throw new TypeError('INCORRECT_EMOJI_ID: Please provide correct emoji id');
if (data.emoji && data.emoji.id && isNaN(data.emoji.id)) throw new TypeError('INCORRECT_EMOJI_ID: Please provide correct emoji id');
if (data.emoji && data.emoji.name && this.isEmoji(data.emoji.name) === false)
throw new TypeError('INCORRECT_EMOJI_NAME: Please provide correct emoji');
if (data.emoji && data.emoji.name && this.isEmoji(data.emoji.name) === false) throw new TypeError('INCORRECT_EMOJI_NAME: Please provide correct emoji');
return {
style: data.style,
label: data.label,
emoji: data.emoji,
disabled: data.disabled,
url: data.url,
custom_id: data.custom_id,
type: MessageComponentTypes.BUTTON,
};
},
resolveMenu(data) {
if (data.type !== MessageComponentTypes.SELECT_MENU) throw new TypeError('INVALID_MENU_TYPE: Invalid type');
return {
style: data.style,
label: data.label,
emoji: data.emoji,
disabled: data.disabled,
url: data.url,
custom_id: data.custom_id,
type: 2
}
},
resolveType(type) {
return typeof type === 'string' ? MessageComponentTypes[type] : type;
},
isEmoji(string) {
let emojiRagex = /(?:[\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 emojiRagex.test(string)
}
}
if (data.placeholder && typeof data.placeholder !== 'string')
throw new Error('INVALID_MENU_PLACEHOLDER: The given menu placeholder is not string');
if (!data.custom_id) throw new Error('NO_MENU_ID: Please provide menu id');
let options = this.resolveMenuOptions(data.options);
if (options.length < 1) throw new Error('NO_BUTTON_OPTIONS: Please provide at least one menu option');
let maxValues = this.resolveMaxValues(data.max_values);
let minValues = this.resolveMinValues(data.min_values);
return {
type: MessageComponentTypes.SELECT_MENU,
placeholder: data.placeholder,
custom_id: data.custom_id,
options: options,
max_values: maxValues,
min_values: minValues,
};
},
resolveMenuOptions(data) {
if (!Array.isArray(data)) throw new Error('INVALID_OPTIONS: The select menu options must be an array');
let options = [];
data.map((d) => {
if (!d.value) throw new Error('VALUE_MISSING: Please provide a value for this option');
if (!d.label) throw new Error('MISSING_LABEL: Please provide label for this option');
options.push({
label: d.label,
value: d.value,
emoji: d.emoji,
description: d.description,
});
});
return options;
},
resolveType(type) {
return typeof type === 'string' ? MessageComponentTypes[type] : type;
},
resolveMaxValues(m1, m2) {
return m1 || m2;
},
resolveMinValues(m1, m2) {
return m1 || m2;
},
isEmoji(string) {
let emojiRagex =
/(?:[\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 emojiRagex.test(string);
},
verifyString(data, allowEmpty = true, errorMessage = `Expected a string, got ${data} instead.`, error = Error) {
if (typeof data !== 'string') throw new error(errorMessage);
if (!allowEmpty && data.length === 0) throw new error(errorMessage);
return data;
},
};

@@ -1,220 +0,413 @@

import {
APIMessage,
APIMessageContentResolvable,
Channel,
Client,
Collection,
Collector,
DMChannel,
Guild,
GuildMember,
Message,
MessageAdditions,
MessageOptions,
NewsChannel,
Snowflake,
SplitOptions,
StringResolvable,
TextChannel,
User,
WebhookClient,
WebhookMessageOptions,
CollectorFilter
} from 'discord.js'
import MessageComponent from '../src/v12/Classes/clickButton';
import discord, {
Snowflake,
Guild,
Channel,
User,
GuildMember,
Collector,
CollectorFilter,
Collection,
CollectorOptions,
APIMessageContentResolvable,
MessageEmbed,
MessageAttachment,
StringResolvable,
SplitOptions,
MessageEmbedOptions,
BitFieldResolvable,
MessageFlagsString,
MessageMentionOptions,
} from 'discord.js';
declare module 'discord-buttons' {
declare module 'discord.js' {
export interface ClientEvents {
clickButton: [MessageComponent];
clickMenu: [MessageComponent];
}
export default function (client: Client)
export interface MessageOptions {
component?: MessageButton | MessageMenu | MessageActionRow;
components?: MessageActionRow[];
button?: MessageButton | MessageButton[];
buttons?: MessageButton | MessageButton[];
menu?: MessageMenu | MessageMenu[];
menus?: MessageMenu | MessageMenu[];
}
interface ExtendedMessageOptions extends MessageOptions {
component?: MessageButton | MessageActionRow;
components?: MessageActionRow[];
}
export interface Message {
components: MessageActionRow[];
createButtonCollector(filter: CollectorFilter, options?: AwaitMessageButtonOptions): ButtonCollector;
awaitButtons(filter: CollectorFilter, options?: AwaitMessageButtonOptions): Promise<Collection<Snowflake, MessageComponent>>;
}
interface MessageButtonCollectorOptions extends CollectorOptions {
max?: number;
maxButtons?: number;
maxUsers?: number;
}
export interface WebhookClient {
editMessage(message: string, content: any, options?: {}): Promise<any>;
deleteMessage(message: string): Promise<void>;
fetchMessage(message: string, cache?: boolean): Promise<any>;
}
interface AwaitMessageButtonOptions extends MessageButtonCollectorOptions {
errors?: string[];
}
export interface PartialTextBasedChannelFields {
send(content: APIMessageContentResolvable | (MessageOptions & { split?: false }) | MessageAdditions): Promise<Message>;
send(options: MessageOptions & { split: true | SplitOptions }): Promise<Message[]>;
send(options: MessageOptions | discord.APIMessage): Promise<Message | Message[]>;
send(content: StringResolvable, options: (MessageOptions & { split?: false }) | MessageAdditions): Promise<Message>;
send(content: StringResolvable, options: MessageOptions & { split: true | SplitOptions }): Promise<Message[]>;
send(content: StringResolvable, options: MessageOptions): Promise<Message | Message[]>;
send(content: StringResolvable, options: MessageButton | MessageActionRow | MessageMenu): Promise<Message | Message[]>;
}
}
export class ExtendedWebhookClient extends WebhookClient {
editMessage(message: string, content: any, options?: {}): Promise<any>;
deleteMessage(message: string): Promise<void>;
fetchMessage(message: string, cache?: boolean): Promise<any>;
}
export enum MessageComponentTypes {
ACTION_ROW = 1,
BUTTON = 2,
SELECT_MENU = 3,
}
export class ExtendedMessage extends Message {
_patch(data: any): Message;
components: Array[MessageActionRow];
createButtonCollector(
filter: CollectorFilter<[MessageComponent]>,
options?: AwaitMessageButtonOptions
): ButtonCollector;
awaitButtons(
filter: CollectorFilter<[MessageComponent]>,
options?: AwaitMessageButtonOptions
): Promise<Collection<Snowflake, MessageComponent>>;
}
export enum MessageButtonStyles {
blurple = 1,
grey = 2,
green = 3,
red = 4,
url = 5,
export class ButtonCollector extends Collector<Snowflake, MessageComponent> {
constructor(
message: Message,
filter: CollectorFilter<[MessageComponent]>,
options?: MessageButtonCollectorOptions
);
message: Message;
users: Collection<Snowflake, User>;
total: number;
empty(): void;
endReason(): string | null;
_handleChannelDeletion(channel: Channel): void;
_handleGuildDeletion(guild: Guild): void;
_handleMessageDeletion(message: Message): void;
//Aliases
gray = 2,
PRIMARY = 1,
SECONDARY = 2,
SUCCESS = 3,
DESTRUCTIVE = 4,
LINK = 5,
}
collect(button: MessageButton): Snowflake;
dispose(button: MessageButton): Snowflake;
on(
event: 'collect' | 'dispose',
listener: (interaction: MessageComponent) => Awaited<void>,
): this;
on(
event: 'end',
listener: (collected: Collection<Snowflake, MessageComponent>, reason: string) => Awaited<void>,
): this;
on(event: string, listener: (...data: any[]) => Awaited<void>): this;
export type MessageButtonStyle = keyof typeof MessageButtonStyles;
once(
event: 'collect' | 'dispose',
listener: (interaction: MessageComponent) => Awaited<void>,
): this;
once(
event: 'end',
listener: (collected: Collection<Snowflake, MessageComponent>, reason: string) => Awaited<void>,
): this;
once(event: string, listener: (...data: any[]) => Awaited<void>): this;
}
export type MessageButtonStyleResolvable = MessageButtonStyle | MessageButtonStyles;
export class MessageComponent {
constructor(client: Client, data: object);
client: Client;
id: Snowflake;
version: any;
token: string;
discordID: Snowflake;
applicationID: Snowflake;
guild: Guild;
channel: Channel;
clicker: {
user: User;
member: GuildMember;
fetch: () => Promise<boolean>;
};
message: Message;
webhook: WebhookClient;
replied: boolean;
deferred: boolean;
defer(ephemeral?: boolean): Promise<void>;
think(ephemeral?: boolean): Promise<void>;
followUp(content: string, options?: {}): Promise<void>;
get reply(): {
send: (content: any, options: ExtendedMessageOptions | WebhookMessageOptions | MessageAdditions | { ephemeral: boolean }) => Promise<any>;
fetch: () => Promise<any>;
edit: (content: any, options?: {}) => Promise<any>;
delete: () => Promise<void>;
};
}
export interface GuildButtonEmoji {
name?: string;
id?: Snowflake;
animated?: boolean;
}
export class BaseMessageComponent {
static create(data: object): MessageActionRow | MessageButton;
constructor(data: object);
type: any;
}
export interface MessageButtonOptions {
type: MessageComponentTypes.BUTTON;
style: MessageButtonStyleResolvable;
label?: string;
disabled?: boolean;
emoji?: string | GuildButtonEmoji;
url?: string;
id?: string;
custom_id?: string;
}
export class MessageActionRow extends BaseMessageComponent {
constructor(data?: {});
setup(data: object): MessageActionRow;
component: MessageActionRow | MessageButton;
components: any;
addComponents(...components: any[]): MessageActionRow;
addComponent(component: any): MessageActionRow;
toJSON(): {
components: Array[MessageButton];
type: any;
};
}
export interface MessageMenuOptions {
type: MessageComponentTypes.SELECT_MENU;
label?: string;
emoji?: string | GuildButtonEmoji;
description?: string;
value?: string;
}
export class MessageButton extends BaseMessageComponent {
constructor(data?: {});
setup(data: object): MessageButton;
style: string;
label: string;
disabled: boolean;
emoji: string;
url: string;
custom_id: string;
setStyle(style: MessageButtonStyles): MessageButton;
setLabel(label: string): MessageButton;
setDisabled(disabled?: boolean): MessageButton;
setURL(url: string): MessageButton;
setID(id: string): MessageButton;
setEmoji(emoji: string): MessageButton;
toJSON(): {
type: any;
style: string;
label: string;
emoji: object;
disabled: boolean;
url: string;
custom_id: string;
};
}
export interface MessageButtonData {
type?: MessageComponentTypes.BUTTON;
style: MessageButtonStyles | number;
label?: string;
disabled?: boolean;
emoji?: GuildButtonEmoji;
url?: string;
custom_id?: string;
}
export interface ExtendedTextChannel extends TextChannel {
send(
content: APIMessageContentResolvable | (ExtendedMessageOptions & { split?: false }) | MessageAdditions,
): Promise<Message>;
}
export interface MessageActionRowData {
type: number | string;
components: MessageButton[];
}
export interface ExtendedDMChannel extends DMChannel {
send(
content: APIMessageContentResolvable | (ExtendedMessageOptions & { split?: false }) | MessageAdditions,
): Promise<Message>;
}
export interface MessageMenuData {
type?: MessageComponentTypes.SELECT_MENU;
placeholder?: string;
custom_id?: string;
max_values?: number;
min_values?: number;
options?: Array<MessageMenuOptions>;
}
export interface ExtendedNewsChannel extends NewsChannel {
send(
content: APIMessageContentResolvable | (ExtendedMessageOptions & { split?: false }) | MessageAdditions,
): Promise<Message>;
}
export interface MessageMenuOptionsData {
label?: string;
emoji?: string | GuildButtonEmoji;
description?: string;
value?: string;
}
enum MessageComponentTypes {
ACTION_ROW,
BUTTON,
SELECT_MENU
}
export class InteractionReply {
constructor(client: discord.Client, component: MessageComponent, webhook: WebhookClient);
client: discord.Client;
component: MessageComponent;
webhook: WebhookClient;
has: boolean;
isEphemeral: boolean;
send(content: APIMessageContentResolvable | (MessageOptions & { split?: false }) | MessageAdditions): Promise<this>;
edit(content: APIMessageContentResolvable | (MessageOptions & { split?: false }) | MessageAdditions): Promise<this>;
defer(ephemeral: boolean): Promise<this>;
think(ephemeral: boolean): Promise<this>;
fetch(): Promise<any>;
delete(): Promise<void>;
}
export enum MessageButtonStyles {
blurple = 1,
grey = 2,
green = 3,
red = 4,
url = 5
}
export class APIMessage extends discord.APIMessage {
public components: MessageActionRow[];
}
export enum MessageButtonStylesAliases {
PRIMARY = 1,
SECONDARY = 2,
SUCCESS = 3,
DESTRUCTIVE = 4,
LINK = 5
}
export class sendAPICallback extends discord.APIMessage {
public components: MessageActionRow[];
public flags: number;
}
export class MessageComponent {
constructor(client: discord.Client, data: any, menu: boolean);
client: discord.Client;
id: Snowflake;
version: any;
token: string;
discordID: Snowflake;
applicationID: Snowflake;
guild: Guild;
channel: Channel;
values?: string[];
clicker: {
id: Snowflake;
user: User;
member: GuildMember;
fetch: () => Promise<boolean>;
};
message: Message;
webhook: WebhookClient;
reply: InteractionReply;
}
/*
Base: https://github.com/AngeloCore/discord-buttons/pull/64/commits/f936d59b0d72bf5a9ae448ebb236957c1dc9ab37#diff-4f45caa500ef03d94d3c2bfa556caa1642df95d4e2b980d76b876a8fd2e8c522
*/
export class BaseMessageComponent {
constructor(data: MessageActionRow | MessageButton);
private static create(data: MessageActionRow | MessageButton): MessageActionRow | MessageButton;
}
export class MessageActionRow extends BaseMessageComponent {
constructor(data?: {});
setup(data: any): MessageActionRow;
component: MessageButton | MessageMenu;
components: MessageButton[] | MessageMenu[];
addComponents(...components: MessageButton[] | MessageMenu[]): MessageActionRow;
addComponent(component: MessageButton | MessageMenu): MessageActionRow;
toJSON(): {
components: MessageButton[];
type: string | number;
};
}
export class MessageButton extends BaseMessageComponent {
constructor(data?: MessageButton | MessageButtonData | MessageButtonOptions);
public setup(data: any): MessageButton;
public style: MessageButtonStyles;
public label: string;
public disabled: boolean;
public emoji: GuildButtonEmoji;
public url: string;
public custom_id: string;
public setStyle(style: MessageButtonStyleResolvable): MessageButton;
public setLabel(label: string): MessageButton;
public setDisabled(disabled?: boolean): MessageButton;
public setURL(url: string): MessageButton;
public setID(id: string): MessageButton;
public setEmoji(emoji: any): MessageButton;
public toJSON(): MessageButtonData;
}
export class MessageMenu extends BaseMessageComponent {
constructor(data?: any);
public placeholder: string;
public max_values: number;
public min_values: number;
public options: MessageMenuOption[];
public custom_id: string;
public type: string;
public setup(data: any): MessageMenu;
public setPlaceholder(label: string): MessageMenu;
public setID(id: string): MessageMenu;
public setMaxValues(number: number): MessageMenu;
public setMinValues(number: number): MessageMenu;
public addOption(option: MessageMenuOption): MessageMenu;
public addOptions(...options: MessageMenuOption[]): MessageMenu;
public removeOptions(index: number, deleteCount: number, ...options: MessageMenuOption[]): MessageMenu;
public toJSON(): MessageMenuData;
}
export class MessageMenuOption extends BaseMessageComponent {
constructor(data?: MessageMenuOptionsData);
public default: boolean;
public description: string;
public emoji: string | GuildButtonEmoji;
public label: string;
public value: string;
public type: string;
public setup(data: MessageMenuOptions): MessageMenuOption;
public setLabel(label: string): MessageMenuOption;
public setValue(value: string): MessageMenuOption;
public setDescription(value: string): MessageMenuOption;
public setDefault(def?: boolean): MessageMenuOption;
public setEmoji(emoji: string | GuildButtonEmoji, animted?: boolean): MessageMenuOption;
public toJSON(): MessageMenuOptionsData;
}
export interface MessageOptions extends discord.MessageOptions {
component?: MessageButton | MessageMenu | MessageActionRow;
components?: MessageActionRow[];
button?: MessageButton | MessageButton[];
buttons?: MessageButton | MessageButton[];
menu?: MessageMenu | MessageMenu[];
menus?: MessageMenu | MessageMenu[];
}
export interface MessageEditOptions {
content?: StringResolvable;
embed?: MessageEmbed | MessageEmbedOptions | null;
code?: string | boolean;
flags?: BitFieldResolvable<MessageFlagsString>;
allowedMentions?: MessageMentionOptions;
component?: MessageButton | MessageActionRow | MessageMenu;
components?: MessageActionRow[] | MessageMenu[];
button?: MessageButton | MessageButton[];
buttons?: MessageButton | MessageButton[];
menu?: MessageMenu;
menus?: MessageMenu[];
}
export interface ReplyOptions extends MessageOptions {
ephemeral?: boolean;
flags?: number;
}
export class WebhookClient extends discord.WebhookClient {
editMessage(message: string, content: any, options?: {}): Promise<any>;
deleteMessage(message: string): Promise<void>;
fetchMessage(message: string, cache?: boolean): Promise<any>;
}
export interface Message extends discord.Message {
components: MessageActionRow[];
createButtonCollector(filter: CollectorFilter, options?: AwaitMessageButtonOptions): ButtonCollector;
awaitButtons(filter: CollectorFilter, options?: AwaitMessageButtonOptions): Promise<Collection<Snowflake, MessageComponent>>;
createMenuCollector(filter: CollectorFilter, options?: AwaitMessageMenuOptions): MenuCollector;
awaitMenus(filter: CollectorFilter, options?: AwaitMessageMenuOptions): Promise<Collection<Snowflake, MessageComponent>>;
edit(
content: APIMessageContentResolvable | MessageEditOptions | MessageEmbed | MessageButton | MessageMenu | MessageActionRow | APIMessage,
): Promise<Message>;
edit(content: StringResolvable, options: MessageEditOptions | MessageEmbed | MessageButton | MessageMenu | MessageActionRow): Promise<Message>;
}
export interface MessageButtonCollectorOptions extends CollectorOptions {
max?: number;
maxButtons?: number;
maxUsers?: number;
}
export interface AwaitMessageButtonOptions extends MessageButtonCollectorOptions {
errors?: string[];
}
export class ButtonCollector extends Collector<Snowflake, MessageComponent> {
constructor(message: Message, filter: CollectorFilter, options?: MessageButtonCollectorOptions);
message: Message;
users: Collection<Snowflake, User>;
total: number;
empty(): void;
endReason(): string | null;
_handleChannelDeletion(channel: Channel): void;
_handleGuildDeletion(guild: Guild): void;
_handleMessageDeletion(message: Message): void;
collect(button: MessageButton): Snowflake;
dispose(button: MessageButton): Snowflake;
on(event: 'collect' | 'dispose', listener: (interaction: MessageComponent) => Awaited<void>): this;
on(event: 'end', listener: (collected: Collection<Snowflake, MessageComponent>, reason: string) => Awaited<void>): this;
on(event: string, listener: (...data: any[]) => Awaited<void>): this;
once(event: 'collect' | 'dispose', listener: (interaction: MessageComponent) => Awaited<void>): this;
once(event: 'end', listener: (collected: Collection<Snowflake, MessageComponent>, reason: string) => Awaited<void>): this;
once(event: string, listener: (...data: any[]) => Awaited<void>): this;
}
export interface MessageMenuCollectorOptions extends CollectorOptions {
max?: number;
maxMenus?: number;
maxUsers?: number;
}
export interface AwaitMessageMenuOptions extends MessageMenuCollectorOptions {
errors?: string[];
}
export class MenuCollector extends Collector<Snowflake, MessageComponent> {
constructor(data: any, filter: CollectorFilter, options?: MessageMenuCollectorOptions);
public message: Message;
public users: Collection<Snowflake, User>;
public total: number;
public _handleChannelDeletion(channel: Channel): void;
public _handleGuildDeletion(guild: Guild): void;
public _handleMessageDeletion(message: Message): void;
public collect(menu: MessageMenu): Snowflake;
public dispose(menu: MessageMenu): Snowflake;
public empty(): void;
public endReason(): string | null;
on(event: 'collect' | 'dispose', listener: (interaction: MessageComponent) => Awaited<void>): this;
on(event: 'end', listener: (collected: Collection<Snowflake, MessageComponent>, reason: string) => Awaited<void>): this;
on(event: string, listener: (...data: any[]) => Awaited<void>): this;
once(event: 'collect' | 'dispose', listener: (interaction: MessageComponent) => Awaited<void>): this;
once(event: 'end', listener: (collected: Collection<Snowflake, MessageComponent>, reason: string) => Awaited<void>): this;
once(event: string, listener: (...data: any[]) => Awaited<void>): this;
}
export type MessageAdditions =
| MessageEmbed
| MessageAttachment
| MessageButton
| MessageActionRow
| (MessageEmbed | MessageAttachment | MessageButton | MessageActionRow | MessageMenu)[];
export type Awaited<T> = T | Promise<T>;
export interface ExtendedTextChannel extends discord.TextChannel {
send(content: APIMessageContentResolvable | (MessageOptions & { split?: false }) | MessageAdditions): Promise<Message>;
send(options: MessageOptions & { split: true | SplitOptions }): Promise<Message[]>;
send(options: MessageOptions | discord.APIMessage): Promise<Message | Message[]>;
send(content: StringResolvable, options: (MessageOptions & { split?: false }) | MessageAdditions): Promise<Message>;
send(content: StringResolvable, options: MessageOptions & { split: true | SplitOptions }): Promise<Message[]>;
send(content: StringResolvable, options: MessageOptions): Promise<Message | Message[]>;
send(content: StringResolvable, options: MessageButton | MessageActionRow | MessageMenu): Promise<Message | Message[]>;
}
export interface ExtendedDMChannel extends discord.DMChannel {
send(content: APIMessageContentResolvable | (MessageOptions & { split?: false }) | MessageAdditions): Promise<Message>;
send(options: MessageOptions & { split: true | SplitOptions }): Promise<Message[]>;
send(options: MessageOptions | discord.APIMessage): Promise<Message | Message[]>;
send(content: StringResolvable, options: (MessageOptions & { split?: false }) | MessageAdditions): Promise<Message>;
send(content: StringResolvable, options: MessageOptions & { split: true | SplitOptions }): Promise<Message[]>;
send(content: StringResolvable, options: MessageOptions): Promise<Message | Message[]>;
send(content: StringResolvable, options: MessageButton | MessageActionRow | MessageMenu): Promise<Message | Message[]>;
}
export interface ExtendedNewsChannel extends discord.NewsChannel {
send(content: APIMessageContentResolvable | (MessageOptions & { split?: false }) | MessageAdditions): Promise<Message>;
send(options: MessageOptions & { split: true | SplitOptions }): Promise<Message[]>;
send(options: MessageOptions | discord.APIMessage): Promise<Message | Message[]>;
send(content: StringResolvable, options: (MessageOptions & { split?: false }) | MessageAdditions): Promise<Message>;
send(content: StringResolvable, options: MessageOptions & { split: true | SplitOptions }): Promise<Message[]>;
send(content: StringResolvable, options: MessageOptions): Promise<Message | Message[]>;
send(content: StringResolvable, options: MessageButton | MessageActionRow | MessageMenu): Promise<Message | Message[]>;
}
declare module 'discord-buttons' {
export default function (client: discord.Client): void;
export function multipleImport(...clients: discord.Client[]): void;
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc