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);
Related
function sendEmail(num, email, customerName) {
var readHTMLFile = function (path, callback) {
fs.readFile(path, { encoding: 'utf-8' }, function (err, html) {
if (err) {
throw err;
callback(err);
}
else {
callback(null, html);
}
});
};
let transporter = nodemailer.createTransport({
host: "smtp.gmail.com",
secure: true,
port: 465,
auth: {
user:process.env.USEREMAIL,
pass:process.env.USERPASS
},
});
readHTMLFile(__dirname + '/views/layouts/first.html', function (err, html) {
var template = handlebars.compile(html);
var replacements = {
otp: `${num}`,
customerName: `${customerName}`
};
var htmlToSend = template(replacements);
var mailOptions = {
from: process.env.USEREMAIL,
to: email,
subject: "Hello ✔",
html: htmlToSend
};
transporter.sendMail(mailOptions, function (error, response) {
if (error) {
console.log(error);
} else {
console.log("Email sent");
}
});
});
}
All this is working fine with my localhost:8000 but after I upload(hosted) with my cyclic.sh account, my app works and getting success message, but did not get any mail with my box. sendEmail function not working in live but working locally. what is issues of the sendEmail function
I had a same problem and fixed it by wrapping sendmail with a promise
new Promise((resolve, reject) => {
transporter.sendMail(mailOptions, function (error, response) {
if (error) {
reject(error)
} else {
resolve("email sent")
}
});
})
When I try to send an email locally it works but in production, in the network tab I get everything right just email doesn't want to send and I don't get any error.
try {
const { name, email, message } = req.body;
const transporter = nodemailer.createTransport({
port: 465,
host: "smtp.gmail.com",
auth: {
user: process.env.NEXT_PUBLIC_GMAIL_EMAIL,
pass: process.env.NEXT_PUBLIC_GMAIL_PASSWORD,
},
secure: true,
});
const mailData = {
from: process.env.NEXT_PUBLIC_GMAIL_EMAIL,
to: process.env.NEXT_PUBLIC_EMAIL_WHICH_RECIEVES_CONTACT_INFO,
subject: `Message From ${email}`,
text: message,
};
transporter.sendMail(mailData, function (err, info) {
if (err) console.log(err);
else console.log(info);
});
res.status(200).json({ message: "Email sent" });
} catch (error: any) {
res.status(500).json({ message: error.message });
}
I kind of had a similar issue with nodemailer and Next.js, try to wrap the transporter in a Promise, hopefully it works for you too:
await new Promise((resolve, reject) => {
transporter.sendMail(mailData, (err, info) => {
if (err) {
console.error(err);
reject(err);
} else {
resolve(info);
}
});
});
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 am developing a register form using Angular6, mongodb and nodejs. There I have written a post method to save users in mongodb if the user does not exist in the database. When the users are added to the database, an email should be sent to user and user should redirect to another view. That view is also in the earlier html and it shows only when the result is success.If the email name is already in the db it should show an error message. I have used the default error message in password. strategy-options.ts for the error message for existing users.But when I try to add a new user it does not navigate to the next view and the terminal shows the following error message.
TypeError: Cannot read property 'send' of undefined
"....node_modules\mongodb\lib\utils.js:132"
Here is my save method.
router.post('/signup', function(req, next) {
console.log("Came into register function.");
var newUser = new userInfo({
firstName : req.body.firstName,
lastName : req.body.lastName,
rank : req.body.lastName,
mobile : req.body.lastName,
email : req.body.email,
userName : req.body.userName,
password : req.body.password,
status : req.body.status
});
newUser.save(function (err, user,res) {
console.log("Came to the save method");
if (err){
console.log(user.email);
res.send(err);
return res;
}
else{
var transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 't36#gmail.com',
pass: '12345'
}
});
var mailOptions = {
from: 'reg#demo.com',
to: newUser.email,
subject: 'Send mails',
text: 'That was easy!'
};
console.log("This is the user email"+" "+newUser.email);
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log("Error while sending email"+" "+error);
} else {
console.log('Email sent: ' + info.response);
}
});
console.log("success");
return res.send("{success}");
}
});
});
Here is my register method in register.component.ts file.
register(): void {
this.errors = this.messages = [];
this.submitted = true;
this.service.register(this.strategy, this.user).subscribe((result: NbAuthResult) => {
this.submitted = false;
if (result.isSuccess()) {
this.messages = result.getMessages();
this.isShowConfirm = true;
this.isShowForm = false;
}
else {
this.errors = result.getErrors();
}
const redirect = result.getRedirect();
if (redirect) {
setTimeout(() => {
return this.router.navigateByUrl(redirect);
}, this.redirectDelay);
}
this.cd.detectChanges();
});
}
I have tried so many methods in internet to solve this. But still did not.
First of all node js router consist of 3 params req, res, next you miss out the res param, in your case the next behave as the res params.
Secondly Model.save only returns error and saved data there no res parameter in it. So the finally code will look like this
router.post('/signup', function(req, res, next) {
console.log("Came into register function.");
var newUser = new userInfo({
firstName : req.body.firstName,
lastName : req.body.lastName,
rank : req.body.lastName,
mobile : req.body.lastName,
email : req.body.email,
userName : req.body.userName,
password : req.body.password,
status : req.body.status
});
newUser.save(function (err, user) {
console.log("Came to the save method");
if (err){
console.log(user.email);
res.send(err);
return res;
}
else{
var transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 't36#gmail.com',
pass: '12345'
}
});
var mailOptions = {
from: 'reg#demo.com',
to: newUser.email,
subject: 'Send mails',
text: 'That was easy!'
};
console.log("This is the user email"+" "+newUser.email);
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log("Error while sending email"+" "+error);
} else {
console.log('Email sent: ' + info.response);
}
});
console.log("success");
return res.send("{success}");
}
});
});
To solve this same error message TypeError: Cannot read property 'send' of undefined in my rest api application, I found that I missed the valid syntax res.status(200).send(data) or res.send(data). Although I found the data in my console.
module.exports.getUsersController = async (req, res) => {
try {
// Password is not allowed to pass to client section
const users = await User.find({}, "-password");
const resData = {
users,
success: {
title: 'All Users',
message: 'All the users info are loaded successfully.'
}
}
console.log(resData)
// This is not correct
// return res.status(200).res.send(resData);
// It should be
return res.status(200).send(resData);
} catch (err) {
console.log(err)
return res.status(500).send(err);
}
};
When you use res.status(), you have to use .send() following this, not use res again.
I think it will be helpful for developers who did the same mistake as well. Happy developers!
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