18 Commits

Author SHA1 Message Date
jcreek e752d3ce80 fix(*): Enable users with spaces in their username to delete their adventure channels
Why on earth does Discord even allow people to have spaces in their usernames?
2020-11-21 14:38:50 +00:00
jcreek 400b34b9e4 fix(*): Hand edge cases for the start command 2020-11-21 14:26:11 +00:00
jcreek 7bf9ae00ee fix(*): Use prefix rather than command text for help and adminhelp commands 2020-11-20 00:00:59 +00:00
jcreek 4429e02b22 fix(*): Missed empty queue check for when a player leaves a queue they were the only one in 2020-11-19 23:36:13 +00:00
jcreek 49cd612f51 feat(*): Finish implementing start command 2020-11-19 23:24:59 +00:00
jcreek f6af7b4327 fix(*): Fix further missed lowercasing of channel names by Discord for text channels 2020-11-19 23:17:48 +00:00
Josh Creek 01768c5567 feat(*): Remove potential feature from readme as it has been implemented 2020-11-19 22:55:58 +00:00
Josh Creek 9700808773 feat(*): Add start command for voting to start the adventure before the queue is full 2020-11-19 22:53:45 +00:00
Josh Creek 857ee29e10 feat(*): Update help commands to use the correct command symbol from the config file rather than hard-coding one 2020-11-19 22:49:41 +00:00
jcreek d37b3f8225 fix(*): Fix bug where text channel names are automatically lowercased by Discord so couldn't be deleted if the username had capital letters 2020-11-18 19:15:57 +00:00
jcreek 6eb1bf5c8a fix(*): Fix broken channel deletion and add more helpful logs 2020-11-16 23:04:21 +00:00
jcreek f32441716f feat(*): Add a dev token for debugging and testing in the dev discord 2020-11-16 23:03:58 +00:00
jcreek 2d113f8a8b feat(*): Enable console logging even in production so Jord can see logs easily 2020-11-05 23:36:32 +00:00
jcreek 4bc416ec56 feat(*): Improve logging and error handling 2020-11-05 23:35:55 +00:00
jcreek e47ff9596b feat(*): Remove unused getCurrentDateAndTime function 2020-11-05 23:23:37 +00:00
jcreek 1dc17b49b9 fix(*): Further fixes to elasticsearch logging to get the stacktrace coming through correctly 2020-11-05 23:21:19 +00:00
jcreek 43778d360a fix(*): Make the elasticsearch logging render out log data correctly for filtering in kibana 2020-11-05 22:52:31 +00:00
jcreek 4e2c79614b feat(*): Implement winston-elasticsearch for logging to Elasticsearch 2020-11-05 16:55:16 +00:00
5 changed files with 357 additions and 50 deletions
+1 -4
View File
@@ -12,6 +12,7 @@ Commands:
* q pokemon ign - Join the queue (first player can set the pokemon and their in-game name) * q pokemon ign - Join the queue (first player can set the pokemon and their in-game name)
* lq - Leave the queue * lq - Leave the queue
* sq - Show the queue * sq - Show the queue
* start - Vote to start the adventure early, without the full number of players (all players in the queue must use this to start early)
* cq - Clear the queue (admin-only, not to be shared with normal users) * cq - Clear the queue (admin-only, not to be shared with normal users)
* ru - Remove a tagged user from the queue (admin-only, not to be shared with normal users) * ru - Remove a tagged user from the queue (admin-only, not to be shared with normal users)
* dc - Delete an adventure channel (only the captain can use this) * dc - Delete an adventure channel (only the captain can use this)
@@ -50,7 +51,3 @@ If you want more of a sanity check here are some following commands you can run
To access the command line inside the docker container you can run: To access the command line inside the docker container you can run:
`docker exec -it <container id> /bin/bash` `docker exec -it <container id> /bin/bash`
## Version 2.0 potential features
* Let three people agree to start early using a voting command, so they don't have to wait for a fourth person (all three must vote to start)
+5
View File
@@ -2,6 +2,11 @@
"channeldeletetimeinminutes": 30, "channeldeletetimeinminutes": 30,
"deletecommandstoggle": false, "deletecommandstoggle": false,
"maxqueuesize": 4, "maxqueuesize": 4,
"elasticsearch" : {
"elasticsearch_address" : "http://jcreek.ddns.net:9200",
"elasticsearch_index_pattern" : "[logs-denbot-]YYYY.MM.DD"
},
"prefix": "!", "prefix": "!",
"token-dev": "Nzc4MDI2MTE1NDkwOTA2MTYz.X7L_SA.bNzC1kQUpBSwEsjp_cDGwR62Soo",
"token": "NzcwMDQyMDEzMjY5NDkxNzUy.X5Xzgg.kcr_51g95iUvEcYCfbQvG1Sx8ao" "token": "NzcwMDQyMDEzMjY5NDkxNzUy.X5Xzgg.kcr_51g95iUvEcYCfbQvG1Sx8ao"
} }
+171 -31
View File
@@ -1,22 +1,69 @@
const Discord = require('discord.js'); const Discord = require('discord.js');
const winston = require('winston'); const winston = require('winston');
const Elasticsearch = require('winston-elasticsearch');
const config = require('./config.json'); const config = require('./config.json');
const client = new Discord.Client(); const client = new Discord.Client();
const { format } = winston;
const { combine, timestamp } = format;
let env = 'dev';
if (process.env.NODE_ENV === 'production') {
env = 'prod';
}
// Custom format function that will look for an error object and log out the stack and if
// its not production, the error itself
const myFormat = format.printf((info) => {
const { timestamp: tmsmp, level, message, error, ...rest } = info;
let log = `${tmsmp} - ${level}:\t${message}`;
// Only if there is an error
if ( error ) {
if ( error.stack) log = `${log}\n${error.stack}`;
if (process.env.NODE_ENV !== 'production') log = `${log}\n${JSON.stringify(error, null, 2)}`;
}
// Check if rest is object
if ( !( Object.keys(rest).length === 0 && rest.constructor === Object ) ) {
log = `${log}\n${JSON.stringify(rest, null, 2)}`;
}
return log;
});
const esTransportOpts = {
level: 'info',
indexPrefix: 'logs_denbot',
clientOpts: {
host: config.elasticsearch.elasticsearch_address,
log: 'info'
},
transformer: logData => {
return {
timestamp: new Date().toISOString(),
severity: logData.level,
message: logData.message,
meta: {
app: 'denBot',
env: env,
stack: logData.meta.stack
}
}
}
};
const logger = winston.createLogger({ const logger = winston.createLogger({
level: 'info', level: 'info',
format: winston.format.combine( format: combine(
winston.format.errors({ stack: true }), // <-- use errors format
winston.format.timestamp(), winston.format.timestamp(),
winston.format.prettyPrint(),
myFormat,
winston.format.json() winston.format.json()
), ),
defaultMeta: { service: 'user-service' }, defaultMeta: { service: 'user-service' },
transports: [ transports: [
//
// - Write all logs with level `error` and below to `error.log`
// - Write all logs with level `info` and below to `combined.log`
//
new winston.transports.File({ filename: 'error.log', level: 'error' }), new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' }), new winston.transports.File({ filename: 'combined.log' }),
new Elasticsearch(esTransportOpts)
], ],
}); });
@@ -24,18 +71,20 @@ const logger = winston.createLogger({
// If we're not in production then log to the `console` with the format: // If we're not in production then log to the `console` with the format:
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) ` // `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
// //
if (process.env.NODE_ENV !== 'production') { //if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({ logger.add(new winston.transports.Console({
format: winston.format.simple(), format: winston.format.simple(),
})); }));
} //}
let playerQueue = []; let playerQueue = [];
let playerVotes = [];
let pokemonName = ''; let pokemonName = '';
let captainInGameName = ''; let captainInGameName = '';
client.login(config.token); client.login(config.token);
client.once('ready', () =>{ client.once('ready', () =>{
logger.log('info', 'denBot logged in successfully!'); logger.info('denBot logged in successfully!');
}) })
/* /*
@@ -62,7 +111,7 @@ function generateRandomCode() {
} }
function checkQueue(message) { function checkQueue(message) {
if (playerQueue.length === config.maxqueuesize) { if (playerQueue.length === config.maxqueuesize || (playerQueue.length > 0 && playerQueue.length == playerVotes.length)) {
// Queue is full // Queue is full
logger.log('info', 'Queue is full'); logger.log('info', 'Queue is full');
@@ -81,15 +130,17 @@ function checkQueue(message) {
client.users.cache.get(player.id).send(adventureMessage); client.users.cache.get(player.id).send(adventureMessage);
}); });
} catch (error) { } catch (error) {
logger.log('error', error); logger.error('Tried to DM users: ', error);
message.channel.send(`There was an error, please let an admin know!\n${error}`); message.channel.send(`There was an error, please let an admin know!\n${error}`);
} }
makeTempChannel(message, adventureMessage); makeTempChannel(message, adventureMessage);
// Clear the queue // Clear the queue and votes
playerQueue = []; playerQueue = [];
logger.log('info', 'Emptied queue'); logger.log('info', 'Emptied queue');
playerVotes = [];
logger.log('info', 'Emptied votes');
} }
else if (playerQueue.length === 0) { else if (playerQueue.length === 0) {
message.channel.send('The queue is empty :('); message.channel.send('The queue is empty :(');
@@ -108,6 +159,7 @@ function checkQueue(message) {
} }
function getUserFromMention(mention) { function getUserFromMention(mention) {
try {
if (!mention) return; if (!mention) return;
if (mention.startsWith('<@') && mention.endsWith('>')) { if (mention.startsWith('<@') && mention.endsWith('>')) {
@@ -119,10 +171,13 @@ function getUserFromMention(mention) {
return client.users.cache.get(mention); return client.users.cache.get(mention);
} }
} catch (error) {
logger.error('Tried to get users from mention: ', error);
}
} }
function getChannelName(username) { function getChannelName(username) {
return `${username}s-adventurers`; return `${username.toLowerCase().replace(' ', '-')}s-adventurers`;
} }
function makeTempChannel(message, adventureMessage) { function makeTempChannel(message, adventureMessage) {
@@ -155,19 +210,29 @@ function makeTempChannel(message, adventureMessage) {
}) })
.catch(logger.error); .catch(logger.error);
try {
// Delete the channel after the configured amount of minutes // Delete the channel after the configured amount of minutes
setTimeout(function(){ deleteChannel(message, channelName); }, (config.channeldeletetimeinminutes * 1000 * 60) ); setTimeout(function(){ deleteChannel(message, channelName); }, (config.channeldeletetimeinminutes * 1000 * 60) );
} catch (error) {
logger.error(`Tried to delete channel ${channelName} after timeout: `, error);
}
} }
function deleteChannel(message, channelName) { function deleteChannel(message, channelName) {
try { try {
// Get a Channel by Name // Get a Channel by Name
const fetchedChannel = message.guild.channels.cache.find(channel => channel.name === channelName); const fetchedChannel = message.guild.channels.cache.find(channel => channel.name.toLowerCase() == channelName.toLowerCase());
logger.info(`Deleting temp channel ${channelName}`) logger.info(`Deleting temp channel ${channelName}`)
fetchedChannel.delete(); fetchedChannel.delete();
} catch (error) { } catch (error) {
logger.error(error); logger.error(`Tried to delete channel ${channelName}: `, error);
let names = [];
message.guild.channels.cache.forEach(channel => {
names.push(channel.name);
});
logger.info(`Channel names in cache: ${names}`);
} }
} }
@@ -188,6 +253,8 @@ client.on('message', function (message) {
message.delete(); message.delete();
} }
logger.info(`${message.author.username} used command q in ${message.channel.name}`);
logger.log('info', `${message.author.username} joined the queue.`); logger.log('info', `${message.author.username} joined the queue.`);
message.channel.send(`=====\n${message.author.username} joined the queue.`); message.channel.send(`=====\n${message.author.username} joined the queue.`);
@@ -206,6 +273,9 @@ client.on('message', function (message) {
if (config.deletecommandstoggle) { if (config.deletecommandstoggle) {
message.delete(); message.delete();
} }
logger.info(`${message.author.username} used command q in ${message.channel.name}`);
message.channel.send(`${message.author.username} is too keen, you're already in the queue mate!`); message.channel.send(`${message.author.username} is too keen, you're already in the queue mate!`);
} }
@@ -216,8 +286,7 @@ client.on('message', function (message) {
message.delete(); message.delete();
} }
logger.log('info', `${message.author.username} left the queue.`); logger.info(`${message.author.username} used command lq in ${message.channel.name}`);
message.channel.send(`${message.author.username} left the queue.`);
for( var i = 0; i < playerQueue.length; i++){ for( var i = 0; i < playerQueue.length; i++){
if ( playerQueue[i] === message.author) { if ( playerQueue[i] === message.author) {
@@ -226,6 +295,16 @@ client.on('message', function (message) {
} }
} }
for( var i = 0; i < playerVotes.length; i++){
if ( playerVotes[i] === message.author) {
playerVotes.splice(i, 1);
i--;
}
}
logger.log('info', `${message.author.username} left the queue.`);
message.channel.send(`${message.author.username} left the queue.`);
checkQueue(message); checkQueue(message);
} }
else if (command === 'lq' && !(playerQueue.includes(message.author))) { else if (command === 'lq' && !(playerQueue.includes(message.author))) {
@@ -233,15 +312,60 @@ client.on('message', function (message) {
if (config.deletecommandstoggle) { if (config.deletecommandstoggle) {
message.delete(); message.delete();
} }
logger.info(`${message.author.username} used command lq in ${message.channel.name}`);
message.channel.send(`${message.author.username} you can't leave the queue before you've joined it!`); message.channel.send(`${message.author.username} you can't leave the queue before you've joined it!`);
} }
// Vote to start early with only the users currently in the queue
if(command === 'start') {
// Delete the message with the bot command
if (config.deletecommandstoggle) {
message.delete();
}
logger.info(`${message.author.username} used command ${command} in ${message.channel.name}`);
if(playerQueue.length == 0) {
message.channel.send(`You can only vote to start an adventure early if there is a queue. You can start a queue by using the command ${config.prefix}help`);
}
else if (!playerQueue.includes(message.author)) {
message.channel.send(`You can only vote to start an adventure early if you are in the queue. You can join the queue by using the command ${config.prefix}q`);
}
else if(playerVotes.length == 0) {
// First player to vote
playerVotes.push(message.author);
message.channel.send(`=====\n${message.author.username} voted to start the adventure.\nAll other players in the queue must also vote to start the adventure for it to begin without ${config.maxqueuesize} players.`);
}
else if (playerVotes.includes(message.author.username)) {
message.channel.send(`=====\n${message.author.username} has already voted to start the adventure.\nAll other players in the queue must also vote to start the adventure for it to begin without ${config.maxqueuesize} players.`);
}
else if (playerVotes.length < config.maxqueuesize) {
// Not the first player to vote
playerVotes.push(message.author);
if (playerVotes.length < playerQueue.length) {
// Still not all players voted
message.channel.send(`=====\n${message.author.username} voted to start the adventure.\nAll other players in the queue must also vote to start the adventure for it to begin without ${config.maxqueuesize} players.`);
}
else {
// All players have voted, we can start the adventure early
checkQueue(message);
}
}
}
// Show the queue // Show the queue
if(command === 'sq') { if(command === 'sq') {
// Delete the message with the bot command // Delete the message with the bot command
if (config.deletecommandstoggle) { if (config.deletecommandstoggle) {
message.delete(); message.delete();
} }
logger.info(`${message.author.username} used command sq in ${message.channel.name}`);
checkQueue(message); checkQueue(message);
} }
@@ -252,14 +376,17 @@ client.on('message', function (message) {
message.delete(); message.delete();
} }
logger.info(`${message.author.username} used command cq in ${message.channel.name}`);
if (playerQueue.length === 0) { if (playerQueue.length === 0) {
message.channel.send(`The queue is already empty...`); message.channel.send(`The queue is already empty...`);
logger.log('info', `${message.author.username} attempted to clear the queue but it was already empty.`); logger.log('info', `${message.author.username} attempted to clear the queue but it was already empty.`);
} }
else { else {
playerQueue = []; playerQueue = [];
playerVotes = [];
message.channel.send(`The queue has been cleared!`); message.channel.send(`The queue has been cleared!`);
logger.log('info', `${message.author.username} cleared the queue.`); logger.log('info', `${message.author.username} cleared the queue and the votes.`);
} }
} }
@@ -272,6 +399,8 @@ client.on('message', function (message) {
message.delete(); message.delete();
} }
logger.info(`${message.author.username} used command ru in ${message.channel.name}`);
if ((playerQueue.includes(user))) { if ((playerQueue.includes(user))) {
// Search for the user // Search for the user
@@ -282,6 +411,13 @@ client.on('message', function (message) {
} }
} }
for( var i = 0; i < playerVotes.length; i++){
if ( playerVotes[i].username === user.username) {
playerVotes.splice(i, 1);
i--;
}
}
message.channel.send(`${user.username} removed from queue.`); message.channel.send(`${user.username} removed from queue.`);
logger.log('info', `${message.author.username} removed ${user.username} from queue.`); logger.log('info', `${message.author.username} removed ${user.username} from queue.`);
@@ -294,25 +430,28 @@ client.on('message', function (message) {
} }
if (command === 'dc') { if (command === 'dc') {
// todo - add logic here to determine if they can delete the channel (i.e. it's their temporary one) - compare the name logger.info(`${message.author.username} used command dc in ${message.channel.name}`);
// Determine if they can delete the channel (i.e. it's their temporary one) - compare the name
if (message.channel.name === getChannelName(message.author.username)) { if (message.channel.name === getChannelName(message.author.username)) {
deleteChannel(message, message.channel.name) deleteChannel(message, message.channel.name)
logger.log('info', `${message.author.username} deleted their adventure channel.`); logger.log('info', `${message.author.username} deleted their adventure channel.`);
} }
else { else {
message.channel.send(`${message.author.username} is not allowed to delete this channel.`); message.channel.send(`${message.author.username} is not allowed to delete this channel.`);
logger.log('info', `${message.author.username} attempted to delete channel ${message.channel.id} but it's not their adventure channel.`); logger.log('info', `${message.author.username} attempted to delete channel ${message.channel.name} but it's not their adventure channel.`);
} }
} }
if (command === 'help') { if (command === 'help') {
let msg = ` let msg = `
The commands available to you are: The commands available to you are:
- !q - Join the queue - ${config.prefix}q - Join the queue
- !q <pokemon> <ign> - Join the queue (first player can set the pokemon and their in-game name) - ${config.prefix}q <pokemon> <ign> - Join the queue (first player can set the pokemon and their in-game name)
- !lq - Leave the queue - ${config.prefix}lq - Leave the queue
- !sq - Show the queue - ${config.prefix}sq - Show the queue
- !dc - Delete an adventure channel (only the captain can use this) - ${config.prefix}start - Vote to start the adventure early, without the full number of players (all players in the queue must use this to start early)
- ${config.prefix}dc - Delete an adventure channel (only the captain can use this)
`; `;
message.channel.send(msg); message.channel.send(msg);
@@ -321,13 +460,14 @@ The commands available to you are:
if (command === 'adminhelp') { if (command === 'adminhelp') {
let msg = ` let msg = `
The commands available to you are: The commands available to you are:
- !q - Join the queue - ${config.prefix}q - Join the queue
- !q <pokemon> <ign> - Join the queue (first player can set the pokemon and their in-game name) - ${config.prefix}q <pokemon> <ign> - Join the queue (first player can set the pokemon and their in-game name)
- !lq - Leave the queue - ${config.prefix}lq - Leave the queue
- !sq - Show the queue - ${config.prefix}sq - Show the queue
- !cq - Clear the queue (admin-only, not to be shared with normal users) - ${config.prefix}start - Vote to start the adventure early, without the full number of players (all players in the queue must use this to start early)
- !ru - Remove a tagged user from the queue (admin-only, not to be shared with normal users) - ${config.prefix}cq - Clear the queue (admin-only, not to be shared with normal users)
- !dc - Delete an adventure channel (only the captain can use this) - ${config.prefix}ru - Remove a tagged user from the queue (admin-only, not to be shared with normal users)
- ${config.prefix}dc - Delete an adventure channel (only the captain can use this)
`; `;
message.channel.send(msg); message.channel.send(msg);
+164
View File
@@ -37,6 +37,29 @@
"event-target-shim": "^5.0.0" "event-target-shim": "^5.0.0"
} }
}, },
"agentkeepalive": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz",
"integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==",
"requires": {
"humanize-ms": "^1.2.1"
}
},
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
},
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
},
"async": { "async": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
@@ -47,6 +70,18 @@
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
}, },
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
}
},
"color": { "color": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz",
@@ -105,6 +140,14 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
}, },
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"requires": {
"ms": "^2.1.1"
}
},
"delayed-stream": { "delayed-stream": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -125,11 +168,26 @@
"ws": "^7.3.1" "ws": "^7.3.1"
} }
}, },
"elasticsearch": {
"version": "16.7.1",
"resolved": "https://registry.npmjs.org/elasticsearch/-/elasticsearch-16.7.1.tgz",
"integrity": "sha512-PL/BxB03VGbbghJwISYvVcrR9KbSSkuQ7OM//jHJg/End/uC2fvXg4QI7RXLvCGbhBuNQ8dPue7DOOPra73PCw==",
"requires": {
"agentkeepalive": "^3.4.1",
"chalk": "^1.0.0",
"lodash": "^4.17.10"
}
},
"enabled": { "enabled": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
}, },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"event-target-shim": { "event-target-shim": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
@@ -150,6 +208,22 @@
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
}, },
"has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
"requires": {
"ansi-regex": "^2.0.0"
}
},
"humanize-ms": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
"integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
"requires": {
"ms": "^2.0.0"
}
},
"inherits": { "inherits": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
@@ -175,6 +249,11 @@
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
}, },
"lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
},
"logform": { "logform": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz",
@@ -200,6 +279,11 @@
"mime-db": "1.44.0" "mime-db": "1.44.0"
} }
}, },
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
},
"ms": { "ms": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -228,6 +312,14 @@
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
}, },
"promise": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz",
"integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==",
"requires": {
"asap": "~2.0.6"
}
},
"readable-stream": { "readable-stream": {
"version": "3.6.0", "version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
@@ -238,6 +330,11 @@
"util-deprecate": "^1.0.1" "util-deprecate": "^1.0.1"
} }
}, },
"retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs="
},
"safe-buffer": { "safe-buffer": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -269,6 +366,19 @@
"safe-buffer": "~5.2.0" "safe-buffer": "~5.2.0"
} }
}, },
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "^2.0.0"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
},
"text-hex": { "text-hex": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
@@ -305,6 +415,60 @@
"winston-transport": "^4.4.0" "winston-transport": "^4.4.0"
} }
}, },
"winston-elasticsearch": {
"version": "0.7.12",
"resolved": "https://registry.npmjs.org/winston-elasticsearch/-/winston-elasticsearch-0.7.12.tgz",
"integrity": "sha512-nH35GlCD/vIFKNFUQSTd16esNKqLgaQgMvCoz3amXNNf8LWq4lYejTWhDQQpKQr+8EA2NOWfSGa2hYECQm/bGA==",
"requires": {
"debug": "4.1.1",
"elasticsearch": "^16.0.0",
"lodash": "^4.17.11",
"moment": "^2.24.0",
"promise": "^8.0.3",
"retry": "^0.12.0",
"triple-beam": "^1.3.0",
"winston": "^3.2.1",
"winston-transport": "4.3.0"
},
"dependencies": {
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
},
"winston-transport": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz",
"integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==",
"requires": {
"readable-stream": "^2.3.6",
"triple-beam": "^1.2.0"
}
}
}
},
"winston-transport": { "winston-transport": {
"version": "4.4.0", "version": "4.4.0",
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz", "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.0.tgz",
+2 -1
View File
@@ -10,6 +10,7 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"discord.js": "12.4.1", "discord.js": "12.4.1",
"winston": "3.3.3" "winston": "3.3.3",
"winston-elasticsearch": "^0.7.12"
} }
} }