在模板化 HTML(Google Apps 脚本)中提供云端硬盘存储的图像

Serving Drive-stored images in templated HTML (Google Apps Script)

我一直按照说明 让我的 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);

}

试试这个:

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

Code.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

这是我的对话框的样子:

  • 您想使用模板 HTML.
  • 将您的 Google 驱动器图像放入您的 Gmail 签名中
  • 您想使用 Google Apps 脚本实现此目的。

如果我的理解是正确的,这个答案怎么样?请将此视为几个可能的答案之一。

问题和解决方法:

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

  • If you added a photo or image from Google Drive, you'll need to share your image publicly for it to appear in your signature. Note: If you use Gmail with your work or school account, ask your administrator to let you share images publicly.
  • Search for an image, like your company logo, then get the image URL.
  • Add your own image to Google and use that URL.

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

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

那么为了把来自Google驱动器的图片放入,下面的流程如何?我认为这是 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;

注:

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

参考文献:

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