问题是,每当出现连接故障时,由于我希望机器人自动重新连接,它将一次发送多条消息,实质上是在向通道发送垃圾邮件。我在树莓派上全天候运行24/7,因此它每天会累积多次打ic,我猜这是正在发生的事情。有时,当时间表达到时,它会发送数十条消息。
通过运行bot几分钟后断开互联网连接,我能够复制2条消息,然后在下次事件发生时重新连接它(我将其设置为每60秒触发一次,而不是午夜进行调试)原因。)到目前为止,我仍无法弄清为什么它会发送多条消息。
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);
预期结果是每个计划事件仅发送一条消息,但是发送多个
答案 0 :(得分:0)
结合使用Promise和isReady标志使Sure机器人准备发送消息
const client = new Client();
let isReady = false
client.on('error', function (d) {
console.log(d.responsee, 'discord client err')
})
client.on('ready', function (d) {
isReady = true
})
function sendMessage(text = 'no text') {
text = String(text)
return new Promise((resolve, reject) => {
if (isReady) {
let message = client.channels.get(config.discordChannel)
message.send(text)
.then(a => {
resolve({ success: true })
}).catch(e => {
reject(e)
})
}
})
}
client.login(config.discord).then(a => {
console.log(a, 'discord client login')
}).catch(e => {
console.log(e, 'discord login err')
});