Hugh Mungus
Hugh Mungus

Reputation: 129

How can I get a 'get' request to run on a schedule in NodeJS?

The function I would like this function to run by itself at time intervals. As it is now I have to visit the '/getCompanyInfo' path to trigger it. I would like it to run every minute as if I was visiting the '/getCompanyInfo' path each minute. The app is on Heroku and I would like the function to execute without any pages open.

The original function that is triggered by visiting the path.

const express = require('express');
const app = express();

/**
 * getCompanyInfo ()
 */
app.get('/getCompanyInfo', function(req,res){

    const companyID = oauthClient.getToken().realmId;
    console.log(companyID)
    const url = OAuthClient.environment.production ;

    oauthClient.makeApiCall({url: url + 'v3/company/0000000000/salesreceipt/8?minorversion=41'})
        .then(function(authResponse){
            console.log("The response for API call is :"+JSON.parse(JSON.stringify(authResponse)));
            res.send(authResponse);
        })
        .catch(function(e) {
            console.error(e);
        });
});

One of my attempts here was to put it in a function that executes each minute using node-schedule.
This one doesn't do anything other than print 'This will run once a minute.' to the console. I tried removing

app.get(function(req,res){  

and the

})

below it but that made the app (hosted on Heroku) fail to build.

const express = require('express');
const app = express();

var schedule = require('node-schedule');

var j = schedule.scheduleJob('* * * * *', function(){
console.log('This will run once a minute.');
app.get(function(req,res){

    const companyID = oauthClient.getToken().realmId;
    console.log(companyID)
    const url = OAuthClient.environment.production ;

    oauthClient.makeApiCall({url: url + 'v3/company/0000000000/salesreceipt/8?minorversion=41'})
        .then(function(authResponse){
            console.log("The response for API call is :"+JSON.parse(JSON.stringify(authResponse)));
            res.send(authResponse);
        })
        .catch(function(e) {
            console.error(e);
        });
});

});

More Context: It is inside an app I have on Heroku. I would like to set the app to make a requests for JSON data from the API every x time without me having to touch it.

Upvotes: 1

Views: 2010

Answers (2)

Ivaylo Atanasov
Ivaylo Atanasov

Reputation: 225

app.get initializes api handler - e.g. this is your api route definition - the thing that will respond when you call GET /getCompanyInfo via web browser or some other client. You should not redefine it regularly with your scheduled action.

The failed build after you've removed the route handler is probably because of the res.send(authResponse); left behind.

You could have something like:

// function that will be used to get the data
const getCompanyInfo = (done) => {
  const companyID = oauthClient.getToken().realmId
  console.log(companyID)
  const url = OAuthClient.environment.production

  oauthClient.makeApiCall({url: url + 'v3/company/0000000000/salesreceipt/8?minorversion=41'})
    .then((authResponse) => {
      console.log("The response for API call is :"+JSON.parse(JSON.stringify(authResponse)))
      done(authResponse)
    })
    .catch((e) => {
      console.error(e)
    })
}

// this will trigger the function regularly on the specified interval
const j = schedule.scheduleJob('* * * * *', () => {
  getCompanyInfo((companyInfo) => {
    // ...do whatever you want with the info
  })
})

// this will return you the data by demand, when you call GET /getCompanyInfo via browser
app.get('/getCompanyInfo', function(req,res) {
  getCompanyInfo((companyInfo) => {
    res.send(companyInfo)
  })
})

Upvotes: 1

mwilson
mwilson

Reputation: 12900

Heroku has an add on called Heroku Scheduler that does what you want. The node-schedule npm package might do the job, but as you mentioned, you probably aren't going to be able to see the execution/results/logs of your jobs that run every 24 hours without making some interface for it on your own.

For your issue, calling app.get doesn't make a lot of sense. That's just telling node about the route. Assuming you have your /getCompanyInfo route up and running, you just need to call it in your scheduled job, not re-register it every time.

You could also just do this (http being the http client you're using):

var j = schedule.scheduleJob('* * * * *', async function(){
    console.log('This will run once a minute.');
    const result = await http.get('/getCompanyInfo');
    console.log(result);
});

Upvotes: 1

Related Questions