import { isAuthorised } from "../util"; import client from "../client"; import { ICommand } from "./command"; import { getRepository } from "typeorm"; import { MessageReaction } from "../entity/MessageReaction"; import { KnownUser } from "../entity/KnownUser"; import { ReactionType, ReactionEmote } from "../entity/ReactionEmote"; const pattern = /^react to\s+"([^"]+)"\s+with\s+\<:[^:]+:([^\>]+)\>$/i; async function getRandomEmotes(allowedTypes: ReactionType[]) { let reactionEmotesRepo = getRepository(ReactionEmote); return await reactionEmotesRepo.query(` select reactionId from ( select type, reactionId from reaction_emote where type in (?) order by type, random() ) group by type`, [ allowedTypes ]) as string[]; } export default { commands: [ { pattern: "react to", action: async (msg, s) => { if (!isAuthorised(msg.member)) return; let contents = pattern.exec(s); if (contents != null) { let reactable = contents[1].trim().toLowerCase(); let reactionEmoji = contents[2]; if (!client.emojis.has(reactionEmoji)) { msg.channel.send(`${msg.author.toString()} I cannot react with this emoji :(`); return; } let repo = getRepository(MessageReaction); let message = repo.create({ message: reactable, reactionEmoteId: reactionEmoji }); await repo.save(message); msg.channel.send(`${msg.author.toString()} Added reaction!`); } } }, { pattern: "remove reaction to", action: async (msg, s) => { if (!isAuthorised(msg.member)) return; let content = s.substring("remove reaction to ".length).trim().toLowerCase(); let repo = getRepository(MessageReaction); let result = await repo.delete({ message: content }); if (result.affected == 0) { msg.channel.send(`${msg.author.toString()} No such reaction available!`); return; } msg.channel.send(`${msg.author.toString()} Removed reaction!`); } }, { pattern: "reactions", action: async msg => { let reactionsRepo = getRepository(MessageReaction); let messages = await reactionsRepo.find({ select: [ "message" ] }); let reactions = messages.reduce((p, c) => `${p}\n${c.message}`, ""); msg.channel.send(`I'll react to the following messages:\n\`\`\`${reactions}\n\`\`\``); } } ], documentation: { "react to \"\" with ": { auth: true, description: "React to with ." }, "remove reaction to ": { auth: true, description: "Stops reacting to ." }, "reactions": { auth: false, description: "Lists all known messages this bot can react to." } }, onMessage: async (actionsDone, msg, content) => { if (actionsDone) return false; let lowerContent = content.toLowerCase(); let reactionRepo = getRepository(MessageReaction); let usersRepo = getRepository(KnownUser); let message = await reactionRepo.findOne({ message: lowerContent }); if(message) { msg.react(client.emojis.get(message.reactionEmoteId)); return true; } if (msg.mentions.users.size == 0) return false; let knownUsers = await usersRepo.find({ select: [ "mentionReactionType" ], where: [...msg.mentions.users.map(u => ({ userId: u.id }))] }); if(knownUsers.length == 0) return false; let reactionEmoteTypes = new Set(); for(let user of knownUsers) { if(user.mentionReactionType == ReactionType.NONE) continue; reactionEmoteTypes.add(user.mentionReactionType); } let randomEmotes = await getRandomEmotes([...reactionEmoteTypes]); if(randomEmotes.length == 0) return false; for(let emote in randomEmotes) await msg.react(client.emojis.find(e => e.id == emote)); return true; }, onIndirectMention: async (actionsDone, msg) => { if (actionsDone) return false; let emoteType = ReactionType.ANGERY; let repo = getRepository(KnownUser); let knownUser = await repo.findOne({ select: [ "mentionReactionType" ], where: [{userID: msg.id}] }); if(!knownUser || knownUser.mentionReactionType == ReactionType.NONE) return false; emoteType = knownUser.mentionReactionType; let emotes = await getRandomEmotes([ emoteType ]); if(emotes.length != 1) return false; let emote = client.emojis.find(e => e.id == emotes[0]); if (!emote) { console.log(`WARNING: Emote ${emotes[0]} no longer is valid. Deleting invalid emojis from the list...`); let emotesRepo = getRepository(ReactionEmote); emotesRepo.delete({ reactionId: emotes[0] }); return false; } msg.channel.send(emote.toString()); return true; } } as ICommand;