Sending email using SES node.js - node.js

I am trying to send email to my other email from amazon SES verified email, but the programs gives an error that email address in to field is not verified. I am making a web app which allows user to log in using AWS Cognito so I dont have their email addresses in database. I need to send email to them on an event(I cannot use SNS because I need to send emails to selective persons which I have figured out.) So my questions are:
a)Do we need to verify SES email of the recipient also?
b)If yes, how can we use the cognito identity pool to verify their email addresses for SES.
code:
var aws = require("aws-sdk");
aws.config.update({
region: "us-west-2",
});
var ses = new aws.SES({"accessKeyId": "Mykey", "secretAccessKey":"YY","region":"us-west-2"})
var to = ['xyz#gmail.com']
var from='abc#gmail.com'
ses.sendEmail( {
Source: from,
Destination: { ToAddresses: to },
Message: {
Subject:{
Data:"Sending emails through SES"
},
Body: {
Text: {
Data: 'Stop your messing around',
}
}
}
}
, function(err, data) {
if(err) throw err
console.log('Email sent:');
console.log(data);
}
Error:
MessageRejected: Email address is not verified. The following identities failed the check in region US-WEST-2: xyz#gmail.com

If you're testing this inside your SES sandbox, you need to manually verify the recipient email addresses before it will allow you to send.
This step isn't required after leaving the sandbox, but it's a reasonable default safety setting when testing email-related functionality during development and not wanting bogus emails to go our for real.
Amazon SES Email Sending Errors (relevant portion in bold):
Email address is not verified. The following identities failed the
check in region : , , —You
are trying to send email from an email address or domain that you have
not verified with Amazon SES. This error could apply to the "From",
"Source", "Sender", or "Return-Path" address. If your account is still
in the sandbox, you also must verify every recipient email address
An easier way to test your email sending in AWS without needing to send actual emails would be to use their mailbox simulator:
The Amazon SES mailbox simulator is a set of test email addresses.
Each email address represents a specific scenario. You can send emails
to the mailbox simulator when you want to:
Test your application without having to create test "To" addresses.

Related

Send email from NestJS, deployed to Firebase functions to the associated Gmail account's address

I've a NestJS application deployed to Firebase wired up with Firebase functions. I've an API which accepts a form data from a different Firebase Angular frontend project (I prefer the BE and FE projects to be separated).
I'd like to send that contact form data through my NestJS backend due to validation purposes via email to the Firebase admin email address (my Google account email) with all the form data, after the validation is succeeded.
So it's basiacally a contact form, by the user, to the admin. I've digged through the documentation and I've found solutions only for the other direction, so the app sends email to the users after something triggers this function (with Nodemailer, and with a 3rd party SMTP mail service).
Is there a solution to send the contact form data to my Gmail (associated with the Firebase account too) in the desired way? Do I really need to use Nodemailer and a 3rd party service to send an email to myself with the data from the contact form?
The process flow should be the following:
Users fills out the contact form
After FE validation the data is sent to the NestJS API
After BE validation the data is sent to my Gmail email address
Thanks for the suggestions in advance!
elyndel
Using Nodemailer would be the easiest option to send an email. You can use the same recipient email as the sender so you don't need any other mail service like SendGrid. Just specify the same email in both from and to:
const mailOptions = {
from: "user#gmail.com",
to: "user#gmail.com",
subject: "New registration",
text: "<Details>",
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
} else {
console.log("Email sent: " + info.response);
}
});

AWS SNS or SES for password reset

