nodemailer fails on Heroku - node.js

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.

Related

Node script to run with Heroku scheduler

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.

how to send email with nodejs from heroku

I have this nodejs app am running and am trying to send an email to newly register users like a verification link. On my local server it works well but when I deployed to heroku it always fails.
my nodejs code
var transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
auth: {
user: 'gmail.com',
pass: 'password'
}
});
var mailOptions = {
from: 'gmail#gmail.com',
to: email,
subject: 'Verification code',
html: `<h1 style="color:blue,font-weight:bold,text-transform-uppercase"></h1></p>
<p style="color:black,font-weight:bold,text-align:center, font-size:20px">${pin}</p>
<span>this verification process helps comfirm that your the real owner of this account, so we can
help protect you from scams</span>
<p>click the link ${v_address} to go to the verification page</p>`
};
transporter.sendMail(mailOptions, async function(error, info){
if (error) {
res.json({error:'failed please check details or network connection'});
}else {
const newCrete = await Create.save()
if(newCrete){
const newVerify = new Verifyuser({
email:email,
pin:pin,
address:v_address
})
const Verified = await newVerify.save()
res.json({success:'success'})
}
}
});
Kindly use the NPM Package (two-step-auth)
This will take care of the whole verification process, you don't need to worry about the backend work :), This will give you an OTP and the client email an OTP and you can check if they match and you can verify the Email ID,
Kindly check the full procedures with example here
Usage
const {Auth} = require('two-step-auth');
async function login(emailId){
const res = await Auth(emailId);
// You can follw the above approach, But we recommend you to follow the one below, as the mails will be treated as important
const res = await Auth(emailId, "Company Name");
console.log(res);
console.log(res.mail);
console.log(res.OTP);
console.log(res.success);
}
login("YourEmail#anyDomain.com")
Output
This will help you a lot taking care of the process of verification under the HOOD :)

MERN Stack Email Confirmation

I've been scouring the internet on how to implement Nodemailer into a MERN stack application to send an email confirmation on user login.
I've got the application setup and properly logging in / logging out users and having them authenticated through that process. However, the implementation of nodemailer, jwt tokens and the front end of react.
I've not been able to find a way to implement this into my application and am asking for any recommendations or for a point in the right direction to learn this particular functionality.
Here's the link to the github repo for a look at the code: https://github.com/sethgspivey/mern-stack-two.git
I've got the initial test code for Nodemailer to work from the index.js file in the root directory. But again, the implementation into the react front end is where I'm hung up.
I did something similar in a project I built first you need to build out an endpoint that will be hit when the login is accepted something along the lines of:
const router = require("express").Router()
const mailer = require('../controllers/mailerController')
router
.route('/your-end-point-here')
.post(mailer.addToMailList)
module.exports = router
Notice this uses a controller that I built out. The controller will look something similar to this:
const nodemailer = require('nodemailer')
module.exports =
{
addToMailList: function (req, res)
{
let { newUser } = req.body
let transporter = nodemailer.createTransport({
service:'gmail',
auth: {
user: 'yourcompanyemail#gmail.com',
pass: 'somepassword'
}
});
message = "You just logged in!"
// setup email data with unicode symbols
let mailOptions = {
from: '"Your Company Name" <yourcompanyemail#gmail.com>', // sender address
to: newUser, // list of receivers
subject: "Welcome Letter", // Subject line
text: message // plain text body
};
// send mail with defined transport object
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return
console.log(error);
}
res.json(info);
});
}
}
// email data with unicode
let mailOption = {
from: '"" yourcompanyemail#gmail.com',
to: #mail,
subject: "hello ",
text: MyMessage
};

Sending emails using Mailgun with NodeMailer package

A couple of days ago I realized that Google has changed the security of gmail accounts, particularly for the possibility of sending emails from applications. After Googling around for a while I couldn't find a fix for it.
So, I resorted to using Mailgun. I created an account and had it enabled with Business verification. However, I still can't send emails. I keep getting an error about the requested URL not being found.
I am suspecting that since I haven't set up a domain yet, it is not picking the mailgun domain it provided by default. Could someone show me how to test sending emails using Mailgun from NodeMailer indicating the sandbox name provided by mailgun.
thanks in advance
José
var nodemailer = require('nodemailer');
// send mail with password confirmation
var transporter = nodemailer.createTransport( {
service: 'Mailgun',
auth: {
user: 'postmaster#sandboxXXXXXXXXXXXXXXXX.mailgun.org',
pass: 'XXXXXXXXXXXXXXXX'
}
});
var mailOpts = {
from: 'office#yourdomain.com',
to: 'user#gmail.com',
subject: 'test subject',
text : 'test message form mailgun',
html : '<b>test message form mailgun</b>'
};
transporter.sendMail(mailOpts, function (err, response) {
if (err) {
//ret.message = "Mail error.";
} else {
//ret.message = "Mail send.";
}
});
I created the Nodemailer transport for mailgun.
Here it how it works.
You install the package with npm install as you would do with any package, then in an empty file:
var nodemailer = require('nodemailer');
var mg = require('nodemailer-mailgun-transport');
// This is your API key that you retrieve from www.mailgun.com/cp (free up to 10K monthly emails)
var auth = {
auth: {
api_key: 'key-1234123412341234',
domain: 'sandbox3249234.mailgun.org'
}
}
var nodemailerMailgun = nodemailer.createTransport(mg(auth));
nodemailerMailgun.sendMail({
from: 'myemail#example.com',
to: 'recipient#domain.com', // An array if you have multiple recipients.
subject: 'Hey you, awesome!',
text: 'Mailgun rocks, pow pow!',
}, function (err, info) {
if (err) {
console.log('Error: ' + err);
}
else {
console.log('Response: ' + info);
}
});
Replace your API key with yours and change the details and you're ready to go!
It worked me, when I added the domain also to the auth object (not only the api_key). Like this:
var auth = {
auth: {
api_key: 'key-12319312391',
domain: 'sandbox3249234.mailgun.org'
}
};

Nodemailer and GMail with access tokens

I try to use Nodemailer to send an email with my GMail account but it doesn't work, it works in local but on my remote server I recieve an email from Google "Someone is using your account...."
How can I do ?
exports.contact = function(req, res){
var name = req.body.name;
var from = req.body.from;
var message = req.body.message;
var to = '******#gmail.com';
var transport = nodemailer.createTransport("SMTP", {
service: 'Gmail',
auth: {
XOAuth2: {
user: "******#gmail.com",
clientId: "*****",
clientSecret: "******",
refreshToken: "******",
}
}
});
var options = {
from: from,
to: to,
subject: name,
text: message
}
transport.sendMail(options, function(error, response) {
if (error) {
console.log(error);
} else {
console.log(response);
}
transport.close();
});
}
Check out the solution from Unable to send email via google smtp on centos VPS:
In my case, my script is on a VPS so I don't have a way to load any url with a browser. What I did: Changed my gmail pw. Gmail > Settings > Accounts. Then in Google Accounts they listed suspicious logins that were blocked by google (these were my script's attempted logins). Then I clicked the option "Yes, that was me". After that, my script worked (using the new pw).

Resources