diff --git a/.gitignore b/.gitignore index 4d03540..cbaaaff 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,9 @@ node_modules # config file config.yml +#plugins data directory +data/ + # IDE config .idea/ diff --git a/src/plugins/admin.js b/src/plugins/admin.js index e8fc8dd..3c5e01d 100644 --- a/src/plugins/admin.js +++ b/src/plugins/admin.js @@ -2,6 +2,14 @@ import { omit } from "ramda"; import commandParser from "../commandParser"; import eventTypes from "../eventTypes"; +const getFormattedConfig = (config) => { + const sanitizedConfig = omit( + ["apiToken", "signingSecret", "appToken", "botToken"], + config + ); + return JSON.stringify(sanitizedConfig, null, 4); +}; + export default (config, emitter, log) => { const processMessage = async (message) => { const command = commandParser(message.text); @@ -19,10 +27,9 @@ export default (config, emitter, log) => { process.exit(); break; case "config": - const txt = JSON.stringify(omit(["apiToken"], config), null, 4); emitter.emit( eventTypes.OUT.sendMessage, - "```" + txt + "```", + "```" + getFormattedConfig(config) + "```", message.channel ); } diff --git a/src/plugins/index.js b/src/plugins/index.js new file mode 100644 index 0000000..1fcd093 --- /dev/null +++ b/src/plugins/index.js @@ -0,0 +1,43 @@ +import createDebug from "debug"; +import adminPlugin from "./admin"; + +export const initPlugins = async (config, emitter, app) => { + const log = createDebug("taperbot:core:plugins"); + const pluginsFolder = "./"; + + const plugins = Object.keys(config.plugins).map((pluginName) => { + log(`Iniciando plugin ${pluginName}`); + const pluginConfig = config.plugins[pluginName]; + try { + // eslint-disable-next-line no-constant-condition + if (!pluginConfig.v2) { + //V1 + return require(`${pluginsFolder}${pluginName}`).default( + pluginConfig, + emitter, + createDebug(`taperbot:${pluginName}`) + ); + } else { + // V2 + log(`${pluginName} esta en la nueva version 🚀`); + const plugin = require(`${pluginsFolder}v2/${pluginName}`).default({ + app, + config: pluginConfig, + log: createDebug(`taperbot:${pluginName}`), + }); + + plugin.commands.forEach((cm) => { + app.command(cm.command, cm.action); + }); + } + } catch (error) { + log(`Error inicializando plugin ${pluginName}`); + } + }); + + await Promise.all(plugins); + + return plugins.concat([ + adminPlugin(config, emitter, createDebug("taperbot:admin")), + ]); +}; diff --git a/src/plugins/v2/echo.js b/src/plugins/v2/echo.js new file mode 100644 index 0000000..a8d712f --- /dev/null +++ b/src/plugins/v2/echo.js @@ -0,0 +1,16 @@ +import { directMention } from "@slack/bolt"; +export const help = ""; + +export const commands = [ + { + command: "/echo", + description: "devuelve lo que le mandes", + }, +]; + +export default ({ app, config, log }) => { + app.message(directMention(), "/echo", async ({ message, say }) => { + log(message); + await say(`${message.text}`); + }); +}; diff --git a/src/plugins/v2/soto.js b/src/plugins/v2/soto.js new file mode 100644 index 0000000..262e29c --- /dev/null +++ b/src/plugins/v2/soto.js @@ -0,0 +1,53 @@ +import fs from "fs/promises"; +import { directMention } from "@slack/bolt"; +import dayjs from "dayjs"; +import "dayjs/locale/es"; +import "dayjs/plugin/relativeTime"; +import commandParser from "../../commandParser"; + +const sotoFile = "data/soto.json"; +let lastSotos = []; +export default async ({ app, log }) => { + try { + lastSotos = JSON.parse(await fs.readFile(sotoFile)); + } catch (error) { + log("Error cargando el archivo de last sotos"); + } + + app.message(directMention(), "soto?", async ({ message, say }) => { + log(message); + const { text } = commandParser(message.text); + const lastSoto = lastSotos[lastSotos.length]; + lastSotos.push({ date: dayjs().format(), text }); + fs.writeFile(sotoFile, JSON.stringify(lastSotos)); + if (lastSoto) { + await say(`Days since last Soto: ~${lastSoto.date}~ 0`); + } + }); + + return { + commands: [ + { + command: "/soto", + description: "Days since last soto", + action: async ({ ack, respond }) => { + log("SOTO"); + // Acknowledge command request + await ack(); + + await respond(`Soto!`); + }, + }, + ], + help: "le decis que viste a un soto y registra la cantidad de dias desde el ultimo avistaje de un soto", + homePage: () => ({ + type: "section", + text: { + type: "mrkdwn", + text: lastSotos + .map((soto) => `- ${dayjs(soto.date).fromNow()}: ${soto.text}`) + .join("\n"), + }, + }), + }; +}; diff --git a/src/run.js b/src/run.js index c207fc3..f9dc427 100644 --- a/src/run.js +++ b/src/run.js @@ -1,6 +1,7 @@ const { App } = require("@slack/bolt"); import { EventEmitter } from "events"; import createDebug from "debug"; + import { getConfig } from "./config"; import { getNextId, @@ -8,31 +9,19 @@ import { shouldProcess, isFromUser, } from "./messageUtil"; -import adminPlugin from "./plugins/admin"; + +import { initPlugins } from "./plugins"; import eventTypes from "./eventTypes"; import { getFromAPI, postToAPI } from "./slackWeb"; -const initPlugins = (config, emitter) => { - const pluginsFolder = "./plugins/"; - - return Object.keys(config.plugins) - .map((pluginName) => { - log(`Iniciando plugin ${pluginName}`); - const pluginConfig = config.plugins[pluginName]; - return require(`${pluginsFolder}${pluginName}`).default( - pluginConfig, - emitter, - createDebug(`taperbot:${pluginName}`) - ); - }) - .concat([adminPlugin(config, emitter, createDebug("taperbot:admin"))]); -}; - const log = createDebug("taperbot:core"); const devLog = createDebug("taperbot:core:dev"); const config = getConfig(); + +log("initing with config:"); log(config); + const app = new App({ token: config.botToken, signingSecret: config.signingSecret, @@ -66,7 +55,7 @@ app.event("reaction_removed", async ({ event, logger }) => { } }); -initPlugins(config, emitter); +initPlugins(config, emitter, app); const startServer = async () => { await app.start(process.env.PORT || 3000); diff --git a/test/commandParser.js b/test/commandParserTest.js similarity index 100% rename from test/commandParser.js rename to test/commandParserTest.js