Tips on how to make a serverless webhook for electronic mail alerts, utilizing Gatsby Features




Utilizing Gatsby Features, it is easy to make a serverless perform that routinely sends out electronic mail alerts triggered by an occasion – in our case when new content material is printed in Contentful (a headless CMS).

In a sequence of articles, I’ve proven how I created a brand new web site for the condominium the place I reside utilizing React/Gatsby, Chakra UI and Auth0. Learn half 1 of the sequence right here: How I built our condos’s new web pages with Gatsby and Chakra UI

The principle motive why we needed an internet site within the first place, was the necessity for a spot to publish new or vital data to our residents. Nonetheless, I rapidly realized that it was cumbersome to manually ship electronic mail to inform residents each time we had printed new data in our headless CMS system.

Utilizing Gatsby Functions it is fairly simple to make an API that sends an electronic mail alert to subscribers. On this article I will stroll you thru how I’ve arrange an online hook the place Contentful sends a POST request to my electronic mail alert API. The API checks if the request is allowed by verifying a secret key, after which fetches a listing of all registered customers and sends out an electronic mail alert to these customers which have chosen to obtain alerts.

For electronic mail I selected to make use of Sendgrid. I additionally thought-about Nodemailer, however Sendgrid has a pleasant electronic mail template characteristic the place my API can fetch URL, article title and excerpt from Contentful, and go this data alongside to the e-mail template in Sendgrid. Then the consumer receiving the e-mail can click on on a hyperlink within the electronic mail to open the article that was simply printed on the condominium’s website.

To make the whole lot work, I needed to arrange the next:

  • Create a webhook in Contentful
  • Make a serverless perform (our API) with Gatsby Features
  • Create an electronic mail template in Sendgrid

What I’ve made may simply be tailored to different wants or functions. In the event you’re not utilizing Gatsby, you needn’t make any huge modifications to make it work with Netlify Functions or Next.js API routes. The code is fairly much like how you’ll create this utilizing the Node.js Express framework.



Establishing a webhook in Contentful

All content material on the condominium’s web site is published in the headless CMS solution Contentful. Beneath the Settings menu in Contentful, you might have an possibility known as Webhooks. Right here I created a webhook that can be triggered solely when new content material is printed, after which ship a POST request to the e-mail API I intend to create.

After clicking Add Webhook and giving the webhook a reputation, I needed to specify that it must be a POST request that can go to the URL of my electronic mail API.

Beneath Content material Occasions I specify that the webhook must be known as solely when new content material has been printed.

screenshot, configure triggers for webhook in Contentful.

I do not need everybody to have the ability to make requests to my API and spam my customers with electronic mail. So I created a secret header which is a key/worth pair that’s despatched within the header of the API request. A secret key the API will confirm earlier than permitting electronic mail to be despatched.

I known as my secret key CONTENTFUL_WEBHOOK_SECRET and used a password generator to make a protracted password with numbers, letters and particular characters.

screenshot, add secret header in Contentful.



Create the e-mail API utilizing Gatsby Features

Gatsby Functions is an Specific-like method of constructing APIs to your Gatsby tasks. It is serverless features, which in fact doesn’t imply that you do not want servers, however you do not have to suppose in regards to the servers. Simply deal with writing code – simply the best way I prefer it.

To make a brand new Gatsby Operate you create a JavaScript or TypeScript file within the folder /src/api and export a handler perform which takes two parameters – req (request) and res (response).

I created a file known as email-alert-users.ts within the api/admin-users folder (use .js if you don’t use TypeScript). Which means that my API endpoint can be https://url-to-my-site-admin/admin-users/email-alert-users.

