Node script to run with Heroku scheduler - node.js

I want to run scheduled task on heroku with Heroku scheduler. I've created a bin folder at root of the project and created a task.js file as follows:
#! /app/.heroku/node/bin/node
var nodemailer = require('nodemailer');
require('dotenv').config({
path: '.env'
})
var mail = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.FROM_EMAIL,
pass: process.env.EMAIL_PASS
}
});
async function rmaEmailReport() {
var mailOptions = {
from: process.env.FROM_EMAIL,
to: process.env.TO_EMAIL,
subject: 'Test Email',
text: 'This is daily test email',
};
await mail.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
process.exit();
} else {
res.send('Email sent: ' + info.response);
process.exit();
}
});
}
rmaEmailReport();
This task needs to run at specific time to send an email. I've run this on my local machine by this command node bin/test.js and it runs smoothly and I receive email but when I add this to Heroku scheduler I never receive an email.
Please see attached image of Heroku scheduler. I want to know where I'm doing wrong and what I need to change in order to work this as it's working on local. Your help would be appreciated.

Related

Why is transport.sendMail() not getting called when I use it with React (nodemailer)

So I'm new to node and react and I was trying to set up nodemailer. At the moment it's working fine if I don't run it with React.
I start a new project with
npm init -y then npm install nodemailer and in a file called index.js I have the following:
const nodemailer = require('nodemailer');
const handleClick = () => {
var transport = nodemailer.createTransport({
host: "smtp.mailtrap.io",
port: 2525,
auth: {
user: "user",
pass: "pass"
}
});
const message = {
from: 'test#test.com',
to: 'to#email.com',
subject: 'This is very frustrating',
text: 'I wish I knew why this is not working in React'
};
transport.sendMail(message, function (err, info) {
console.log("transport.sendMail called")
if (err) {
console.log(err)
} else {
console.log(info);
}
});
}
handleClick();
I run this with node index.js and it works as expected and I can view the email in mailtrap.io (fake SMTP server I've found for testing).
However! My problem occurs when I try to do this in my React project.
I have the following (exact same handleClick() function) in Contact.js
import React from 'react';
import './App.css';
const nodemailer = require('nodemailer');
const Contact = () => {
const handleClick = () => {
var transport = nodemailer.createTransport({
host: "smtp.mailtrap.io",
port: 2525,
auth: {
user: "user",
pass: "pass"
}
});
const message = {
from: 'test#test.com', // Sender address
to: 'to#email.com', // List of recipients
subject: 'This is very frustrating', // Subject line
text: 'I wish I knew why this is not working in React' // Plain text body
};
transport.sendMail(message, function (err, info) {
console.log("transport.sendMail called")
if (err) {
console.log(err)
} else {
console.log(info);
}
});
}
return (
<button onClick={handleClick}>CLICK</button>
)
}
export default Contact
Which I am using as <Contact/> in my App.js file. The button displays, and the click works. But transport.sendMail() does not even execute (I don't see the output from console.log("transport.sendMail called"))
I'm not sure how to even start debugging, and I've spent quite a good while googling but I've found nothing of use so far, just examples that are doing the same as I. Any help would be greatly appreciated.
More details (that I don't think are relevant, but including just in case) about my react project
I started the React project by using npx create-react-app and then I run it with npm start, it runs on localhost and port 3000
I am using reactstrap
When clicking the button in my React app I see this and when expanded (both) look like this

Nodemailer fails on live server but works on local machine

Using nodemailer to send a registration confirmation email. Works fine on my local machine, but fails from live server (using DigitalOcean droplet & InMotionHosting email account).
I have tried as many things as I can think of to no avail, so I don't know what to do next. Any help is appreciated.
Here's the code:
let transporter = nodemailer.createTransport({
host: 'mail.domain.com',
port: 587,
secure: false,
auth: {
user: 'test#domain.com',
pass: '654cba'
},
// true for live server, false for local machine
tls: {
rejectUnauthorized: true
}
});
let mailOptions = {
from: '"Register" <test#domain.com>',
to: user.username, // email address from user object
subject: 'Registration',
html: '<h1>mail content</h1>'
};
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
console.log(error);
return res.send('Error sending confirmation email to: ' + user.username);
}
console.log('Message sent: %s', info.messageId);
req.flash('success', 'Success! Welcome ' + user.fullname + '! Please check your email, and click the link to complete your registration.');
res.redirect('/');
});
I set the tls.rejectUnauthorized to 'false' for the local machine and it works as expected.
On the live server, I set it to 'true', but receive the error message ('Error sending confirmation email to: ' + user.username) after transporter.sendMail() is executed. I tried eliminating this among many other tests to no avail.
Thank you for any assistance.

TypeError: tls.connect is not a function

