独立脚本 - Google Drive Picker - “不是一个功能”

时间:2017-12-13 12:06:01

标签: google-apps-script

我们正在使用Google工作表进行费用索赔。 在每个月末,每位员工填写他们的费用索赔,并通过表格将他们的收据附在谷歌驱动器上,然后通过电子邮件提交数据。 这已经实施并运作良好。

但是,我们目前有一份附加到我们与员工共享的每个工作表的脚本副本,因此如果代码更新,我们必须对每个文档进行更新,这非常耗时且容易出错。 / p>

我想使用一个独立的脚本,可以从与个人共享的所有Google工作表中访问。

我无法让驱动程序选择器在独立的Google脚本中运行。

这是我的 picker.html 文件

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
  <script>
    // IMPORTANT: Replace the value for DEVELOPER_KEY with the API key obtained
    // from the Google Developers Console.
    var DEVELOPER_KEY = 'purposely removed';
    var DIALOG_DIMENSIONS = {width: 600, height: 425};
    var pickerApiLoaded = false;

    /**
     * Loads the Google Picker API.
     */
    function onApiLoad() {
      gapi.load('picker', {'callback': function() {
        pickerApiLoaded = true;
      }});
     }

    /**
     * Gets the user's OAuth 2.0 access token from the server-side script so that
     * it can be passed to Picker. This technique keeps Picker from needing to
     * show its own authorization dialog, but is only possible if the OAuth scope
     * that Picker needs is available in Apps Script. Otherwise, your Picker code
     * will need to declare its own OAuth scopes.
     */
    function getOAuthToken() {
      google.script.run.withSuccessHandler(createPicker)
          .withFailureHandler(showError).getOAuthToken();
    }

    /**
     * Creates a Picker that can access the user's spreadsheets. This function
     * uses advanced options to hide the Picker's left navigation panel and
     * default title bar.
     *
     * @param {string} token An OAuth 2.0 access token that lets Picker access the
     *     file type specified in the addView call.
     */
    function createPicker(token) {
      if (pickerApiLoaded && token) {
        var picker = new google.picker.PickerBuilder()
            // Instruct Picker to display only spreadsheets in Drive. For other
            // views, see https://developers.google.com/picker/docs/#otherviews
            .addView(google.picker.ViewId.SPREADSHEETS)
            // Hide the navigation panel so that Picker fills more of the dialog.
            .enableFeature(google.picker.Feature.NAV_HIDDEN)
            // Hide the title bar since an Apps Script dialog already has a title.
            .hideTitleBar()
            .setOAuthToken(token)
            .setDeveloperKey(DEVELOPER_KEY)
            .setCallback(pickerCallback)
            .setOrigin(google.script.host.origin)
            // Instruct Picker to fill the dialog, minus 2 pixels for the border.
            .setSize(DIALOG_DIMENSIONS.width - 2,
                DIALOG_DIMENSIONS.height - 2)
            .build();
        picker.setVisible(true);
      } else {
        showError('Unable to load the file picker.');
      }
    }

    /**
     * A callback function that extracts the chosen document's metadata from the
     * response object. For details on the response object, see
     * https://developers.google.com/picker/docs/result
     *
     * @param {object} data The response object.
     */
    function pickerCallback(data) {
      var action = data[google.picker.Response.ACTION];
      if (action == google.picker.Action.PICKED) {
        var doc = data[google.picker.Response.DOCUMENTS][0];
        var id = doc[google.picker.Document.ID];
        var url = doc[google.picker.Document.URL];
        var title = doc[google.picker.Document.NAME];
        document.getElementById('result').innerHTML =
            '<b>You chose:</b><br>Name: <a href="' + url + '">' + title +
            '</a><br>ID: ' + id;
      } else if (action == google.picker.Action.CANCEL) {
        document.getElementById('result').innerHTML = 'Picker canceled.';
      }
    }

    /**
     * Displays an error message within the #result element.
     *
     * @param {string} message The error message to display.
     */
    function showError(message) {
      document.getElementById('result').innerHTML = 'Error: ' + message;
    }
  </script>
</head>
<body>
  <div>
    <button onclick='getOAuthToken()'>Select a file</button>
    <p id='result'></p>
  </div>
  <script src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
</body>
</html>

然后我得到这个: Google Drive Picker

但是当我点击选择文件按钮时,我得到了这个:

Uncaught TypeError: google.script.run.withSuccessHandler(...).withFailureHandler(...).getOAuthToken is not a function
at getOAuthToken (userCodeAppPanel:20)
at HTMLButtonElement.onclick (userCodeAppPanel:1)

我的 Code.gs 包含此功能以及处理所选文件的功能。

function getOAuthToken() {
   DriveApp.getRootFolder();
   return ScriptApp.getOAuthToken();
}

如果您需要更多信息,请与我们联系。

我已经尝试过这个解决方案而且它不起作用: Cannot call Google Script API Functions from Web App (TypeError: Cannot read property 'run' of undefined)

非常感谢任何帮助。

谢谢

如何重现问题:

  1. 转到:https://script.google.com/ 创建一个新脚本。 在Code.gs文件中输入:

    function saonopen() {
      var ui = SpreadsheetApp.getUi();
    
      // add some functions to the UI
      ui.createMenu('Menu')
          .addItem('Add Attachments', 'tsc.showPicker')
          .addToUi();
    }
    
    function showPicker() {
      var html = HtmlService.createHtmlOutputFromFile('picker.html')
          .setWidth(600)
          .setHeight(425)
          .setSandboxMode(HtmlService.SandboxMode.IFRAME);
      SpreadsheetApp.getUi().showModalDialog(html, 'Select a file');
    }
    
    function processFilesChosen(ids, titles, urls) {
      var targetSheetCost = switchTargetMonth('sheet').cost;
    
      // record the files on the target cost sheet
      for (var i in titles) {
        i = parseInt(i)
        targetSheetCost.getRange("H"+(i+3)).setFormula('=HYPERLINK("'+urls[i]+'","'+titles[i]+'")');
        targetSheetCost.getRange("I"+(i+3)).setValue(ids[i]);
        // Because of Google security update, we can not use this setSharing.
        // DriveApp.getFileById(ids[i]).setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.COMMENT);
      }
    }
    
    function getOAuthToken() {
      DriveApp.getRootFolder();
      return ScriptApp.getOAuthToken();
    }
    
  2. 添加一个新的html文件,将其命名为picker.html并将之前发布的代码放在picker.html下。

  3. 将脚本发布为API可执行文件,并记下API ID

  4. 创建一个新的Google工作表,并使用前面提到的API ID从脚本视图的资源菜单中将独立脚本导入为库。它将作为标识符 - put:

    TSC

  5. 在Code.gs文件中输入:

    function onOpen(){    tsc.saonopen() }

  6. 最后为这两个项目启用Picker和Drive API Access。

  7. Drive & Picker API Access

0 个答案:

没有答案