如何使用“exec”网址而不是“dev”网址从 Google Apps 脚本创建 webhook。执行返回 403 错误

Chu*_*Keg 7 javascript webhooks google-sheets google-apps-script trello

一直在尝试在 Google Sheets Apps 脚本中设置一个 Webhook,该脚本将在 Trello 中进行更改时做出响应。为此,建议将脚本部署为 Web 应用程序(需要返回 HTML 的doGet函数)以创建用于接收和请求doPost的 URL 目标。postget

Web 应用程序创建两个 URL,一个以 结尾/dev并用于开发目的(不响应post请求),另一个以 结尾/exec用于正常访问。

我已经部署了 Web 应用程序,两个 URL 都可以在我的浏览器中访问和响应(可以在不登录的情况下以隐身方式查看 exec),应用程序发布为以“我”身份执行,并且可以由“任何人,甚至匿名”访问。

我已经能够成功使用下面的代码为/devURL 创建网络挂钩,但不是/execURL。

function create() {
  var url = 'https://api.trello.com/1/tokens/ae6ebe60b45abcd2d4aa945c9ab4c4571bd6b6f7856b1df0cd387fbffc649579/webhooks/?key=a211f4aca7fb3e521d652730dd231cb6'

  var payload = { 
    "key": "xxxxxxxxxxx",
    "token" : "xxxxxxxxxxxxx",
    "callbackURL": "https://script.google.com/macros/s/AKfycbw51TYGWHe95hKdcAs4l7E2eg0AtBi8e48lf_iafKYI/dev",
    "idModel":"xxxxxxxx",
    "description": "GW Test"  
  }
  var options = {"method" : "post",
                 "payload" : payload,
                 "muteHttpExceptions": true
                 };

  var response = UrlFetchApp.fetch(url,options);
}
Run Code Online (Sandbox Code Playgroud)

使用该/devURL 时,我可以看到 Trello 中添加了一个新的 Web-hook,但该/execURL 返回以下错误:

