The issue is that whenever there is a connection hiccup then the bot reconnects because I want it to, it will send multiple messages at a time essentially spamming a channel. I run it 24/7 on a raspberry pi so it accumulates multiple hiccups per day and I'm guessing this is what happening. On occasion it has send tens of messages when its time schedule hits.
I have been able to replicate it duplicating 2 messages by unconnecting my internet while running the bot for a few mins then when it reconnects the next time the event happens (I have it set to trigger every 60 seconds rather than midnight for debugging reasons.) So far I cannot figure out why it would be sending multiple messages.
const Discord = require('discord.js');
const bot = new Discord.Client({autoReconnect: true});
const cfg = require('./config.json');
const fs = require('fs');
const folder = './countdown/';
const schedule = require('node-schedule')
var currentdate = new Date();
const days = 1000 * 60 * 60 * 24;
//This section checks which command is used
bot.on('message', message => {
//This will check if the message starts with the command prefix '!'. Then it will store the parameters in $args and #command
if (!message.content.startsWith(cfg.prefix) || message.author.bot) return;
const eventName = message.content.slice(cfg.prefix.length).split(/ +/);
const command = eventName.shift();
const args = eventName.splice(0,3);
console.log(`Args: ${args}\nCommand: ${command}`);
switch(command.toLowerCase()){
//This will check if the event is in the past or not, if not then it will store it as a json with information: Event name and date
case "countdown":
var releasedate = new Date(`${args}`),
currentdate = new Date(),
diff = releasedate - currentdate;
if(Math.ceil(diff / days) > 0 && `${eventName.length}` > 0){ //this will check if the event has a name and if it has happened
message.channel.send(Math.ceil(diff / days) + ` days until ${eventName.join(' ')}`);
//This will create a .json file with a specific format containing the event name and date
var fileContent = `{\n"releasedate": "${args.join(' ')}", \n"eventName": "${eventName.join(' ')}"\n}`,
filepath = `./countdown/${eventName.join('_')}.json`;
fs.writeFile(filepath, fileContent, (err) => {
if (err) throw err;
console.log("The file was succesfully saved!");
});
}
else if(`${eventName.length}` == 0){ //if the event does not have a name
message.channel.send('Please enter an event date.')
}
else{ //if the user enters a date that already occured
message.channel.send('Event already occured. Use "!days_since" instead.')
}
break;
//This will tell how many days has happened since an event
case "days_since":
var start = new Date(`${args}`), //ex January 1, 2016"
end = new Date(),
diff = end - start;
message.channel.send(Math.floor(diff / days) + " days have passed since " + start)
break;
case "help":
message.channel.send('usage is !{command} \n!countdown notation is Month Day Year Eventname ex. January 1, 2019 New Years!\n!days_since notation is the same as !countdown without {name}');
break;
default:
message.channel.send('This is not a command refer to !help');
}
});
bot.on('ready', () => {
var sendChannel = bot.channels.find(channel => channel.id === '556254985114091531') //id of channel to send in 277649480877211649 = countdown chat 556254985114091531 = test channel
//This is a cron job which activates at 00:01 every day
var j = schedule.scheduleJob('01 * * * * *', function(){ //second(0 - 59)(optional), minute(0 - 59), hour(0 - 23), day(1 - 31), month (1 - 12), day of week(0 - 7)
var currentdate = new Date();
//This function will read the data in the .json files and retrieve the data
fs.readdir(folder, (err, files) => {
if(files.length < 24 && !files.length == 0) { //this will check if there are more than 25 files, and not 0 so that .addField does not error (max 25).
var embed = new Discord.RichEmbed()
for(i = 0; i < files.length; i++){ //loop through all files in ./countdown
var input = require(folder+files[i]);
if(((new Date(input.releasedate) - currentdate) / days) > 0) //this checks if the event has happened or not
{
//This section creates the embeded message of all current active countdowns
embed.addField(input.eventName, Math.ceil((new Date(input.releasedate) - currentdate) / days) + ' days until ' + input.eventName, true) //this adds however many events are stored
r = Math.floor(Math.random() * 256).toString(16);
g = Math.floor(Math.random() * 256).toString(16);
b = Math.floor(Math.random() * 256).toString(16);
r = (r.length==2)?r:'0' + r; //this checks if r.length is 2 digits then if not adds a 0 infront
g = (g.length==2)?g:'0' + g;
b = (b.length==2)?b:'0' + b;
var color = `#${r}${g}${b}`;
embed.setColor(color);
}
else if(Math.ceil((new Date(input.releasedate) - currentdate) / days) == 0){ //this will send a message saying today is "x"
sendChannel.send(`Today is ${input.eventName}!`);
console.log(`${input.eventName} is today`);
}
else //this lets you know which .json value is negative
{
console.log("arg not passed, invalid or past: "+input.eventName)
}
}
}
else if(files.length == 0){
sendChannel.send('Add an event to start counting down.')
}
else{
sendChannel.send('Too many events, contact owner to remove some.');
}
sendChannel.send(embed);
});
});
console.log("Ready")
console.log(`Logged in at ${currentdate}`)
console.log(`Logged in as ${bot.user.tag} (${bot.user.id}) on ${bot.guilds.size} servers`);
bot.user.setActivity(`Counting things down | ${bot.guilds.size} servers`);
});
bot.on('error', err => {
console.error(err);
});
bot.login(cfg.token);
The expected result would be to only send one message per schedule event, but it is sending multiple