UNPKG

winston-discord-webhook

Version:

Transport for winston to send logs on Discord via Webhook

99 lines (80 loc) 2.71 kB
const Transport = require("winston-transport"); const { WebhookClient } = require("discord.js"); const { EmbedBuilder } = require("discord.js"); function postEmbeds(queue, hook) { const embeds = []; while (embeds.length < 10 && queue.length > 0) { embeds.push(queue.shift()); } if (embeds.length == 0) return; return hook.send({ embeds }); } module.exports = class DiscordTransport extends Transport { /** * * @param {Object} opts Options for Discord Transport * @param {string} opts.webhook Webhook URL to send logs to * @param {string} opts.mode Mode to use. 'codeblock' or 'embed' or 'hybrid' or 'standard' Default: hybrid * @param {Map<string, string>} opts.colors Colors to use for embeds depending on log level. * @param {number} opts.interval Interval to send messages in queue. Default: 2500 * @param {number} opts.maxLength Maximum length of a message to send. Default: 1900 */ constructor(opts) { super(opts); if (!opts.webhook) { throw new Error("No webhook given for Discord Transport"); } /** * @type {boolean} */ this.mode = opts.mode || "hybrid"; this.colors = opts.colors || new Map(); /** * @type {number} */ this.interval = opts.interval || 2500; /** * @type {number} */ this.maxLength = opts.maxLength || 1900; this.queue = []; this.hook = new WebhookClient({ url: opts.webhook }); if (this.mode == "embed" || this.mode == "hybrid") { setInterval(() => { postEmbeds(this.queue, this.hook); }, this.interval); } else { setInterval(() => { const content = []; while (content.length < this.maxLength) { content.push(this.queue.shift()); } if (content.length == 0) return; if (content != "") { this.hook.send({ content: content.join("\n") }); } }, this.interval); } } log(info, callback) { setImmediate(() => { this.emit("logged", info); if (["hybrid", "embed"].includes(this.mode)) { const embed = new EmbedBuilder(); if (this.colors.has(info[Symbol.for("level")])) embed.setColor(this.colors.get(info[Symbol.for("level")])); if (this.mode == "hybrid") { embed.setDescription(`\`\`\`ansi\n${info[Symbol.for("message")]}\`\`\``); } else { embed.setDescription(info[Symbol.for("message")]); } this.queue.push(embed); } else if (this.mode == "codeblock") { this.queue.push(`\`\`\`ansi\n${info[Symbol.for("message")]}\n\n\n`); } else { this.queue.push(info[Symbol.for("message")]); } }); callback(); } };