guys! I have a task to create AWS lambda endpoint for resetting user's password. I have to send a new password to user's email. I have read a lot about SNS and SES and currently have no idea what service is better for my purpose. Will be glad to hear from you advice!
Here is my lambda code
const requestData = AdminResetPasswordDto.from(event.body);
const errors = await AdminResetPasswordDto.validate(requestData);
if (errors) {
return new BadRequestError({ message: "errors.invalid-request-params", errors })
}
const repo = new UsersRepo();
const entity = await repo.getOneByEmail(requestData.email);
if (!entity) {
return new BadRequestError({ message: 'errors.user-not-exists' })
}
// const newPass = generatePassword();
// sending newPass to user via SNS
// use SNS or SES ???
// https://docs.aws.amazon.com/sns/latest/dg/sns-email-notifications.html
const user = UserDto.fromEntity(entity);
const result = await repo.updateUserPassword(user.userId, user.userRole, newPass);
if (!result) {
return new BadRequestError({ message: 'errors.password-not-updated' })
}
return new ResponseSuccessNoBody();
SES is meant for sending high-volume e-mail efficiently and securely. Once you have verified that you are the owner of an e-mail address, you can send e-mails through SES to any other e-mail address without the recipient's consent. SES takes care of the engineering required to ensure the delivery of their e-mails.
SNS is meant as a channel publisher/subscriber service. In order to receive e-mails from SNS, the end-user must first subscribe and approve that subscription through e-mail before amazon delivers e-mails from the subscribed channel to that end-user. End-users can subscribe via e-mail, SMS, webhooks, and other means up to the user independent of the publisher.
On a practical level, we use SES to send our users e-mails about their content and we use SNS to send our developers notifications (via SMS and e-mail) when servers go down or have issues.
In short,
SNS
email messages
SMS
push notifications to mobile device
messages between services/apps
Clients have to subscribe, to receive above notifications
SES
email messages
No subscriptions required
SNS is used for “technical” notifications; delivery as e-mail is possible, but rather limited. First, you need to create dedicated subscriptions and provide the destination mail address at this point. Second, you can’t really “design” your messages, it will just be a blob of text. You should go with SES for messages where the recipient is determined at runtime and you want to have control over the message layout.

Node JS: Sendgrid Mail 403 'Forbidden' error

