summaryrefslogtreecommitdiff
path: root/server/src/commands/reaction
diff options
context:
space:
mode:
author8cy <[email protected]>2020-07-23 23:24:17 -0700
committer8cy <[email protected]>2020-07-23 23:24:17 -0700
commitbb511abc03bb66848947e37a999502b813c77269 (patch)
tree612c010fc8317e1cdf11471a18aad0270819d33e /server/src/commands/reaction
parentfix: if clear amount equal or over 100, round down to 99 (diff)
downloaddep-core-bb511abc03bb66848947e37a999502b813c77269.tar.xz
dep-core-bb511abc03bb66848947e37a999502b813c77269.zip
goodbye old uwufier :cry:
Diffstat (limited to 'server/src/commands/reaction')
-rw-r--r--server/src/commands/reaction/List.ts46
-rw-r--r--server/src/commands/reaction/New.ts168
-rw-r--r--server/src/commands/reaction/Remove.ts61
3 files changed, 275 insertions, 0 deletions
diff --git a/server/src/commands/reaction/List.ts b/server/src/commands/reaction/List.ts
new file mode 100644
index 0000000..36c1156
--- /dev/null
+++ b/server/src/commands/reaction/List.ts
@@ -0,0 +1,46 @@
+import { Command } from 'discord-akairo';
+import { Message } from 'discord.js';
+import { oneLine } from 'common-tags';
+import { colour } from '../../Config';
+
+export default class ListReaction extends Command {
+ public constructor() {
+ super('reactionlist', {
+ aliases: ['reactionlist', 'reactionls'],
+ category: 'reactions',
+ description: {
+ content: 'Lists all current reaction roles.',
+ usage: '',
+ examples: [
+ ''
+ ]
+ },
+ ratelimit: 3,
+ userPermissions: ['MANAGE_ROLES'],
+ channel: 'guild'
+ });
+ }
+
+ public async exec(msg: Message): Promise<Message | Message[]> {
+ const reactions = this.client.settings.cache.reactions.filter(r => r.guildID === msg.guild!.id && r.active);
+ if (!reactions.size) return msg.reply('you have no live reaction roles!');
+
+ const embed = this.client.util.embed()
+ .setColor(colour)
+ .setTitle('Live Reaction Roles')
+ .setDescription(
+ reactions
+ .map(r => {
+ const emoji = r.emojiType === 'custom' ? this.client.emojis.cache.get(r.emoji) : r.emoji;
+ return oneLine`[\`${r.id}\`] ${emoji}
+ ${this.client.channels.cache.get(r.channelID) || '#deleted-channel'}
+ ${msg.guild!.roles.cache.get(r.roleID) || '@deleted-role'}
+ `;
+ })
+ .join('\n')
+ .substring(0, 2048),
+ );
+
+ return msg.reply({ embed });
+ }
+} \ No newline at end of file
diff --git a/server/src/commands/reaction/New.ts b/server/src/commands/reaction/New.ts
new file mode 100644
index 0000000..c695dbc
--- /dev/null
+++ b/server/src/commands/reaction/New.ts
@@ -0,0 +1,168 @@
+import { Command } from 'discord-akairo';
+import { Message, MessageReaction, Permissions, Role, TextChannel, User } from 'discord.js';
+import { stripIndents } from 'common-tags';
+import * as nodemoji from 'node-emoji';
+import { colour } from '../../Config';
+
+export default class NewReaction extends Command {
+ public constructor() {
+ super('reactionnew', {
+ aliases: ['reactionnew', 'reactionadd'],
+ category: 'reactions',
+ description: {
+ content: 'Create a new reaction role.',
+ usage: '[type] [channel] [message id] [emoji] [role]',
+ examples: [
+ '1 #welcome 603009228180815882 🍕 @Pizza Lover'
+ ]
+ },
+ ratelimit: 3,
+ userPermissions: ['MANAGE_ROLES'],
+ clientPermissions: ['ADD_REACTIONS', 'MANAGE_ROLES', 'MANAGE_MESSAGES'],
+ channel: 'guild'
+ });
+ }
+
+ public *args(m: Message): object {
+ const type = yield {
+ type: 'number',
+ prompt: {
+ start: stripIndents`
+ What type of reaction role do you wish to create?
+
+ \`[1]\` for react to add and remove. *Classic*
+ ~~\`[2]\` for react to add only.
+ \`[3]\` for react to delete only.~~
+ `,
+ restart: stripIndents`
+ Please provide a valid number for which type of reaction role do you wish to create?
+
+ \`[1]\` Both react to add and remove. *Classic*
+ ~~\`[2]\` Only react to add.
+ \`[3]\` Only react to remove role.~~
+ `,
+ },
+ };
+
+ const channel = yield {
+ type: 'textChannel',
+ prompt: {
+ start: "What channel of the message you'd like to add this reaction role to?",
+ retry: 'Please provide a valid channel.',
+ },
+ };
+
+ const message = yield {
+ type: async (_: Message, str: string): Promise<null | Message> => {
+ if (str) {
+ try {
+ const m = await channel.messages.fetch(str);
+ if (m) return m;
+ } catch {}
+ }
+ return null;
+ },
+ prompt: {
+ start: 'What is the ID of the message you want to add that reaction role to?',
+ retry: 'Please provide a valid message ID.',
+ },
+ };
+
+ const emoji = yield {
+ type: async (_: Message, str: string): Promise<string | null> => {
+ if (str) {
+ const unicode = nodemoji.find(str);
+ if (unicode) return unicode.emoji;
+
+ const custom = this.client.emojis.cache.find(r => r.toString() === str);
+ if (custom) return custom.id;
+ return null;
+ }
+
+ const message = await m.channel.send(
+ stripIndents`Please **react** to **this** message with the emoji you wish to use?
+ If it's a custom emoji, please ensure I'm in the server that it's from!`,
+ );
+ // Please **react** to **this** message or respond with the emoji you wish to use?
+ // If it's a custom emoji, please ensure I'm in the server that it's from!
+
+ const collector = await message.awaitReactions((_: MessageReaction, u: User): boolean => m.author.id === u.id, {
+ max: 1,
+ });
+ if (!collector || collector.size !== 1) return null;
+
+ const collected = collector.first()!;
+
+ if (collected.emoji.id) {
+ const emoji = this.client.emojis.cache.find(e => e.id === collected.emoji.id);
+ if (emoji) return emoji.id;
+ return null;
+ }
+
+ return null;
+ },
+ prompt: {
+ start:
+ "Please **respond** to **this** message with the emoji you wish to use? If it's a custom emoji, please ensure I'm in the server that it's from!",
+ retry:
+ "Please **respond** to **this** message with a valid emoji. If it's a custom emoji, please ensure I'm in the server that it's from!",
+ },
+ };
+
+ const role = yield {
+ type: 'role',
+ match: 'rest',
+ prompt: {
+ start: 'What role would you like to apply when they react?',
+ retry: 'Please provide a valid role.',
+ },
+ };
+
+ return { type, channel, message, emoji, role };
+ }
+
+ public async exec(msg: Message, { type, channel, message, emoji, role }: { type: number; channel: TextChannel; message: Message; emoji: string; role: Role }): Promise<Message | Message[] | void> {
+ if (!channel.permissionsFor(this.client.user!.id)!.has(Permissions.FLAGS.ADD_REACTIONS))
+ return msg.reply(`I'm missing the permissions to react in ${channel}!`);
+
+ const reaction = await message.react(emoji).catch((err: Error) => err);
+
+ if (reaction instanceof Error)
+ return msg.reply(`an error occurred when trying to react to that message: \`${reaction}\`.`);
+
+ const id = this.makeID();
+
+ await this.client.settings.new('reaction', {
+ guildID: msg.guild!.id,
+ messageID: message.id,
+ userID: msg.author.id,
+ channelID: channel.id,
+ id,
+ emoji,
+ emojiType: emoji.length >= 3 ? 'custom' : 'unicode',
+ roleID: role.id,
+ uses: 0,
+ type,
+ });
+
+ const embed = this.client.util.embed()
+ .setColor(colour)
+ .setTitle('New Reaction Role!')
+ .setDescription("Please make sure my highest role is above the one you're trying to assign!")
+ .addField('🔢 Reference ID', id)
+ .addField('🏠 Channel', `${channel} \`[${channel.id}]\``)
+ .addField('💬 Message', `\`${message.id}\``)
+ .addField('🍕 Emoji', emoji.length >= 3 ? `${emoji} \`[${emoji}]\`` : emoji)
+ .addField('💼 Role', `${role} \`[${role.id}]\``);
+ return msg.channel.send({ embed });
+ }
+
+ public makeID(times?: number): string {
+ const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+ return 'X'
+ .repeat(times || 4)
+ .split('')
+ .map(() => possible.charAt(Math.floor(Math.random() * possible.length)))
+ .join('');
+ }
+} \ No newline at end of file
diff --git a/server/src/commands/reaction/Remove.ts b/server/src/commands/reaction/Remove.ts
new file mode 100644
index 0000000..0a58cdd
--- /dev/null
+++ b/server/src/commands/reaction/Remove.ts
@@ -0,0 +1,61 @@
+import { Command } from 'discord-akairo';
+import { Message, TextChannel } from 'discord.js';
+import { Reaction } from '../../database/models/ReactionModel';
+
+export default class RemoveReaction extends Command {
+ public constructor() {
+ super('reactionremove', {
+ aliases: ['reactionremove', 'reactionrm', 'reactiondelete', 'reactiondel'],
+ category: 'reactions',
+ description: {
+ content: 'Removes a reaction from a message via an discriminator.',
+ usage: '[discriminator]',
+ examples: [
+ '[fV9k]'
+ ]
+ },
+ ratelimit: 3,
+ userPermissions: ['MANAGE_ROLES'],
+ channel: 'guild',
+ args: [
+ {
+ id: 'reaction',
+ type: (msg: Message, str: string): Reaction | null => {
+ const req = this.client.settings.cache.reactions.find(r => r.id === str && r.guildID === msg.guild!.id);
+ if (!req) return null;
+ return req;
+ },
+ match: 'rest',
+ prompt: {
+ start: "Please provide the unique identifier for the reaction you'd like to delete.",
+ retry:
+ "Please provide a valid identifier for the reaction role you'd like to delete. You can also delete the whole message to delete reaction roles on it.",
+ },
+ },
+ ],
+ });
+ }
+
+ public async exec(msg: Message, { reaction }: { reaction: Reaction }): Promise<Message | Message[] | void> {
+ this.client.logger.info(reaction);
+ try {
+ const chan = this.client.channels.cache.get(reaction.channelID) as TextChannel;
+ if (!chan) throw new Error("That channel doesn't exist!");
+ const message = await chan.messages.fetch(reaction.messageID);
+ if (!message) throw new Error("That message doesn't exist!");
+ await message.reactions.cache.get(reaction.emoji)!.users.remove(this.client.user!.id);
+ } catch (err) {
+ this.client.logger.error(`[ERROR in REMOVE CMD]: ${err}.`);
+ }
+
+ this.client.settings.set(
+ 'reaction',
+ { messageID: reaction.messageID },
+ {
+ active: false,
+ },
+ );
+
+ return msg.reply('successfully deleted that reaction role.');
+ }
+} \ No newline at end of file