I keep getting this issue tls.connect is not a function.
I am using nodemailer with my Reactjs and Nextjs application.
sendmail.js?71c0a4a:33 Error: TypeError: tls.connect is not a function
at SMTPConnection.connect (index.js?49b6f52:228)
at getSocket (index.js?55ebb9c:234)
at setImmediate (index.js?55ebb9c:70)
at run (setImmediate.js?d2412a6:40)
at runIfPresent (setImmediate.js?d2412a6:69)
at onGlobalMessage (setImmediate.js?d2412a6:109)
The weird part is if I run the script in the console it will work, but running though the browser I get the tls.connect is not a function error.
const nodemailer = require('nodemailer');
let transporter = nodemailer.createTransport({
service: 'gmail',
secure: false,
port: 465,
auth: {
user: '',
pass: ''
},
});
class mail {
options (to, text, subject, html) {
console.log(to)
var mailOptions = {
from: '',
to: to,
subject: subject,
text: text,
html: html
}
return(mailOptions);
}
sendMail(mailOptions) {
console.log(mailOptions)
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.error('Error:', error);
}
console.log('Message %s sent: %s', info.messageId, info.response);
});
}
}
export default mail;
You're using nodemailer inside a bundler, on Client Side,
NodeMailer should only be used at ServerSide.
This issue is environmental and also be aware that even if that was working, you would be exposing that google account and password by using it at client side.
Consider creating a serverside nodejs api to send your emails
issue

how to send an email in nodejs

I read the following, Sending emails in Node.js? but I'm looking for a way to send an email, not through an smtp server. As in the linux envirement you have different options such as sendmail and others
I could ofc use the environment I'm in to make use of the already existing functionality, but I would be interested to learn how one would dispatch the email using only js, if even possible..
I set up an smtp server using the smtp module: https://github.com/andris9/smtp-server why I'm interested in the delivery part of a server I already setup.
Take a look at node-mailer. You can set it up without smtp server. https://github.com/nodemailer/nodemailer
var nodemailer = require('nodemailer');
var send = require('gmail-send');
var mailserverifo = nodemailer.createTransport({
service: 'gmail',
host : "smtp.gmail.com",
port : "465",
ssl : true,
auth: {
user: 'email#gmail.com',
pass: 'password#'
}
});
var Mailinfo = {
from: 'email#gmail.com',
to: 'email#info.com',
subject: 'Testing email from node js server',
text: 'That was easy!'
};
mailserverifo.sendMail(Mailinfo, function(error, info){
if (error) {
console.log(error);
} else {
console.log('Email Send Success: ' + info.response);
}
});
Enable less secure app form setting -
https://www.google.com/settings/security/lesssecureapps
Disable Captcha -
https://accounts.google.com/b/0/displayunlockcaptcha
You can use sendmail in Node js. I'v using it and it's working fine for me.
npm install sendmail --save
const sendmail = require('sendmail')();
sendmail({
from: 'no-reply#yourdomain.com',
to: 'test#qq.com, test#sohu.com, test#163.com ',
subject: 'test sendmail',
html: 'Mail of test sendmail ',
}, function(err, reply) {
console.log(err && err.stack);
});
https://www.npmjs.com/package/sendmail
First:Install nodemailernpm install nodemailer
Then put this into your node file:
var nodemailer = require('nodemailer');
var http = require('http');
var url = require('url');
console.log("Creating Transport")
var transporter = nodemailer.createTransport({
service:'Hotmail',
auth: {
user:'salace2008765#outlook.com',
pass: 'alice123#'
}
});
var mailOptions = {
from:'salace2008765#outlook.com',
to: 'jerome20090101#gmail.com',
subject: 'This is a test: test',
text:'TgK'
}
console.log("Sending mail")
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response)
}
})
It usally works
Sources:W3Schools and Nodemailer's official site

nodemailer fails on Heroku

I trying to send an email using node.js and the module node-mailer on heroku, but it is failing. I show you the code I have (I think simple), and after I´ll explain better.
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'example#gmail.com',
pass: 'pass'
}
});
exports.sendAnEmail = function(receivers, tittle, user, message, jsonBack, callBack)
{
var mailOptions =
{
from: "User example#gmail.com", // sender address
to: receivers,
subject: tittle, // Subject line
html: message // html body
};
transporter.sendMail(mailOptions, function(err, response)
{
if(err)
console.log("email.js->sendAnEmail-> error: " + err)
else
console.log("email.js->sendAnEmail-> NO error")
if(callBack && typeof(callBack)=="function")
callBack();
});
}
If I execute this code (or rather, the code that invoke that) on local it works fine, but if I execute (on the git console) heroku run cron (it will be a schedule task on heroku), the console spits this: "email.js->sendAnEmail-> error: Error: Invalid login".
I tryed to access my account coying and pasting the user and the pass and it let me in.
Do I need to do something else using heroku (or using schedule) to make it works??
Thank you.

Resources