htmlgoogle-apps-scriptbase64gmailquota

Sending Google Doc as HTML with images in email body it does Not Work Anymore


This code has always worked, it displayed the HTML content of a Google Docs in an email, with formatted text and images:

function sendGoogleDocAsHTML() {
  var docId = "GOOGLE_DOCS_ID";
  var destinatario = "xxxxxx@gmail.com";
  var oggetto = "SUBJECT";
  
  var url = "https://docs.google.com/document/d/" + docId + "/export?format=html";
  var param = {
    method      : "get",
    headers     : { "Authorization": "Bearer " + ScriptApp.getOAuthToken() },
    muteHttpExceptions:true,
  };
  var html = UrlFetchApp.fetch(url, param);

  var raw = Utilities.base64EncodeWebSafe("Subject: " + oggetto + "\r\n" +
                                          "To: " + destinatario + "\r\n" +
                                          "Content-Type: text/html; charset=UTF-8\r\n\r\n" +
                                          html+"\r\n\r\n");
  var message = Gmail.newMessage();
  message.raw = raw;
  var sentMsg = Gmail.Users.Messages.send(message, 'me');

}

It hasn't shown the images for a few days. It shows them empty or it shows its base64 code (see below) which blocks all other content of the document.

<img alt="" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/...

I'm not the only one who has encountered this problem.

Are there any solutions? Thank you!


Solution

  • Also, I had the same situation with you. In this case, I used a workaround. The flow of this workaround is as follows.

    1. Retrieve the base64 data from the exported HTML data.
    2. Create each base64 data as the image file.
    3. Retrieve the hyperlink from the image file.
    4. Replace the base64 data in HTML data with the retrieved hyperlink.

    When this flow is reflected in your script, it becomes as follows.

    Sample script 1:

    In this sample, the image files are publicly shared and the webContentLinks of those images are used.

    Before you test this script, please set tempFolderId.

    function sendGoogleDocAsHTML1() {
      var docId = "GOOGLE_DOCS_ID";
      var destinatario = "xxxxxx@gmail.com";
      var oggetto = "SUBJECT";
    
      var url = "https://docs.google.com/document/d/" + docId + "/export?format=html";
      var param = {
        method: "get",
        headers: { "Authorization": "Bearer " + ScriptApp.getOAuthToken() },
        muteHttpExceptions: true,
      };
    
      // --- I modified the below script.
      var tempFolderId = "###"; // Please set the folder ID of the folder for putting the images.
      var folder = DriveApp.getFolderById(tempFolderId);
      var html = UrlFetchApp.fetch(url, param).getContentText();
      [...html.matchAll(/src\="(data:image.*?)"/g)].forEach(([, e], i) => {
        var [mimeType, data] = e.split(",");
        var temp = folder.createFile(Utilities.newBlob(Utilities.base64Decode(data), mimeType, `image${i + 1}`));
        temp.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
        var url = `https://drive.google.com/uc?export=download&id=${temp.getId()}`;
        html = html.replace(e, url);
      });
      // ---
    
      var raw = Utilities.base64EncodeWebSafe("Subject: " + oggetto + "\r\n" +
        "To: " + destinatario + "\r\n" +
        "Content-Type: text/html; charset=UTF-8\r\n\r\n" +
        html + "\r\n\r\n");
      var message = Gmail.newMessage();
      message.raw = raw;
      var sentMsg = Gmail.Users.Messages.send(message, 'me');
    }
    

    Sample script 2:

    In this sample, the thumbnail links of the images are used.

    Before you test this script, please set tempFolderId. And also, please enable Drive API at Advanced Google services. In this case, the image files are not required to be publicly shared.

    function sendGoogleDocAsHTML2() {
      var docId = "GOOGLE_DOCS_ID";
      var destinatario = "xxxxxx@gmail.com";
      var oggetto = "SUBJECT";
    
      var url = "https://docs.google.com/document/d/" + docId + "/export?format=html";
      var param = {
        method: "get",
        headers: { "Authorization": "Bearer " + ScriptApp.getOAuthToken() },
        muteHttpExceptions: true,
      };
    
      // --- I modified the below script.
      var tempFolderId = "###"; // Please set the folder ID of the folder for putting the images.
      var folder = DriveApp.getFolderById(tempFolderId);
      var html = UrlFetchApp.fetch(url, param).getContentText();
      [...html.matchAll(/src\="(data:image.*?)"/g)].forEach(([, e], i) => {
        var [mimeType, data] = e.split(",");
        var temp = folder.createFile(Utilities.newBlob(Utilities.base64Decode(data), mimeType, `image${i + 1}`));
        var url = Drive.Files.get(temp.getId()).thumbnailLink.replace("=s220", "=s1000");
        html = html.replace(e, url);
      });
      // ---
    
      var raw = Utilities.base64EncodeWebSafe("Subject: " + oggetto + "\r\n" +
        "To: " + destinatario + "\r\n" +
        "Content-Type: text/html; charset=UTF-8\r\n\r\n" +
        html + "\r\n\r\n");
      var message = Gmail.newMessage();
      message.raw = raw;
      var sentMsg = Gmail.Users.Messages.send(message, 'me');
    }
    

    Note: