This is a sample script for sending multiple emails using the batch request with Gmail API using Google Apps Script. When multiple emails are sent using "GmailApp.sendEmail" and "MailApp.sendEmail", a loop is used. But in this case, the process cost becomes high. In this post, I would like to introduce the sample script for reducing the process cost under this situation. Gmail API can be requested with the batch request. The batch request can be processed with the asynchronous process. By this, I thought that the process cost for sending multiple emails. So, this sample script sends multiple emails using the batch request with Gmail API.
This sample script uses a Google Apps Script library of BatchRequest. So, before you use this script, please install a Google Apps Script library of BatchRequest. You can see how to install this library at here.
And, please enable Gmail API at Advanced Google services.
And please set obj
and if you want to attachment files, please set the file IDs of attachmentFileIds
.
const convert_ = ({
to,
cc,
bcc,
fromName,
fromEmail,
subject,
textBody,
htmlBody,
attachments,
}) => {
if (!to) throw new Error("Please set 'to'.");
const obj = [`MIME-Version: 1.0`, `To: ${to}`];
if (cc) obj.push(`CC: ${cc}`);
if (bcc) obj.push(`BCC: ${bcc}`);
if ((fromName && fromEmail) || fromEmail) {
obj.push(
fromName && fromEmail ? `From: "${fromName}" <${fromEmail}>` : fromEmail
);
}
const boundary1 = "boundaryboundary001";
const boundary2 = "boundaryboundary002";
if (attachments && attachments.length > 0) {
obj.push(
`Subject: =?UTF-8?B?${Utilities.base64Encode(
subject || "",
Utilities.Charset.UTF_8
)}?=`,
`Content-Type: multipart/mixed; boundary=${boundary1}`,
``,
`--${boundary1}`,
`Content-Type: multipart/alternative; boundary=${boundary2}`,
``,
`--${boundary2}`,
`Content-Type: text/plain; charset=UTF-8`,
``,
textBody || "",
`--${boundary2}`,
`Content-Type: text/html; charset=UTF-8`,
`Content-Transfer-Encoding: base64`,
``,
Utilities.base64Encode(htmlBody || "", Utilities.Charset.UTF_8),
`--${boundary2}--`
);
attachments.forEach((f) => {
obj.push(
`--${boundary1}`,
`Content-Type: ${f.mimeType}; charset=UTF-8; name="${f.filename}"`,
`Content-Transfer-Encoding: base64`,
``,
f.data,
`--${boundary1}`
);
});
} else {
obj.push(
`Subject: =?UTF-8?B?${Utilities.base64Encode(
subject || "",
Utilities.Charset.UTF_8
)}?=`,
`Content-Type: multipart/alternative; boundary=${boundary1}`,
``,
`--${boundary1}`,
`Content-Type: text/plain; charset=UTF-8`,
``,
textBody || "",
`--${boundary1}`,
`Content-Type: text/html; charset=UTF-8`,
`Content-Transfer-Encoding: base64`,
``,
Utilities.base64Encode(htmlBody || "", Utilities.Charset.UTF_8),
`--${boundary1}`
);
}
return Utilities.base64EncodeWebSafe(obj.join("\r\n") + "--");
};
// Please run this function.
function main() {
const attachmentFileIds = [
"### file ID1 of attachment file ###",
"### file ID1 of attachment file ###",
];
const attachmentFiles = attachmentFileIds.map((id) => {
const file = DriveApp.getFileById(id);
return {
filename: file.getName(),
mimeType: file.getMimeType(),
data: Utilities.base64Encode(file.getBlob().getBytes()),
};
});
const obj = [
{
to: "### email address 1 ###",
cc: "###",
fromEmail: "###",
fromName: "###",
subject: "sample mail 1",
textBody: "Hello World",
htmlBody: "<p>Hello World</p>",
},
{
to: "### email address 2 ###",
bcc: "###",
subject: "sample mail 2",
textBody: "Hello World",
attachments: attachmentFiles,
},
];
const raws = obj.map((e) => convert_(e));
const requests = raws.map((raw) => ({
method: "POST",
endpoint: "https://gmail.googleapis.com/gmail/v1/users/me/messages/send",
requestBody: { raw: raw },
}));
const res = BatchRequest.EDo({
batchPath: "batch/gmail/v1",
accessToken: ScriptApp.getOAuthToken(),
requests: requests,
});
console.log(res);
}
- When you run this script, 2 emails are sent.
-
When you change the endpoint from
https://gmail.googleapis.com/gmail/v1/users/me/messages/send
tohttps://gmail.googleapis.com/gmail/v1/users/me/drafts
, the draft emails are created. -
When you use this script, please be careful about the limitation of Gmail API. Ref1 and Ref2
-
This is a simple sample script. So please modify it for your actual situation.
- Batching Requests for Gmail API
- BatchRequest of Google Apps Script library
- Method: users.messages.send
- I answered this sample script at this thread of Stackoverflow.