403 Forbidden in Node.js while sending email using sendgrid - node.js

I am designing a contact page in which UI is rendered using React. I have a form which is supposed to send email on submit. Here is the UI code for handling submit:
handleSubmit = (event) => {
event.preventDefault();
this.setState({
disabled: true
});
Axios.post('http://localhost:3040/api/email', this.state)
.then( res => {
if(res.data.success){
this.setState({
disabled: false,
emailSent: true
});
} else{
this.setState({
disabled: false,
emailSent: false
});
}
})
.catch(err => {
this.setState({
disabled: false,
emailSent: false
});
});
}
The api to send email is written in Node.js. Used #sendgrid//mail to trigger send. On debugging I can see that the form values are reaching the api but on send it throws 403 Forbidden error. Here is the api code:
app.post('/api/email', (req, res, next) => {
sendGrid.setApiKey('<Generated key in sendgrid>');
const msg = {
to: 'some#email.com',
from: req.body.email,
subject: 'Website Contact Page',
text: req.body.message
}
sendGrid.send(msg).then(result => {
res.status(200).json({
success: true
});
})
.catch(err => {
console.log('error: ', err);
res.status(401).json({
success: false
});
});
});
The following is the error trace I am getting in the VSCode console while debugging:
stack:"Error: Forbidden
at axios.then.catch.error (c:\react\portfolio-api\node_modules\#sendgrid\client\src\classes\client.js:105:29)
at process._tickCallback (internal/process/next_tick.js:68:7)"
proto:Error {constructor: , toString: , toJSON: }
Not sure why its giving me Forbidden error. Please let me know if I need to add more info here. Thanks in advance :)
EDIT:-
Followed the doc here at sendgrid to create an API key and used the same in sendGrid.setApiKey().

