Integrating twillio SendGrid web API with Nextjs.

What is Next.js?

What is SendGrid?

File Structure after creating sendMailToMe.js
import fetch from "node-fetch";

const SENDGRID_API_URL = "https://api.sendgrid.com/v3/mail/send";
const SENDGRID_API_KEY = process.env.NEW_SENDGRID_API_KEY;

const sendMailToMe = async (
recepient_email, // email_address to send mail
name_, // from name on email
subject = "sample subject",
client_message, // value we receive from our contact form
client_email // value we receive from our contact form
) => {
const sgResponse = await fetch(SENDGRID_API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${SENDGRID_API_KEY}`,
},
body: JSON.stringify({
personalizations: [
{
to: [
{
email: recepient_email,
},
],
subject: subject,
},
],
from: {
email: "YOUR VERIFIED SENDGRID MAIL HERE",
name: "YOUR NAME",
},
content: [
{
type: "text/html",
value: `<strong>Client Name: ${name_} </strong> \n <p>
sent you a query regarding <strong>${subject}</strong></p>
\n <p>Client's Message: <strong>${client_message}</strong><\p>
<p>Client's Email : <strong> ${client_email} </strong></p>`,
},
],
}),
});
return sgResponse;
};

export { sendMailToMe };
File Structure after creating ssenMail.js
import { sendMailQueryToMe } from "../../utils/sendMailToMe";

export default async function handler(req, res) {
if (req.method === "POST") {
// req.body carries all the data

try {
const { email, name_, subject, client_message } = req.body;

if (
typeof (email || name_ || subject || client_message) === "undefined"
) {
console.log(" ************* Invalid Data received ************ ");

return res
.status(400)
.send({ error: "bad request, missing required data!" });
} else {
// Data received as expected
try {
const sendGridResponse = await sendMailQueryToMe(
"your_mail@gmail.com",
name_,
subject,
client_message,
email
);

return res.status(200).send({
sg_response: sendGridResponse,
});
} catch (err) {
console.log(
"ERROR WHILE SENDING MAIL TO *YOU* THROUGH WEB API >> ",
err
);

return res.status(400).send({
err_message: "bad request",
});
}
}
} catch (err) {
console.log("Err while sending Mail through send grid >> ", err);
return res
.status(400)
.send({ error: "Error in sendgrid Service.", errMsg: err });
}
}

res.status(400).send({ error: "bad request" });
}
import React, { useState } from "react";
import MailOutlineIcon from "@material-ui/icons/MailOutline";
import { MenuItem, Input } from "@material-ui/core";
import TextField from "@material-ui/core/TextField";
import https from "https";

function contact() {
const [formError, setFormError] = useState({ error: "" });
const [querySubject, setQuerySetsubject] = useState("");
const [name_, setName_] = useState("");
const [clientEmail, setClientEmail] = useState("");
const [clientMsg, setClientMsg] = useState("");

const serviceOptions = [
{
value: "option1",
label: "option1",
},
{
value: "option2",
label: "option2",
},
{
value: "option3",
label: "option3",
},
{
value: "option4",
label: "option4",
},
];

const sendMail = async (
client_name,
client_email,
client_message,
client_subject
) => {
const data = JSON.stringify({
name_: client_name,
email: client_email,
client_message: client_message,
subject: client_subject,
});

const options = {
path: "/api/sendMail",
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": data.length,
},
};

const req = https.request(options, (res) => {
// console.log(`statusCode: ${res.statusCode}`);

res.on("data", (d) => {
// process.stdout.write(d);
// console.log("data from API >> ", JSON.parse(d));
});
});

req.on("error", (error) => {
setFormError({
error: "Unable to send your message please try after some time.",
});
});

req.write(data);
req.end();
};

return (
<div>
<form
style={{ display: "flex", flexDirection: "column", padding: "50px" }}
>
<Input
style={{ width: "100%", color: "black" }}
type="text"
value={name_}
placeholder="What is your name ?"
onChange={(e) => setName_(e.target.value)}
required
/>
<Input
style={{ width: "100%", color: "black" }}
value={clientEmail}
type="email"
placeholder="What is your email ?"
onChange={(e) => setClientEmail(e.target.value)}
required
/>
<TextField
style={{ width: "100%", color: "black" }}
id="standard-select-Interest"
select
label="What are you interested in ?"
value={querySubject}
onChange={(e) => setQuerySetsubject(e.target.value)}
required
>
{serviceOptions.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</TextField>

<TextField
style={{ width: "100%", color: "black" }}
id="client-message-textarea"
label="Message"
multiline
rows={4}
value={clientMsg}
onChange={(e) => setClientMsg(e.target.value)}
/>
{formError.error ? (
<div className="form__error">
<span style={{ color: "black" }}>{formError.error}</span>
</div>
) : (
""
)}
<div>
<button
disabled={!name_ || !clientEmail || !clientMsg || !querySubject}
type="submit"
style={
!name_ || !clientEmail || !clientMsg || !querySubject
? {
backgroundColor: "#878a8f",
color: "white",
transform: "scale(1)",
cursor: "default",
margin: "50px 0",
}
: { margin: "50px 0" }
}
onClick={(e) => {
e.preventDefault();
sendMail(name_, clientEmail, clientMsg, querySubject);
}}
>
<MailOutlineIcon /> Send
</button>
</div>
</form>
</div>
);
}

export default contact;

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store