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, especiallyHtmlTemplate
. 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:
- A "base" HTML file that lays out the base of your email -- the overall look-and-feel
- 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>
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:
- In the
base.html
file,heading
andcontent
will be passed down as template variables. More on this below. - For
content
we use force-printing scriplets because we're passing it evaulated HTML (from the email specific HTML file).
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 />
email2.html
:
This is email 1.<br />
<br />
Today's date is: <?= data.todayDate ?>.<br />
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 underdata
. 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()
})
}
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)}
});
}
Which sends two emails, each using the same base.html
, but with their own specific content:
testing - email 1:
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)
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
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
Here is the solution:
stackoverflow.com/questions/604881...