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.
Related
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);
}
});
I am working on deploying my Node.js app. However I am having issues with having the registration email getting sent out.
const transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: GMAIL_USER,
pass: GMAIL_PASS,
},
});
......
......
transporter.sendMail({
to: newUser.email,
subject: 'Confirm Email',
html: `Please click this email to confirm your email: ${url}`
});
This works perfectly when I try running it on local host, but as soon as I upload the files to my server and try it, google blocks the sign in attempt, and I get an email saying
Someone just used your password to try to sign in to your account. Google blocked them, but you should check what happened.
Every time, I click the button "this was me", but any future attempts still get blocked.
I have "less secure apps" enabled. Is there a way to whitelist an IP to send from my gmail? or a way to get this working in general?
You have two options.Either you set the access to less secure apps setting to Enabled or you obtain an accessToken and a refreshToken from Google OAuth2.0 and use them in your nodemailer config
For option one go to https://www.google.com/settings/security/lesssecureapps
For option two go to https://console.developers.google.com/apis/credentials
if you choose option two your config for the transport will look something like this:
auth: {
type: 'OAuth2',
user: 'user#example.com',
accessToken: 'ya29.Xx_XX0xxxxx-xX0X0XxXXxXxXXXxX0x'
}
Sometimes people who don't assign recovery email, phone number .In that scenario also google hinders login. In my case google first allowed me on turning less secure app but very next day it denied. So I added recovery email for that particular email and it worked. So that's how I think google security algo works.
Had to fill out some hidden captcha for gmail, then everything worked fine. Sadly dont have the link, or id post it.
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.
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));
}
});
});
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.