|
@@ -1,49 +1,84 @@
|
|
|
-import { db, IRandomElementMixin } from "../db";
|
|
|
import { isAuthorised } from "../util";
|
|
|
import client from "../client";
|
|
|
import { ICommand } from "./command";
|
|
|
-import { ObjectChain, CollectionChain } from "lodash";
|
|
|
+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: (msg, s) => {
|
|
|
- if (!isAuthorised(msg.member)) return;
|
|
|
+ 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;
|
|
|
}
|
|
|
- db.get("messageReactions").set(reactable, reactionEmoji);
|
|
|
- db.write();
|
|
|
+
|
|
|
+ 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: (msg, s) => {
|
|
|
- if (!isAuthorised(msg.member)) return;
|
|
|
+ action: async (msg, s) => {
|
|
|
+ if (!isAuthorised(msg.member))
|
|
|
+ return;
|
|
|
+
|
|
|
let content = s.substring("remove reaction to ".length).trim().toLowerCase();
|
|
|
- if (!db.get("messageReactions").has(content).value()) {
|
|
|
+ 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;
|
|
|
}
|
|
|
- db.get("messageReactions").unset(content).write();
|
|
|
msg.channel.send(`${msg.author.toString()} Removed reaction!`);
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
pattern: "reactions",
|
|
|
- action: msg => {
|
|
|
- let reactions = db.get("messageReactions").keys().value().reduce((p: string, c: string) => `${p}\n${c}`, "");
|
|
|
- msg.channel.send(`I'll react to the following messages:\n\`\`\`${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\`\`\``);
|
|
|
}
|
|
|
}
|
|
|
],
|
|
@@ -61,67 +96,79 @@ export default {
|
|
|
description: "Lists all known messages this bot can react to."
|
|
|
}
|
|
|
},
|
|
|
- onMessage: (actionsDone, msg, content) => {
|
|
|
+ onMessage: async (actionsDone, msg, content) => {
|
|
|
if (actionsDone)
|
|
|
return false;
|
|
|
|
|
|
let lowerContent = content.toLowerCase();
|
|
|
- if (db.get("messageReactions").has(lowerContent).value()) {
|
|
|
- msg.react(client.emojis.get((db.get("messageReactions") as ObjectChain<any>).get(lowerContent).value()));
|
|
|
+
|
|
|
+ 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;
|
|
|
|
|
|
- if (!(db.get("reactableMentionedUsers") as CollectionChain<any>).intersectionWith(msg.mentions.users.map(u => u.id)).isEmpty().value()) {
|
|
|
- const emoteId = ((db
|
|
|
- .get("emotes") as ObjectChain<any>)
|
|
|
- .get("angery") as IRandomElementMixin)
|
|
|
- .randomElement()
|
|
|
- .value();
|
|
|
- msg.react(client.emojis.find(e => e.id == emoteId));
|
|
|
- return true;
|
|
|
+ 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);
|
|
|
}
|
|
|
|
|
|
- return false;
|
|
|
+ let randomEmotes = await getRandomEmotes([...reactionEmoteTypes]);
|
|
|
+
|
|
|
+ for(let emote in randomEmotes)
|
|
|
+ await msg.react(client.emojis.find(e => e.id == emote));
|
|
|
+
|
|
|
+ return true;
|
|
|
},
|
|
|
- onIndirectMention: (actionsDone, msg) => {
|
|
|
+ onIndirectMention: async (actionsDone, msg) => {
|
|
|
if (actionsDone)
|
|
|
return false;
|
|
|
- let emoteType = "angery";
|
|
|
- if ((db.get("specialUsers") as CollectionChain<any>).includes(msg.author.id).value())
|
|
|
- emoteType = "hug";
|
|
|
- else if ((db.get("bigUsers") as CollectionChain<any>).includes(msg.author.id).value())
|
|
|
- emoteType = "big";
|
|
|
- else if ((db.get("dedUsers") as CollectionChain<any>).includes(msg.author.id).value())
|
|
|
- emoteType = "ded";
|
|
|
-
|
|
|
- let id = ((db
|
|
|
- .get("emotes") as ObjectChain<string>)
|
|
|
- .get(emoteType) as IRandomElementMixin)
|
|
|
- .randomElement()
|
|
|
- .value();
|
|
|
-
|
|
|
- let emote = client.emojis.find(e => e.id == id);
|
|
|
+ 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 ${id} no longer is valid. Deleting invalid emojis from the list...`);
|
|
|
- ((db.get("emotes") as ObjectChain<any>)
|
|
|
- .get(emoteType) as CollectionChain<any>)
|
|
|
- .remove((id: string) => !client.emojis.has(id))
|
|
|
- .write();
|
|
|
-
|
|
|
- id = ((db
|
|
|
- .get("emotes") as ObjectChain<any>)
|
|
|
- .get(emoteType) as IRandomElementMixin)
|
|
|
- .randomElement()
|
|
|
- .value();
|
|
|
- emote = client.emojis.find(e => e.id == id);
|
|
|
- }
|
|
|
+ console.log(`WARNING: Emote ${emotes[0]} no longer is valid. Deleting invalid emojis from the list...`);
|
|
|
|
|
|
- if (!emote)
|
|
|
+ let emotesRepo = getRepository(ReactionEmote);
|
|
|
+ emotesRepo.delete({ reactionId: emotes[0] });
|
|
|
return false;
|
|
|
+ }
|
|
|
|
|
|
msg.channel.send(emote.toString());
|
|
|
return true;
|