winston-discord-webhook
Version:
Transport for winston to send logs on Discord via Webhook
99 lines (80 loc) • 2.71 kB
JavaScript
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();
}
};