Hello folks,
I am having the most difficult time getting the GmailApp sendEmail() method to successfully use an existing email (e.g. a draft) that contains images inline as a template for new messages.
It seems like this is a problem, as I have found devs having this problem here and here and proposed solutions here, here, and here. Each of these solutions is 4+ years old, so perhaps they're out of date. I have been unable to use any of these solutions to replicate a success.
Currently, I'm running this code from my Google Scripts backend (thanks to Romain and Amit for publishing some helpful code on this topic):
function generateMessageFromTemplate () {
var selectedTemplate = GmailApp.getMessageById('MESSAGE_ID');
//////////////////////////////////////////////////////////////////////////////
// Get inline images and make sure they stay as inline images (via Romain Vialard)
//////////////////////////////////////////////////////////////////////////////
var emailTemplate = selectedTemplate.getBody();
var rawContent = selectedTemplate.getRawContent();
var attachments = selectedTemplate.getAttachments();
var regMessageId = new RegExp(selectedTemplate.getId(), "g");
if (emailTemplate.match(regMessageId) != null) {
var inlineImages = {};
var nbrOfImg = emailTemplate.match(regMessageId).length;
var imgVars = emailTemplate.match(/<img[^>]+>/g);
var imgToReplace = [];
if(imgVars != null){
for (var i = 0; i < imgVars.length; i++) {
if (imgVars[i].search(regMessageId) != -1) {
var id = imgVars[i].match(/realattid=([^&]+)&/);
if (id != null) {
var temp = rawContent.split(id[1])[1];
temp = temp.substr(temp.lastIndexOf('Content-Type'));
var imgTitle = temp.match(/name="([^"]+)"/);
if (imgTitle != null) imgToReplace.push([imgTitle[1], imgVars[i], id[1]]);
}
}
}
}
for (var i = 0; i < imgToReplace.length; i++) {
for (var j = 0; j < attachments.length; j++) {
if(attachments[j].getName() == imgToReplace[i][0]) {
inlineImages[imgToReplace[i][2]] = attachments[j].copyBlob();
attachments.splice(j, 1);
var newImg = imgToReplace[i][1].replace(/src="[^\"]+\"/, "src=\"cid:" + imgToReplace[i][2] + "\"");
emailTemplate = emailTemplate.replace(imgToReplace[i][1], newImg);
}
}
}
}
//////////////////////////////////////////////////////////////////////////////
GmailApp.sendEmail('test@email.com', selectedTemplate.getSubject(), '', {
attachments: attachments,
htmlBody: emailTemplate,
inlineImages: inlineImages
});
};
The Google Scripts documentation on the sendEmail() method is here.
This is the Output of this Function as Is
When I send emails from Apps Script as is, I get emails that look like this:
I've replicated the test with an old yahoo.com email account and had the exact same results as a Gmail account.
If you can help, I would be extremely grateful!
Kind regards,
Davis
imgVars[i].match(/realattid=([^&]+)&/)
function myFunction() {
var draftMessageId = "16b23268b028fb65";
var message = Gmail.newMessage();
var rawContent = Gmail.Users.Messages.get("me", draftMessageId, {format: 'raw'}).raw;
Gmail.Users.Messages.send(message, "me", Utilities.newBlob(rawContent, "message/rfc822"));
}
function sendFromDraft (id, recipient) {
// get the draft by ID and its raw content
var message = GmailApp.getMessageById(id);
var rawContent = message.getRawContent();
// determines if recipient is already defined in draft, routes accordingly, updates with new recipient
var addRecipient = 'To: <' + recipient + '>';
var recipientFromTemplate = rawContent.match(/To:.[^>]+>/);
if (recipientFromTemplate === null) {
var fromField = rawContent.match(/From:.[^>]+>/);
var updateWithRecipient = fromField + '\n' + addRecipient;
rawContent = rawContent.replace(fromField, updateWithRecipient);
} else {
rawContent = rawContent.replace(recipientFromTemplate, addRecipient);
}
var message = Gmail.newMessage();
var encodedMsg = Utilities.base64EncodeWebSafe(rawContent);
message.raw = encodedMsg;
Gmail.Users.Messages.send(message, "me", Utilities.newBlob(rawContent, "message/rfc822"));
};
function createDraftReplyWithInlineImage() {
var googleLogoUrl = "http://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif";
var googleLogoBlob = UrlFetchApp.fetch(googleLogoUrl).getBlob().setName("googleLogoBlob")
// Create a draft reply in the most recent inbox thread
GmailApp.getInboxThreads(0, 1)[0].createDraftReply("my plain text", {
htmlBody: "inline Google Logo<img src='cid:googleLogo'> image!",
inlineImages: {
googleLogo: googleLogoBlob
}
});
}