discord-winston-transport
Version:
Discord Winston Transport for sending logs to Discord
138 lines (137 loc) • 4.73 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DiscordTransport = void 0;
/* eslint-disable no-console */
const winston_transport_1 = __importDefault(require("winston-transport"));
const axios_1 = __importDefault(require("axios"));
const os_1 = __importDefault(require("os"));
/**
* Discord Transport for winston
*/
class DiscordTransport extends winston_transport_1.default {
/** Webhook obtained from Discord */
webhook;
/** Discord webhook id */
id;
/** Discord webhook token */
token;
/** Initialization promise resolved after retrieving discord id and token */
initialized;
/** Meta data to be included inside Discord Message */
defaultMeta;
/** Available colors for discord messages */
static COLORS = {
error: 14362664, // #db2828
warn: 16497928, // #fbbd08
info: 2196944, // #2185d0
verbose: 6559689, // #6435c9
debug: 2196944, // #2185d0
silly: 2210373, // #21ba45
};
constructor(opts) {
super(opts);
this.webhook = opts.webhook;
this.defaultMeta = opts.defaultMeta || {};
this.initialized = this.initialize();
}
/** Helper function to retrieve url */
getUrl = () => `https://discordapp.com/api/webhooks/${this.id}/${this.token}`;
/**
* Initialize the transport to fetch Discord id and token
*/
initialize = () => new Promise((resolve, reject) => {
axios_1.default
.get(this.webhook)
.then((response) => {
this.id = response.data.id;
this.token = response.data.token;
resolve();
})
.catch((err) => {
console.error(`Could not connect to Discord Webhook at ${this.webhook}`, err);
reject(err);
});
});
/**
* Function exposed to winston to be called when logging messages
* @param info Log message from winston
* @param callback Callback to winston to complete the log
*/
log(info, callback) {
if (info.discord !== false) {
setImmediate(() => {
this.initialized
.then(() => {
this.sendToDiscord(info);
})
.catch((err) => {
console.error('Error sending message to discord', err);
});
});
}
callback();
}
/**
* Sends log message to discord
*/
sendToDiscord = async (info) => {
// Use formatted message if available - using string access for Symbol
// Access the formatted message from Symbol
const messageSymbol = Object.getOwnPropertySymbols(info).find((sym) => sym.toString() === 'Symbol(message)');
// Get the formatted message or fall back to regular message
const message = messageSymbol
? info[messageSymbol]
: info.message;
const postBody = {
embeds: [
{
description: message,
color: DiscordTransport.COLORS[info.level] || DiscordTransport.COLORS.info,
fields: [],
timestamp: new Date().toISOString(),
},
],
};
if (info.level === 'error' && info.error && info.error.stack) {
postBody.content = `\`\`\`${info.error.stack}\`\`\``;
}
if (this.defaultMeta) {
Object.keys(this.defaultMeta).forEach((key) => {
postBody.embeds[0].fields.push({
name: key,
value: this.defaultMeta[key],
});
});
}
if (info.meta) {
Object.keys(info.meta).forEach((key) => {
if (info.meta && key in info.meta) {
postBody.embeds[0].fields.push({
name: key,
value: info.meta[key],
});
}
});
}
postBody.embeds[0].fields.push({
name: 'Host',
value: os_1.default.hostname(),
});
try {
await axios_1.default.post(this.getUrl(), postBody, {
headers: {
'Content-Type': 'application/json',
},
});
}
catch (err) {
const error = err;
console.error(`Error sending to discord`, error);
}
};
}
exports.default = DiscordTransport;
exports.DiscordTransport = DiscordTransport;