公共Google Script不会从Chrome扩展程序运行

时间:2018-06-14 15:12:23

标签: google-apps-script google-chrome-extension

我有一个谷歌脚本修改了谷歌电子表格的内容(当然它不是最终的脚本),但是我有一个问题是从谷歌浏览器扩展程序运行这个简单的脚本。 这是附加到我的电子表格的脚本:

function insertData(parameters) {
  var spreadsheet = SpreadsheetApp.openByUrl(THE_URL_OF_THE_SPREADSHEET)
  spreadsheet.getRange('A5').activate();
  spreadsheet.getCurrentCell().setValue(parameters.data1);
  spreadsheet.getRange('B5').activate();
  spreadsheet.getCurrentCell().setValue(parameters.data2);
}

我将此脚本部署为Web应用程序(以我身份执行+访问所有人,甚至匿名)和可执行API(访问任何人)。

然后我尝试使用这个JS脚本从Google Chrome扩展程序运行我的google脚本,使用我从谷歌Chrome扩展示例中获得的代码:

sendDataToExecutionAPICallback: function() {
    post({  'url': 'https://script.googleapis.com/v1/scripts/' + SCRIPT_ID + ':run',
            'callback': obj.executionAPIResponse,
            'token': 'MY_GENERATED_TOKEN'
            'request': {
                'function': 'insertData',
                'parameters': {                 
                    'data1': 'ok1 from script',
                    'data2': 'ok2 from script'
                },
                'devMode': true
            }
        });
}, 

executionAPIResponse: function(response){
    var obj = this;
    var info;
    if (response.response.result.status == 'ok'){
        info = 'Data has been entered';
    } else {
        info = 'Error...';
    }
    obj.displayMessage(info);
}

我有这个帖子功能:

function post(options) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
            // JSON response assumed. Other APIs may have different responses.
            options.callback(JSON.parse(xhr.responseText));
        } else if(xhr.readyState === 4 && xhr.status !== 200) {
            console.log('post', xhr.readyState, xhr.status, xhr.responseText);
        }
    };
    xhr.open('POST', options.url, true);
    // Set standard Google APIs authentication header.
    xhr.setRequestHeader('Authorization', 'Bearer ' + options.token);
    xhr.send(JSON.stringify(options.request));
}

当我调用sendDataToExecutionAPICallback函数时,我收到了这个身份验证错误:

"error": {
    "code": 401,
    "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "status": "UNAUTHENTICATED"
}

EDIT1: 生成令牌并将其添加到我的代码后,我有这个错误:

 "error": {
    "code": 403,
    "message": "The caller does not have permission",
    "status": "PERMISSION_DENIED"
  }

1 个答案:

答案 0 :(得分:0)

我想提出这两种方法。请选择其中一个。

方法1:Execution API (Method: scripts.run of Apps Script API)

要使用Execution API运行这些功能,请执行以下流程。

  1. 创建项目(独立或绑定脚本)。
  2. 将GAS脚本复制并粘贴到项目中。在这种情况下,您的GAS脚本未被修改。
  3. Deploy API executable.作为示例,选择“仅限我自己”作为“谁有权访问脚本”
  4. 在API控制台上启用Apps Script API。
  5. 使用保存按钮,将项目保存在脚本编辑器中。这是一个重点。这样,脚本就会反映到已部署的执行API。
  6. 从此项目的客户端ID和客户端密钥中检索访问令牌。
    • 请在范围中加入https://www.googleapis.com/auth/drivehttps://www.googleapis.com/auth/drive.scriptshttps://www.googleapis.com/auth/spreadsheetshttps://www.googleapis.com/auth/drive可能不会用于此情况。
  7. 请将检索到的访问令牌用于以下修改后的脚本。

    Javascript:
    sendDataToExecutionAPICallback: function() {
      post({
        'url': 'https://script.googleapis.com/v1/scripts/' + SCRIPT_ID + ':run',
        'callback': obj.executionAPIResponse,
        'token': 'MY_GENERATED_TOKEN',
        'request': {
          'function': 'insertData',
          'parameters': [{
            'data1': 'ok1 from script',
            'data2': 'ok2 from script',
          }],
          'devMode': true,
        }
      });
    },
    
    executionAPIResponse: function(response) {
      var info;
      if (!response.error) {
        info = 'Data has been entered';
      } else {
        info = 'Error...';
      }
      obj.displayMessage(info);
    },
    
    function post(options) {
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function() {
        if (xhr.readyState === 4 && xhr.status === 200) {
          // JSON response assumed. Other APIs may have different responses.
          options.callback(JSON.parse(xhr.responseText));
        } else if(xhr.readyState === 4 && xhr.status !== 200) {
          console.log('post', xhr.readyState, xhr.status, xhr.responseText);
        }
      };
      xhr.open('POST', options.url, true);
      // Set standard Google APIs authentication header.
      xhr.setRequestHeader('Authorization', 'Bearer ' + options.token);
      xhr.setRequestHeader('Content-Type', 'application/json');
      xhr.send(JSON.stringify(options.request));
    }
    

    注意:

    • 在我的环境中,此修改后的脚本有效。但如果在您的环境中,这不起作用,请您尝试方法2吗?

    方法2:Web Apps

    从您的问题和评论中,我担心可能无法使用访问令牌。所以我想提出使用Web Apps的方法。在这种情况下,您可以在没有访问令牌的情况下运行该功能。但是要运行的密码密钥用于有效负载。

    使用此功能时,请将网络应用部署为"Execute the app as:" : Me"Who has access to the app:": Anyone, even anonymous。如果您想了解Web Apps的详细信息,请查看here

    在此示例脚本中,它不使用xhr.setRequestHeader('Authorization', 'Bearer ' + options.token);的{​​{1}}。

    修改后的脚本如下。请将GAS放到部署Web应用程序的脚本编辑器中。

    加油站 :
    post()
    Javascript:
    function doPost(e) {
      var p = JSON.parse(e.postData.contents);
      if (p.password == 'samplePassword') {
        insertData(p.parameters);
        return ContentService.createTextOutput("ok");
      } else {
        return ContentService.createTextOutput("error");
      }
    }
    
    function insertData(parameters) {
      var spreadsheet = SpreadsheetApp.openByUrl(THE_URL_OF_THE_SPREADSHEET);
      spreadsheet.getRange('A5').activate();
      spreadsheet.getCurrentCell().setValue(parameters.data1);
      spreadsheet.getRange('B5').activate();
      spreadsheet.getCurrentCell().setValue(parameters.data2);
    }
    

    注意:

    • 如果您使用Web Apps,在将GAS脚本复制并粘贴到脚本编辑器后,请将Web Apps重新部署为新版本。通过此,反映了最新的脚本。

    在我的环境中,我可以确认两种方法都有效。如果这些对你的情况没用,我很抱歉。