DEV Community

Cover image for How to Build Your Own Serverless Contact Form
Sai gowtham
Sai gowtham

Posted on

19 8

How to Build Your Own Serverless Contact Form

Static Sites are developed by using Html, CSS, and JavaScript.
You don't need to set up any database or server. GitHub, Netlify offers us free hosting for the static sites by adding a Contact form to a site you need to pay for the server even though if no user visits to your site. By using Serverless Aws only charges for you when someone hits your webpage if there is no traffic it means no charges.

In this Article, You will learn about how to build A Serverless Contact form by using SES(Simple Email Service), Aws Lambda and Serverless Framework.

email

What are Requirements?

  1. Aws Account
  2. Nodejs
  3. Serverless framework cli.
  4. DashBird Account

Let's build a Serverless Contact Form

one

First we need to install the Serverless Framework cli.

Open your terminal and run below command.

npm install -g serverless

sls login // SLS is a shortcut of serverless

Enter fullscreen mode Exit fullscreen mode

number 2

After sls login, You need to configure Your Aws Credentials with a serverless framework.

Get Aws Credentials

threee

Create a New Directory in your Pc.

mkdir contactform
cd contactfrom
Enter fullscreen mode Exit fullscreen mode

four

Serverless Offers us a different type of templates but we are using Nodejs as our Backend so that we are creating nodejs template.

serverless create --template aws-nodejs
Enter fullscreen mode Exit fullscreen mode

The above command generates the boilerplate.

five

Now we need to initialize the Package.json file and install some dependencies.

npm init -y // generates package.json file

npm i -s body-parser cors express serverless-http aws-sdk
Enter fullscreen mode Exit fullscreen mode

Now open contact form folder in your Favourite code Editor.

Navigate to the handler.js file

Clear everything in the handler.js because we are writing it from scratch.

const serverless = require("serverless-http");
const AWS = require("aws-sdk");
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const app = express();
if (!AWS.config.region) {
AWS.config.update({
region: "add your region" //example us-east-1
});
}
const ses = new AWS.SES();
app.use(cors());
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
app.use(bodyParser.json());
app.post("/", (req, res) => {
const name = req.body.name;
const email = req.body.email;
const message = req.body.message;
});
module.exports.form = serverless(app);
view raw handler.js hosted with ❤ by GitHub

.

We are invoking the SES constructor on line 15 and a single endpoint. If you want to know about How to Create a Serverless Endpoints Using Express Checkout My Article Build and Deploy a Rest API Using Serverless, Express, and Nodejs.

We need to invoke the ses.sendEmail(params,function(err,data){}) method inside the post method.

params

Source — (String):
The email address that is sending the email. This email address must be either individually verified with Amazon SES.

To verify Your email address

  1. Open your Aws Console and type ses in a Search bar
  2. Click on Simple Email Service.
  3. Once it is open in your left sidebar click on email address add Your Email Address.
  4. You will receive a Verification email.

verify

Destination:

The destination for this email, composed of To, CC, and BCC fields.

ToAddresses — Array of email addresses.
CcAddresses — Array of email addresses.
BccAddresses — Array of email addresses.

Message:

Subject[Object]:
The subject of the message: A short summary of the content, which will appear in the recipient's inbox.

Data(String): The content of your form.

const emailParams = {
Source: "yourname@mail.com", // Your Verified Email
Destination: {
ToAddresses: ["yourname@mail.com"] // Your verfied Email
},
ReplyToAddresses: [req.body.email],
Message: {
Body: {
Text: {
Charset: "UTF-8",
Data: `${message} from ${req.body.email}`
}
},
Subject: {
Charset: "UTF-8",
Data: "You Received a Message from www.domainname.com"
}
}
};
view raw params hosted with ❤ by GitHub

We need to pass these params object to the ses.sendEmail method.

Updated handler.js file

const serverless = require("serverless-http");
const AWS = require("aws-sdk");
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const app = express();
if (!AWS.config.region) {
AWS.config.update({
region: "us-east-1"
});
}
const ses = new AWS.SES();
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post("/", (req, res) => {
const name = req.body.name;
const email = req.body.email;
const message = req.body.message;
const emailParams = {
Source: "yourname@mail.com", // Your Verified Email
Destination: {
ToAddresses: ["yourname@mail.com"] // Your verfied Email
},
ReplyToAddresses: [req.body.email],
Message: {
Body: {
Text: {
Charset: "UTF-8",
Data: `${message} from ${req.body.email}`
}
},
Subject: {
Charset: "UTF-8",
Data: "You Received a Message from www.domainname.com"
}
}
};
ses.sendEmail(emailParams, (err, data) => {
if (err) {
res.status(402).send(`${err} ${err.stack}`);
}
if (data) {
res.send(data);
}
});
});
module.exports.form = serverless(app);

