Setup Heroku Scheduler job to email all users (Meteor/MongoDB) - node.js

Does anyone know if it's possible to make a Heroku Scheduler job that would send an email to all of my users once per day? I'm using Meteor and MongoDB.
I can see that the Heroku Scheduler can run a command such as "node somefile.js" but I can't seem to figure out how to make a connection to the mongodb in a file like this. Can I somehow tap into the DB without involving Meteor in this?
Any help would be appreciated!

I eventually found a package to do so: synced-cron. Basically, you need to setup a method in which use the package to fire a recurring job.
The package website also has a sample code:
SyncedCron.add({
name: 'Crunch some important numbers for the marketing department',
schedule: function(parser) {
// parser is a later.parse object
return parser.text('every 2 hours');
},
job: function() {
var numbersCrunched = CrushSomeNumbers();
return numbersCrunched;
}
});
Here you just need to replace the code in the job function to send out the email.
The job supports schedules like "every 5 minutes", "at 5:00pm", etc. The package relies on the text parser in Later.js to parse the schedule. You can refer to the Later.js doc.

Two different options.
The first is to use Heroku's scheduler,
In which you create a text file in your bin directory:
#! /app/.heroku/node/bin/node
var test = require('./jobToDo') //put your job in this file (jobToDo.js)
Now you don't have to put the job in another .js file, but it makes it easier to work with, rather than coding in a plain text file. (put again that is up to you)
The first line #! /app/.heroku/node/bin/node may be different for you depending on how your configuration is set up, depending on your OS and node/npm set up.
The second option is a cron style library. This will allow you to decide when you want your code to run.
This is pretty easy, and for me the preferred method.
var CronJob = require('cron').CronJob;
var fn = function(){
// Do Something
}
var job = new CronJob({
cronTime: "00 00 02 * * 1-5",
onTick: fn,
start: true,
timeZone: 'America/Los_Angeles'
});
You can look at documentation on github

Related

Implement infinite long running service in NodeJS

I have a list of URLs in DB. I want to periodically check if those URLs are alive or not.
So I create a long running service which run infinite loop, each iteration:
Query database to get list of urls
For each URL, make request to check if it is alive or not
Please guide me how to implement that service.
I looked at Bull and Kue, but they seem not support infinite loop service?
You can use something very simple like setInterval() to have your task repeat x amount of times.
var testUrls = function(){
//do your magic of connecting to the DB and checking urls.
}
setInterval(testUrls, 60000);
The above code snippet will call your function testUrls every minute.
Or if you need more control over the scheduling you can use a npm package like cron.
You can use node-schedule
Its very simple
var schedule = require('node-schedule');
var j = schedule.scheduleJob('42 * * * *', function(){
console.log('The answer to life, the universe, and everything!');
});

node-schedule undoing cancellation

I've been working with node for the first time in a while again and stumbled upon node-schedule, which for the most part has been a breeze, however, I've found resuming a scheduled task after canceling it via job.cancel() pretty difficult.
For the record, I'm using schedule to perform specific actions at a specific date (non-recurring) and under some circumstances cancel the task at a specific date but would later like to resume it.
I tried using job.cancel(true) after cancelling it via plain job.cancel() first as the documentation states that that would reschedule the task, but this has not worked for me. Using job.reschedule() after having cancelled job first yields the same result.
I could probably come up with an unelegant solution, but I thought I'd ask if anyone knows of an elegant one first.
It took me a while to understand node-schedule documentation ^^
To un-cancel a job, You have to give to reschedule some options.
If you don't pass anything to reschedule, this function returns false (Error occured)
For exemple, you can declare options, and pass this variable like this :
const schedule = require('node-schedule');
let options = {rule: '*/1 * * * * *'}; // Declare schedule rules
let job = schedule.scheduleJob(options, () => {
console.log('Job processing !');
});
job.cancel(); // Cancel Job
job.reschedule(options); // Reschedule Job
Hope it helps.

How to run a node script automatically at specified intervals

I'm making a dating app. Every day at midnight I want 'new matches' to be randomly found and displayed to a user.
If anyone could give a give high level overview of how this would work I'd be really grateful?
If want to execute a Node task every midnight then Cron jobs is a powerful, yet simple tool that can help us get there. You can user Cron Package to achieve this in node.
You can add cron dependency using
npm install cron
You can modify following script
var CronJob = require('cron').CronJob;
var job = new CronJob('00 00 01 * * *', function() {
console.log('You see this message every day 01 AM America/Los_Angeles');
}, null, true, 'America/Los_Angeles');
Where you can replace console.log with the logic you want to implement the code that will find match for each users of app and replace timezone with yours.

