javascript - 使用 Apps Script API 的 Chrome 应用

标签 javascript google-apps-script google-chrome-app

今天遇到了另一个障碍,在我编写用于记录用户项目时间的桌面 Chrome 应用程序的道路上。

我正在尝试做(但失败了)的是使用 Apps 脚本 API 访问保留信息(项目编号)的 Google 工作表,我想在我的 Chrome 应用程序用户界面中填充一个下拉列表。

更新: 我重新措辞以切中要点,并清楚地说明我的问题是什么。

我似乎无法实现的是从我的 chrome 应用程序调用 Apps 脚本函数。我读过这个Execution API但似乎仍然无法着色。由于某些原因,我不断在我的控制台中收到“未捕获的 ReferenceError:gapi 未定义”。

我设法做到的是在 Developers Console 中将 Apps 脚本和 Chrome 应用程序置于同一个项目名称下。不确定是否需要它,但认为它可能只对 1 个 Oauth2 请求有帮助。

我的脑袋是不是缺了什么?

如有任何帮助或想法,我们将不胜感激。

这是我的 manifest.json

{
  "manifest_version": 2,
  "name": "TimeSheet",
  "description": "Small and easy desktop app for entering time spent on project files",
  "version": "0.1.0",
  "icons": {
    "128": "icon_128.png"
  },
  "app": {
    "background": {
      "scripts": ["background.js"]
    }
  },
  "permissions": [
    "identity",
    "app.window.alwaysOnTop"
    ],
  "oauth2": {
    "client_id": "clientid.apps.googleusercontent.com",
    "scopes": [
      "https://www.googleapis.com/auth/drive",
      "https://www.googleapis.com/auth/spreadsheets"
      
      ]
  },
  "key": "very long string"
}

这是在我的 main.js 中运行的 Oauth2 代码的一部分

//This code confirms Oauth2 for access to google drive and related files

window.onload = function(){
  
  document.querySelector("#Oauth2").addEventListener("click", function(){
    
    chrome.identity.getAuthToken({"interactive": true}, function(token){
      console.log(token);
      
    });
  });

};

// ID of the script to call. Acquire this from the Apps Script editor,
// under Publish > Deploy as API executable.
var scriptId = "blah";
// Create execution request.
var request = {
    'function': 'getProjectNumbers',
};

// Make the request.
var op = gapi.client.request({
    'root': 'https://script.googleapis.com',
    'path': 'v1/scripts/' + scriptId + ':run',
    'method': 'POST',
    'body': request
});
// Log the results of the request.
op.execute(function(resp) {
  if (resp.error && resp.error.status) {
    // The API encountered a problem before the script started executing.
    console.log('Error calling API: ' + JSON.stringify(resp, null, 2));
  } else if (resp.error) {
    // The API executed, but the script returned an error.
    var error = resp.error.details[0];
    console.log('Script error! Message: ' + error.errorMessage);
    if (error.scriptStackTraceElements) {
      // There may not be a stacktrace if the script didn't start executing.
      console.log('Script error stacktrace:');
      for (var i = 0; i < error.scriptStackTraceElements.length; i++) {
        var trace = error.scriptStackTraceElements[i];
        console.log('\t' + trace.function + ':' + trace.lineNumber);
      }
    }
  } else {
    // Here, the function returns an array of strings.
    var projectNumbers = resp.response.result;
    console.log('Project numbers in spreadsheet:');
    projectNumbers.forEach(function(name){
      console.log(name);
    });
  }
});

这是应用脚本代码:

var projectDatabaseKey = 'blah'; //Project Database Sheet spreadsheet key
var pprojectDatabaseSheet = 'Project Database'; //Project Database  Sheet spreadsheet sheet

//Function to revieve data of project numbers for drop down list
function getProjectNumbers() {
  return SpreadsheetApp
   .openById(projectDatabaseKey).getSheetByName(projectDatabaseSheet)
   .getRange("A2:A" + (SpreadsheetApp.openById(projectDatabaseKey).getSheetByName(projectDatabaseSheet).getLastRow()))
   .getValues();
}

我真的不确定如何使用 Oauth2 token 以及如何将它应用到应用程序脚本。

