AppScript:如何创建上传表单?

mtl*_*eis 0 google-apps-script gmail-addons

我正在使用 AppScript 开发 Gmail 插件。我的目标是创建类似于下图的东西。任何提示?

上传图片

Ole*_*ter 5

问题

在 Gmail 插件中上传文件。简而言之——不完全是。Gmail 附加组件使用CardService类来构建用户界面- 它没有file输入类型,也没有任何拖放功能。但是有一个解决方法。

步骤 1. 创建触发器小部件

然后,确保您Card包含一个CardSection带有ImageButton,TextButtonKeyValue小部件(KeyValue已弃用,使用DecoratedText),并OpenLink在其上设置了操作。当使用setUrl(url)设置 URL 以在小部件单击时打开的方法时,使用可以通过ScriptApp.getService().getUrl()调用动态访问的当前项目的 URL(同时部署为 WebApp 和附加组件时)。

步骤 2. 创建文件提交表单

在 Add-on 项目中,创建一个 Html 文件来处理文件上传。您可以使用示例之一或创建自己的实现。示例文件使用FileReaderWeb API 来处理提交的文件(请注意,Google Apps 脚本中的客户端到服务器通信需要阻止submit事件处理程序并goolge.script.run仅通过API调用服务器端函数)。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <form>
      <input name="file" type="file" />
      <button id="submit" type="submit">Save file</button>
    </form>
    <script>
      var form = document.forms[0];
      
      form.addEventListener('submit', (event) => {
        event.preventDefault();
        
        var file = form.elements[0].files[0];
        
        var reader = new FileReader();
        reader.readAsArrayBuffer(file);
        reader.onload = () => { 
          var buffer = reader.result;
          
          var data = Array.from(new Int8Array(buffer));
          
          google.script.run.withSuccessHandler((server) => {
            top.window.close();
          }).saveFile(data,file.name,file.type);
        };
      });
  </script>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

步骤 3. 设置 doGet()

在您的 WebApp 代码中,添加doGet()将显示我们在第 2 步中创建的文件上传表单所需的函数。它可以像几行代码一样简单(只需确保返回由 解析的 html 文件HtmlService):

function doGet() {
  var html = HtmlService.createHtmlOutputFromFile('file name from step 2');
  return html;
}
Run Code Online (Sandbox Code Playgroud)

步骤 4. 处理文件上传

在您的 WebApp 代码中,添加将接收文件数据的处理程序(此示例假定您将其读取为 byte[],有关详细信息,请参阅步骤 2)。

function saveFile(upload,name,mime) {
  var blob = Utilities.newBlob(upload,mime,name);
  
  var file = DriveApp.createFile(blob);
  Logger.log(file.getUrl()) //test upload;

  //handle file as needed;
  return;
}
Run Code Online (Sandbox Code Playgroud)

步骤 5. 部署为 WebApp

最后,您必须将您的附加组件部署为 WebApp(或捆绑在一起)和附加组件。假设您已经为加载项配置了清单,请转到“发布”菜单,选择“部署为 Web 应用程序”,创建部署并允许任何人访问。

笔记

  1. 此方法不允许您轻松更新 Ui 以显示哪些文件已上传,但您可以在服务器端成功处理上传的文件时添加withSuccessHandler()调用google.script.run,关闭带有表单的窗口,将状态信息保存到缓存 /用户属性。然后,如果您将OpenLinkOnClose属性设置为RELOAD_ADD_ON(参见步骤 1),您将能够有条件地更新 Ui 以通知用户上传成功。
  2. 更新:在 Tanaike 发表评论后,我重新设计了上传过程以更好地处理文件:将读取的二进制字符串文件更改为ArrayBuffer转换为Int8Array并作为Array实例上传。
  3. 当前问题是.g*文件上传(尽管传输正确)。解决后会更新答案。

参考

  1. OpenLink参考
  2. FileReaderMDN 上的Web API参考
  3. newBlob()方法引用Utilities类);
  4. GAS指南中的客户端到服务器通信;
  5. 在 GAS指南中创建和提供 HTML ;
  6. 网络应用指南

  • 在您的脚本中,可以上传文本文件。但是当二进制文件(例如可以用zip文件测试)上传时,由于字符编码的问题,数据与原始文件不同。例如,当数据在 Google Drive 中创建为文件时,无法打开该文件。请小心这一点。 (2认同)
  • 嗨田池!确实,最初的脚本远非完美,谢谢!我已经更新它以正确处理文件,上传测试二进制文件以及文本和图像文件 - 工作正常。 (2认同)