how to send the auth verification email using sendgrid in node js? - 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

Related

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
}
}

403 Forbidden in Node.js while sending email using sendgrid

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.

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.

Unable to send email using MailGun Node API

When trying to send a simple test message via mailgun using their Node api I don't get any errors, but I also am not receiving emails nor am I seeing any response in the mailgun logs.
Here is the code I am using ...
const mailgun = require('mailgun-js')({
apiKey: 'XXXXXXXXXX',
domain: 'https://api.mailgun.net/v3/XXXXXXXXX'
})
async function sendInvite() {
var email = process.argv[process.argv.length - 1]
const data = {
from: 'support#acme.com',
to: email,
subject: 'Welcome!',
html: '<p>Welcome!</p><p>You are very special!</p>'
}
return new Promise((resolve, reject) => {
mailgun.messages().send(data, (error, body) => {
if (error) {
console.error(error)
reject(error)
return
}
console.log(`Invite sent to ${email}`)
console.log(data)
console.log(body)
resolve();
})
})
}
sendInvite().then(() => console.log('Done')).catch((err) => console.error(err))
I discovered that the problem I had was in the format of the domain I was passing into mailgun.
Before I had the following :
const mailgun = require('mailgun-js')({
apiKey: 'XXXXXXXXXX',
domain: 'https://api.mailgun.net/v3/XXXXXXXXX'
})
The problem is that the value for domain should not include the https://api.mailgun.net/v3/ portion of the URL. Instead it should ONLY have your domain, e.g. mail.mydomain.com
Did you attach your credit card to mailGun account? Or if you just need to test your logic, in your account settings you should confirm any email address, which will get emails from mailgun
https://wordpress.org/support/topic/mailgun-http-api-test-failure-status-free-accounts-are-for-test-purposes-only/

How to send customize e-mail with Firebase cloud functions

I want to send a mail once a user is created with a firebase cloud functions, using nodemail and postmark.
I followed this tutorial : Tutorial link from Dave Martin
But keep getting this error:
There was an error while sending the welcome email: { status: 422, message: 'Zero recipients specified', code: 300 }
Here is my code to send a mail from cloud functions:
//Mail
const nodemailer = require('nodemailer')
const postmarkTransport = require('nodemailer-postmark-transport')
// Google Cloud environment variable used:
// firebase functions:config:set postmark.key="API-KEY-HERE"
const postmarkKey = functions.config().postmark.key
const mailTransport = nodemailer.createTransport(postmarkTransport({
auth: {
apiKey: postmarkKey
}
}))
exports.OnUserCreation = functions.auth.user().onCreate((user) =>
{
console.log("user created: " + user.data.uid);
console.log("user email: " + user.data.email);
sendEmail(user);
})
function sendEmail(user)
{
// Send welcome email to new users
const mailOptions =
{
from: '"test" <test#test.com>',
to: user.email,
subject: 'Welcome!',
html: 'hello'
}
// Process the sending of this email via nodemailer
return mailTransport.sendMail(mailOptions)
.then(() => console.log('Welcome confirmation email sent'))
.catch((error) => console.error('There was an error while sending the welcome email:', error))
}
My postmark.key is already setup in the firebase config... The API tell me the problem is the format I use to send the mail informations.. How could I fix it ?
Update
I also tried to modify the mailOptions as follow and still the same error:
const mailOptions = {
from: 'test#test.com',
to: user.email,
subject: 'Welcome!',
textBody: 'hello'
}
Decided to restart from scratch by following only postmark documentation (wich is really good by the way).
So here are the very simple steps to send mail from events in firebase cloud functions:
1- download packages:
Run: npm install postmark
2- register to postmark
Register to PostMark
- then find your API key.
3- setup firebase environment config:
Run : firebase functions:config:set postmark.key="API-KEY-HERE"
4 index.js code to be added:
//Mail
const postmark = require('postmark')
const postmarkKey = functions.config().postmark.key;
const mailerClient = new postmark.ServerClient(postmarkKey);
exports.OnUserCreation = functions.auth.user().onCreate((user) => {
console.log("user created: " + user.data.uid);
console.log("user email: " + user.data.email);
return sendEmail(user);
})
// Send welcome email to new users
function sendEmail(user) {
const mailOptions = {
"From": "XYZ#YOURDOMAIN.com",
"To": user.data.email,
"Subject": "Test",
"TextBody": "Hello from Postmark!"
}
return mailerClient.sendEmail(mailOptions)
.then(() => console.log('Welcome confirmation email sent'))
.catch((error) => console.error('There was an error while sending the welcome email:', error))
}
That's it.
No need to download nodemailer nor use a transporter.

Resources