更新

好的,我已经尝试在不同的庄园调用应用程序脚本,我今天尝试的是使用 gapi-chrome-apps.js 库来完成 oauth2 工作。

现在我的问题是我得到了这个错误,这可能是我猜测的一系列事情:

POST https://www.googleapis.com/v1/scripts/blahblah:run 404 ()

gapi.client.request @ VM80 gapi-chrome-apps.js:105

getSheetsList @ gapiCallback.js:17

(anonymous function) @ gapiCallback.js:49

callbackWrapper @ VM80 gapi-chrome-apps.js:68

target.(anonymous function) @ extensions::SafeBuiltins:19

safeCallbackApply @ extensions::sendRequest:21

handleResponse @ extensions::sendRequest:72

这个错误来自 gapi-chrome-apps.js 脚本:

Uncaught SyntaxError: Unexpected token N in JSON at position 0

真的不确定是什么原因造成的,这是我更新的代码:

//get listof sheets in spreadsheet
function getSheetsList(){
  var scriptId = "blahblah";
  // Initialize parameters for function call.
  var sheetId = "blahblah";
  // Create execution request.
  var requests = {
      'function': 'getSheetNames',
      'parameters': [sheetId],
      'devMode': true   // Optional.
  };
  // Make the request.
  gapi.client.request({
      'root': 'https://script.googleapis.com',
      'path': 'v1/scripts/' + scriptId + ':run',
      'method': 'POST',
      'body': requests,
      'callback': printSheetsList
  });
}
// Log the results of the request.
function printSheetsList(resp) {
  if (resp.error && resp.error.status) {
    // The API encountered a problem before the script started executing.
    console.log('Error calling API: ' + JSON.stringify(resp, null, 2));
  } else if (resp.error) {
    // The API executed, but the script returned an error.
    var error = resp.error.details[0];
    console.log('Script error! Message: ' + error.errorMessage);
  } else {
    // Here, the function returns an array of strings.
    var sheetNames = resp.response.result;
    console.log('Sheet names in spreadsheet:');
    sheetNames.forEach(function(name){
    console.log(name);
    });
  }
}
//Prompts the user for authorization and then proceeds to 
function authorize(params, callback) {
  gapi.auth.authorize(params, function(accessToken) {
    if (!accessToken) {
      console.log("Error getting authorization");
    } else {
      callback();
    }
  });
}
function gapiIsLoaded() {
  var params = { 'immediate': true };
  if (!(chrome && chrome.app && chrome.app.runtime)) {
    params.scope = "https://www.googleapis.com/auth/drive";
    params.client_id = "blahblah";
    gapi.auth.init(authorize.bind(null, params, getSheetsList));
  } else {
    authorize(params, getSheetsList);
  }
}

最佳答案

使用传统的 GAPI 是行不通的,因为它会动态加载更多外部脚本和应用程序 are not allowed to do that .

一种可能的解决方案是在 sandboxed page 中运行 GAPI 代码,可以克服远程代码限制。然而,这很麻烦,因为您需要使用 postMessage 来回传递数据。

另一种方法是尝试使用 Google 提供的库 gapi-chrome-apps.js ,适用于 Chrome 应用程序(并使用 chrome.identity 来管理 OAuth)——但请注意以下评论:

This library is likely not suitable for use without additional modifications.

关于javascript - 使用 Apps Script API 的 Chrome 应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36810966/

相关文章:

java - 将文件从我的计算机上的 "Synced Folder"移动到 Google Drive 上的其他文件夹

javascript - Chrome扩展异步问题

google-chrome-extension - "Broad host permissions"错误,尽管我的主机权限很窄

javascript - Chrome 存储集中出现意外字符串

javascript - iframe跨域访问

mysql - MySQL查询错误“非法小时值”导致Google Apps脚本中的循环和写入问题

javascript - 在 javascript 中,如果 : x = []; x. push(x); 会发生什么?

google-apps-script - 将值和格式从工作表复制到新的谷歌电子表格文档?

javascript - 更改一个选择选项会更改许多其他选项(JavaScript、JQuery)

javascript - 无法在包布局上显示工具提示