Unsubscribe Link in Email with AWS Lambda and Terraform

GitHub Repository

Introduction

You are sending emails to users, but don’t provide them a way to unsubscribe from these emails? Let me show you pretty quick how I added unsubscribe link to Pomodoro by Increaser newsletter so that you can do the same in no time.

unsubscribing from Pomodoro by Increaser news

In this story, we will add a link in the newsletter that will lead to the page triggering AWS lambda responsible for unsubscribing the user. To create all the needed infrastructure, we will use Terraform. Code for both infrastructure description and nodeJS lambda you can find in the GitHub repository.

Link

First, we are going to add an unsubscribe link to the email. The link from the example below ask to unsubscribe a given user from Pomodoro by Increaser news.

<a target="_blank" href="https://pomodoro-subscriber.increaser.org/pomodoro-news-email/{{id}}/unsubscribe">unsubscribe</a>

This link leads to AWS Lambda that will handle email subscriptions — pomodoro-subscriber.increaser.org. The route has three parts:

  1. Type of email(pomodoro-news-email)
  2. User Id
  3. Action(unsubscribe)

Lambda

You can find all the lambda code in the repository here.

From lambda.js, we export function that will process the incoming request. It extracts type, id, and action we’ve specified in the link and calls the handler function to receive HTML.

If something went wrong, we return 400. If an error hasn’t thrown intentionally, we report it to Sentry.

Implementation of the handler function we can find here. It checks if a request is valid, updates the user, and returns appropriate HTML.

Infrastructure

You can find everything related to the infrastructure in the repository here. Very similar infrastructure has already covered in other stories — AWS for Website CI/CD with Terraforms and Amazon DocumentDB and AWS Lambda with Terraform. Therefore we will only cover variables here.

To create the infrastructure, we need to set environment variables(AWS credentials) first.

$ export AWS_ACCESS_KEY_ID=<YOUR_AWS_ACCESS_KEY_ID>
$ export AWS_SECRET_ACCESS_KEY=<YOUR_AWS_SECRET_ACCESS_KEY>
$ export AWS_REGION=<YOUR_AWS_REGION>

In vars.tf, we specify all variables we need to create resources on AWS.

The only required variable here is the name that we will use in almost every resource.

Everything else is optional, if you are using Sentry, you can specify sentry_key.

If you have a registered domain and certificate for it, you can specify set values for these variables: domain, zone_id, and certificate_arn.

If you like an idea of using AWS CodePipeline for CI/CD and have your code in the GitHub repository and have a Docker container in the AWS ECS registry, you can also specify the last four variables. Also, you will need to set the token as an environment variable. It quite simple to get, you can find steps there.

$ export GITHUB_TOKEN=<YOUR_GITHUB_TOKEN>

To find more information about the CD part, you can check this story.

We can specify variables by editing a file or by setting environment variables like this.

$ export TF_VAR_name=<NAME_FOR_RESOURCES>
$ export TF_VAR_docdb_password=<PASSWORD_FOR_AMAZON_DOCUMENTDB>
$ export TF_VAR_certificate_arn=<YOUR_DOMAIN_SERTIFICATE_ARN>
$ export TF_VAR_zone_id=<YOUR_DOMAIN_ZONE_ID>
$ export TF_VAR_domain=<YOUR_DOMAIN>

Now let’s run those two commands to create resources.

$ terraform init
$ terraform apply

That’s it. The only thing left is to update the function name in the deployment script.

Reach the next level of focus and productivity with increaser.org.

Increaser

--

--

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