To be able to send email from sendgrid, you need to setup Single Sender Verification or Domain Verification.
Please check the docs to verify sender.
To ensure our customers maintain the best possible sender reputations
and to uphold legitimate sending behavior, we require customers to
verify their Sender Identities. A Sender Identity represents your
“From” email address—the address your recipients will see as the
sender of your emails.
You can verify one or more Sender Identities using either Domain
Authentication or Single Sender Verification.
In your api application console log, the error message must be like this:
(to see the real error message in the reactjs side, you need to use err.response.data.
The from address does not match a verified Sender Identity. Mail
cannot be sent until this error is resolved.

Related

how to send the auth verification email using sendgrid in node js?

I am a new person learning Node.js and also building a project at the same time. I want that as soon as the user provides their email, it should be verified first. For that, I am using SendGrid, but I am not understanding the errors that SendGrid is giving. Can someone please provide me with the code for how to verify the email using SendGrid for authentication in node js.
below is the code that I found on google
import mail from "#sendgrid/mail";
export const registerEmail = (to) => {
try {
mail.setApiKey(api_key);
const msg = {
to: to,
from: "no-reply#example.com",
subject: "Authentication Code",
text: `Your authentication code is:`,
};
// send the email
mail
.send(msg)
.then(() => {
console.log(`Authentication code sent to ${to}`);
})
.catch((error) => {
console.error(error);
});
} catch (err) {
console.log("this is the error", err);
}
};
error

cannot set headers after they are sent to the client Nodejs?

im trying to make a create methode to create an user with sending email after creat account ,
when i test this method
cannot set headers after they are sent to the client Nodejs
My Method:
export function registerUser(req, res, next) {
// log the request body
console.log(JSON.stringify(req.body))
const { name, email, password, phone, role, level } = req.body
userModel.create(
{
name: name,
email: email,
password: password,
createdAd: Date.now(),
phone: phone,
photo: `${req.protocol}://${req.get('host')}/images/${
req.file.filename
}`,
level: 1,
role: role,
status: 0,
},
(err, result) => {
if (err){ next(err) ;}
else {
sendMail(req, res)
res.status(201).json({
message: 'User added successfully!',
})
}
}
)
}
Email Method
export function sendMail(req, res) {
var mailOptions = {
from: 'neublua.game10#gmail.com',
to: req.body.email,
subject: 'Sending Email using Node.js',
text: 'That was easy!',
}
transporter.sendMail(mailOptions, function (error, info) {
if (error)
res.status(500).json({
message: 'Error sending email',
})
else console.log('Email sent: ' + info.response)
})
}
i put res and req to can access to the email
how can i solve it
This error shows up when you send the response two times.
What express does is that it will only send the first response back to the client, while any responses after that won't be sent. That's basically how the HTTP protocol works, you send a request, you get one response back.
1 request = 1 response
So, the problem actually comes from here
You're saying:
sendMail()
and after that you're saying:
res.status(201).json({
message: 'User added successfully!',
})
where the sendMail is actually sending a response, because an error is happening when it tries to send the email look:
the following screenshot is inside your sending email middleware:
So, you shouldn't send a response twice, either send it here, or there.
What exactly are you trying to achieve? If it's an unimportant email you're trying to send such as the "welcome" email, then keep checking for an error if emails are failing to sent but remove the response from there, the client doesn't need to know that the "welcome" email had a problem while being sent.
If this is an important email, such as an email verification email, then, remove the response sending lines from the user creation middleware, and only send the response (Success or fail) inside the email middleware.

async await not working if sendgrid failed to sent email

I have a question.
I am trying to sent the user a email when they have created an account.
But when Sendgrid fails to sent the email the async await function didn't notice that and the code runs further.
This is my email module
const sgMail = require('#sendgrid/mail')
sgMail.setApiKey(process.env.SENDGRID_API_KEY)
module.exports = {
FreshleafVerificationEmail: async(receiver) => {
const msg = {
to: receiver,
from: 'xxxx#xxxx.com',
subject: 'Verifieer uw email adres - FreshLeaf',
text: 'Verifieer uw email adres door te klikken op de onderstaande link'
}
await sgMail
.send(msg)
.then((response) => {
console.log(response[0].statusCode)
console.log(response[0].headers)
})
.catch((error) => {
console.log(error)
})
}
}
And this is where the method gets executed
try {
//Save settings and user in the database
await FreshleafVerificationEmail(newUser.email)
await newSetting.save();
const user = await newUser.save();
res.status(201).json({message: 'Er is een nieuwe gebruiker aangemaakt', user: user})
}
catch(error) {
res.status(400).json({message: 'Er is een probleem opgetreden', error: error})
}
Can someone help me with this problem
I agree that the answer by #Matt covers the error situation when Sendgrid does not accept the email. As #O.Jones does suggest, the API would be the way to go. I do not work with this particular library, but Sendgrid should return a uniq ID of the email if it was accepted. That can be used to search for the status of the email via API.
Sendgrid provides multiple statuses:
https://docs.sendgrid.com/ui/analytics-and-reporting/email-activity-feed
You should look for Delivered or in case of Deferred you should wait more.
I assume that this may be a bad news, but Sendgrid copies hear a behavior of any other standard email server. With a simpler interface.
The catch is handling the error condition and allows the code to continue. If you want other error handlers to see the error then it needs to throw again:
FreshleafVerificationEmail: async(receiver) => {
const msg = {
to: receiver,
from: 'xxxx#xxxx.com',
subject: 'Verifieer uw email adres - FreshLeaf',
text: 'Verifieer uw email adres door te klikken op de onderstaande link'
}
try {
const response = await sgMail.send(msg)
console.log('Email sent', response[0].statusCode, response[0].headers)
}
catch (error) {
console.log('Email failed to send', msg, error)
throw error
}
}

AWS SES Error: Email address is not verified

I am trying to send email using aws-sdk ses in nodejs.
While executing the code the response I am getting is:
message:
'Email address is not verified. The following identities failed the check in region US-EAST-1:xxxtestemailxxx#gmail.com',
code: 'MessageRejected'
I have already verified the sender as well as receiver email(destination email in a array).
On SES settings of aws console, it is showing the email is verified. I removed the email and then once again successfully verified it.
Last time(few months back) when I used it, everything was working fine.
Below is the screenshot of my aws console related to SES:
Also when I am sending the test email using aws console, its working fine. This is only happening when I am trying to send email using aws-sdk.
Does anyone knows what is wrong, just to be clear I am also posting the code below:
const send_email = function (email, subject, source, payload) {
console.log(email, subject, source, payload);
let email_param = {
Destination: {
ToAddresses: email
},
// ConfigurationSetName: 'XXXRANDOMTEXT_PLATFORM',
Message: {
Body: {
Html: {
Charset: "UTF-8",
Data: payload
}
// Text: {
// Charset: "UTF-8",
// Data: payload
// }
},
Subject: {
Charset: "UTF-8",
Data: subject
}
},
Source: source
};
let send_email = SES.sendEmail(email_param).promise();
send_email
.then(data => {
return true;
})
.catch(error => {
console.log('sending email error:', error);
return false
});
}
If your AWS account is still in the sandbox mode then you have to verify your sender, receiver etc. Go to the prod mod to have access to the full features.

Sending emails to a mailing list with Mailgun

I am creating a personal app for email marketing/news letter/campaign, for this am using the Mailgun API with node.js and a simple HTML form to send emails.
As of now, sending emails is working fine when I give the "to"-address directly in my front part. But when I try to send to a mailing list, I encounter some issues.
I'm trying to send emails to a list which is already created in my Mailgun account.
My below post method is to send mails.
app.post('/', function(req, res) {
var api_key = 'key-here';
var domain = 'mydomin.in';
var Mailgun = require('mailgun-js');
var mailgun = new Mailgun({ apiKey: api_key, domain: domain });
var data = {
from: req.body.myname + "<" + req.body.email + ">",
to: req.body.to,
subject: req.body.subject,
text: req.body.plaintext,
'o:tag': req.body.tag
};
console.log(req.body);
mailgun.messages().send(data, function(error, body) {
console.log(body);
var list = mailgun.lists(req.body.to);
list.members().list(function (err, members) {
// `members` is the list of members
console.log(members);
});
if (error) {
// email not sent
res.render('index', { title: 'No Email', msg: 'Error. Something went wrong.', err: true })
} else {
// Yay!! Email sent
res.render('index', { title: 'Sent Email', msg: 'Yay! Message successfully sent.', err: false })
}
});
});
In the code I mention my mailing list. What happens is when I hit send, it shows success as in the following image:
Finally, here are some logs from the mailgun dashboard
Please point out what I did wrong and share your suggestions how to send emails to the list. My approach may be totally wrong, so any guidance will be appreciated.
NOTE: from my console.it shows "thank you,the messages are in queue". but am not receiving any mails yet. Many many thanks for any help.
Official docs
https://help.mailgun.com/hc/en-us/articles/217531258:
If you're on the Free plan without credit card information present or using your sandbox domain for testing, you're restricted to sending just to Authorized Recipients.

Resources