首页 > 解决方案 > AppScript:如何创建上传表单?

问题描述

我正在使用 AppScript 为 Gmail 开发插件。我的目标是创建类似于下图的内容。有什么提示吗?

上传图片

标签: google-apps-scriptgmail-addons

解决方案


问题

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

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

然后,确保您Card包含一个CardSection带有一个ImageButton或小部件(已弃用,使用),该小部件对它们设置了一个TextButton操作。当使用设置 URL 以在小部件单击时打开的方法时,使用可以通过调用动态访问的当前项目的 URL(当部署为 WebApp 和 Add-on 时)。KeyValueKeyValueDecoratedTextOpenLinksetUrl(url)ScriptApp.getService().getUrl()

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

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

<!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>

步骤 3. 设置 doGet()

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

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

步骤 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;
}

步骤 5. 部署为 WebApp

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

笔记

  1. 此方法不允许您轻松更新 Ui 以显示已上传的文件,但您可以在服务器端成功处理上传文件时添加一个withSuccessHandler()调用,关闭带有表单的窗口,将状态信息保存到缓存 /google.script.run用户属性。然后,如果您将OpenLink'OnClose属性设置为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. 网络应用指南

推荐阅读