【问题标题】:Serving Drive-stored images in templated HTML (Google Apps Script)以模板化 HTML 格式提供云端硬盘存储的图像(Google Apps 脚本)
【发布时间】:2020-01-18 13:18:49
【问题描述】:

我一直按照说明 here 让我的 Gmail 签名模板将存储在 Google 云端硬盘上的图像显示为徽标。

目标是让图像标签的'src'属性指向图像并内联显示。在上面链接的答案中,图像 blob 是使用 UrlFetchApp 获取的。在我的代码中,我调用 DriveApp 的 openById(id) 方法来打开图像文件并获取 blob。

但是,这两种方法似乎都不起作用。只有当我将“src”直接指向图像 URL 时,它才会加载图像。我尝试同时使用 base64Encodebase64EncodeWebSafe 但签名只显示图像的空容器。

我在这里错过了什么?

HTML 模板

<table>
<tbody>
 <tr>
  <td> 
    <img src="{{config.imgData}}" alt="my logo">
  </td>
   <td>
    <table>
     <tbody>
       <tr><td> My name is {{config.name}} </td> </tr>
       <tr><td> www.example.com </td> </tr>
     </tbody>
    </table>
   </td>
  </tr>

</tbody>
</table>

GS 代码

var config = {
  name: "Anton",
  imgData: ""
}

function updateSignature() {

var imgFileId = "DRIVE FILE ID";

var imgFile = DriveApp.getFileById(imgFileId);

var imgBlob = imgFile.getBlob().getAs("image/png"); //getAs doesn't change anything

//Get content type and bytes
var contentType = imgBlob.getContentType();
var imgBytes = imgBlob.getBytes();
var imgData = contentType + ";base64," + Utilities.base64Encode(imgData);
config.imgData = imgData;


  var alias = Gmail.Users.Settings.SendAs.get("me", myEmail);
 //Get signature html as a string
  var templateString = HtmlService.createHtmlOutputFromFile("signature_template").getContent();

   for (var configKey in config) {
    if (config.hasOwnProperty(configKey)) {
       templateString = templateString.replace("{{config." + configKey + "}}", config[configKey]);
    }  
  }

 var finalTemplate = HtmlService.createHtmlOutput(templateString).getContent();

  alias.signature = finalTemplate;
  Gmail.Users.Settings.SendAs.update(alias, "me", myEmail);

}

