I cannot figure out how to get nodemailer to work, I have inserted my credentials for gmail too and tried sending an email to myself but it did not send me anything and it did not err, so I am confused. It is possible that I am missing stuff from my code...
here is the email file:
var nodemailer = require('nodemailer');
var config = require('./config/config');
var smtpTransport = nodemailer.createTransport("SMTP",{
service: "Gmail",
auth: {
user: config.mailer.auth.user,
pass: config.mailer.auth.pass
}
});
var EmailAddressRequiredError = new Error('email address required');
exports.sendOne = function(templateName, locals, fn) {
if(!locals.email) {
return fn(EmailAddressRequiredError);
}
if(!locals.subject) {
return fn(EmailAddressRequiredError);
}
// template
var transport = smtpTransport;
transport.sendMail({
from: config.mailer.defaultFromAddress,
to: locals.email,
subject: locals.subject,
html: html,
text: text
}, function (err, responseStatus) {
if(err) {
return fn(err);
}
return fn(null, responseStatus.message, html, text);
});
};
Here is the route file sending the email:
exports.forgotPasswordPost = function(req, res, next) {
console.log("Forgot Password Post");
if(req.body.email === '') {
console.log('err');
} else {
crypto.randomBytes(48, function(ex, buf) {
var userToken = buf.toString('hex');
console.log(userToken);
User.findOne({email: (req.body.email)}, function(err, usr) {
if(err || !usr) {
res.send('That email does not exist.');
} else {
console.log(usr);
//just call the usr found and set one of the fields to what you want it to be then save it and it will update accordingly
usr.token = userToken;
usr.tokenCreated = new Date ();
usr.save(function(err, usr){
// res.redirect('login', {title: 'Weblio', message: 'Your token was sent by email. Please enter it on the form below.'});
console.log(usr);
});
console.log(usr);
var resetUrl = req.protocol + '://' + req.host + '/password_reset/' + usr.token;
console.log(resetUrl);
var locals = {
resetUrl: resetUrl,
};
console.log(locals);
mailer.sendOne('password_reset', locals, function(err, email) {
console.log('email sent');
res.redirect('successPost');
});
}
});
});
}
};
Do I need anything else beside what I have here?
I did not identify the locals correctly.
This is the code that worked for me:
var nodemailer = require('nodemailer');
var config = require('./config/config');
var smtpTransport = nodemailer.createTransport("SMTP",{
// host: "smtp.gmail.com",
// secureConnection: true,
// port: 465,
service: "Gmail",
//debug : true,
auth: {
user: config.mailer.auth.user,
pass: config.mailer.auth.pass
}
});
var EmailAddressRequiredError = new Error('email address required');
exports.sendOne = function(template, locals, err) {
var message = {
from: config.mailer.defaultFromAddress,
to: locals.email,
subject: locals.subject,
html: locals.html,
text: locals.text
};
console.log('hitlocal email');
console.log(message);
//console.log(message.to.locals.email);
if(!locals.email) {
// console.log('email err');
}
if(!locals.subject) {
console.log('subj err');
}
// template
var transport = smtpTransport;
// console.log('hit here');
// console.log(transport);
transport.sendMail(message, function(err) {
if(err) {
console.log('email js error');
console.log(err);
}
console.log('Message sent')
//return fn(null, responseStatus.message, html, text);
});
};
And this is the routes file:
var locals = {
email: 'first last <' + req.body.email + '>',
subject: 'Password Reset',
html: '<p> Please go to the following link to reset your password.' + resetUrl + '</p>',
text: 'Texty Text it'
};
console.log('locals spot here');
console.log(locals.email);
mailer.sendOne('forgotPassword', locals, function(err) {
console.log('email sent');
});
I think you need to point to the gmail server not Gmail. I forget what it is exactly but sometihng like gmail.smtp
Related
I'm new to website building. I am using node js, express, and express-handlebars. I have 3 hbs page file called signup, verify, and login. I am trying to check if signup page has any errors using exports.signup and then if it's alright then rendering verify page and authenticating it using otp. Now my problem is I need to enter signup page values from verify page in the database after user is verified. How can I get signup page values from exports.signup and use it in exports.verify function?
This works to check in signup page:
exports.signup = (req, res) => { console.log(req.body);
const { name, email, password, passwordConfirm } = req.body;
db.query("select email from test where email=?",[email],async (error, results) => {
if (error) {
console.log(error);
}
if (results.length > 0) {
return res.render("signup", {
message: "The email is already in use",
});
} else if (password !== passwordConfirm) {
return res.render("signup", {
message: "Passwords do not match",
});
}
let hashedPassword = await bcrypt.hash(password, 8);
console.log(hashedPassword);
var digits = "0123456789";
let OTP = "";
for (let i = 0; i < 6; i++) {
OTP += digits[Math.floor(Math.random() * 10)];
}
let transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: process.env.GMAIL,
pass: process.env.GMAIL_PASSWORD,
},
});
let mailOptions = {
from: "checkmate.sdp#gmail.com",
to: email,
subject: "Verification code for Checkmate profile.",
text: "Your OTP is : " + OTP,
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
} else {
console.log("Email sent: " + info.response);
res.render("verify");
}
});
}
);
};
This verifies the user and enters values in database: (I haven't added anything here yet)
exports.verify = (req, res) => {
console.log(req.body);
};
Just an overview for you
signup.js
'use-strict';
exports.signup = (params) => { console.log("Hit", params) }
controller.js
'use-strict';
var signup = require('./signup');
var http = require('http');
// you can now access the signup function,
signup.signup({username: 'test', password: 'test'})
Looks like you want this to be an HTTP endpoint reciever,
depending on what library youre using, example with Koa route
Backend--
signup.js
var route = require('koa-route');
exports.init = (app) => {
app.use(route.post('/signup', signup));
}
async function signup(ctx) {
var body = ctx.request.body;
//operate
}
Frontend --
$.ajax({
url: "/signup",
type: "post",
data: JSON.stringify({username: 'get from html', password: 'get from html'})
});
I am using nodemailer to send email in my server using express. Everything worked perfectly in the localhost but when I deploy it on Heroku, it does not work anymore, look like it not support nodemailer on Heroku (that is what I have researched). This is my code, would you please help me out to deal with it. Thank you so much and have a good day
This is sending single mail
exports.send_mail = (req, res, next) => {
var {subjectTo, mailList, content} = req.body;
var {attachURL} = req;
var transporter = nodemailer.createTransport({
service: 'gmail',
secure: false,
port: 465,
auth: {
user: process.env.EMAIL,
pass: process.env.PASSWORD,
},
});
var mailOptions = {
from: 'sale.shopeeholic#gmail.com',
to: mailList,
cc: mailList,
subject: subjectTo,
text: `${content} \n Attached files: ${attachURL}`,
};
transporter.sendMail(mailOptions, (err, info) => {
if (err) {
console.log(err);
return res.status(400).json({err});
} else {
return res.status(200).json({message: `Mail sent to ${mailList}`});
}
});
};
This is sending merge mail/multiple mail
exports.merge_mail = (req, res, next) => {
console.log('merge mail begin');
const mailOptionList = req.body;
// {mails, mailContent, mailTitle}
var counter = 0;
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL,
pass: process.env.PASSWORD,
},
});
for (var i = 0; i < mailOptionList.length; i++) {
var mailOptions = {
from: 'sale.shopeeholic#gmail.com',
to: mailOptionList[i].mails.join(','),
cc: mailOptionList[i].mails.join(','),
subject: mailOptionList[i].mailTitle,
text: mailOptionList[i].mailContent,
};
transporter.sendMail(mailOptions, (err, info) => {
if (err) {
console.log(err);
return res
.status(400)
.json({err, message: `trouble in sending mail at index ${i}`});
} else {
console.log(`mail sent to ${JSON.stringify(mailOptionList[i].mails)}`);
counter++;
}
});
console.log(`mail sent to ${JSON.stringify(mailOptionList[i].mails)}`);
counter++;
console.log(counter);
}
if (counter === mailOptionList.length) {
return res.status(200).json({message: 'mail sent all'});
}
Probably process.env.EMAIL and process.env.PASSWORD are undefined. You have to set env variables in Heroku. Here's how:
https://devcenter.heroku.com/articles/config-vars
I can't cancel the request after sending the email successfully. How can I return properly after sending the email? This might be a callback hell, but I cant figure out how to solve it.
I tried to put some return in different parts but it didn't work.
const router = require('express').Router();
const nodemailer = require('nodemailer');
const emailExistence= require('email-existence');
module.exports = router;
// Send email when user has forgotten his/her password
router.post('/forgetPass', (req, res, next) => {
if(!req.body.email){
next(new Error("Email is required."));
return;
}
emailExistence.check(req.body.email, function(err,res){
if(err || !res){
next(new Error("The email does'nt exist."));
return;
}else{
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'myemail#gmail.com',
pass: 'mypassword'
}
});
let mailOptions = {
from: 'myemail#gmail.com',
to: req.body.email,
subject: 'Link for setting a new password',
html: 'Set a new password'
text: 'email text'
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
next(new Error("Error in sending email."));
return;
}
res.json(Object.assign(req.base, {
message: "The email has been sent successfully.",
data: info
}));
return;
});
}
});
});
Once you set your response field on successful sending, call next() as a last step, so the next middleware gets the request and sends the response back. So basically:
...
res.json(yourResponse);
next();
...
Or, if this is the last middleware, send the response back to client:
res.send(yourResponse);
I solved it in this way. The emailExistence didn't let me to use promises, so I used email-ckeck instead of it:
const router = require('express').Router();
const nodemailer = require('nodemailer');
const emailExistence= require('email-existence');
var emailCheck = require('email-check');
module.exports = router;
router.post('/forgetPass', (req, res, next) => {
if(!req.body.email){
next(new Error("Email is required."));
return;
}
// Check the req.body.email with email pattern regex
var patt = new RegExp (process.env.EMAIL_PATTERN__REGEX),
isEmail = patt.test(req.body.email);
if(!isEmail){
next(new Error("The email does'nt seem to be a valid email. If you are sure about your email validity contact the website admin."));
return;
}
return emailCheck(req.body.email)
.then(function(result){
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL,
pass: process.env.EMAILPASSWORD
}
});
let mailOptions = {
from: process.env.EMAIL,
to: req.body.email,
subject: 'Link for setting a new password',
html: 'Set a new password from this link.'
};
return transporter.sendMail(mailOptions)
.then(function (result2) {
res.status(200).json(Object.assign(req.base, {
message: "The email has been sent successfully.",
data: null
}));
return;
},
function(error2){
next(new Error("Error in sending email."));
return;
});
},
function(error) {
next(new Error("The email does'nt seem to be a valid email. If you are sure about your email validity contact the website admin."));
return;
});
});
I am new to Nodejs. Process is not waiting until response back from function. Because of asynchronous calling of Nodejs. how to make synchronous. Please help me.
Here is my code
module.exports.signup = function(req, res){
console.log('signup');
User.findOne({'emails.email' : req.body.email}, function(err, doc) {
if (doc === null) {
var vr_token= genRandomString(16);
var ex_date = Date.now();
var user = new User();
user.emails.push({
email : req.body.email,
email_verification_token : vr_token,
verify_key_expire : ex_date });
user.save(function(err2,user1) {
if (!err2) {
var result = send_email.sync(vr_token);//process not waiting
if(result) {
res.json ({
status: 200,
message:"mail sent successfully",
data:user1
})
}
}
});
}
})
}
here is my function
function send_email(vr_token){
var mailOpts = {
from: process.env.Mail_From_Addr,
to: 'xxxxxxxxxxxxx',
subject: 'Verify Your New Account Email',
html:'<p>Hello,</p>code : '+vr_token
};
mailgun.messages().send(mailOpts, function (err, response){
if (!err){
return true;
}else{
return false;
}
})
}
Add a callback to it:
function send_email(vr_token, callback){
var mailOpts = {
from: process.env.Mail_From_Addr,
to: 'xxxxxxxxxxxxx',
subject: 'Verify Your New Account Email',
html:'<p>Hello,</p>code : '+vr_token
};
mailgun.messages().send(mailOpts, function (err, response){
callback(null, !err);
})
}
The Code:
module.exports.signup = function(req, res){
console.log('signup');
User.findOne({'emails.email' : req.body.email}, function(err, doc) {
if (doc === null) {
var vr_token= genRandomString(16);
var ex_date = Date.now();
var user = new User();
user.emails.push({
email : req.body.email,
email_verification_token : vr_token,
verify_key_expire : ex_date });
user.save(function(err2,user1) {
if (!err2) {
send_email.sync(vr_token, function(err, result){
if(result) {
res.json ({
status: 200,
message:"mail sent successfully",
data:user1
})
}
});
}
});
}
})
}
I'm using nodemailer to try and get an admin to send an email, but the code I have so far returns no info or error.
The promise returns with no issue, but it's always empty.
Trying to use transporter.verify returns no info or error as well.
There are no issues with finding the admin in question.
var deferred = Q.defer();
Admin.findOne({username: 'admin'}, function(err, res)
{
if(err) deferred.resolve(err);
if(res)
{
var admin = _.omit(res.toJSON(), 'password');
var transporter = nodemailer.createTransport("SMTP", {
service: 'gmail',
auth: {
user: 'sender#gmail.com',
pass: "password_here"
}
});
var mailOptions = {
from: 'sender#gmail.com',
to: 'destination#hotmail.com',
subject: 'TEST',
text: 'TEST',
html: '<p> TEST EMAIL </p>'
};
transporter.sendMail(mailOptions, function (err, info) {
if (err) deferred.reject(err);
if(info){
deferred.resolve(info);
} else {
deferred.resolve();
}
});
} else {
deferred.reject("Cannot find admin");
}
});
return deferred.promise;
Please edit the code, it looks like you have an error on mongo with 'Admin.findOne'
if(err) deferred.resolve(err);
to
if(err) deferred.reject(err);