From d449d1d85d43fa860ec8bbfde3103af06c8d674d Mon Sep 17 00:00:00 2001 From: "Ean Milligan (Bastion)" Date: Sun, 14 Mar 2021 23:27:53 -0400 Subject: [PATCH] utils.log implemented Log files will now be created locally for easy debugging api.ts, mod.ts, intervals.ts, solver.ts - replaced console.log with utils.log mod.d.ts - made object syntax consistent utils.enums.ts - Created LogTypes enum for utils.log utils.ts - Created initLog and log for logging to files --- mod.ts | 232 +++++++++++++++++++++++---------------------- src/api.ts | 74 ++++++++------- src/intervals.ts | 4 +- src/mod.d.ts | 10 +- src/solver.ts | 4 +- src/utils.enums.ts | 13 +++ src/utils.ts | 56 ++++++++++- 7 files changed, 233 insertions(+), 160 deletions(-) create mode 100644 src/utils.enums.ts diff --git a/mod.ts b/mod.ts index 5ef0e74..2ba9367 100644 --- a/mod.ts +++ b/mod.ts @@ -23,6 +23,7 @@ import utils from "./src/utils.ts"; import solver from "./src/solver.ts"; import { EmojiConf } from "./src/mod.d.ts"; +import { LogTypes as LT } from "./src/utils.enums.ts"; import { DEVMODE, DEBUG, LOCALMODE } from "./flags.ts"; import config from "./config.ts"; @@ -37,13 +38,16 @@ const dbClient = await new Client().connect({ password: config.db.password }); +// Initialize logging client with folder to use for logs, needs --allow-write set on Deno startup +utils.initLog("logs"); + // Start up the Discord Bot startBot({ token: LOCALMODE ? config.localtoken : config.token, intents: [Intents.GUILD_MESSAGES, Intents.DIRECT_MESSAGES, Intents.GUILDS], eventHandlers: { ready: () => { - console.log(`${config.name} Logged in!`); + utils.log(LT.INFO, `${config.name} Logged in!`); editBotsStatus(StatusTypes.Online, "Booting up . . .", ActivityType.Game); // Interval to rotate the status text every 30 seconds to show off more commands @@ -51,34 +55,34 @@ startBot({ try { // Wrapped in try-catch due to hard crash possible editBotsStatus(StatusTypes.Online, intervals.getRandomStatus(cache), ActivityType.Game); - } catch (err) { - console.error("Failed to update status 00", err); + } catch (e) { + utils.log(LT.ERROR, `Failed to update status: ${JSON.stringify(e)}`); } }, 30000); // Interval to update bot list stats every 24 hours - LOCALMODE ? console.log("updateListStatistics not running") : setInterval(() => intervals.updateListStatistics(botID, cache.guilds.size), 86400000); + LOCALMODE ? utils.log(LT.INFO, "updateListStatistics not running") : setInterval(() => intervals.updateListStatistics(botID, cache.guilds.size), 86400000); // setTimeout added to make sure the startup message does not error out setTimeout(() => { - LOCALMODE ? console.log("updateListStatistics not running") : intervals.updateListStatistics(botID, cache.guilds.size); + LOCALMODE ? utils.log(LT.INFO, "updateListStatistics not running") : intervals.updateListStatistics(botID, cache.guilds.size); editBotsStatus(StatusTypes.Online, `Boot Complete`, ActivityType.Game); - sendMessage(config.logChannel, `${config.name} has started, running version ${config.version}.`).catch(() => { - console.error("Failed to send message 00"); + sendMessage(config.logChannel, `${config.name} has started, running version ${config.version}.`).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(e)}`); }); }, 1000); }, guildCreate: (guild: Guild) => { - sendMessage(config.logChannel, `New guild joined: ${guild.name} (id: ${guild.id}). This guild has ${guild.memberCount} members!`).catch(() => { - console.error("Failed to send message 01"); + sendMessage(config.logChannel, `New guild joined: ${guild.name} (id: ${guild.id}). This guild has ${guild.memberCount} members!`).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(e)}`); }); }, guildDelete: (guild: Guild) => { - sendMessage(config.logChannel, `I have been removed from: ${guild.name} (id: ${guild.id}).`).catch(() => { - console.error("Failed to send message 02"); + sendMessage(config.logChannel, `I have been removed from: ${guild.name} (id: ${guild.id}).`).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(e)}`); }); }, - debug: (DEVMODE ? console.error : () => { }), + debug: dmsg => utils.log(LT.LOG, `${JSON.stringify(dmsg)}`), messageCreate: async (message: Message) => { // Ignore all other bots if (message.author.bot) return; @@ -96,16 +100,16 @@ startBot({ // Its a ping test, what else do you want. if (command === "ping") { // Light telemetry to see how many times a command is being run - dbClient.execute(`CALL INC_CNT("ping");`).catch(err => { - console.error("Failed to call procedure 00", err); + dbClient.execute(`CALL INC_CNT("ping");`).catch(e => { + utils.log(LT.ERROR, `Failed to call stored procedure INC_CNT: ${JSON.stringify(e)}`); }); // Calculates ping between sending a message and editing it, giving a nice round-trip latency. try { const m = await utils.sendIndirectMessage(message, "Ping?", sendMessage, sendDirectMessage); m.edit(`Pong! Latency is ${m.timestamp - message.timestamp}ms.`); - } catch (err) { - console.error("Failed to send message 10", message, err); + } catch (e) { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); } } @@ -113,12 +117,12 @@ startBot({ // Displays a short message I wanted to include else if (command === "rip" || command === "memory") { // Light telemetry to see how many times a command is being run - dbClient.execute(`CALL INC_CNT("rip");`).catch(err => { - console.error("Failed to call procedure 01", err); + dbClient.execute(`CALL INC_CNT("rip");`).catch(e => { + utils.log(LT.ERROR, `Failed to call stored procedure INC_CNT: ${JSON.stringify(e)}`); }); - utils.sendIndirectMessage(message, "The Artificer was built in memory of my Grandmother, Babka\nWith much love, Ean\n\nDecember 21, 2020", sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 11", message, err); + utils.sendIndirectMessage(message, "The Artificer was built in memory of my Grandmother, Babka\nWith much love, Ean\n\nDecember 21, 2020", sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } @@ -126,12 +130,12 @@ startBot({ // Help command specifically for the roll command else if (command === "rollhelp" || command === "rh" || command === "hr" || command === "??" || command?.startsWith("xdy")) { // Light telemetry to see how many times a command is being run - dbClient.execute(`CALL INC_CNT("rollhelp");`).catch(err => { - console.error("Failed to call procedure 02", err); + dbClient.execute(`CALL INC_CNT("rollhelp");`).catch(e => { + utils.log(LT.ERROR, `Failed to call stored procedure INC_CNT: ${JSON.stringify(e)}`); }); - utils.sendIndirectMessage(message, longStrs.rollhelp.join("\n"), sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 21", message, err); + utils.sendIndirectMessage(message, longStrs.rollhelp.join("\n"), sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } @@ -139,12 +143,12 @@ startBot({ // Help command, prints from help file else if (command === "help" || command === "h" || command === "?") { // Light telemetry to see how many times a command is being run - dbClient.execute(`CALL INC_CNT("help");`).catch(err => { - console.error("Failed to call procedure 03", err); + dbClient.execute(`CALL INC_CNT("help");`).catch(e => { + utils.log(LT.ERROR, `Failed to call stored procedure INC_CNT: ${JSON.stringify(e)}`); }); - utils.sendIndirectMessage(message, longStrs.help.join("\n"), sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 20", message, err); + utils.sendIndirectMessage(message, longStrs.help.join("\n"), sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } @@ -152,12 +156,12 @@ startBot({ // Info command, prints short desc on bot and some links else if (command === "info" || command === "i") { // Light telemetry to see how many times a command is being run - dbClient.execute(`CALL INC_CNT("info");`).catch(err => { - console.error("Failed to call procedure 04", err); + dbClient.execute(`CALL INC_CNT("info");`).catch(e => { + utils.log(LT.ERROR, `Failed to call stored procedure INC_CNT: ${JSON.stringify(e)}`); }); - utils.sendIndirectMessage(message, longStrs.info.join("\n"), sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 22", message, err); + utils.sendIndirectMessage(message, longStrs.info.join("\n"), sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } @@ -165,12 +169,12 @@ startBot({ // Privacy command, prints short desc on bot's privacy policy else if (command === "privacy") { // Light telemetry to see how many times a command is being run - dbClient.execute(`CALL INC_CNT("privacy");`).catch(err => { - console.error("Failed to call procedure 04", err); + dbClient.execute(`CALL INC_CNT("privacy");`).catch(e => { + utils.log(LT.ERROR, `Failed to call stored procedure INC_CNT: ${JSON.stringify(e)}`); }); - utils.sendIndirectMessage(message, longStrs.privacy.join("\n"), sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 2E", message, err); + utils.sendIndirectMessage(message, longStrs.privacy.join("\n"), sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } @@ -178,12 +182,12 @@ startBot({ // Returns version of the bot else if (command === "version" || command === "v") { // Light telemetry to see how many times a command is being run - dbClient.execute(`CALL INC_CNT("version");`).catch(err => { - console.error("Failed to call procedure 05", err); + dbClient.execute(`CALL INC_CNT("version");`).catch(e => { + utils.log(LT.ERROR, `Failed to call stored procedure INC_CNT: ${JSON.stringify(e)}`); }); - utils.sendIndirectMessage(message, `My current version is ${config.version}.`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 30", message, err); + utils.sendIndirectMessage(message, `My current version is ${config.version}.`, sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } @@ -191,15 +195,15 @@ startBot({ // Manually report a failed roll else if (command === "report" || command === "r") { // Light telemetry to see how many times a command is being run - dbClient.execute(`CALL INC_CNT("report");`).catch(err => { - console.error("Failed to call procedure 06", err); + dbClient.execute(`CALL INC_CNT("report");`).catch(e => { + utils.log(LT.ERROR, `Failed to call stored procedure INC_CNT: ${JSON.stringify(e)}`); }); - sendMessage(config.reportChannel, ("USER REPORT:\n" + args.join(" "))).catch(err => { - console.error("Failed to send message 50", message, err); + sendMessage(config.reportChannel, ("USER REPORT:\n" + args.join(" "))).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); - utils.sendIndirectMessage(message, "Failed command has been reported to my developer.\n\nFor more in depth support, and information about planned maintenance, please join the support server here: https://discord.gg/peHASXMZYv", sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 51", message, err); + utils.sendIndirectMessage(message, "Failed command has been reported to my developer.\n\nFor more in depth support, and information about planned maintenance, please join the support server here: https://discord.gg/peHASXMZYv", sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } @@ -207,22 +211,22 @@ startBot({ // Displays stats on the bot else if (command === "stats" || command === "s") { // Light telemetry to see how many times a command is being run - dbClient.execute(`CALL INC_CNT("stats");`).catch(err => { - console.error("Failed to call procedure 07", err); + dbClient.execute(`CALL INC_CNT("stats");`).catch(e => { + utils.log(LT.ERROR, `Failed to call stored procedure INC_CNT: ${JSON.stringify(e)}`); }); // Calculate how many times commands have been run - const rollQuery = await dbClient.query(`SELECT count FROM command_cnt WHERE command = "roll";`).catch(err => { - console.error("Failed to query 17", err); + const rollQuery = await dbClient.query(`SELECT count FROM command_cnt WHERE command = "roll";`).catch(e => { + utils.log(LT.ERROR, `Failed to query DB: ${JSON.stringify(e)}`); }); - const totalQuery = await dbClient.query(`SELECT SUM(count) as count FROM command_cnt;`).catch(err => { - console.error("Failed to query 27", err); + const totalQuery = await dbClient.query(`SELECT SUM(count) as count FROM command_cnt;`).catch(e => { + utils.log(LT.ERROR, `Failed to query DB: ${JSON.stringify(e)}`); }); const rolls = BigInt(rollQuery[0].count); const total = BigInt(totalQuery[0].count); - utils.sendIndirectMessage(message, `${config.name} is rolling dice for ${cache.members.size} active users, in ${cache.channels.size} channels of ${cache.guilds.size} servers.\n\nSo far, ${rolls} dice have been rolled and ${total - rolls} utility commands have been run.`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 60", message, err); + utils.sendIndirectMessage(message, `${config.name} is rolling dice for ${cache.members.size} active users, in ${cache.channels.size} channels of ${cache.guilds.size} servers.\n\nSo far, ${rolls} dice have been rolled and ${total - rolls} utility commands have been run.`, sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } @@ -230,8 +234,8 @@ startBot({ // API sub commands else if (command === "api" && args.length > 0) { // Light telemetry to see how many times a command is being run - dbClient.execute(`CALL INC_CNT("api");`).catch(err => { - console.error("Failed to call procedure 0A", err); + dbClient.execute(`CALL INC_CNT("api");`).catch(e => { + utils.log(LT.ERROR, `Failed to call stored procedure INC_CNT: ${JSON.stringify(e)}`); }); // Local apiArg in lowercase @@ -239,8 +243,8 @@ startBot({ // Alert users who DM the bot that this command is for guilds only if (message.guildID === "") { - utils.sendIndirectMessage(message, `API commands are only available in guilds.`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 24", message, err); + utils.sendIndirectMessage(message, `API commands are only available in guilds.`, sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); return; } @@ -250,61 +254,61 @@ startBot({ // [[api help // Shows API help details if (apiArg === "help") { - utils.sendIndirectMessage(message, longStrs.apihelp.join("\n"), sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 23", message, err); + utils.sendIndirectMessage(message, longStrs.apihelp.join("\n"), sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } // [[api allow/block // Lets a guild admin allow or ban API rolls from happening in said guild else if (apiArg === "allow" || apiArg === "block" || apiArg === "enable" || apiArg === "disable") { - const guildQuery = await dbClient.query(`SELECT guildid FROM allowed_guilds WHERE guildid = ?`, [message.guildID]).catch(err => { - console.error("Failed to query 1A", err); - utils.sendIndirectMessage(message, `Failed to ${apiArg} API rolls for this guild. If this issue persists, please report this to the developers.`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 29", message, err); + const guildQuery = await dbClient.query(`SELECT guildid FROM allowed_guilds WHERE guildid = ?`, [message.guildID]).catch(e0 => { + utils.log(LT.ERROR, `Failed to query DB: ${JSON.stringify(e0)}`); + utils.sendIndirectMessage(message, `Failed to ${apiArg} API rolls for this guild. If this issue persists, please report this to the developers.`, sendMessage, sendDirectMessage).catch(e1 => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e1)}`); }); return; }); if (guildQuery.length === 0) { // Since guild is not in our DB, add it in - await dbClient.execute(`INSERT INTO allowed_guilds(guildid,active) values(?,?)`, [BigInt(message.guildID), ((apiArg === "allow" || apiArg === "enable") ? 1 : 0)]).catch(err => { - console.error("Failed to inersert 2A", err); - utils.sendIndirectMessage(message, `Failed to ${apiArg} API rolls for this guild. If this issue persists, please report this to the developers.`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 26", message, err); + await dbClient.execute(`INSERT INTO allowed_guilds(guildid,active) values(?,?)`, [BigInt(message.guildID), ((apiArg === "allow" || apiArg === "enable") ? 1 : 0)]).catch(e0 => { + utils.log(LT.ERROR, `Failed to insert into DB: ${JSON.stringify(e0)}`); + utils.sendIndirectMessage(message, `Failed to ${apiArg} API rolls for this guild. If this issue persists, please report this to the developers.`, sendMessage, sendDirectMessage).catch(e1 => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e1)}`); }); return; }); } else { // Since guild is in our DB, update it - await dbClient.execute(`UPDATE allowed_guilds SET active = ? WHERE guildid = ?`, [((apiArg === "allow" || apiArg === "enable") ? 1 : 0), BigInt(message.guildID)]).catch(err => { - console.error("Failed to inersert 3A", err); - utils.sendIndirectMessage(message, `Failed to ${apiArg} API rolls for this guild. If this issue persists, please report this to the developers.`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 28", message, err); + await dbClient.execute(`UPDATE allowed_guilds SET active = ? WHERE guildid = ?`, [((apiArg === "allow" || apiArg === "enable") ? 1 : 0), BigInt(message.guildID)]).catch(e0 => { + utils.log(LT.ERROR, `Failed to update DB: ${JSON.stringify(e0)}`); + utils.sendIndirectMessage(message, `Failed to ${apiArg} API rolls for this guild. If this issue persists, please report this to the developers.`, sendMessage, sendDirectMessage).catch(e1 => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e1)}`); }); return; }); } // We won't get here if there's any errors, so we know it has bee successful, so report as such - utils.sendIndirectMessage(message, `API rolls have successfully been ${apiArg}ed for this guild.`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 27", message, err); + utils.sendIndirectMessage(message, `API rolls have successfully been ${apiArg}ed for this guild.`, sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } // [[api delete // Lets a guild admin delete their server from the database else if (apiArg === "delete") { - await dbClient.execute(`DELETE FROM allowed_guilds WHERE guildid = ?`, [message.guildID]).catch(err => { - console.error("Failed to query 1B", err); - utils.sendIndirectMessage(message, `Failed to delete this guild from the database. If this issue persists, please report this to the developers.`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 2F", message, err); + await dbClient.execute(`DELETE FROM allowed_guilds WHERE guildid = ?`, [message.guildID]).catch(e0 => { + utils.log(LT.ERROR, `Failed to query DB: ${JSON.stringify(e0)}`); + utils.sendIndirectMessage(message, `Failed to delete this guild from the database. If this issue persists, please report this to the developers.`, sendMessage, sendDirectMessage).catch(e1 => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e1)}`); }); return; }); // We won't get here if there's any errors, so we know it has bee successful, so report as such - utils.sendIndirectMessage(message, `This guild's API setting has been removed from The Artifier's Database.`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 2G", message, err); + utils.sendIndirectMessage(message, `This guild's API setting has been removed from The Artifier's Database.`, sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } @@ -312,10 +316,10 @@ startBot({ // Lets a guild admin check the status of API rolling in said guild else if (apiArg === "status") { // Get status of guild from the db - const guildQuery = await dbClient.query(`SELECT active, banned FROM allowed_guilds WHERE guildid = ?`, [message.guildID]).catch(err => { - console.error("Failed to query 1A", err); - utils.sendIndirectMessage(message, `Failed to check API rolls status for this guild. If this issue persists, please report this to the developers.`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 2A", message, err); + const guildQuery = await dbClient.query(`SELECT active, banned FROM allowed_guilds WHERE guildid = ?`, [message.guildID]).catch(e0 => { + utils.log(LT.ERROR, `Failed to query DB: ${JSON.stringify(e0)}`); + utils.sendIndirectMessage(message, `Failed to check API rolls status for this guild. If this issue persists, please report this to the developers.`, sendMessage, sendDirectMessage).catch(e1 => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e1)}`); }); return; }); @@ -324,24 +328,24 @@ startBot({ if (guildQuery.length > 0) { // Check if guild is banned from using API and return appropriate message if (guildQuery[0].banned) { - utils.sendIndirectMessage(message, `The Artificer's API is ${config.api.enable ? "currently enabled" : "currently disabled"}.\n\nAPI rolls are banned from being used in this guild. This will not be reversed.`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 2B", message, err); + utils.sendIndirectMessage(message, `The Artificer's API is ${config.api.enable ? "currently enabled" : "currently disabled"}.\n\nAPI rolls are banned from being used in this guild. This will not be reversed.`, sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } else { - utils.sendIndirectMessage(message, `The Artificer's API is ${config.api.enable ? "currently enabled" : "currently disabled"}.\n\nAPI rolls are ${guildQuery[0].active ? "allowed" : "blocked from being used"} in this guild.`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 2C", message, err); + utils.sendIndirectMessage(message, `The Artificer's API is ${config.api.enable ? "currently enabled" : "currently disabled"}.\n\nAPI rolls are ${guildQuery[0].active ? "allowed" : "blocked from being used"} in this guild.`, sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } } else { // Guild is not in DB, therefore they are blocked - utils.sendIndirectMessage(message, `The Artificer's API is ${config.api.enable ? "currently enabled" : "currently disabled"}.\n\nAPI rolls are blocked from being used in this guild.`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 2D", message, err); + utils.sendIndirectMessage(message, `The Artificer's API is ${config.api.enable ? "currently enabled" : "currently disabled"}.\n\nAPI rolls are blocked from being used in this guild.`, sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } } } else { - utils.sendIndirectMessage(message, `API commands are powerful and can only be used by guild Owners and Admins.\n\nFor information on how to use the API, please check the GitHub README for more information: `, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 25", message, err); + utils.sendIndirectMessage(message, `API commands are powerful and can only be used by guild Owners and Admins.\n\nFor information on how to use the API, please check the GitHub README for more information: `, sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } } @@ -350,14 +354,14 @@ startBot({ // Dice rolling commence! else if ((command + args.join("")).indexOf(config.postfix) > -1) { // Light telemetry to see how many times a command is being run - dbClient.execute(`CALL INC_CNT("roll");`).catch(err => { - console.error("Failed to call procedure 08", err); + dbClient.execute(`CALL INC_CNT("roll");`).catch(e => { + utils.log(LT.ERROR, `Failed to call stored procedure INC_CNT: ${JSON.stringify(e)}`); }); // If DEVMODE is on, only allow this command to be used in the devServer if (DEVMODE && message.guildID !== config.devServer) { - utils.sendIndirectMessage(message, "Command is in development, please try again later.", sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 70", message, err); + utils.sendIndirectMessage(message, "Command is in development, please try again later.", sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); return; } @@ -421,7 +425,7 @@ startBot({ if (DEVMODE && config.logRolls) { // If enabled, log rolls so we can verify the bots math dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,0,1)", [originalCommand, "NoGMsFound", m.id]).catch(e => { - console.log("Failed to insert into database 00", e); + utils.log(LT.ERROR, `Failed to insert into DB: ${JSON.stringify(e)}`); }); } return; @@ -440,7 +444,7 @@ startBot({ if (DEVMODE && config.logRolls) { // If enabled, log rolls so we can verify the bots math dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,0,1)", [originalCommand, "NoOrderFound", m.id]).catch(e => { - console.log("Failed to insert into database 05", e); + utils.log(LT.ERROR, `Failed to insert into DB: ${JSON.stringify(e)}`); }); } return; @@ -463,7 +467,7 @@ startBot({ if (DEVMODE && config.logRolls) { // If enabled, log rolls so we can verify the bots math dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,0,1)", [originalCommand, "MaxAndNominal", m.id]).catch(e => { - console.log("Failed to insert into database 01", e); + utils.log(LT.ERROR, `Failed to insert into DB: ${JSON.stringify(e)}`); }); } return; @@ -483,7 +487,7 @@ startBot({ if (DEVMODE && config.logRolls) { // If enabled, log rolls so we can verify the bots math dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,0,1)", [originalCommand, returnmsg.errorCode, m.id]).catch(e => { - console.log("Failed to insert into database 02", e); + utils.log(LT.ERROR, `Failed to insert into DB: ${JSON.stringify(e)}`); }); } return; @@ -523,7 +527,7 @@ startBot({ if (DEVMODE && config.logRolls) { // If enabled, log rolls so we can verify the bots math dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,0,0)", [originalCommand, returnText, m.id]).catch(e => { - console.log("Failed to insert into database 03", e); + utils.log(LT.ERROR, `Failed to insert into DB: ${JSON.stringify(e)}`); }); } } else { @@ -547,12 +551,12 @@ startBot({ if (DEVMODE && config.logRolls) { // If enabled, log rolls so we can verify the bots math dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,0,0)", [originalCommand, returnText, m.id]).catch(e => { - console.log("Failed to insert into database 04", e); + utils.log(LT.ERROR, `Failed to insert into DB: ${JSON.stringify(e)}`); }); } } - } catch (err) { - console.error("Something failed 71"); + } catch (e) { + utils.log(LT.ERROR, `Undandled Error: ${JSON.stringify(e)}`); } } @@ -560,22 +564,22 @@ startBot({ // Check if the unhandled command is an emoji request else { // Start looping thru the possible emojis - config.emojis.some((e: EmojiConf) => { + config.emojis.some((emoji: EmojiConf) => { // If a match gets found - if (e.aliases.indexOf(command || "") > -1) { + if (emoji.aliases.indexOf(command || "") > -1) { // Light telemetry to see how many times a command is being run - dbClient.execute(`CALL INC_CNT("emoji");`).catch(err => { - console.error("Failed to call procedure 09", err); + dbClient.execute(`CALL INC_CNT("emoji");`).catch(e => { + utils.log(LT.ERROR, `Failed to call stored procedure INC_CNT: ${JSON.stringify(e)}`); }); - // Send the needed emoji - utils.sendIndirectMessage(message, `<${e.animated ? "a" : ""}:${e.name}:${e.id}>`, sendMessage, sendDirectMessage).catch(err => { - console.error("Failed to send message 40", message, err); + // Send the needed emoji1 + utils.sendIndirectMessage(message, `<${emoji.animated ? "a" : ""}:${emoji.name}:${emoji.id}>`, sendMessage, sendDirectMessage).catch(e => { + utils.log(LT.ERROR, `Failed to send message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); // And attempt to delete if needed - if (e.deleteSender) { - message.delete().catch(err => { - console.error("Failed to delete message 41", message, err); + if (emoji.deleteSender) { + message.delete().catch(e => { + utils.log(LT.WARN, `Failed to delete message: ${JSON.stringify(message)} | ${JSON.stringify(e)}`); }); } return true; diff --git a/src/api.ts b/src/api.ts index fce7471..87c143e 100644 --- a/src/api.ts +++ b/src/api.ts @@ -20,6 +20,8 @@ import { } from "../deps.ts"; import solver from "./solver.ts"; +import { LogTypes as LT } from "./utils.enums.ts"; +import utils from "./utils.ts"; import config from "../config.ts"; @@ -27,7 +29,7 @@ import config from "../config.ts"; // start initializes and runs the entire API for the bot const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string, m: (string | MessageContent)) => Promise, sendDirectMessage: (c: string, m: (string | MessageContent)) => Promise): Promise => { const server = serve({ hostname: "0.0.0.0", port: config.api.port }); - console.log(`HTTP api running at: http://localhost:${config.api.port}/`); + utils.log(LT.LOG, `HTTP api running at: http://localhost:${config.api.port}/`); // rateLimitTime holds all users with the last time they started a rate limit timer const rateLimitTime = new Map(); @@ -108,8 +110,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string let erroredOut = false; // Insert new key/user pair into the db - await dbClient.execute("INSERT INTO all_keys(userid,apiKey) values(?,?)", [apiUserid, newKey]).catch(() => { - console.log("Failed to insert into database 20"); + await dbClient.execute("INSERT INTO all_keys(userid,apiKey) values(?,?)", [apiUserid, newKey]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); request.respond({ status: Status.InternalServerError, body: STATUS_TEXT.get(Status.InternalServerError) }); erroredOut = true; }); @@ -139,8 +141,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string let erroredOut = false; // Get all channels userid has authorized - const dbAllowedChannelQuery = await dbClient.query("SELECT * FROM allowed_channels WHERE userid = ?", [apiUserid]).catch(() => { - console.log("Failed to query database 22"); + const dbAllowedChannelQuery = await dbClient.query("SELECT * FROM allowed_channels WHERE userid = ?", [apiUserid]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); request.respond({ status: Status.InternalServerError, body: STATUS_TEXT.get(Status.InternalServerError) }); erroredOut = true; }); @@ -206,8 +208,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string request.respond({ status: Status.BadRequest, body: STATUS_TEXT.get(Status.BadRequest) }); // Always log API rolls for abuse detection - dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,1,1)", [originalCommand, "EmptyInput", null]).catch(() => { - console.log("Failed to insert into database 10"); + dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,1,1)", [originalCommand, "EmptyInput", null]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); }); break; } @@ -217,8 +219,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string request.respond({ status: Status.BadRequest, body: STATUS_TEXT.get(Status.BadRequest) }); // Always log API rolls for abuse detection - dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,1,1)", [originalCommand, "BadOrder", null]).catch(() => { - console.log("Failed to insert into database 10"); + dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,1,1)", [originalCommand, "BadOrder", null]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); }); break; } @@ -238,8 +240,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string request.respond({ status: Status.InternalServerError, body: returnmsg.errorMsg }); // Always log API rolls for abuse detection - dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,1,1)", [originalCommand, returnmsg.errorCode, null]).catch(() => { - console.log("Failed to insert into database 11"); + dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,1,1)", [originalCommand, returnmsg.errorCode, null]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); }); break; } else { @@ -268,8 +270,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string request.respond({ status: Status.BadRequest, body: STATUS_TEXT.get(Status.BadRequest) }); // Always log API rolls for abuse detection - dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,1,1)", [originalCommand, "NoGMsSent", null]).catch(() => { - console.log("Failed to insert into database 12"); + dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,1,1)", [originalCommand, "NoGMsSent", null]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); }); break; } @@ -307,12 +309,12 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string // Send the return message as a DM or normal message depening on if the channel is set if ((query.get("channel") || "").length > 0) { m = await sendMessage(query.get("channel") || "", failedSend).catch(() => { - request.respond({ status: Status.InternalServerError, body: "Message 10 failed to send." }); + request.respond({ status: Status.InternalServerError, body: "Message failed to send." }); errorOut = true; }); } else { m = await sendDirectMessage(query.get("user") || "", failedSend).catch(() => { - request.respond({ status: Status.InternalServerError, body: "Message 11 failed to send." }); + request.respond({ status: Status.InternalServerError, body: "Message failed to send." }); errorOut = true; }); } @@ -320,8 +322,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string }); // Always log API rolls for abuse detection - dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,1,0)", [originalCommand, returnText, ((typeof m === "object") ? m.id : null)]).catch(() => { - console.log("Failed to insert into database 13"); + dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,1,0)", [originalCommand, returnText, ((typeof m === "object") ? m.id : null)]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); }); // Handle closing the request out @@ -362,8 +364,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string } // If enabled, log rolls so we can verify the bots math - dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,1,0)", [originalCommand, returnText, ((typeof m === "object") ? m.id : null)]).catch(() => { - console.log("Failed to insert into database 14"); + dbClient.execute("INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,1,0)", [originalCommand, returnText, ((typeof m === "object") ? m.id : null)]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); }); // Handle closing the request out @@ -376,7 +378,7 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string } } catch (err) { // Handle any errors we missed - console.log(err) + utils.log(LT.ERROR, `Unhandled Error: ${JSON.stringify(err)}`); request.respond({ status: Status.InternalServerError, body: STATUS_TEXT.get(Status.InternalServerError) }); } } else { @@ -404,8 +406,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string let erroredOut = false; // Insert new user/channel pair into the db - await dbClient.execute("INSERT INTO allowed_channels(userid,channelid) values(?,?)", [apiUserid, BigInt(query.get("channel"))]).catch(() => { - console.log("Failed to insert into database 21"); + await dbClient.execute("INSERT INTO allowed_channels(userid,channelid) values(?,?)", [apiUserid, BigInt(query.get("channel"))]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); request.respond({ status: Status.InternalServerError, body: STATUS_TEXT.get(Status.InternalServerError) }); erroredOut = true; }); @@ -463,8 +465,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string } // Execute the DB modification - await dbClient.execute("UPDATE all_keys SET ?? = ? WHERE userid = ?", [key, value, apiUserid]).catch(() => { - console.log("Failed to update database 28"); + await dbClient.execute("UPDATE all_keys SET ?? = ? WHERE userid = ?", [key, value, apiUserid]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); request.respond({ status: Status.InternalServerError, body: STATUS_TEXT.get(Status.InternalServerError) }); erroredOut = true; }); @@ -503,8 +505,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string } // Execute the DB modification - await dbClient.execute("UPDATE allowed_channels SET banned = ? WHERE userid = ? AND channelid = ?", [value, apiUserid, BigInt(query.get("channel"))]).catch(() => { - console.log("Failed to update database 24"); + await dbClient.execute("UPDATE allowed_channels SET banned = ? WHERE userid = ? AND channelid = ?", [value, apiUserid, BigInt(query.get("channel"))]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); request.respond({ status: Status.InternalServerError, body: STATUS_TEXT.get(Status.InternalServerError) }); erroredOut = true; }); @@ -543,8 +545,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string } // Update the requested entry - await dbClient.execute("UPDATE allowed_channels SET active = ? WHERE userid = ? AND channelid = ?", [value, apiUserid, BigInt(query.get("channel"))]).catch(() => { - console.log("Failed to update database 26"); + await dbClient.execute("UPDATE allowed_channels SET active = ? WHERE userid = ? AND channelid = ?", [value, apiUserid, BigInt(query.get("channel"))]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); request.respond({ status: Status.InternalServerError, body: STATUS_TEXT.get(Status.InternalServerError) }); erroredOut = true; }); @@ -583,8 +585,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string // User has recieved their delete code and we need to delete the account now let erroredOut = false; - await dbClient.execute("DELETE FROM allowed_channels WHERE userid = ?", [apiUserid]).catch(() => { - console.log("Failed to delete from database 2A"); + await dbClient.execute("DELETE FROM allowed_channels WHERE userid = ?", [apiUserid]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); request.respond({ status: Status.InternalServerError, body: STATUS_TEXT.get(Status.InternalServerError) }); erroredOut = true; }); @@ -592,8 +594,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string break; } - await dbClient.execute("DELETE FROM all_keys WHERE userid = ?", [apiUserid]).catch(() => { - console.log("Failed to delete from database 2B"); + await dbClient.execute("DELETE FROM all_keys WHERE userid = ?", [apiUserid]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); request.respond({ status: Status.InternalServerError, body: STATUS_TEXT.get(Status.InternalServerError) }); erroredOut = true; }); @@ -615,8 +617,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string let erroredOut = false; // Execute the DB modification - await dbClient.execute("UPDATE all_keys SET deleteCode = ? WHERE userid = ?", [deleteCode, apiUserid]).catch(() => { - console.log("Failed to update database 29"); + await dbClient.execute("UPDATE all_keys SET deleteCode = ? WHERE userid = ?", [deleteCode, apiUserid]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); request.respond({ status: Status.InternalServerError, body: STATUS_TEXT.get(Status.InternalServerError) }); erroredOut = true; }); @@ -689,8 +691,8 @@ const start = async (dbClient: Client, cache: CacheData, sendMessage: (c: string let erroredOut = false; // Insert new key/user pair into the db - await dbClient.execute("INSERT INTO all_keys(userid,apiKey,email) values(?,?,?)", [BigInt(query.get("user")), newKey, (query.get("email") || "").toLowerCase()]).catch(() => { - console.log("Failed to insert into database 20"); + await dbClient.execute("INSERT INTO all_keys(userid,apiKey,email) values(?,?,?)", [BigInt(query.get("user")), newKey, (query.get("email") || "").toLowerCase()]).catch(e => { + utils.log(LT.ERROR, `Failed to insert into database: ${JSON.stringify(e)}`); request.respond({ status: Status.InternalServerError, body: STATUS_TEXT.get(Status.InternalServerError) }); erroredOut = true; }); diff --git a/src/intervals.ts b/src/intervals.ts index e2e772b..ad83819 100644 --- a/src/intervals.ts +++ b/src/intervals.ts @@ -8,6 +8,8 @@ import { // Discordeno deps CacheData } from "../deps.ts"; +import { LogTypes as LT } from "./utils.enums.ts"; +import utils from "./utils.ts"; import config from "../config.ts"; @@ -47,7 +49,7 @@ const updateListStatistics = (botID: string, serverCount: number): void => { "headers": tempHeaders, "body": JSON.stringify(e.body).replace('"?{server_count}"', serverCount.toString()) // ?{server_count} needs the "" removed from around it aswell to make sure its sent as a number }); - console.log(response); + utils.log(LT.LOG, `${JSON.stringify(response)}`); } }); }; diff --git a/src/mod.d.ts b/src/mod.d.ts index e1f3cfb..9470dd6 100644 --- a/src/mod.d.ts +++ b/src/mod.d.ts @@ -2,9 +2,9 @@ // EmojiConf is used as a structure for the emojis stored in config.ts export type EmojiConf = { - "name": string, - "aliases": Array, - "id": string, - "animated": boolean, - "deleteSender": boolean + name: string, + aliases: Array, + id: string, + animated: boolean, + deleteSender: boolean }; diff --git a/src/solver.ts b/src/solver.ts index 4f1be5e..c50236d 100644 --- a/src/solver.ts +++ b/src/solver.ts @@ -5,6 +5,8 @@ */ import { RollSet, SolvedStep, SolvedRoll, ReturnData } from "./solver.d.ts"; +import { LogTypes as LT } from "./utils.enums.ts"; +import utils from "./utils.ts"; // MAXLOOPS determines how long the bot will attempt a roll // Default is 5000000 (5 million), which results in at most a 10 second delay before the bot calls the roll infinite or too complex @@ -987,7 +989,7 @@ const parseRoll = (fullCmd: string, localPrefix: string, localPostfix: string, m errorMsg = "Error: Roll became undefined, one or more operands are not a roll or a number, check input"; break; default: - console.error(errorName, errorDetails); + utils.log(LT.ERROR, `Undangled Error: ${errorName}, ${errorDetails}`); errorMsg = "Unhandled Error: " + solverError.message + "\nCheck input and try again, if issue persists, please use `[[report` to alert the devs of the issue"; break; } diff --git a/src/utils.enums.ts b/src/utils.enums.ts new file mode 100644 index 0000000..4e87094 --- /dev/null +++ b/src/utils.enums.ts @@ -0,0 +1,13 @@ +/* The Artificer was built in memory of Babka + * With love, Ean + * + * December 21, 2020 + */ + +// enum for all possible console.log types +export enum LogTypes { + LOG = "log", + INFO = "info", + WARN = "warn", + ERROR = "error" +} \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index 5a3bd3d..abd7c99 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -6,9 +6,19 @@ import { // Discordeno deps - Message, MessageContent + Message, MessageContent, + + // nanoid deps + nanoid } from "../deps.ts"; +import { LogTypes } from "./utils.enums.ts"; + +// Constant initialized at runtime for consistent file names +let startDate: string; +let logFolder: string; +let initialized = false; + // split2k(longMessage) returns shortMessage[] // split2k takes a long string in and cuts it into shorter strings to be sent in Discord const split2k = (chunk: string): string[] => { @@ -143,6 +153,46 @@ const sendIndirectMessage = async (originalMessage: Message, messageContent: (st } }; -// Write logging function with trace and whatnot for errors and necessary messages to log, log bot state in server to determine if user is at fault or if I am at fault (maybe message user if its their fault?) +// initLog() returns nothing +// Handles ensuring the required directory structure is created +const initLog = (name: string): void => { + // Initialize the file name + startDate = new Date().toISOString().split("T")[0]; + logFolder = name; + const startupMessage = ` +--------------------------------------------------------------------------------------------------- +---------------------------------------- LOGGING STARTED ----------------------------------------- +------------------------------------ ${new Date().toISOString()} ------------------------------------- +---------------------------------------------------------------------------------------------------`; -export default { split2k, cmdPrompt, sendIndirectMessage }; + // Make all required folders if they are missing + const folders = ["combined", "traces"]; + Object.values(LogTypes).forEach(level => { + folders.push(level) + }); + + // Make each folder if its missing and insert the startup message + folders.forEach(level => { + Deno.mkdirSync(`./${logFolder}/${level}`, { recursive: true }); + Deno.writeTextFileSync(`./${logFolder}/${level}/${startDate}.log`, `${startupMessage}\n`, {append: true}); + }); + initialized = true; +}; + +// log(level, message) returns nothing +// Handles sending messages to console.log and sending a copy of the log to a file for review on crashes +const log = async (level: LogTypes, message: string, error = new Error()): Promise => { + const msgId = await nanoid(10); + const formattedMsg = `${new Date().toISOString()} | ${msgId} | ${level} | ${message}`; + const traceMsg = `${error.stack}` + // Default functionality of logging to console + console[level](formattedMsg); + // Logging to files for permanent info + if (initialized) { + await Deno.writeTextFile(`./${logFolder}/${level}/${startDate}.log`, `${formattedMsg}\n`, {append: true}); + await Deno.writeTextFile(`./${logFolder}/combined/${startDate}.log`, `${formattedMsg}\n`, {append: true}); + await Deno.writeTextFile(`./${logFolder}/traces/${startDate}.log`, `${formattedMsg}\n${traceMsg}\n\n`, {append: true}); + } +}; + +export default { split2k, cmdPrompt, sendIndirectMessage, initLog, log };