MongoDB find calls twice - node.js

On init of my application i start function with settings.
const schedule = require('node-schedule');
const monk = require('monk');
const db = monk(config.mdbConnect);
var TGusers = db.get('TG-users');
...
...
TGusers.find({'cron.status': true}, {chatid:1, cron: 1})
.then((users) => {
console.log('twise');
for(var i=0;i<users.length;i++){
cronbox[users[i]] = {};
cronbox[users[i]].reminder = schedule.scheduleJob('*/1 * * * *', function(chatid){
console.log('chatid = '+ chatid);
tg.api.sendMessage(chatid, '🐳 Nuclear launch detected! / ' +chatid,
{'parse_mode': 'Markdown'}
);
}.bind(null, users[i].chatid));
}
}).catch((err) => {
if(err) saveerr(err);
}).then(() => db.close())
And this Monk find finction fired twice. I got two "twice" in my console, and .. looks like two cron tasks... What I did wrong?

Related

How do I get data from mongodb, manipulate it and print it

I want to connect to MongoDB and query a collection based on the filter 'category'. From the results, I want to randomly select one of entries, concatenate with another string and print to console. I am a novice at this and can't figure out how to get the results of my query and randomly select one of the entries from the query results.
//Connecting To DB
const mongoose = require('mongoose');
//const { makeCard } = require('./utils/card');
const db = mongoose.connection;
const host = process.env.host;
console.log(host)
const dbupdate = {
useNewUrlParser : true,
useUnifiedTopology : true
};
mongoose.connect(host, dbupdate);
db.on('error', (err) => console.log('Error, DB not connected'));
db.on('connected', () => console.log('connected to mongo'));
db.on('disconnected', () => console.log('Mongo is disconnected'));
db.on('open', () => console.log('Connection Made!'));
const Schema= mongoose.Schema;
const cardSchema = new Schema({
word: String,
visual : String,
category : String
});
const Card = mongoose.model('expressions', cardSchema );
--I want this function to return the results of the query, but it doesn't.
function getWords(ctgry ) {
const result = Card.find({"category" : ctgry },(error,results) => {
return results;
});
};
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) + min);
};
function getWord( ctgry ) {
const result = getWords( ctgry );
const num = getRandomInt(0,result.length); --this doesn't work
return result[num];
};
console.log("Sample text: " + getWord());
What you seem to be doing here is that you're fetching all the documents from the Card model for a particular category and picking a random one from it, which I wouldn't recommend. Not sure what data you're storing here, but what if your app grows to a point where there are a million documents in your cards collection? You wouldn't fetch them all in memory and pick a random one.
A good practice while using any database is to try to only fetch as much data is required. There's no way to fetch a random document from a query in mongodb from what I know, but there's a way to do this (inspired from this answer which I recommend you read).
async function getRandomWord(ctgry) {
const count = await User.count({
"category": ctgry,
}).exec();
const random = Math.floor(Math.random() * count);
return User.findOne({
"category": ctgry,
}).skip(random).exec();
}

Crone Task runs multiple times in a single interval NodeJS

I have the problem that in the server the Crone Task is running X4 number of times for each scheduled interval, not only the logs are shown x4 but also the API is called 4 times.
const taskCron = nodeCron.schedule('*/1 * * * *', function () {
const timeZone = moment.tz('America/Mexico_City').format();
const currentDate = splitDate(timeZone);
const currentTime = splitTime(timeZone);
console.info(`EXECUTING CRON TASK ${currentDate} ${currentTime}`);
campaign.find(
{ hour_to_send: currentTime, date_to_send: { $gte: currentDate, $lte: currentDate}}
).exec().then(data => {
console.log('number of campaigns programmed: ' + data.length);
const campaignsMapped = data.map(campaign => {
return {
id: campaign._id
};
});
const secretBulk = 'secret-bulk';
const bodyRequest = {
campaignsList: campaignsMapped,
key: secretBulk
};
if (campaignsMapped.length > 0) {
axios.post(url_bulk, bodyRequest, {})
.then(data => {
console.info(data.status);
})
.catch(error => {
console.error(error.code);
});
}
}).catch(error => {console.log(error)});
function splitDate(date) {
return date.slice(0, 10);
}
function splitTime(date) {
return date.slice(11, 16) + ':00';
}
}, {scheduled: false});
taskCron.start();
Use the library node-cron npm
The server is derived from centos Oracle version, the program runs in a docker container official Node JS image version 10, docker Docker version 19.03.11, build 42e35e61f3, It is worth mentioning that on my local machine with windows 10 this behavior does not happen.

Node-Cron: Running multiple schedules a day

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!

Node-Cron Does Not Working On Heroku (Push Scheduled Notification)- Node Cron Not Execute On Heroku Server

I am trying to send a scheduled notification with the node-cron library and it is working fine in my local system but after deploying the codes to the Heroku server it is not working.
const triggerPushNotification = (notifiction, startMinutes, startHour) => {
console.log('Checked Trigger Push Notification Function ...');
cron.schedule(`${startMinutes} ${startHour} * * *`, async () => {
console.log('Checked Inner Cron ...');
await notificationHelper.pushNotification(notifiction.receiversTokens, notifiction.notificationTitle, notifiction.notificationBody, notifiction.notificationURL, notifiction.notificationImage);
});
};
cron.schedule('*/55 * * * * *', async () => {
console.log('Checked Outer Cron ...');
const notifiction = await notificationHelper.viewScheduledNotification();
const formattedStartDate = `${notifiction.startDate}`;
const formattedEndtDate = `${notifiction.endDate}`;
const fullTodayDate = new Date();
const fullEndDate = new Date(formattedEndtDate);
const fullStartDate = new Date(formattedStartDate);
const startHour = notifiction.time.split(':')[0];
const startMinutes = notifiction.time.split(':')[1];
if (fullStartDate <= fullTodayDate && fullTodayDate <= fullEndDate) {
console.log('Checked Middle Cron ...');
console.log(startHour, ':', startMinutes);
triggerPushNotification(notifiction, startMinutes, startHour);
}
});

Agenda not running jobs on schedule

I am trying to use agenda to schedule jobs at a certain date and time, but the jobs are not running when the specified date is reached.
This is how I'm creating the job:
agenda.create(type, data)
.schedule(new Date(startDate))
.repeatEvery('11 21 * * *', {timezone: 'Europe/Bucharest'})
.save();
This is how I start agenda:
const Agenda = require('agenda');
const mongoDB = process.env.DB_PATH;
const mongoConnectionString = mongoDB;
let agenda = new Agenda({db: {address: mongoConnectionString, collection: 'jobs'}});
let jobTypes = process.env.JOB_TYPES ? process.env.JOB_TYPES.split(',') : [];
jobTypes.forEach(function(type) {
require('./jobs/' + type)(agenda);
});
if(jobTypes.length) {
agenda.on('ready', function() {
console.log('agenda start')
agenda.start();
});
}
function graceful() {
agenda.stop(function() {
process.exit(0);
});
}
process.on('SIGTERM', graceful);
process.on('SIGINT' , graceful);
export default agenda;
This is an example with a job that didn't start on the scheduled date:
Is there something I'm doing wrong?
EDIT:
The job is triggered if I do schedule(new Date()), but it won't using a defined date.

Resources