Search code examples
node.jsportnodemailer

How to make node.js function run without visiting port


This might be a completely stupid question but I have a very simple node.js test app that just sends an email every 3 minutes (pointless but just for learning purposes). The app works but only once I visit port:3000 - I understand why because that's where the listener is but how would I make the email code execute without having to visit the port? Or am I misunderstanding how it works? Code below - appreciate any help 😃

const http = require('http');
const nodemailer = require('nodemailer');

let app = http.createServer((req, res) => {
    const init = async () => {

        const email = async () => {
    
            let transport = nodemailer.createTransport({
                host: "smtp.mailtrap.io",
                port: 2525,
                auth: {
                  user: "user",
                  pass: "pass"
                }
              });
            
            const message = {
                from: 'nodeapp.test.com', // Sender address
                to: 'to@email.com',         // List of recipients
                subject: 'Test Email', // Subject line
                text: 'Testing testing 123' // Plain text body
            };
        
            let info = await transport.sendMail(message, function(err, email) {
                if (err) {
                  console.log(err)
                } else {
                  console.log(email);
                }
            });
    
        }
    
    
        email()
        setInterval(email, 180000)
    }  
    init()
})

app.listen(process.env.PORT || 3000, () => {
    console.log('Server running at http://127.0.0.1:3000/')
})


Solution

  • Yes of course one of the practical ways to have that is using Cron. For that just install that package at first: "npm i cron". Create some "index.js" (content is below) and run "node index.js":

    const CronJob = require('cron').CronJob;
    const nodemailer = require('nodemailer');
    
    const runSendEmail = async () => {
        // HERE YOU CAN IMPLEMENT WHAT YOU WANT (I just kept your code the same)
        // for example you can test this only with logging something like this
        // console.log(new Date());
        // and after that you can implement your functionality here
        // or you can separate the function logic in different file
    
        let transport = nodemailer.createTransport({
            host: "smtp.mailtrap.io",
            port: 2525,
            auth: {
                user: "user",
                pass: "pass"
            }
        });
    
        const message = {
            from: 'nodeapp.test.com', // Sender address
            to: 'to@email.com',         // List of recipients
            subject: 'Test Email', // Subject line
            text: 'Testing testing 123' // Plain text body
        };
    
        let info = await transport.sendMail(message, function(err, email) {
            if (err) {
                console.log(err);
            } else {
                console.log(email);
            }
        });
    }
    
    class Cron {
        static async start() {
            await new CronJob(
                '*/3 * * * *', // cron time period (At every 3rd minute)
                () => { // RUNNING FUNCTION
                    try {
                        runSendEmail();
    
                        // you can also get the result of "runSendEmail" function
                        // for that you need to return the value from "runSendEmail"
                        // and may you'll need to do that with async/await like this:
                        // const result = await runSendEmail();
                        // also in this case don't forget to add "async" before RUNNING FUNCTION's parentheses
                    } catch (err) {
                        console.log(err.message); // or   throw Error(err.message);
                    }
                },
                null,
                true
            );
        }
    }
    
    Cron.start();