Send emails using Gmail API advanced services in Apps Script

Use the build-in Apps Script methods to send emails using Gmail API.

Send emails using Gmail API advanced services in Apps Script
Photo by Brett Jordan / Unsplash

Backstory

Recently, I had the need to send emails using the Gmail API but most of the official and community resources pointed towards making a POST request to the users.messages.send endpoint as opposed to effectively make use of the Gmail.Users.Messages.send() method within Apps Script.

After extensive digging, I stumbled upon this GitHub gist from Kanshi Tanaike but I wanted to further explore making use of all/other/available methods that came as part of Advanced Gmail Service (ex: call the Gmail.newMessage() function).

Prerequisites

  1. Enable the Gmail API in your Apps Script project by clicking on the ➕ icon next to Services (on the left navigation menu where you see the Code.gs file) and selecting Gmail API from the pop-up list
  2. Ensure you have access to a second email account to which you can send emails to for testing purposes — this is important because the information that you'd get to see in the emails from your own Sent folder may not be the same as that of the recipient's email in their Inbox (more on this can be found under Further Reading below)

Architecture

The most important thing to know/understand when using the Gmail API is that everything relies on how you create your message MIME, which has to be —

...compliant with RFC 2822 and encoded as base64url strings...

Source: Google Workspace > Gmail > Guides > Sending Email > Creating messages

Here's an example of what that actual content structure should look like —

From: FRÖM NAME <YYYYYYYYYY@example.com>
To: TO NÂME <ZZZZZZZZZZ@example.com>
Subject: Sending email usiñg Gmäil API 🚀
Content-Type: multipart/alternative; boundary=e099eaff-0b66-4354-9142-de1e178250d3

--e099eaff-0b66-4354-9142-de1e178250d3
Content-Type: text/plain; charset="UTF-8"

This is what plaiń text's suppośed to look like

--e099eaff-0b66-4354-9142-de1e178250d3
Content-Type: text/html; charset="UTF-8"

<html><body>This iš suppösed to be in <b>HTML</b> 👩🏽‍💻</body></html>

--e099eaff-0b66-4354-9142-de1e178250d3--

You can find a similar structure in any of the emails from your Gmail inbox, by opening the email, clicking on the 3 dots on the right, and selecting Show original.

Codebase

You can access the entire code from my GitHub repository here or make a copy of this script instead.

function sendEmail() {
  const input = {
    from: {
      name: `FRÖM NAME`, // use `` if empty
      email: `##########`, // YYYYYYYYYY@example.com
    },
    to: {
      name: `TO NÂME`, // use `` if empty
      email: `##########`, // ZZZZZZZZZZ@example.com
    },
    subject: `Sending email usiñg Gmäil API 🚀`,
    body: {
      plainText: `This is what plaiń text's suppośed to look like`,
      html: `<html><body>This iš suppösed to be in <b>HTML</b> 👩🏽‍💻</body></html>`
    }
  };

  const boundaryId = Utilities.getUuid();
  // Email message as per RFC 2822 format
  const message =
    `From: =?UTF-8?B?${Utilities.base64Encode(input.from.name, Utilities.Charset.UTF_8)}?= <${input.from.email}>` + `\r\n` +
    `To: =?UTF-8?B?${Utilities.base64Encode(input.to.name, Utilities.Charset.UTF_8)}?= <${input.to.email}>` + `\r\n` +
    `Subject: =?UTF-8?B?${Utilities.base64Encode(input.subject, Utilities.Charset.UTF_8)}?=` + `\r\n` +
    `Content-Type: multipart/alternative; boundary=${boundaryId}` + `\r\n\r\n` +
    `--${boundaryId}` + `\r\n` +
    `Content-Type: text/plain; charset="UTF-8"` + `\r\n` +
    `Content-Transfer-Encoding: base64` + `\r\n\r\n` +
    `${Utilities.base64Encode(input.body.plainText, Utilities.Charset.UTF_8)}` + `\r\n\r\n` +
    `--${boundaryId}` + `\r\n` +
    `Content-Type: text/html; charset="UTF-8"` + `\r\n` +
    `Content-Transfer-Encoding: base64` + `\r\n\r\n` +
    `${Utilities.base64Encode(input.body.html, Utilities.Charset.UTF_8)}` + `\r\n\r\n` +
    `--${boundaryId}--`;
  
  const newMsg = Gmail.newMessage();
  newMsg.raw = Utilities.base64EncodeWebSafe(message, Utilities.Charset.UTF_8);

  try {
    Gmail.Users.Messages.send(newMsg, "me");
    console.log("Email sent.");
  } catch (error) {
    console.log("Error: " + error);
  }
}

Further reading

  • If you wish to add attachments while sending emails via Gmail API, this post from Amit Agarwal (@labnol) has some amazing tips + code snippet
  • Some of the odd behavior that I noticed (ex: plain text data not showing up in recipients inbox) led me to this cool post from Ajay Goel (@PartTimeSnob)