DEV Community

IMTheNachoMan
IMTheNachoMan

Posted on • Edited on

Templated Emails With Google Apps Script To Make Your Brand Team Happy

Table of Contents

About

While we may not think about branding -- font, format, layout, structure, etc. -- in our personal emails, if you work in an organization then you probably can't get away from their branding requirements, even for emails. And rightfully so -- staying on brand with your communication is crucial for your customers/clients, including emails.

If your organization is using G-Suite (now known as Google Workspaces) then you're hopefully using Google Apps Script to automate your email communication. (If you aren't, why not? It's a brilliant way to manage your communications.) You probably have different types of emails -- for different purposes.

Do all of your emails have the same look-and-feel? Do they all match your organization's branding requirements? How easy is it to update the format for all of them if you need to change a core/base element? Maybe the company tagline and color theme changed -- how quickly can you get all of your emails updated?

I am going to show you how to create templated emails so that all of the emails you send have the same look-and-feel and are easy to maintain/update.

Pre-Requisites

  • Doing this does require working with HTML -- the HTML that will be used for the email. HTML is out-of-scope for this article. If you need help with writing HTML for your emails, there are many online sites that let you compose your emails in WYSIWYG and spit out the associated HTML.
    • In a future article I will explain how to do this using a Google DocS for the email template, instead of having to mess with HTML.
  • You should also understand how Google Apps Script's HtmlService works, especially HtmlTemplate. See https://developers.google.com/apps-script/reference/html/html-service for more information.

How It Works

The basic idea is very simple. You have:

  1. A "base" HTML file that lays out the base of your email -- the overall look-and-feel
  2. X # of email specific HTML files that include the actual specific content for that email without having to worry about style/formatting/look-and-feel

For example, you may have the following types of emails you send and you want all of them to have the same look-and-feel:

  • Welcome email
  • Support request auto-reply
  • Bill/Invoice
  • Newsletter
  • etc...

When you need to send an email, you just need to specify the email specific HTML file (#2) and the code will put it together with the base HTML file (#1).

Let's Do It

You can view my code at https://script.google.com/d/1KirtuDBLCzWMNIBYEb1MNI_tQ93f3UCyS7iuBinAf3LNtXukqvrn-F7S/edit?usp=sharing.

Step 1: The Core HTML File

The first thing you need to do is create the base HTML file with the HTML elements that you want all of your emails to have. Example:

base.html:

<!DOCTYPE html>
<html>
    <head>
        <base target="_top">
    </head>

    <body style="font-family: Consolas; font-size: 12px; color: blue">
        <div><h1><?= header ?></h1></div>
        <div><hr /></div>
        <div>
            <?!= content ?>
        </div>
        <div><hr /></div>
        <div>
            Thank you!<br />
            _Nacho
        </div>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

My example has:

  • CSS formatting styles
  • a heading area that all of my emails will hvae
  • a content area where the actual specific email content will go
  • a signature area that all of my emails will have

Notes:

Step 2: The Email Specific HTML Files - One For Each Email I Want To Send

Now you need X # of specific email HTML files. Examples:

email1.html:

This is email 1.<br />
<br />
Today's date is: <?= data.todayDate ?>.<br />
Enter fullscreen mode Exit fullscreen mode

email2.html:

This is email 1.<br />
<br />
Today's date is: <?= data.todayDate ?>.<br />
Enter fullscreen mode Exit fullscreen mode

Notes:

  • These files only include the content specific to those emails. They don't need to include all the other HTML elements that base.html takes care of because, in the next part, we'll put them together.
  • Notice that each email specific HTML file can reference its own relevant template variables.
  • All of the email specific HTML files will reference their relevant template variables through the data variable. This is because when we combine the templates to put the email together we don't know what template variables we need. So, instead, we'll pass all the specific email template variables under data. This will make more sense below.

Step 3: Putting It All Together

Now the only thing left is to put it all together. We're going to use a helper function that we can call when we want to send an email. The helper function will put the email together and send it.

/**
 * send a templated email
 * 
 * @param {Object} data - configuration options
 * @param {string} data.to - recipient's email address
 * @param {string} data.subject - the email subject
 * @param {string} data.header - the header of the email body
 * @param {string} data.emailTemplate - the name of the email file we want to send
 * @param {string} data.emailData - any data we want to pass down to the email body
 */
function _sendTemplatedEmail_(data)
{
    // first, lets get the generated content of the specific email we want to send
    var specificEmail = HtmlService.createTemplateFromFile(data.emailTemplate);

    // we need to send the data relevnat to this specific email
    specificEmail.data = data.emailData;

    // next we need to get the base.html file and put it all together
    var baseEmail = HtmlService.createTemplateFromFile("base");

    // send the header (used in base.html)
    baseEmail.header = data.header;

    // send the content for this specific email
    // we need to evaulate it and get the HTML content
    baseEmail.content = specificEmail.evaluate().getContent();

    // now we can send the email
    GmailApp.sendEmail(data.to, data.subject, "", {
        // for the emial we need the evaulated HTML content
        "htmlBody": baseEmail.evaluate().getContent()
    })
}
Enter fullscreen mode Exit fullscreen mode

And that is it. We can test it out like so:

function testIt()
{
    // lets send email1
    _sendTemplatedEmail_({
        "to": Session.getActiveUser().getEmail(),

        // the subject we want for this email
        "subject": "testing - email 1",

        // the header we want for this email
        // this will go in the header area of base.html
        "header": "this is a test of email 1",

        // the email specific HTML file: email1.html
        "emailTemplate": "email1",

        // the data relevant to email1.htlm
        "emailData": {"todayDate": Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy-mm-dd")}
    });

    // lets send email2
    _sendTemplatedEmail_({
        "to": Session.getActiveUser().getEmail(),
        "subject": "testing - email 2",
        "header": "this is a test of email 2",
        "emailTemplate": "email2",

        // notice we are sending different data
        // because email2.html expects different template variables
        "emailData": {"randomNumber": Math.floor((Math.random() * 100) + 1)}
    });
}
Enter fullscreen mode Exit fullscreen mode

Which sends two emails, each using the same base.html, but with their own specific content:

testing - email 1:

testing - email 1

testing - email 2:

testing - email 2

The End

Now you can have as many email specific HTML files you need and all of them will use the same base.html so they will all have the same look-and-feel. When you need to change something, the style, the signature, anything, you just have to update base.html and you're done.

I hope you found this article helpful. Please leave a comment with any questions, concerns, feedback, or anything. Would love to hear what you think!

Top comments (3)

Collapse
 
mkw999 profile image
Martin

Hi IMTheNachoMan
great script, I try to use it but have trouble with HTML-formatting the inserted content. The mail shows all the HTML tags. Could You give a short example on how to insert HTML? Thank You!

Martin

Collapse
 
mkw999 profile image
Martin

This is my code:

first, I have the data definition in the custom mail:

Your trip: <?= data.intCalDescription ?> is really beautiful!

The value of intCalDescription :
this.intCalDescription = ('

' + this.bookID + '

' + this.Condo + '

' +
'
' +
'' );

And finally, in the joined mail, my intCalDescription is displayed with all HTML tags.

I am sure there is a quick fix to that, I hope You can help.
Martin

Anfrage: ' + this.stampDateString + '
Collapse
 
mkw999 profile image
Martin