I am developing an AWS lambda function using node.js 14.x for my runtime.
I create a nodemailer layer and upload it to my lambda function. I am trying to test my function and just return a simple console log but I don't see the console log anywhere including my cloud watch logs.
exports.handler = async (event) => {
// TODO implement
const nodemailer = require("nodemailer");
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
// user: process.env.USER_NAME,
// pass: process.env.EMAIL_PASS,
user: "********",
pass: "********",
},
});
const mailOptions = {
from: "taxs#gmail.com",
to: "trdmon#gmail.com",
subject: "subject",
text: "message",
};
transporter.sendMail(mailOptions, function (error, info) {
console.log('hit')
if (error) {
console.log(error);
} else {
console.log("Email sent: " + info.response);
}
});
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
If the transporter.sendEmail function were running I should see the console log. Any ideas why my function isn't running?
Related
I tried to add nodemailer to my node js project but it shows Error: Missing credentials for "LOGIN"
This is my code:
const transporter = nodemailer.createTransport({
service: "hotmail",
auth: {
usre: "abcd#outlook.com",
pass: "abcd",
},
});
const options = {
from: "abcd#outlook.com",
to: "md.mygmail#gmail.com",
subject: "sending email form nodemailer",
text: "This is nodemailer bot",
};
transporter.sendMail(options, function (err, info) {
if (err) {
console.log(err);
return;
}
console.log("sent: " + info.response);
});```
When I make a request to my endpoint I need to get a successful response only if the email is sent! otherwise, it should throw an error:
myendpoint.js
router.post("/", upload.none(), async (req, res) => {
try {
let body = JSON.parse(req.body.contact);
await getDb("messages").insertOne({
name: body.name,
email: body.email,
phone: body.phone,
subject: body.subject,
message: body.message,
});
await sendEmail(body);
res.send(
JSON.stringify({
success: true,
msg: "Message has been sent successfully",
})
);
} catch (err) {
res.send(JSON.stringify({ success: false, msg: err }));
}
});
sendEmail.js
const sendEmail = async function (props) {
const transporter = nodemailer.createTransport({
service: process.env.EMAIL_SERVICE,
host: process.env.EMAIL_HOST,
auth: {
user: process.env.EMAIL_FROM,
pass: process.env.EMAIL_PASS,
},
});
const mailOptions = {
from: process.env.EMAIL_FROM,
to: process.env.EMAIL_TO,
name: props.name,
email: props.email,
phone: props.phone,
subject: props.subject,
text: props.message,
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
throw new Error("Message did Not send!");
}
});
};
the problem is before "await sendEmail(body);" ends and i get the error, i get the "Message has been sent successfully" and then server crashes!
what am i missing?
Check document function sendMail from nodemailer at here
If callback argument is not set then the method returns a Promise object. Nodemailer itself does not use Promises internally but it wraps the return into a Promise for convenience.
const sendEmail = async function (props) {
const transporter = nodemailer.createTransport({
service: process.env.EMAIL_SERVICE,
host: process.env.EMAIL_HOST,
auth: {
user: process.env.EMAIL_FROM,
pass: process.env.EMAIL_PASS,
},
});
const mailOptions = {
from: process.env.EMAIL_FROM,
to: process.env.EMAIL_TO,
name: props.name,
email: props.email,
phone: props.phone,
subject: props.subject,
text: props.message,
};
// remove callback and function sendMail will return a Promise
return transporter.sendMail(mailOptions);
};
Hello you can change your Transporter sendMail to :
return await transporter.sendMail(mailOptions);
Or You can Use Promise.
const handler = async ({ subject, name, body, contact }) => {
const transporter = nodemailer.createTransport({
service: "zoho",
// Disable MFA here to prevent authentication failed: https://accounts.zoho.com/home#multiTFA/modes
// ********************* OR *****************
// set up Application-Specific Passwords here: https://accounts.zoho.com/home#security/device_logins
auth: { user: process.env.NEXT_PUBLIC_EMAIL_ADDRESS, pass: process.env.NEXT_PUBLIC_EMAIL_PASSWORD },
});
return transporter
.sendMail(mailOptions({ subject, name, body, contact }))
.then((info) => {
if (process.env.NODE_ENV !== "production") console.log("Email sent: " + info.response);
return true;
})
.catch((err) => {
if (process.env.NODE_ENV !== "production") console.log("error sending mail", err);
return false;
});
};
I have implemented nodemailer after the user registration, in the following way:
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL_USERNAME,
pass: process.env.EMAIL_PASSWORD
}
});
let mailOptions = {
from: process.env.EMAIL_USERNAME,
to: user.email,
subject: 'Verify your account',
text: 'Click here for verify your account'
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
});
I don't like much this code because if I need to send an email in another module, I need to rewrite all the stuff above.
Since I'm new to NodeJS, I would like to know if I can remove this code redundancy make something like a utility or maybe an helper class. The goal is import the wrapper class and call a simple function to send the email.
Which is the best way to handle that?
I refactored your code to look like below and then save it as mail.js
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL_USERNAME,
pass: process.env.EMAIL_PASSWORD
}
});
let sendMail = (mailOptions)=>{
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
});
};
module.exports = sendMail;
in Your other modules, say activation.js
var mailer = require('./mail.js');
mailer({
from: process.env.EMAIL_USERNAME,
to: user.email,
subject: 'Verify your account',
text: 'Click here for verify your account'
};);
you can use module.exports as follow :
create common service mail.js and write your mail sent code here
mails.js
module.exports = function (){
// mail sent code
}
require mail.js where you write mail sent code in other service and call mail sent function
otherService.js
var mail = require('mail.js') // require mail sent in other service where you want to send mail
mail.sent() // call function of mail.js
I have created a class for this:
import NodeMailer from 'nodemailer'
import emailConfig from '../../config/mail' // read email credentials from your config
class EmailSender {
transport
constructor() {
this.transport = NodeMailer.createTransport({
host: emailConfig.MAIL_HOST,
port: emailConfig.MAIL_PORT,
auth: {
user: emailConfig.MAIL_USERNAME,
pass: emailConfig.MAIL_PASSWORD,
},
})
}
async sendMessage(to, subject, text, html) {
let mailOptions = {
from: emailConfig.MAIL_FROM_ADDRESS,
to,
subject,
text,
html,
}
await this.transport.sendMail(mailOptions)
}
}
export default new EmailSender()
Now you can implement it in your any routes:
router.get('/email', async (req, res) => {
try {
await EmailSender.sendMessage(
'bijaya#bijaya.com',
'Hello world',
'test',
'<h1>Test</h1>'
)
return res.status(200).send('Successfully sent email.')
} catch (exception) {
return res.status(500).send(exception.message)
}
})
I need to return some response when I send a email through Nodemailer and I have this function:
async function dispatchEmail(email) {
const transporter = nodemailer.createTransport({
service: `${nconf.get('EMAIL_SMTP_SERVICE')}`,
auth: {
user: nconf.get('EMAIL_ACCOUNT'),
pass: nconf.get('EMAIL_PASSWORD'),
},
});
const mailOptions = {
from: `"Shagrat Team "${nconf.get('EMAIL_ACCOUNT')}`,
to: email,
subject: 'Hi from Shagrat Team !',
text: '',
html: '',
};
const success = await transporter.sendMail(mailOptions, async (error, sent) => {
if (error) {
return error;
}
return {some_response};
});
return success;
}
Where I need to send{some_response} with some value either true, false or something else, but I got 'undefined' value inside the same function or calling it externally:
const success = await dispatchEmail(emailConsumed);
What value can I return and catch it? because I need to test this function.
An exit is to return the transporter.sendmail () itself, which is a promise, in the return contera the data of the sending or the error, it is good to use a trycatch for other errors.
async function dispatchEmail(email) {
const transporter = nodemailer.createTransport({
service: `${nconf.get('EMAIL_SMTP_SERVICE')}`,
auth: {
user: nconf.get('EMAIL_ACCOUNT'),
pass: nconf.get('EMAIL_PASSWORD'),
},
});
const mailOptions = {
from: `"Shagrat Team "${nconf.get('EMAIL_ACCOUNT')}`,
to: email,
subject: 'Hi from Shagrat Team !',
text: '',
html: '',
};
return transporter.sendMail(mailOptions)
}
Another option is to use the nodemailer-promise module.
const success = await dispatchEmail(emailConsumed);
Result:
console.log(sucess);
{ envelope:
{ from: 'example#example.com',
to: [ 'example2#example.com' ] },
messageId:'01000167a4caf346-4ca62618-468f-4595-a117-8a3560703911' }
I am using nodemailer to send email using nodejs. Here is my code
export function createOrder(req, res) {
var transporter = nodemailer.createTransport({
service: 'gmail',
secure: false,
port: 25,
auth: {
user: 'fahadsubzwari924#gmail.com',
pass: 'Jumpshare1'
},
tls: {
rejectUnauthorized: false
}
});
var mailOptions = {
from: 'Fahad <fahadsubzwari924#gmail.com>',
to: 'shan4usmani#hotmail.com',
subject: 'Order Status ',
text: 'Your order has finished'
}
transporter.sendMail(mailOptions, function (err, res) {
if (res) {
console.log(res);
res.json({
message: res,
status: 200
})
} else {
console.log(err, 'Error');
}
})
}
When i am trying to send email then email is sending successfully but request is going on pending for a long time which is shown in network section of chrome.
How can i get rid of this request pending issue?