I am sending a very straightforward email using Send grid in my node js project. But I get returned a 403 Forbidden error. The API Key has full access. The code is also correctly integrated, as I used another API Key from another account and it works perfectly.
Error log:
Any suggestions?
The error exists as the email address in the "from" field in the message(in your nodejs code,, to be sent using sendgrid) is not verified by sendgrid. Only put that email address in the "from" field which is explicitely verified by sendgrid.
To verify your sender email address to be able to send emails, refer to the link below:-
https://sendgrid.com/docs/ui/sending-email/sender-verification
Hope this helps.
(There could be further issues regarding domain name, read the link properly, they have a warning regarding use of gmail.com addresses, you can ignore that)
Pasting the entire ERROR here
ResponseError: Forbidden
at node_modules/#sendgrid/client/src/classes/client.js:133:29
at processTicksAndRejections (internal/process/task_queues.js:93:5) {
code: 403,
response: {
headers: {
server: 'nginx',
date: 'Sat, 10 Oct 2020 17:22:02 GMT',
'content-type': 'application/json',
'content-length': '281',
connection: 'close',
'access-control-allow-origin': 'https://sendgrid.api-docs.io',
'access-control-allow-methods': 'POST',
'access-control-allow-headers': 'Authorization, Content-Type, On-behalf-of, x-sg-elas-acl',
'access-control-max-age': '600',
'x-no-cors-reason': 'https://sendgrid.com/docs/Classroom/Basics/API/cors.html'
},
Here is the solution to further expand on what #Aman answered above.
You have to verify the email address you are sending from.
so meaning the from: address here
const msg = {
to: 'recepient#email.com',
from: 'sender#email.com', //this is the address that needs to be verified by sendgrid
subject: 'Sending from Sendgrid',
text: 'here is the test from node',
html: `<strong> Here is the order #${orderNumber} user: ${user} </strong>`,
}
Here is how to verify it
https://sendgrid.com/docs/ui/sending-email/sender-verification/
See screenshot below:
Check whether from email address is used when you are verifying your send address.
I was having the same problem.
I discovered that the emails from of my application and the sender authentication of the SendGrid API need to be the same.
const sendMailHtml = async (subject, html) => {
try {
const msg = {
to: 'to#email.com',
from: {
email: "sample#hotmail.com"
},
subject: subject,
html: html,
}
await sendgrid.send(msg)
} catch (e) {
return e
}
}
sendgrid API email field
To fix this error you need go to perform SendGrid Sender Authentication for your sender email.
To do this, You need to login to your SendGrid Dashboard and visit Sender Authentication which is under the Settings dropdown.
There are 2 Types of Sender Authentication
Domain Authentication // recommended
Single Sender Verification
1 Domain Authentication
IF you allow SendGrid to authenticate your domain e.g. webapp.com
THEN you will be able to successfully send an email with your SendGrid API KEY if the email from key matches the verified domain from: *#webapp.com
2 Single Sender Authentication
This is another option where you verify a single email e.g. person#email.com.
Which will then allow you to send out emails from: person#email.com via your SendGrid API KEY
In the latest release of sendgrid they have made the compulsion to verify the "Single Sender" i.e you as a single sender. So, to make it work the From field in your Sendgrid Send Email API should match the email you verified as a "single sender"
verify your single sender account where Sender Authentication/Single Sender Verification/ action column (three-dot)(send verify email- edit -delete menu)
[Tulio Faria] solved it by performing 'Single Sender Authentication' on his Sendgrid account.
I also had a similar issue not too long ago. What helped me fix this issue was to go to settings > API keys and then change the settings of the key I'm using to full-access.

Google apps bounces emails sent from nodemailer, but gmail receives them fine

I've set up some google apps mailing groups, but emails from nodemailer to the groups are always getting 'bounced' (but no bounce-back email).
Individual gmail addresses receive the same nodemail fine. The admin email log looks like this for successful email to individual gmail user address. The email headers from the successful email show no issues (eg no spf failures).
The groups do receive emails from external users (including from the same address nodemailer uses) when sent through the gmail web client, so it it isn't a group permission issue. Successful emails to the group yields an admin log like this.
The group is set to forward all spam to users.
Nodemailer is using a gmail account, and the GApps are using a Google domain hosted address, so it shouldn't be an issue with routing or conflicting servers
What am I missing here?
This was resolved by reconfiguring the 'from' field in the nodemailer message.
// Nodemailer ignores the bad `from` value (not a valid email)
// Nodemailer sends with from ==''
// This gets bounced by google group addresses
var msg = {
from: "System",
to: "usergroupaddress#gmail.com,
subject: "Your generated email",
text: "Hello user",
html: "<p>Hello user</p>"
};
I had thought 'from' would define the name displayed on the email. It didn't do that, but it didn't cause any problems either for most email recipients. But google groups was bouncing those emails.
Nodemailer was just leaving 'from' as blank (rather than using my dummy string). Apparently this field must be a valid email address. Set it to an email address, and nodemailer will include it in the message envelope, which google groups will then stop bouncing.
// Nodemailer accepts and forwards the valid `from`
// google groups address will accept the email
var msg = {
from: "system#myserver.com",
to: "usergroupaddress#gmail.com,
subject: "Your generated email",
text: "Hello user",
html: "<p>Hello user</p>"
};
The google apps email also hints at this: emails with an empty 'from' envelope have a blank 'sender' in the google apps email log search. But as soon as I corrected nodemailer, the 'sender' started populating in email log search, and google stopped bouncing the emails. See the email log here.

Node AWS-SDK SES email send verification fail

I am using aws-sdk using Node to send AWS SES emails and I was able to successfully send emails using AWS CLI. However, from my Node script, verification for my email fails for some reason.
Below is the code:
const aws = require('aws-sdk')
const ses = new aws.SES()
const message = {
Destination: {
ToAddresses: ['example#example.com']
},
Message: {
Body: {
Text: {
Charset: 'UTF-8',
Data: 'Test body'
}
},
Subject: {
Charset: 'UTF-8',
Data: 'Test subject'
}
},
Source: 'example#example.com'
}
ses.sendEmail(message, function (err, data) {
if (err) console.log(err);
else console.log(data);
});
Below is the error:
message: 'Email address is not verified. The following identities failed the check in region US-EAST-1: example#example.com',
code: 'MessageRejected',
time: 2017-12-15T15:37:26.312Z,
requestId: 'random-id',
statusCode: 400,
retryable: false,
retryDelay: 15.030260565173382
Please help! Thank you!
Per AWS troubleshooting documentation:
Email address is not verified. The following identities failed the check in region (region): (identity1), (identity2), (identity3) — You are trying to send email from an email address or domain that you have not verified with Amazon SES. This error could apply to the "From", "Source", "Sender", or "Return-Path" address.
If your account is still in the sandbox, you also must verify every recipient email address except for the recipients provided by the Amazon SES mailbox simulator. If Amazon SES is not able to show all of the failed identities, the error message ends with an ellipsis.
Note: Amazon SES has endpoints in multiple AWS regions, and email address verification status is separate for each AWS region. You must complete the verification process for each sender in the AWS region(s) you want to use.
I strongly suspect that your application's configuration does not 100% match the configuration you used to successfully send your test email via the CLI.
Check the following configuration:
The 'Source' address must be an SES verified sender in the us-east-1 region. Check that the source address that you expect to send email from is a verified sender in each region that you intend to send email from.
If SES sandbox mode is enabled, email recipients (the 'ToAddresses' value) must also be SES verified senders in the us-east-1 region. See 'Moving Out of the Amazon SES Sandbox' for instructions on how to remove this restriction.
Make sure all clients you're testing with are being tested in the same region, since configuration needs to be distinct per-region. The error message mentioned the application attempted to hit SES in us-east-1, so explicitly perform your CLI test in the us-east-1 region again by using the --region option. It is possible that the initial CLI test was flawed if the CLI default region was used, and that region happened to not be us-east-1.
If all of the above looks correct, carefully review your node application. Make sure the SES client is configured for the region you expect to use, and that the client is correctly writing the emails that you expect to the SES request.
Further Reading
AWS Documentation - Verifying Email Addresses and Domains in Amazon SES
AWS Documentation - Sending Email Using Amazon SES
Here is my code using node.js with express, ejs and npm package node-ses
The solution is mentioned above, but is easy to miss. It's the third part, after key and secret, the callback to amazon - the url needs to be there and it needs to be customised for your region, in my case eu-west-1, the other two choices are us-east-1 or us-west-2.
The key and the secret was found in IAM - User. Once you have set up a user with Programmatic access and AmazonSESFullAccess permissions. Select your User and then select the "Security credentials" tab. Scoot down and click on Create Access Key.
You will only be given access to your Secret Password once. When you get access, highlight the Secret Password, copy it and paste it somewhere safely along with your Key.
Your from email must be related to the domain registered on the AWS SES page. If you don't host with Route 53, you will need to register and verify the email on the AWS SES page as well.
Here's the router code:
app.post('/email', function(req, res) {
var ses = require('node-ses'),
client = ses.createClient({
key: 'xxx',
secret: 'xxx',
amazon: 'https://email.eu-west-1.amazonaws.com'});
client.sendEmail({
to: 'xxx'
, from: 'xxx'
, cc: ''
, bcc: ''
, subject: 'greetings'
, message: 'your <b>message</b> goes here'
, altText: 'plain text'
}, function (err, data, res) {
if (err) {
console.log('Email send Error: ',JSON.stringify(err, null, 2));
} else {
console.log('Email send Success: ', JSON.stringify(data,null,2));
}
});
});

Resources