How to call external function in background tasks in arangodb

I have a functionality fully working and I want to call this every 30 min from background task. But It is not calling and throwing error as 'undefined'.
app.js
function hourly() { require("console"); console.log('I am running');}
controller.get('/testOnce', function(req, res) {
var tasks = require("org/arangodb/tasks");
tasks.register({
id : "Test",
name : "Testing background task",
period : 5,
command : "hourly()"
});
});
I tried defining hourly in a separate js and then calling that with 'require' But this throws cannot locate module 'myjob'
myjob.js
function hourly() { require("console"); console.log('I am running');
app.js
controller.get('/testOnce', function(req, res) {
var tasks = require("org/arangodb/tasks");
tasks.register({
id : "Test",
name : "Testing background task",
period : 5,
command : "var job = require('myjob');"
});
});
The contents of the command attribute cannot refer to variables defined in other scopes. For example, in the app.js variant you're using a variable named hourly which may not be present anymore when the command gets executed.
In the simple case of just logging something, the app.js variant could be made working if its command parameter is changed to the following (which won't require any variables):
var tasks = require("org/arangodb/tasks");
tasks.register({
period : 5,
command : "require('console').log('I am running from inline command');"
});
The variant that defines the job function in a separate file (named myjob.js) can be made working by making the function available via an export of that module:
function hourly() {
require("console").log('I am running from myjob.js');
}
exports.hourly = hourly;
This is because a require() will only expose what the module exported. In the above case the module will expose a function named hourly, which can now be invoked from a background task as follows:
var tasks = require("org/arangodb/tasks");
tasks.register({
period : 5,
command : "require('myjob').hourly();"
});
Please note that in order for this to work, the file myjob.js needs to be located in the module search path. IIRC that is js/node by default. Also note that this directory already includes the bundled modules and may change on ArangoDB updates.
If the regular command is to be executed from within a Foxx route, then using Foxx queues might also be an option as they should allow putting the script with the job function inside the application directory. However, I have not tried this yet.
The "Foxx way" of solving this would be using the queue and a script-based job (introduced in 2.6).
I've covered this in the last Foxx webinar and am working on a blog post and cookbook recipe.
The problem with doing it this way is that Foxx jobs can not be periodic in 2.6. The feature is planned for 2.7 but with 2.6 only just having been released, you probably won't be able to use it any time soon.
Personally I would recommend using an external scheduler and invoking the Foxx script from there (via the foxx-manager CLI or the HTTP API).

Cleaning up Netsuite scripts

Are there any suggestions for cleaning up unused scripts in NetSuite? We have an implementation that includes scripts and bundles from a third party and then innumerable scripts (especially restlets and workflows) that we have written, changed, rewritten, tossed aside, etc by multiple developers. Many of the scripts were released in error logging or don't have any debug log statements, which is the only way I can think to determine when, and how many times a script is run.
I am looking for a way to to determine just that - when and how often every script and/or deployment is run (hopefully without going into each script and adding log info), so we can clean up before the new version is implemented.
Thanks!
In version 14.2 (coming soon), there is a script queue monitor tool that should tell you when scripts are running, which queue is being used, etc (SuiteCloud Plus customers). See the release notes for 14.2 for more detail.
The best way I can find is doing a Script Deployment search. You can condition on is Deployed = Yes/No, Status is anyof/noneOf Released/Scheduled, and Execution Log: Date within last year.
I am only giving example conditions based on what you mentioned. The Yes/No and anyof/Noneof depends on if you want to see those that are inactive (to clean them up) or those that are active. The execution log condition would only work if either the script errored (which does not require a nlapiLogExecution() call) or if there is a logExecution call in the script.
You could at least play with this a bit from what you know of your scripts to work off that. You can do a similar thing for Workflows by doing a workflow search.
You could undeploy the scripts using a saved search. For example I want to undeploy the scripts which were created before a year ago.
var start = function(request, response)
{
var filters = new Array();
var columns = new Array();
filters[0] = new nlobjSearchFilter('formuladate', null, 'before', 'lastfiscalyear');
columns[0] = new nlobjSearchColumn('internalid');
var search = nlapiSearchRecord('scriptdeployment', null, filters, columns);
for(var i in search)
{
var rec = nlapiLoadRecord('scriptdeployment', search[i].getValue('internalid'));
rec.setFieldValue('isdeployed', 'F');
nlapiSubmitRecord(rec, true);
}
}

Resources