【问题讨论】:

    标签: google-apps-script gmail web-standards


    【解决方案1】:
    • 您希望使用 HTML 模板将 Google 云端硬盘的图片添加到 Gmail 签名中。
    • 您希望使用 Google Apps 脚本实现此目的。

    如果我的理解是正确的,那么这个答案呢?请认为这只是几个可能的答案之一。

    问题和解决方法:

    当我检查the official document时,我看到签名的图像如下。

    • 如果您从 Google 云端硬盘添加了照片或图片,则需要公开分享您的图片才能显示在您的签名中。注意:如果您通过工作或学校帐户使用 Gmail,请让您的管理员允许您公开分享图片。
    • 搜索图片,例如您的公司徽标,然后获取图片 URL。
    • 将您自己的图片添加到 Google 并使用该网址。

    data:image/png;base64,###用于图片标签的src时,发现Gmail.Users.Settings.SendAs.update()更新的签名不包含src属性。当使用https://### 时,使用Gmail.Users.Settings.SendAs.update() 更新的签名包含src 属性。

    从以上情况来看,data:image/png;base64,###可能无法用于签名的图片标签src。这可能是规范。

    那么,为了从 Google Drive 中放图片,下面的流程如何?我认为这是the official document处显示的方法。

    1. 在 Google 云端硬盘中公开分享图片。
    2. 将图片的 URL 放入签名中。

    修改后的脚本:

    当你的脚本被修改后,接下来的修改呢?

    发件人:

    var imgBlob = imgFile.getBlob().getAs("image/png"); //getAs doesn't change anything
    
    //Get content type and bytes
    var contentType = imgBlob.getContentType();
    var imgBytes = imgBlob.getBytes();
    var imgData = contentType + ";base64," + Utilities.base64Encode(imgData);
    

    收件人:

    imgFile.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
    var imgData = "https://drive.google.com/uc?export=download&id=" + imgFileId;
    

    注意:

    • 手动将图片放入签名时,使用上述网址,文件自动公开分享。
    • 顺便说一句,在您当前的脚本中,var imgData = contentType + ";base64," + Utilities.base64Encode(imgData); 中的imgData 可能是imgBytes。而当您想使用base64数据将图像放到src时,请使用src="data:image/png;base64,###"。在您的脚本中,使用了src="image/png;base64,###"

    参考资料:

    如果我误解了您的问题并且这不是您想要的方向,我深表歉意。

    【讨论】:

      【解决方案2】:

      试试这个:

      您需要做的就是将默认图像文件 ID 添加到函数 convertImageToDataURI,然后启动对话框。或者,您也可以部署为 webapp。出于我的目的,我通常将图像的大小减小到小于 1000 像素宽并保持纵横比小于 1。

      代码.gs:

      function onOpen() {
        SpreadsheetApp.getUi().createMenu('My Tools')
        .addItem('Display Dialog', 'displayDialog')
        .addItem('Get File Ids from FolderId','getFileIds')
        .addToUi();
      }
      
      function convertImageToDataURI(fileId) {
        var fileId=fileId||'default image file id';
        if(fileId) {
          var file=DriveApp.getFileById(fileId);
          var blob=file.getBlob();
          var dataUri='data:' + blob.getContentType() + ';base64,' + Utilities.base64Encode(blob.getBytes());
          return dataUri;
        }
      }
      
      function include(filename) {
        return HtmlService.createHtmlOutputFromFile(filename).getContent();
      }
      
      function displayDialog() {
        var userInterface=HtmlService.createTemplateFromFile('image').evaluate();
        SpreadsheetApp.getUi().showModelessDialog(userInterface, "For the Birds");
      }
      
      function doGet() {
        return HtmlService.createTemplateFromFile('image').evaluate();
      }
      

      resources.html:(本例不需要)

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
      <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
      

      css.html:(本例不需要)

      <style>
      body {background-color:#ffffff;}
      input{padding:2px;margin:2px;}
      </style>
      

      script.html:(本例不需要)

      <script>
        console.log('script.html code');
      </script>
      

      content.html 为空

      images.html:

      <!DOCTYPE html>
      <html>
        <head>
          <base target="_top">
          <?!= include('resources') ?>
          <?!= include('css') ?>
        </head>
        <body>
          <img id="birds" src="<?!=convertImageToDataURI()?>" width="320" />
          <?!= include('content') ?>
          <?!= include('script') ?>
        </body>
      </html>
      <html><head>
      

      如果您需要一个工具来获取文件夹中图像的文件 ID,请尝试使用此功能:

      function getFileIds() {
        var resp=SpreadsheetApp.getUi().prompt("Folder Id","Enter Folder Id", SpreadsheetApp.getUi().ButtonSet.OK_CANCEL);
        if(resp.getSelectedButton()==SpreadsheetApp.getUi().Button.OK && resp.getResponseText().length>0) {
          try{
          var folder=DriveApp.getFolderById(resp.getResponseText());
          var files=folder.getFiles();
          var html='<style>td,th{border:1px solid black;padding:2px 5px;}</style><table><tr><th>File Name</th><th>File Id</th><th>Type</th></tr>';
          while(files.hasNext()) {
            var file=files.next();
            html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>', file.getName(),file.getId(),file.getMimeType());
          }
          html+='</table><br /><input type="button" value="Close" onClick="google.script.host.close();" />';
          var userInterface=HtmlService.createHtmlOutput(html).setWidth(800).setHeight(400);
          SpreadsheetApp.getUi().showModelessDialog(userInterface, "Files in Folder");
          }
          catch(e){SpreadsheetApp.getUi().alert(e);}
        }else{
          SpreadsheetApp.getUi().alert("Invalid or Missing Inputs: No FileId Provided");
        }
      }
      

      Scriplets

      Web Apps

      这是我的对话框的样子:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-10
        • 1970-01-01
        • 2019-02-28
        • 1970-01-01
        • 1970-01-01
        • 2017-07-13
        • 1970-01-01
        • 2017-09-21
        相关资源
        最近更新 更多