Today I had the task of implementing a newsletter for internal updates and decided to use Google Apps Script since I was already using it for managing the project data. Based upon past experiences with emails using HTML I need this area was full of landmines and I didn't want to navigate through it. đŁ
So I decided to use MJML with Google Apps Script.
Overview of MJML
MJML is a markup language designed to reduce the pain of coding a responsive email. Its semantic syntax makes it easy and straightforward and its rich standard components library speeds up your development time and lightens your email codebase. MJMLâs open-source engine generates high quality responsive HTML compliant with best practices.
The syntax looks like the following code snippet and has mechanisms for properly applying styles to the elements.
<mjml>
<mj-body>
<mj-section>
<mj-column width="200px">
<!-- First column content -->
</mj-column>
<mj-column width="400px">
<!-- Second column content -->
</mj-column>
</mj-section>
</mj-body>
</mjml>
But what about the Apps Script Runtime! đą
I wasn't sure what issues I was going to run into with the MJML compiler, but it actually wasn't that bad! My process went like this:
Note: I'm using Google Clasp and ESBuild.
- Try using the mjml package. Nope, tries to use Node's
fs
andpath
. â - Try using the mjml-browser package. Success â
This requires me to give up some of the includes functionality, which didn't matter to me anyhow.
Since I'm using Google Clasp and ESBuild, the files in my project look like this:
My ESBuild file looks like the following, (note the platform: "node"
):
await esbuild.build({
entryPoints: ["./src/index.ts"],
bundle: true,
outdir,
sourceRoot,
platform: "node", // !! combining Node with mjml-browser
format: "esm",
plugins: [],
inject: ["polyfill.js"],
minify: true,
banner: { js: "// Generated code DO NOT EDIT\n" },
entryNames: "zzz_bundle_[name]",
chunkNames: "zzz_chunk_[name]",
});
const passThroughFiles = ["main.js", "appsscript.json"];
My Apps Script Code
I used the sample from https://mjml.io/try-it-live/templates/basic in my code and sent a test email to myself:
function main() {
const { html } = mjml2html(
`<mjml>
<mj-body>
... OMITTED for brevity
</mj-body>
</mjml>`
);
// send html email
GmailApp.sendEmail(
Session.getActiveUser().getEmail(), "Test", '',
{ htmlBody: html });
}
And it worked!
Conclusion
You can checkout the code in my Apps Script repository.
Everything Apps Script
This repository is a monorepo containing tools, projects, and more related to Apps Script.
Next I need to publish a library, MJMLApp
, that hides the gnarly bits! But for now I need to get back to that newsletter I need to send. đ¤
Top comments (0)