When you are setting up email marketing campaigns or newsletters, one thing often forgotten is an Unsubscribe link. Not providing an option to unsubscribe from the mailing list can land your emails in spam.
In this tutorial, you’ll learn to add an Unsubscribe link in your emails sent using Google Apps Script.
Contents
- Setting Up a Spreadsheet
- Writing a Hash Function
- Writing Email Template
- Writing Unsubscribe Code
- Results
Setting Up a Spreadsheet
The first task is to set up a Spreadsheet. For this:
- Create a new Google Spreadsheet and name the sheet as emails.
- Add the following fields in the first row of your spreadsheet.
Writing a Hash Function
To provide a secure way to unsubscribe, you need to create a unique token for each of your subscribers. Google Apps Script provides you with utility functions to create a hash of a string using the MD5 hashing algorithm. The following function is used to create a hash of the string value
, provided as a parameter:
function getMD5Hash(value) {
const digest = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5,
value,
Utilities.Charset.UTF_8)
let hash = ''
for (i = 0; i < digest.length; i++) {
let byte = digest[i]
if (byte < 0) byte += 256
let bStr = byte.toString(16)
if (bStr.length == 1) bStr = '0' + bStr
hash += bStr
}
return hash
}
Since no two strings in the world have the same hash, this is the right way to provide unsubscribe tokens to your subscribers in your marketing campaigns or newsletters.
However, there is a security issue involved. If anyone knows the email of your subscriber, the attacker can easily compute the hash and unsubscribe the subscriber from your email list. So, to make the hash impossible to guess, you can add some randomness to your email string. You can create a random string and append it to your original email string.
The following snippet of code will help you to achieve your purpose:
function getMD5Hash(value) {
value = value + generateRandomString(8) // added this
const digest = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5,
value,
Utilities.Charset.UTF_8)
let hash = ''
for (i = 0; i < digest.length; i++) {
let byte = digest[i]
if (byte < 0) byte += 256
let bStr = byte.toString(16)
if (bStr.length == 1) bStr = '0' + bStr
hash += bStr
}
return hash
}
function generateRandomString(length) {
const randomNumber = Math.pow(36, length + 1) - Math.random() * Math.pow(36, length)
const randomString = Math.round(randomNumber).toString(36).slice(1)
return randomString
}
Writing Email Template
You can use a basic HTML template for testing your Google Apps Script for the unsubscribing feature:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>We are testing our unsubscribe feature</h1>
<a href="{{WEBAPP_URL}}?email={{EMAIL}}&unsubscribe_hash={{TOKEN}}">Unsubscribe</a>
</body>
</html>
This email template contains the link for unsubscribing. You have also provided two parameters, email
and unsubscribe_hash
. When the subscriber will tap this link, it will send a GET request to your Google Apps Script deployed as a Web App.
Make sure to replace the values in curly braces.
Writing Unsubscribe Code
The final step to bring your workflow together is to write a code that handles your unsubscribe functionality.
In your Main.gs, add the following code to handle the GET request made to your Apps Script web app:
function doGet(e) {
const email = e.parameter['email']
const unsubscribeHash = e.parameter['unsubscribe_hash']
const success = unsubscribeUser(email, unsubscribeHash)
if (success) {
return ContentService.createTextOutput().append('You have unsubscribed')
}
return ContentService.createTextOutput().append('Failed')
}
In the above script, you retrieve the email
and unsubscribe_hash
from the query parameters and pass them to your unsubscribeUser
function. Based on the output of your function, you return an appropriate response.
Next, add the implementation for unsubscribeUser
function in the Main.gs file:
function unsubscribeUser(emailToUnsubscribe, unsubscribeHash) {
// get the active sheet which contains your emails
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('emails')
// get the data in it
const data = sheet.getDataRange().getValues()
// get sheet headers i.e. top row of the sheet
const headers = data[0]
// get the index for each header
const emailIndex = headers.indexOf('email')
const unsubscribeHashIndex = headers.indexOf('unsubscribe_hash')
const subscribedIndex = headers.indexOf('subscribed')
// iterate through the data, starting at index 1
for (let i = 1; i < data.length; i++) {
const row = data[i];
const email = row[emailIndex];
const hash = row[unsubscribeHashIndex];
// if the email and unsubscribe hash match with the values in the sheet
// then update the subscribed value to 'no'
if (emailToUnsubscribe === email && unsubscribeHash === hash) {
sheet.getRange(i+1, subscribedIndex+1).setValue('no')
return true;
}
}
}
In the above function, you simply iterate over your sheet
using the for
loop and check for the details for every subscriber. If the subscriber’s email
and unsubscribeHash
match with those sent as a query parameter, you unsubscribe the subscriber by updating the value in the sheet
.
Results
For testing the script, send a test email to one of your subscribers specified in the Google Sheet. You can see that you have received an email with an option to Unsubscribe.
At this point, click the Unsubscribe link and check whether your sheet gets updated.
Oo Yea! You can see that the value for the subscribed
field changed to no.
Using this workflow, you can provide your subscribers with an option to opt out of your mailing list for newsletters or marketing emails.