cover image
Cloud

Easy Netlify Functions for Contact Messaging

Netlify Functions are serverless code that are easy to deploy. Here I want to show how to program a simple Netlify Function to send a contact message from my website to an email address and log it into an Airtable sheet. Behind the scenes, Netlify uses AWS Lambda functions and handles all the complex chores like configuring an API gateway and so on.

Netlify

Netlify is a San Francisco based company offering hosting of static sites and serverless functions. It was founded in 2014 and has a generous amount of free serverless functions. The company focuses on the Jamstack use-case, which is an evolving movement to use static sites and serverless code to deliver simpler, faster and more secure websites.

Sendgrid

The service I use here to send the contact message to my email address is Sendgrid by Twilio.

Twilio is a San Francisco based communication web company that offers cloud APIs for messaging. You can send a number of emails for free per month with the free plan.

Airtable

Airtable is also San Francisco based and is a provider of a communication platform with an API. For our purpose, you need to create a base that we use for logging the contact request from our website. You need to add the four fields ("Name", "Email" and "Message" and "Date"). Later, when a user sends a message, the data will be logged in the Airtable base, and you can view it.

Preparation

For simple deployment, Netlify offers a command line based tool called Netlify CLI. You can install it via:

npm install netlify-cli -g

For more information on setting up Netlify CLI and logging into your account, visit the documentation page:

https://docs.netlify.com/cli/get-started/

The package.json

The contact form TypeScript project uses the following third-party packages:

{
  "name": "contact-form",
  "version": "1.0.0",
  "description": "Netlify function for contact form messaging",
  "main": "contact-form.ts",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "netlify",
    "serverless",
    "typescript"
  ],
  "author": "Netlify",
  "license": "MIT",
  "dependencies": {
    "@netlify/functions": "^0.7.2",
    "@sendgrid/mail": "^7.4.7",
    "airtable": "^0.11.1",
    "typescript": "^4.0.0"
  },
  "devDependencies": {
    "@types/node": "^16.9.6"
  }
}

The two packages for the integration of Sendgrid and Airtable are included in this file.

The Contact Function

The contact function is written in TypeScript and looks like this:

import { Handler } from "@netlify/functions";
import sendgridMail from "@sendgrid/mail";
import Airtable from 'airtable';

sendgridMail.setApiKey(process.env.SENDGRID_API_KEY);

Airtable.configure({ apiKey: process.env.AIRTABLE_API_KEY })
const base = Airtable.base('app1x2RVWTmxkxcxx');

export const handler: Handler = async (event) => {
  const { email, name, message } = event.queryStringParameters;
  const date = new Date();

  base('Table 1').create([
    {
      "fields": {
        Name: name,
        Email: email,
        Message: message,
        Date: `${date.getMonth()+1}/${date.getDate()}/${date.getFullYear()}`,
      }
    },
  ], (err) => {
    if (err) {
      console.error(err);
    } else {
      console.log("Successfully logged to Airtable!");
    }
  });

  const msg = {
    to: "[email protected]",
    from: "[email protected]",
    subject: "Contact Message from Website",
    text: `Message from ${name} with email ${email}: ${message}`,
    html: `Message from ${name} with email ${email}: ${message}`,
  };

  try {
    await sendgridMail.send(msg);
  } catch (error) {
    console.error(error);

    if (error.response) {
      console.error(error.response.body);

      return {
        statusCode: 400,
        headers: {
          'Access-Control-Allow-Origin': '*', // Required for CORS support to work
        },
        body: JSON.stringify({
          message: 'Error: '+JSON.stringify(error.response.body)
        }),
      };
    }
  }

  return {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Origin': '*', // Required for CORS support to work
    },
    body: JSON.stringify({
      message: 'Success!'
    }),
  };
};

Before you can run the function locally, you need to set the environmental variables. In Linux-based systems, you can simply run export SENDGRID_API_KEY=your-key in the terminal. The same with the variable AIRTABLE_API_KEY.

Furthermore, you need to adapt the Airtable variable in the code with your own ID, as well as adapt the table name ("Table 1") if it is different.

Also, in order to receive the email message, you should enter your email address in the '''msg.to''' property.

Testing the Function

You can run and test the function locally with the following command:

netlify dev

You can test the GET http function in your web browser or using a tool like Insomnia by going to:

http://localhost:8888/.netlify/functions/contact-form/?name=Wolf&[email protected]&message=Hi!

If it was successful, you should receive an email and the parameters should be logged in your Airtable base.

Deploying to Production

Now if everything worked fine you can deploy your function to production with one simple command:

netlify deploy --prod

You also get a secure https endpoint after the deployment. This secure endpoint you can use in your frontend code to call the function.

Be aware that you need to set your environmental variables in the Netlify web application where you configured and set up your function.

Conclusion

Netlify Functions are an easy way to program and deploy AWS lambda functions. They integrate well with third party APIs and using the CLI tool you can test it easily locally, thus speeding up development.

References

  • Netlify Functions: https://docs.netlify.com/functions/overview/

  • Twilio Sendgrid: https://www.twilio.com/sendgrid

  • Airtable: https://airtable.com

  • Insomnia API client: https://insomnia.rest/

Published 26 Sep 2021
Thomas Derflinger

Written by Thomas Derflinger

I am a visionary entrepreneur and software developer. In this blog I mainly write about web programming and related topics like IoT.