Export Multiple Gmail Threads as PDFs or One Single PDF: GAS111
Introduction
In this Google Apps Script project, I am sharing a solution to export multiple Gmail threads into multiple PDFs or you can have the option to merge them into one single PDF. Check this video for the details, tips, demos.
Source Code
Make a Copy or Check on Github
Utility Functions (1)
Create a base64 encoded image from an image blob so we can use it in the html file for PDF print.
/**
* @param {GoogleAppsScript.Base.Blob} blob
*/
const _toBase64ImageUri_ = (blob) => {
const encodedData = Utilities.base64Encode(blob.getBytes());
return `data:${blob.getContentType()};base64,${encodedData}`;
};
Core Functions (2)
Convert a Gmail thread into html text body with image links replaced with base64 encoded image data for PDF creation.
- name: createThreadContent_
- thread: a Gmail Thread object
- printMessageOnly: Weather include the thread header info like subject, from, cc, bcc
- return html body for PDF creation in next core function
/**
* @param {GoogleAppsScript.Gmail.GmailThread} thread
*/
const createThreadContent_ = (thread, printMessagesOnly = false) => {
const content = [];
const imageLinks = [];
thread.getMessages().forEach((message) => {
let body = message.getBody();
const images = message
.getAttachments()
.filter((v) => v.getName() === "image.png");
if (images.length) {
const cids = body.match(/img src="cid:[^"]+" /gi);
if (cids) {
cids.forEach((cid, index) => {
const image = images[index];
if (!image) return;
const uri = _toBase64ImageUri_(image);
body = body.replace(cid, `img src="${uri}"`);
});
}
}
const links = body.match(/img[^\<\>]+src="http[^"]+"/gi);
if (links) {
const urls = links.map((v) => v.split("src=")[1].slice(1, -1));
imageLinks.push(...urls);
}
if (!printMessagesOnly) {
const date = message.getDate().toLocaleString();
const subject = message.getSubject();
const from = message.getFrom();
const to = message.getTo();
const cc = message.getCc();
const bcc = message.getBcc();
content.push(`<div><strong>Subject: ${subject}</strong></div>`);
content.push(`<div>Date: ${date}</div>`);
content.push(`<div>From: ${from}</div>`);
content.push(`<div>To: ${to}</div>`);
cc && content.push(`<div>CC: ${cc}</div>`);
bcc && content.push(`<div>BCC: ${bcc}</div>`);
}
content.push(`<br/><div>${body}</div><br/>`);
});
let htmlBody = content.join("");
if (imageLinks.length) {
const requests = [...new Set(imageLinks)].map((url) => {
return {
url,
method: "GET",
};
});
UrlFetchApp.fetchAll(requests).forEach((response, index) => {
const blob = response.getBlob();
const uri = _toBase64ImageUri_(blob);
const url = requests[index].url;
htmlBody = htmlBody.replace(new RegExp(url, "g"), uri);
});
}
return htmlBody;
};
Convert html body as PDF on Google Drive. It will create a temporary html file then convert the html file into PDF, the temporary html file will be trashed after the PDF creation.
- body : the html body content
- name : the output pdf file name
- return a PDF file on the Google Drive
const htmlToPdf_ = (body, name) => {
const head = [
"<head>",
'<meta charset="UTF-8">',
'<meta name="viewport" content="width=device-width, initial-scale=1">',
"</head>",
].join("");
const html = [
"<!DOCTYPE html>",
'<html lang="en">',
head,
`<body>${body}</body>`,
"</html>",
].join("");
const file = DriveApp.createFile(name, html, "text/html").setName(
`${name}.html`,
);
const pdf = DriveApp.createFile(file.getAs("application/pdf")).setName(
`${name}.pdf`,
);
file.setTrashed(true);
return pdf;
};
GoogleAppsScript Playlist
Links
Comments
Post a Comment