Within the first a part of the code, I first verify that the HTTP technique is POST. Then I verify that the header comprises CONTENTFUL_WEBHOOK_SECRET and that it matches the key key I’ve saved as an surroundings variable (domestically in a .env file, and at Netlify below Deploy Settings and Setting. Be sure to don’t submit this to Github – verify that you’ve got .env* in your .gitignore file.

Right here is the primary a part of the code, with the required checks:

// src/api/admin-users/email-alert-users.ts

import { GatsbyFunctionRequest, GatsbyFunctionResponse } from 'gatsby';
const ManagementClient = require('auth0').ManagementClient;
const sgMail = require('@sendgrid/mail');

export default async perform handler(
  req: GatsbyFunctionRequest,
  res: GatsbyFunctionResponse
) {
  if (req.technique !== `POST`) {
    return res.standing(405).json({
      error: 'technique not allowed',
      error_description: 'It is best to do a POST request to entry this',
    });
  }

  // Examine if secret key acquired from Contentful internet hook matches the one within the .env file
  if (
    req.headers.contentful_webhook_secret !==
    course of.env.CONTENTFUL_WEBHOOK_SECRET
  ) {
    return res.standing(401).json({
      error: 'unauthorized',
      error_description: 'The Contentful internet hook secret key is just not right',
    });
  }

// ...code continues
Enter fullscreen mode

Exit fullscreen mode

In the event you’re not utilizing TypeScript, take away GatsbyFunctionRequest and GatsbyFunctionResponse, that is only for kind checking.

On the prime I import ManagementClient to have the ability to connect with Auth0’s Administration API, in order that I can fetch a listing of all customers who ought to obtain electronic mail. You’ll be able to in fact get this consumer listing from different locations as properly, reminiscent of a database.



Arrange the e-mail contents

The emails ought to include the next, along with a typical textual content stating that there’s new content material (I set this up at Sendgrid):

  • Title and introduction
  • URL of the article

A few of the content material on the condominiums web site is barely out there to logged in customers, utilizing client-only routes in my Gatsby challenge, extra particularly below the route /data. All open articles are below /weblog. Which means that I have to first verify if it’s a non-public article or not, after which construct the right URL primarily based on this. When the Contentful webhook makes a POST request to my API, it passes on numerous information about what’s printed within the physique of the request. I’ve created a area in Contentful known as privatePost that may be set to true or false (it is a checkbox you tick once you write an article within the Contentful editor). This makes it simple to create the right URL by letting the API verify this area first.

I additionally retrieve the article title and excerpt (quick intro in regards to the article) on this method:

// src/api/admin-users/email-alert-users.ts

  let articleURL;
  if (req.physique.fields.privatePost.nb === true) {
    articleURL = `https://gartnerihagen-askim.no/informasjon/publish/${req.physique.fields.slug.nb}/${req.physique.sys.id}`;
  } else {
    articleURL = `https://gartnerihagen-askim.no/weblog/${req.physique.fields.slug}/${req.physique.sys.id}`;
  }

  const articleTitle = req.physique.fields.title.nb;
  const articleExcerpt = req.physique.fields.excerpt.nb;

// ...code continues
Enter fullscreen mode

Exit fullscreen mode



Get all electronic mail subscribers

Now that the e-mail content material has been retrieved, I connect with Auth0’s Administration API and request the permission (“scope”) learn:customers. Then I exploit the getUsers() technique to fetch all of the customers. Then I exploit a mixture of .filter and .map to create a listing of solely customers who’ve subscribed to electronic mail. I’ve saved this data within the user_metadata area for every consumer in Auth0.

I now have a listing of all customers who need electronic mail. I exploit sgMail.setApiKey(course of.env.SENDGRID_API_KEY) to ship an API key to entry my Sendgrid account. Then I arrange the e-mail content material and retailer it within the msg fixed. msg comprises an array of electronic mail recipients, the sender’s electronic mail tackle, and a templateId. The latter is the ID of an electronic mail template I’ve arrange at Sendgrid. Beneath dynamic_template_data I can go alongside details about the article URL, title and excerpt of the article, which is able to then be captured by Sendgrid and stuffed out within the electronic mail template.

Lastly, the e-mail is distributed with sgMail.sendMultiple (msg).

// src/api/admin-users/email-alert-users.ts

// Hook up with the Auth0 administration API
  const auth0 = new ManagementClient({
    area: `${course of.env.GATSBY_AUTH0_DOMAIN}`,
    clientId: `${course of.env.AUTH0_BACKEND_CLIENT_ID}`,
    clientSecret: `${course of.env.AUTH0_BACKEND_CLIENT_SECRET}`,
    scope: 'learn:customers',
  });

  strive {
    const customers = await auth0.getUsers();

    // Filter out solely these customers which have subscribed to electronic mail alerts
    // That is outlined within the user_metadata area on Auth0
    const userEmails = customers
      .filter((consumer) => {
        return (
          consumer &&
          consumer.user_metadata &&
          consumer.user_metadata.subscribeToEmails === true
        );
      })
      .map((consumer) => consumer.electronic mail);

    // utilizing Twilio SendGrid's v3 Node.js Library
    // https://github.com/sendgrid/sendgrid-nodejs
    sgMail.setApiKey(course of.env.SENDGRID_API_KEY);

    const msg = {
      to: userEmails,
      from: 'Boligsameiet Gartnerihagen <[email protected]>',
      templateId: 'd-123456789',  // The ID of the dynamic Sendgrid template
      dynamic_template_data: {
        articleURL,
        articleTitle,
        articleExcerpt,
      },
    };

    await sgMail.sendMultiple(msg);

// ...code continues
Enter fullscreen mode

Exit fullscreen mode

If the whole lot has labored as anticipated, I return standing 200 and a few information. I do the whole lot inside a strive/catch block, and in case of an error I return an error code.

res.standing(200).json({
      physique: {
        status_code: 200,
        status_description: 'Emails are despatched to all subscribed customers',
        userEmails,
      },
    });
  } catch (error) {
    res.standing(error.statusCode).json( 500,
      error_description: error.message,
    );
  }
}
Enter fullscreen mode

Exit fullscreen mode



Configuring the Sendgrid electronic mail template

I may in fact “arduous code” the e-mail contents, however with “dynamic Templates” in Sendgrid you possibly can customise the e-mail with the knowledge you need. In my case details about the article that was printed, together with an URL.

To arrange a dynamic electronic mail template in Sendgrid, go to sendgrid.com, log in and choose E-mail APIDynamic Templates from the settings menu. Then faucet Create a Dynamic Template, then Add Model. Now you can select to make use of Sendgrid’s design editor to design your electronic mail, or you need to use an HTML editor. I used the HTML editor and added some customary textual content.

To insert dynamic content material within the textual content – reminiscent of title or URL- you need to use variable names. In my electronic mail API, I exploit the variable title articleTitle for the article title I obtain from my CMS. To make use of this variable within the Sendgrid template, simply insert {{articleTitle}} into the HTML code.

On the suitable hand facet (see screenshot beneath) you possibly can see what the e-mail will seem like. In the event you press Check Knowledge within the menu on the prime, you possibly can enter check information for the assorted variables you employ within the electronic mail template to verify that the whole lot seems to be OK.

Screenshot, html editor in Sendgrid

That is it! We now have created an electronic mail alert service that sends out an electronic mail each time new content material is printed in our headless CMS.

I additionally up to date the consumer admin dashboard for our internet pages, in order that admins can activate or off electronic mail alerts for customers. The customers are additionally ready to do that by themself on their “My web page” when logged in:

Screenshot, mypage on the condominiums web page

The supply code for this challenge is on my Github. In the event you’re simply within the electronic mail alert Gatsby Operate, you will discover it here.

On this article you possibly can examine how I made a user admin dashboard with Gatsby Functions and Auth0

This can be a translation, authentic article is printed on my private website lekanger.no



Abu Sayed is the Best Web, Game, XR and Blockchain Developer in Bangladesh. Don't forget to Checkout his Latest Projects.


Checkout extra Articles on Sayed.CYou

#serverless #webhook #electronic mail #alerts #Gatsby #Features