{“message”:“URL(https://script.google.com/macros/s/AKfycbxo90ucgXXz7MG6Z3wb2KD-PJn3akGKoelXLJ2mkg/exec)未返回200状态代码,得到403”,“错误”:“错误”}

因此 Trello 期望返回“200 状态代码”来验证脚本是否正常运行,但收到​​的却是 403。让我困惑的是为什么使用时不会发生这种情况/dev?我怎样才能让它接受我的/exec网址?

更多信息:

当我使用链接或直接在浏览器中加载 URL时,我可以让我的代码响应put 和请求。它通过填充电子表格中的前六 (6) 个单元格来做出响应。get

我已重新发布为新版本并验证代码仍然有效,但我仍然收到来自 Trello 的错误消息,说他们收到了 403 而不是 200 代码。我只在使用/execnot时收到此错误/dev。由于/dev无法接收post请求,因此不会有帮助:(

下面是示例的其余部分:


function doSomething() {
  var values = [11,12];
  SpreadsheetApp.getActiveSheet().getRange("A1:B1").setValue(values);
}


function create() {
  var url = 'https://api.trello.com/1/tokens/ae6ebe60b45abcd2d4aa945c9ab4c4571bd6b6f7856b1df0cd387fbffc649579/webhooks/?key=a211f4aca7fb3e521d652730dd231cb6'  
  var payload = { 
    "key": "xxxxxxxxxxxxxxxxxx",
    "token" : "xxxxxxxxxxxxxxxxxxx": "https://script.google.com/macros/s/AKfycbw51TYGWHe95hKdcAs4l7E2eg0AtBi8e48lf_iafKYI/dev",
    "idModel":"xxxxxxxxxxxxxxxxxxxxxxxx",
    "description": "GW Test"  
  }
  var options = {"method" : "delete",
                 "payload" : payload,
              // "muteHttpExceptions": true
                 };

  var response = UrlFetchApp.fetch(url,options);           // creates webhook
}


// function that fires when the webapp receives a GET request
function doGet(e) {
  doSomething();
  var values = [21,22];
  SpreadsheetApp.getActiveSheet().getRange("A2:B2").setValue(values);
  return HtmlService.createHtmlOutput("something Get-ed");
}

function doPost(e) {
  doSomething();
  var values = [31,32];
  SpreadsheetApp.getActiveSheet().getRange("A3:B3").setValue(values);
  return ContentService.createTextOutput("something Posted");
  //var params = JSON.stringify(e);
}


Run Code Online (Sandbox Code Playgroud)

Tan*_*ike 9

这个答案怎么样?

问题:

根据您的问题,API 返回以下错误。

{“message”:“URL(https://script.google.com/macros/s/AKfycbxo90ucgXXz7MG6Z3wb2KD-PJn3akGKoelXLJ2mkg/exec)未返回200状态代码,得到403”,“错误”:“错误”}

关于上述错误的原因,首先我认为最新的脚本可能没有反映到Web Apps中。但从您的回复评论中发现,最新的脚本已反映到Web Apps中。403在这种情况下,我尝试从部署的 Web 应用程序中检索错误。

准备:

作为准备,Web 应用程序的“执行应用程序为”和“谁有权访问应用程序”分别部署为MeAnyone, even anonymous。Web Apps 的示例脚本如下。

function doGet(e) {return ContentService.createTextOutput("GET: Done.")}
Run Code Online (Sandbox Code Playgroud)

实验:

使用 Google Apps 脚本:

首先,当它请求 Web Apps 时,我使用 Google Apps 脚本检查了状态代码。脚本如下。

function myFunction() {
  var url_exec = "https://script.google.com/macros/s/###/exec";
  var url_dev = "https://script.google.com/macros/s/###/dev";
  var res = UrlFetchApp.fetchAll([{url: url_exec}, {url: url_dev}]);
  res.forEach(function(e) {
    Logger.log(e.getResponseCode());
  });
}
Run Code Online (Sandbox Code Playgroud)

在本例中,和200的两个端点都获得了的状态代码。使用 Google Apps 脚本,无法检索的状态代码。execdev403

使用卷曲:

为了使用curl 检索状态代码,curl -s -o /dev/null -w "%{http_code}" http://www.example.org/使用了。这是来自这个线程。此处,使用curl 命令调查状态代码。因为curl可以通过如下所示的选项访问2种请求。

  1. --include:在输出中包含 HTTP 响应标头。HTTP 响应标头可以包括服务器名称、cookie、文档日期、HTTP 版本等内容...

  2. --head: (HTTP FTP 文件) 仅获取标头!HTTP 服务器具有 HEAD 命令,该命令只获取文档的标题。当用于 FTP 或 FILE 文件时,curl 仅显示文件大小和上次修改时间。

使用上述选项,研究了以下 4 种模式。

  1. exec使用选项向端点发出请求--include
    • curl -sL --include -o /dev/null -w "%{http_code}" "https://script.google.com/macros/s/###/exec"
    • 200被退回。
  2. dev使用选项向端点发出请求--include
    • curl -sL --include -o /dev/null -w "%{http_code}" "https://script.google.com/macros/s/###/dev"
    • 200被退回。
  3. exec使用选项向端点发出请求--head
    • curl -sL --head -o /dev/null -w "%{http_code}" "https://script.google.com/macros/s/###/exec"
    • 403被退回。
  4. dev使用选项向端点发出请求--head
    • curl -sL --head -o /dev/null -w "%{http_code}" "https://script.google.com/macros/s/###/dev"
    • 200被退回。

结果发现,当exec使用 option 请求端点的 Web Apps 时,获取到--head的状态码。403

结果和讨论:

当该选项--head用于curl命令时,从文档来看,这意味着它仅请求标头而不请求正文。由此发现403返回了 的状态码。

200这里,为什么的两个选项--include以及--head当它请求 的端点时都返回状态代码dev?考虑是由于返回登录界面所致。访问的端点时dev,需要使用访问令牌。当不使用访问令牌时,将返回登录屏幕。此时,200返回 的状态码。作为测试用例,当访问令牌用于dev使用以下curl命令的端点时,

curl -sL --head -H "Authorization: Bearer ###" -o /dev/null -w "%{http_code}" "https://script.google.com/macros/s/###/dev"
Run Code Online (Sandbox Code Playgroud)

403返回了的状态码。根据该结果,得到以下的结果。

  • 当仅检索到 Web 应用程序正常工作的标头时,403返回。
  • 当返回登录屏幕时,200返回。

综上所述,认为错误原因{"message":"URL (https://script.google.com/macros/s/AKfycbxo90ucgXXz7MG6Z3wb2KD-PJn3akGKoelXLJ2mkg/exec) did not return 200 status code, got 403","error":"ERROR"}是上述情况造成的。

解决方法:

从上面的结果来看,当 Web Apps 部署为“执行应用程序为”和“谁有权访问应用程序”分别为Me和时,当它请求使用选项Only myself的端点时,发现状态码为将被退回。因为此时,显示的是登录界面。exec--head200

针对这种情况,以下流程作为解决方法怎么样?

  1. 当 Web 应用程序的端点注册到 API 时,请将“执行应用程序为”和“谁有权访问该应用程序”分别部署为MeOnly myself

  2. 注册完成后,请将“执行应用程序为”和“谁有权访问应用程序”分别部署为MeAnyone, even anonymous

    • 这样就可以访问Web Apps了。

通过上述流程,只有当端点注册时,200才会返回 的状态码。但在此解决方法中,它假设您要使用的 API 可能会检查请求的标头。如果我的猜测不正确,则无法使用此解决方法。在这种情况下,我必须道歉。

参考:

添加:

在我的环境中,我可以确认 Web 应用程序的端点exec可以使用上述解决方法向 trello API 注册。我使用的脚本如下。

  • 在运行脚本之前,请按如下方式设置 Web 应用程序。
    • “执行应用程序为”和“谁有权访问应用程序”分别是MeOnly myself
  • 收到点赞回复后{"id":"###","description":"sample","idModel":"###","callbackURL":"https://script.google.com/macros/s/###/exec","active":true},请按如下方式设置Web Apps。
    • “执行应用程序为”和“谁有权访问应用程序”分别是MeAnyone, even anonymous

通过此流程,可以使用 webhook。

示例脚本:

var url = 'https://api.trello.com/1/tokens/###/webhooks/?key=###'
var payload = { 
  "callbackURL": "https://script.google.com/macros/s/###/exec",
  "idModel":"###",
  "description": "sample"
}
var options = {method: "post", payload: payload};
var res = UrlFetchApp.fetch(url,options);
Logger.log(res.getContentText())
Run Code Online (Sandbox Code Playgroud)