123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- import { client } from "../client";
- import { getRepository } from "typeorm";
- import { MessageReaction } from "@db/entity/MessageReaction";
- import { KnownUser } from "@db/entity/KnownUser";
- import { ReactionType, ReactionEmote } from "@db/entity/ReactionEmote";
- import { isAuthorisedAsync } from "../util";
- import { CommandSet, Command, Action, ActionType } from "src/model/command";
- import { Message } from "discord.js";
- const pattern = /^react to\s+"([^"]+)"\s+with\s+\<:[^:]+:([^\>]+)\>$/i;
- async function getRandomEmotes(allowedTypes: ReactionType[], limit: number) {
- let reactionEmotesRepo = getRepository(ReactionEmote);
- let a = await reactionEmotesRepo.query(`
- select distinct on (type) type, "reactionId"
- from
- ( select *
- from reaction_emote
- where type in (${allowedTypes.map((s, i) => `$${i + 1}`).join(",")})
- order by random(), random()
- limit ${limit}
- ) as sub`, allowedTypes) as ReactionEmote[];
- return a;
- }
- @CommandSet
- export class ReactCommands {
- @Command({ pattern: "react to", auth: true, documentation: {description: "React to <message> with <emote>.", example: "react to \"<message>\" with <emote>"} })
- async addReaction(msg: Message, s: string) {
- if (!await isAuthorisedAsync(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!`);
- }
- }
- @Command({ pattern: "remove reaction to", auth: true, documentation: {description: "Stops reacting to <message>.", example: "remove reaction to <message>"} })
- async removeReaction(msg: Message, s: string) {
- if (!await isAuthorisedAsync(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!`);
- }
- @Command({ pattern: "reactions", documentation: {description: "Lists all known messages this bot can react to.", example: "reactions"} })
- async listReactions(msg: Message) {
- 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\`\`\``);
- }
- @Action(ActionType.MESSAGE)
- async reactToMentions(actionsDone: boolean, msg: Message, content: string) {
- 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<ReactionType>();
- for (let user of knownUsers) {
- if (user.mentionReactionType == ReactionType.NONE)
- continue;
- reactionEmoteTypes.add(user.mentionReactionType);
- }
- let randomEmotes = await getRandomEmotes([...reactionEmoteTypes], 5);
- if (randomEmotes.length == 0)
- return false;
- for (let emote of randomEmotes)
- await msg.react(client.emojis.find(e => e.id == emote.reactionId));
- return true;
- }
- @Action(ActionType.INDIRECT_MENTION)
- async reactToPing(actionsDone: boolean, msg: Message) {
- if (actionsDone)
- return false;
- let emoteType = ReactionType.ANGERY;
- let repo = getRepository(KnownUser);
- let knownUser = await repo.findOne({
- select: ["replyReactionType"],
- where: [{
- userID: msg.author.id
- }]
- });
- if (knownUser) {
- if (knownUser.replyReactionType == ReactionType.NONE)
- return false;
- emoteType = knownUser.replyReactionType;
- }
- let emotes = await getRandomEmotes([emoteType], 1);
- if (emotes.length != 1)
- return false;
- let emote = client.emojis.find(e => e.id == emotes[0].reactionId);
- if (!emote) {
- console.log(`WARNING: Emote ${emotes[0]} no longer is valid. Deleting invalid emojis from the list...`);
- let emotesRepo = getRepository(ReactionEmote);
- await emotesRepo.delete({ reactionId: emotes[0].reactionId });
- return false;
- }
- msg.channel.send(emote.toString());
- return true;
- }
- };
|