Open Your serverless.yml file and Update with below code.

service: contact-form
provider:
name: aws
runtime: nodejs8.10
region: us-east-1
iamRoleStatements:
- Effect: "Allow"
Action:
- "ses:SendEmail"
Resource: "*"
functions:
app:
handler: handler.form
events:
- http: ANY /
- http: 'ANY {proxy+}'
view raw serverless.yml hosted with ❤ by GitHub

Now Open your Terminal and run sls deploy to deploy your code in Aws. Once you run the command after some time your API endpoints are visible in your terminal.

terminal endpoints

Front-end Setup

Html Markup

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name= "viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Contact us</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="all">
<form action="" class="items">
<h1>Contact Us</h1>
<div class="error-items">
<p style="color:red" class="error"></p>
</div>
<div>
<label for="name">Name</label>
<input type="text" id="name" required placeholder="Enter Your Name" class="name" />
</div>
<div>
<label for="email">Email</label>
<input type="email" required placeholder="Your Email" id="email" class="normal" />
</div>
<div class="area">
<label for="message" class="area-label">Message</label>
<textarea type="text" placeholder="Message" required id="message" class="txt"></textarea>
</div>
<button>Send</button>
</form>
</div>
<p class="success"></p>
<script src="./script.js"></script>
</body>
</html>
view raw index.html hosted with ❤ by GitHub

Css

*{
box-sizing: border-box;
padding: 0;
margin: 0
}
body{
font-family: sans-serif;
}
.items{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 2rem;
font-size: 1.1rem;
padding: 1rem;
}
input{
padding: 1rem;
margin: .8rem;
width: 25rem;
height: 3rem;
font-size: 1.1rem;
border: 3px solid rgb(31, 121, 255);
outline: none;
}
textarea{
width: 25rem;
height: 10rem;
padding: 1rem;
display: flex;
justify-content: center;
outline: none;
border: 3px solid rgb(31, 121, 255);
font-size: 1.1rem;
}
.area{
display: flex;
}
.area-label{
margin-left:-2rem;
}
.txt{
margin-left:.6rem;
}
button{
padding: 1rem;
width: 10rem;
margin-top: 2rem;
text-align: center;
background-color: rgb(75, 224, 75);
font-size: 1.3rem;
color: rgb(2, 2, 15);
box-shadow: 0 .2rem .2rem black;
}
.success{
background-color: rgb(75, 214, 224);
font-size: 1.2rem;
text-transform: capitalize;
text-align: center;
margin-top: 10rem;
padding: 2rem;
box-shadow: 0 .2rem .2rem rgb(0, 0, 0);
display: none;
}
.error{
display: none;
animation: move .2s ease-in ;
}
@keyframes move{
0%{
opacity: 0;
transform: translateY(-80%);
}
50%{
opacity: .6;
transform: translate(-20%);
}
70%{
opacity: .7;
transform: translate(20%);
}
100%{
opacity: 1;
transform: translate(0);
}
}
view raw style.css hosted with ❤ by GitHub

JavaScript

  • We need to make an ajax request to the endpoint.
let name = document.querySelector("#name");
let email = document.querySelector("#email");
let message = document.querySelector("#message");
let error = document.querySelector(".error");
let btn = document.querySelector("button");
let success = document.querySelector(".success");
btn.addEventListener("click", submit);
function submit(e) {
e.preventDefault();
var xhr = new XMLHttpRequest();
xhr.open("POST", "yourendpoint", true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
}
};
var data = {
name: name.value,
email: email.value,
message: message.value
};
if (name.value && email.value && message.value) {
success.style.display = "block";
success.innerHTML = "Thanks for submitting";
document.querySelector(".all").style.display = "none";
xhr.send(JSON.stringify(data));
} else {
error.style.display = "block";
error.innerHTML = "Please Fill All Details";
}
}
view raw script.js hosted with ❤ by GitHub

Final Output

email

For monitoring, Debugging and error detection of lambdas we are using Dashbird

Why Dashbird?

  • Dashbird helps us actively monitoring the health and errors.

  • One main thing about Dashbird is its user-friendly Interface.

  • Dashbird visualizes all your AWS Lambda metrics like
    memory utilization, invocation count, and execution duration.

DashBird Interface

Dashbird monitoring

Hope you guys enjoyed if you have any doubts feel free to ask.

Code Repository

Other Interesting Posts on Serverless

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (1)

Collapse
 
1c7 profile image
Cheng Zheng

Thanks for the tutorial.

But I always fail to send Emails. says my Email address is not verified,
even though in AWS SES Console I can see them clearly verified.
Both from and to address are the same, as the code you provided.
Anyway I give up fixing this issue

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more