const db = require("../db.js"); const util = require("../util.js"); const documentation = { "make name: keywords: contents: ": { auth: true, description: "Creates a new guide of the specified type, the specified keywords and content." }, "delete ": { auth: true, description: "Deletes a guide of the specified type." }, "guides": { auth: false, description: "Lists all guides and keywords that trigger them." }, "memes": { auth: false, description: "Lists all memes and keywords that trigger them." }, "miscs": { auth: false, description: "Lists all additional keywords the bot reacts to." } }; const VALID_GUIDE_TYPES = new Set(["meme", "guide", "misc"]); const makePattern = /^make (\w+)\s+name:(.+)\s*keywords:(.+)\s*contents:((.*[\n\r]*)+)$/i; const deletePattern = /^delete (\w+)\s+(.+)$/i; function listGuides(msg, guideType, message){ let guides = db .get(guideType) .reduce((p, c) => `${p}\n${c.displayName} -- ${c.name}`, "\n") .value(); msg.channel.send(`${msg.author.toString()} ${message}\n\`\`\`${guides}\`\`\`\n\nTo display the guides, ping me with one or more keywords, like \`@NoctBot sybaris com\``); } const commands = [ { pattern: makePattern, action: (msg, s, match) => { if (!util.isAuthorised(msg.member)) return; let type = match[1].toLowerCase(); let name = match[2].trim(); let keywords = match[3].trim().toLowerCase(); let contents = match[4].trim(); if(contents.length == 0){ msg.channel.send( `${msg.author.toString()} The guide must have some content!` ); return; } if(!VALID_GUIDE_TYPES.has(type)){ msg.channel.send( `${msg.author.toString()} The type ${type} is not a valid guide type!` ); return; } let typeDB = `${type}s`; let guide = db.get(typeDB).find({ name: keywords }); if (!guide.isUndefined().value()) { guide.assign({ displayName: name, content: contents }).write(); } else { db.get(typeDB) .push({ name: keywords, displayName: name, content: contents }) .write(); } msg.channel.send( `${msg.author.toString()} Added/updated "${name}" (keywords \`${keywords}\`)!` ); } }, { pattern: deletePattern, action: (msg, s, match) => { if (!util.isAuthorised(msg.member)) return; let type = match[1]; let keywords = match[2].trim(); if(!VALID_GUIDE_TYPES.has(type)){ msg.channel.send( `${msg.author.toString()} The type ${type} is not a valid guide type!` ); return; } let typeDB = `${type}s`; let val = db.get(typeDB).find({ name: keywords }); if (val.isUndefined().value()) { msg.channel.send(`${msg.author.toString()} No ${type} "${keywords}"!`); return; } db.get(typeDB) .remove({ name: keywords }) .write(); msg.channel.send( `${msg.author.toString()} Removed ${type} "${keywords}"!` ); } }, { pattern: "guides", action: msg => listGuides(msg, "guides", "Here are the guides I have:") }, { pattern: "memes", action: msg => listGuides(msg, "memes", "Here are some random memes I have:") }, { pattern: "misc", action: msg => listGuides(msg, "misc", "These are some misc stuff I can also do:") }, ]; const onDirectMention = (msg, content, actionsDone) => { if (actionsDone) return false; if(msg.attachments.size > 0 || content.length == 0) return false; let parts = content.trim().split(" "); let guide = db .get("guides") .clone() .concat(db.get("memes").value(), db.get("miscs").value()) .map(g => Object.assign({ parts: g.name.toLowerCase().split(" ") }, g)) .sortBy(g => g.parts.length) .maxBy(k => db._.intersection(parts, k.parts).length) .value(); let hits = guide !== undefined && db._.intersection(guide.name.toLowerCase().split(" "), parts).length > 0; if (hits) { msg.channel.send(guide.content); return true; } return false; }; module.exports = { commands: commands, onDirectMention: onDirectMention, documentation: documentation };