0

Tags:

node-cron, ExpressJs, NodeJs, Replit, Uptimerobot

Situation:

Hey all!

I am trying to get my discord bot to send multiple messages every day on specific times. I deployed my bot on Replit and use Uptimerobot to ping my app every 10 min to keep the bot live.

In my code I used node-cron shedules for each spicific time it should send a message:

imports

const express = require("express");
const router = express.Router();

const { Client, Intents, Guild } = require("discord.js");
const cron = require("node-cron");
const token = process.env['BOT_TOKEN']
const { promotions } = require("./promotions");
const { testServers } = require("./test-servers");
const { buildMessage } = require("./generateMessage");

Message generator

router.get("/", function(req, res, next) {

    const client = new Client({
        intents: [Intents.FLAGS.GUILDS],
        allowedMentions: { parse: ["users", "roles"] }
    });

    const composeMessage = guilds => {
        let thisGuild;
        let discordChannel;
        let role;
        let holidays;
        let start;
        let end;

        guilds.map((guild, key) => {

            guild.channels.cache.map(channel => {

                testServers.forEach((promo, index) => {
                    thisGuild = promo.guild_id;
                    discordChannel = promo.channel_id;
                    role = promo.role_id;
                    holidays = promo.holidays;
                    start = promo.start;
                    end = promo.end;

                    // All relevant promotions
                    if (discordChannel === channel.id.toString()) {
                        const notAHoliday = [];
                        const currentDate = new Date();

                        holidays.forEach(holiday => {
                            if (
                                currentDate >= holiday.start &&
                                currentDate.setUTCHours(23, 59, 59) <= holiday.end
                            ) {
                                notAHoliday.push(false);
                            }
                        });

                        if (
                            notAHoliday.length === 0 &&
                            (currentDate >= promo.start &&
                                currentDate.setUTCHours(23, 59, 59) <= promo.end)
                        ) {
                            const unfilteredMessage = buildMessage(role);
                            channel.send(unfilteredMessage);
                        }
                    }
                });
            });
        });
    };

When running the Bot

    client.once("ready", () => {
        console.log("READY!");
        const guilds = client.guilds.cache.map(guild => guild);

        cron.schedule("0 55 7 * * Mon,Tue,Wed,Thu,Fri", () => {
          console.log("morning");
          composeMessage(guilds);
        });
        cron.schedule("0 31 11 * * Mon,Tue,Wed,Thu,Fri", () => {
          console.log("start lunch");
          composeMessage(guilds);
        });
        cron.schedule("0 25 12 * * Mon,Tue,Wed,Thu,Fri", () => {
          console.log("end lunch");
          composeMessage(guilds);
        });
        cron.schedule("0 0 16 * * Mon,Tue,Wed,Thu,Fri", () => {
          console.log("evening");
          composeMessage(guilds);
        });
    });
    client.login(token);
    botStatus = "Active";

    res.render('index', { status: botStatus, version: "1.0.0" })
});

module.exports = router;

Issue:

The timers work but every time it runs a schedule, I get back a bunch of messages (the longer between schedules, the more messages my bot sends)

I suspect that it has to do with the pinging and the schedules stocking those runs until the shedule runs active and releases it all.. But how should I fix this?

Thanks in advance!

Basile
  • 150
  • 11
  • _I suspect that it has to do with the pinging and the schedules stocking those runs until the shedule runs active and releases it all_, to confirm that, can you include all of your code to the post? – Max Dec 29 '21 at 10:44
  • @Max This should be all the relevant code I think, I will update it with the full file, just in case. – Basile Dec 29 '21 at 10:52
  • @Max So I updated the code, I have deployed it on Replit which keeps the project online for 30min before going to sleep mode. in order to prevent it from going into sleep mode, I use UptimeRobot that pings my Replit every 10 minutes. – Basile Dec 29 '21 at 11:00
  • 1
    If I understood your code correctly, then every time you ping your server, you create a new set of cron jobs - that's why you have this problem with multiple messages. One solution could be to create a client and cron jobs when you start the server. And to keep it alive, use the same approach with UptimeRobot, but don't run any code on the server when UptimeRobot makes a new request. Ideally, you shouldn't use UptimeRobot at all, but if works for you, you can keep it – Max Dec 29 '21 at 11:09

0 Answers0