Send scheduled email reports from Angular using node.js - node.js

I have set up an Angular project and it is consuming APIs from the NodeJS app.
Angular dashboards have some reports/charts, I will configure a schedule somewhere in DB.
I want to add scheduling functionality so that I will get an automated email containing a graph/chart as an email body.
Can anyone guide me here!

Your scheduling will have to happen out of the NodeJS app since that can be always 'alive' The Angular project is only doing things when you've loaded it in your browser and cannot process that scheduled emails when you don't have it open (unless you were to make it a PWA perhaps, but then still it would be rather convoluted to do it out of Angular).
Do all the processing on the server, including generating and rendering the charts to an email message that you send over SMTP or through a service like Mailgun or Sendgrid.

You can use node-schedule package from npm node-schedule, it will help you to schedule cron jobs whenever you want to send email.
const schedule = require('node-schedule')
const job = schedule.scheduleJob('21 * * * *', function(){
console.log('Send my email.')
})
This will excute this cron at exactly 21min of any hour.
You can go through the npm package for more scheduling details.

Related

Send a PUT request from all accounts in the database after every 24hours in Production

I have deployed my website, in my website user have to complete 10 orders every day, i want to reset orders at 9am everyday. i am using MERN stack. how to reset orders ? i am thinking of sending put requests that modifies user orders to 0 at 9am everyday.
import schedule from 'node-schedule'
const { currentUser } = useSelector((state) => state.user) //using Redux to fetch current user
schedule.scheduleJob('0 9 * * *', async () => {
try {
await axios.put(`/details/${currentUser._id}`, {
dailyOrders: 0,
})
} catch (err) {
console.log(err)
}
})
I have tried using node-cron but that didn't work well. it will work only if the user is logged in to the account and have opened the site all the time. If he closes site , node cron will not work.
I have deployed my website! and tried using pm2 start myapi
There are potentially multiple options, depending on your architecture and the complexity of your backend servers. Also, I strongly believe that this is a task to be completed on the backend servers rather than the client:
You would need a database query to reset all users' orders
This could be a secure route (e.g accessible only to admins through authentication)
Here are some examples of potential solutions depending on your architecture:
If you are using cloud deployment (e.g AWS) you could set up a lambda function to accomplish this and call it on a given schedule via EventBridge (this is basically a serverless cron job)
If you have only one instance of the backend server running you could set up a cron job on that instance (thinking of node-cron job). However, beware of server downtimes and/or multiple servers running at the same time
In a nutshell, there are many ways to accomplish this (it's not one size fit all situation) however this has to be done on the backend servers

How to automatically send a ``get request`` in a loop after some interval of time?

I am making a web application that is scrapping the news from a news site and saves to my database (scrapping is done just for learning purpose). After the database is updated all the stored data is sent to the user frontend.
Here is the route responsible for the above action.
router.get('/news, postController.getNewsPost);
New news are added to the site being scrapped as the day passes. Lets say if no user logs in to my application my database does not updates because the route mentioned above does not fires.
I want my database to be updated periodically even when no users have logged into my web application.
I am new to backend development so please guide me on how i can achieve this, also let me know if more information is required.
The simplest solution would be to use a setInterval to execute a specific function every N seconds:
setInterval(function() {
// scrap news and save them to the database every 5 seconds
}, 5000)
More versatile and solid solutions can be implemented using an external library for scheduling task, something like Agenda
You can use node-cron module to schedule your scrapping job.
Install node-cron using npm:
$ npm install --save node-cron
Import node-cron and schedule your scrapping job:
var cron = require('node-cron');
cron.schedule('* * * * *', () => {
console.log('Scrapping....');
});
Here is the module link. https://www.npmjs.com/package/node-cron
You can use the following method
$ npm install --save node-cron
var cron = require('node-cron');
cron.schedule('second minute hour day month', () => {
//update database code
});
library link enter link description here

scraping a site without need of client request to server

I am building a scraper app with nodejs and I'd like it to scrape a certain site 2 times a day.
now, there's a problem though.
what I am used to doing is that from client side, someone makes a request and the app scrapes data and shows the result.
but what If I want the app to just do the scraping 2 times a day, without the need for client to make a request to server.
how does one do that?
Basically, it's a site where the user puts in keywords they are searching for.
the app searches for that keyword everyday and it notifies the user when the keyword shows up on the page.
so, how does one do that without having the user to search for the keyword everyday?
Seems like we can use cron jobs for scheduling, and the scraping will happen twice a day or any times I choose, but the thing is how do I send the data from the scraping to client side?
Or how do I notify the site user that the keyword was found and he can come to the site and look at it?
but what If I want the app to just do the scraping 2 times a day, without the need for client to make a request to server. how does one do that?
You use a task scheduler, such as Cron.
how do I notify the site user that the keyword was found and he can come to the site and look at it?
There are lots of options.
Email
SMS
Twitter messages
Notications + Service Workers
etc
The request npm module would allow you to do that. The following (server) app queries from an external API every 10 seconds:
const request = require('request');
function doRequest() {
request('http://www.randomtext.me/api/', function (error, response, body) {
console.log('error:', error);
console.log('statusCode:', response && response.statusCode);
console.log('body:', body);
// do whatever you need to do with you result
// and notify the user (... not clear what channel you want to use)
// could be done with sockets, email, ... or text messages (twillio) ...
});
}
setInterval(doRequest, 10000); // <-- adapt your intervall here
So this is an easy example for server to server requests ... hope that helps.

cronJob and HTTP requests

i'm new to web development and have some questions about http requests and cron jobs. I npm installed cron and wanted to incorporate it into my app, where app.js is getting requests from clients that adds data into a database (using mongoose) from a form that client filled out. I want to run a script (executer.js) to be called every 10 seconds to execute a task that will use the data in the same database. Any suggestions on how I could accomplish this?
You don't need to use a cron job for this (though if you need such a library there is the excellent: https://github.com/kelektiv/node-cron). I'd recommend using setInterval for your particular example.
See https://nodejs.org/api/timers.html#timers_setinterval_callback_delay_args for detailed documentation on this.
var intervalMs = 10000;
function updateDB() {
console.log("Updating db..");
/* insert db update code here. */
}
setInterval(updateDB, intervalMs);

Nodejs can I make a GET request to my own application?

I have a route in my app that I've defined with tasks to be run in the style of a few cron jobs. I know that this can be triggered by a GET request from an external devise when necessary (and that's ideal). (FYI: I will be adding validations for security purposes to this route.)
router.get('/cron', function(req) {
/**
*
* Do cron things...
*/
task();
});
What I'm wondering is if I'd also be able to trigger this via a GET request from my own system when necessary?
What would be really helpful is to reuse the same route above with an npm module like node-crontab and simply make a request to the route every few hours.
var doEveryThirtyMinutes = crontab.scheduleJob("*/30 * * * *", function(){
/**
* Make GET request to '/cron' controller.
* Live a happy life.
*/
});
I can't find any information on how to make that request (to my same system), even in the npm request module documentation. Is there a reason not to do this? Am I missing something? Is this a bad practice?
The reason this setup would be incredibly beneficial is that I connect to my database via an extension of the req object and don't want to implement a new connection module. Also, I already have a logging procedure implemented for successful/ unsuccessful route executions, so I would be able to reuse that as well.
Thanks ahead of time for your help!
Yes, you can make a get request to your own application. You would make this request like any other request, just use your application's host and port.
If you want to grab the hostname from your os, you can do this with require('os').hostname
https://nodejs.org/api/os.html#os_os_hostname
The reason you wouldn't do this is you are already in your application, so you shouldn't need to communicate via it's network interface.

Resources