Reputation: 58790
I have a node application that contain cron in it. Right now, it run perfectly on Ubuntu server.
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const router = express.Router();
const cron = require('node-cron');
const nodemailer = require('nodemailer');
const request = require('request');
const cheerio = require('cheerio');
const FCM = require('fcm-node');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
var admin = require('firebase-admin');
var serviceAccount = require('./serviceAccountKey.json');
var fcm = new FCM(serviceAccount);
var firebase = admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://ios-base-88.firebaseio.com'
});
const FETCH_DOMAIN = 'https://finance.yahoo.com/lookup/all?s=';
router.get('/', (req, res) => {
res.json({
msg: 'Something happening'
})
});
const checkPrice = () => {
var db = admin.database();
var ref = db.ref('alerts');
ref.on('value', (snapshot) => {
console.log(snapshot.val());
if (snapshot.val()) {
snapshot.forEach((child) => {
trackPrice(child);
})
}
}, (error) => {
console.log('The read failed: ' + error.code);
})
}
const sendEmailNotification = async (email, text, snapshot) => {
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: '[email protected]',
pass: '***'
}
});
let mailOptions = {
from: '[email protected]',
to: email,
subject: text,
html: text
};
let info = await transporter.sendMail(mailOptions);
// update notify params
var db = admin.database();
var ref = db.ref('alert').child(snapshot.key);
const company = snapshot.val();
ref.update({
companyName: company.companyName,
price: company.price,
ticker: company.ticker,
notified: true
})
console.log('Message sent: %s', info.messageId);
console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
}
const trackPrice = (child) => {
var snapshot = child.val();
const company = snapshot.companyName;
const price = snapshot.price;
const url = `${FETCH_DOMAIN}${snapshot.ticker}`;
request(url, (error, response, html) => {
if (!error && response.statusCode === 200) {
var $ = cheerio.load(html);
var stock_price = null;
$('table').find('tbody').find('tr').each(function(i, e) {
var column = $(this).prev();
if (column.children('td.data-col1').text() === snapshot.companyName) {
stock_price = column.children('td.data-col2').text();
}
});
stock_price = parseFloat(stock_price.replace(/,/g, ''));
if (stock_price && snapshot.price == Math.floor(stock_price)) {
// send email notification
admin.auth().listUsers()
.then((list) => {
list.users.forEach((user) => {
var customer = user.toJSON();
sendEmailNotification(customer.email, `The company ${snapshot.companyName}' stock price is reached to ${snapshot.price}`, child);
});
}).catch((error) => {
console.log('Error listing users:', error);
})
// Send push notification
var ref = firebase.database().ref('users');
ref.once('value')
.then(function(snapshot) {
var data = snapshot.val();
var fcmToken = '***';
var message = {
to: fcmToken,
data: {},
notification: {
title: 'Stock Price',
body: `The company ${company}' stock price is reached to ${price}`,
tag: collapseKey,
icon: 'ic_notification',
color: '#18d821',
sound: 'default'
}
};
fcm.send(message, function(err, response) {
if (err) {
console.log(err);
} else {
console.log("Successfully sent with response: ", JSON.stringify(response));
}
})
})
}
}
})
}
const run_job = () => {
cron.schedule('0 * * * * *', () => {
checkPrice();
});
}
//run_job();
checkPrice();
app.use('/api', router);
app.listen(3000, () => {
console.log('\x1b[33m%s\x1b[0m', '** Express Development is listening on localhost:3000, open your browser on http://localhost:3000 **');
})
I want to make sure it run as cron the background.
I know that I can't do this
* * * * * node /home/forge/bheng/public/ios-base-api/index.js >> /tmp/tmpfile.log 2>&1 &
Because I already cron server in my node already.
How would one go about and debug this further?
Upvotes: 1
Views: 661
Reputation: 651
I have faced the same problem and I resolved it using pm2.
install pm2 globally:
npm install -g pm2
if you run your script using npm start
run this in your project folder
pm2 start index.js
pm2 will turn your script in to a daemon that will run in the background and it will restart the script if it fails. To check the logs run
pm2 monit
If you want to run your script when the system starts run
pm2 startup
and follow the instructions.
Upvotes: 1