【问题标题】:How to parse a simple JSON object (accessing single elements)?如何解析一个简单的 JSON 对象(访问单个元素)?
【发布时间】:2020-07-05 18:50:31
【问题描述】:

我正在尝试在 Google-Apps-Script(Webhook 接收器)中处理简单的 JSON 数据。对于测试,我从控制台发送数据:

curl -d "{"result":true,"count":42,"exchange":"Kroakex"}" -H "Content-Type: application/json" -X POST https://script.google.com/macros/s/xxx/exec

...但我无法访问处理函数中的 json 元素:

function doPost(e) {
  var jsonString = JSON.stringify(e.postData.contents);
  var jsonObj = JSON.parse(jsonString);

  console.log(jsonObj);       // ---> "{result:true,count:42,exchange:Kroakex}"
  console.log(jsonObj.count); // ---> "undefined"

  var sheet = SpreadsheetApp.getActiveSheet();
  var lastRow = Math.max(sheet.getLastRow(),1);
  sheet.insertRowAfter(lastRow);

  sheet.getRange(lastRow + 1, 1).setValue(jsonObj['count']); // ---> nothing
  sheet.getRange(lastRow + 1, 2).setValue(jsonObj['exchange']); // ---> nothing
  sheet.getRange(lastRow + 1, 3).setValue(jsonObj); // ---> {result:true,count:42,exchange:Kroakex}

  SpreadsheetApp.flush();
  return HtmlService.createHtmlOutput("post request received");
}

当我改为使用这一行手动创建 JSON 字符串时,一切正常:

const jsonString = '{"result":true, "count":42, "exchange":"Kroakex"}';

谁能帮忙?

【问题讨论】:

  • 根据Documentation e.postData.contents 已经是文本,为什么要在上面使用stringify?
  • 谢谢你,你可能是对的......但是当我离开该行时,我在以下解析行收到错误“位置 0 处的意外标记”

标签: json parsing google-apps-script split webhooks


【解决方案1】:

我想提出以下修改。

修改点:

  • 我认为在你的 curl 命令中,有修改点。

    1. 使用 curl 命令时,e.postData.contents"{result:true,count:42,exchange:Kroakex}"。因为在-d "{"result":true,"count":42,"exchange":"Kroakex"}"" 用在了"{,,,}"。在这种情况下,您的 Google Apps 脚本无法将值解析为 JSON 对象。请转义" 或附上'。这样,e.postData.contents 变为 "{\"result\":true,\"count\":42,\"exchange\":\"Kroakex\"}"

    2. 在这种情况下,请使用-L-X POST 不是必需的。

    3. 修改后的curl命令如下。

       curl -L -d '{"result":true,"count":42,"exchange":"Kroakex"}' -H "Content-Type: application/json" https://script.google.com/macros/s/###/exec
      
    •   curl -L -d "{\"result\":true,\"count\":42,\"exchange\":\"Kroakex\"}" -H "Content-Type: application/json" https://script.google.com/macros/s/###/exec
      

通过以上修改,您的 Google Apps Script 变为如下。

修改脚本:

function doPost(e) {
  var jsonObj = JSON.parse(e.postData.contents);  // <--- Modified

  console.log(jsonObj);
  console.log(jsonObj.count);

  var sheet = SpreadsheetApp.getActiveSheet();
  var lastRow = Math.max(sheet.getLastRow(),1);
  sheet.insertRowAfter(lastRow);

  sheet.getRange(lastRow + 1, 1).setValue(jsonObj['count']);
  sheet.getRange(lastRow + 1, 2).setValue(jsonObj['exchange']);
  sheet.getRange(lastRow + 1, 3).setValue(JSON.stringify(jsonObj));  // <--- Modified

  SpreadsheetApp.flush();
  return HtmlService.createHtmlOutput("post request received");
}

注意:

  • 当您修改 Web Apps 的脚本时,请将 Web Apps 重新部署为新版本。这样,最新的脚本就会反映到 Web 应用程序中。请注意这一点。
  • 当你使用 curl 命令时,我认为返回的值可能适合return ContentService.createTextOutput("post request received"); 而不是return HtmlService.createHtmlOutput("post request received");

参考资料:

补充:

当您想使用https://script.google.com/macros/s/###/dev 的 URL 访问 Web Apps 时,需要使用访问令牌。修改后的curl命令如下。

curl -L \
  -H "Authorization: Bearer ### access token ###" \
  -H "Content-Type: application/json" \
  -d '{"result":true,"count":42,"exchange":"Kroakex"}' \
  "https://script.google.com/macros/s/#####/dev"
  • 在这种情况下,https://www.googleapis.com/auth/drive.readonlyhttps://www.googleapis.com/auth/drive 可用于范围。

参考:

【讨论】:

  • 哦,谢谢你!!! :-D 非常感谢你......你拯救了我的一天!!我按照您的指示进行操作,现在按预期工作。也许你也知道我可以如何使用“.../dev”webhook url(而不是“.../exec”)?如果我不必在每次微小的代码更改后重新部署新的 Web App 版本,那就太好了……
  • @cody 感谢您的回复。关于您的新问题,我又添加了一个 curl 示例命令。你能确认一下吗?
  • 哦,我忘了,现在确认了,谢谢! :-) 我明白了,我需要一个令牌...正如您在参考资料中描述的那样,我可以通过调用“ScriptApp.getOAuthToken()”来检索一个令牌...但是我该怎么处理它呢?要我在这里开一个新话题来问你这个问题吗? :-)
  • @cody 感谢您的回复。虽然我不确定我是否能正确理解您关于but what do I do with it then? 的问题,但如果您想使用ScriptApp.getOAuthToken(),请使用检索到的访问令牌到-H "Authorization: Bearer ### access token ###"。本例中,token 的过期时间为 1 小时。请注意这一点。如果我误解了您的问题并且您无法理解,您可以通过包含更多信息将其作为新问题发布吗?借此,我想确认一下。如果您能合作解决您的新问题,我很高兴。
  • 好的,我问:我的 dev-webhook 被触发了,我的 funktion 获取了一个 AuthToken。现在我想用传入的 JSON 数据更新电子表格。我该如何使用该令牌?我的意思是,如何在 doPost() 函数中编写代码?我想让它自动使用令牌(无需手动发送任何进一步的命令)...?
猜你喜欢
  • 1970-01-01
  • 2014-07-09
  • 2017-08-20
  • 2012-10-31
  • 2012-11-09
  • 1970-01-01
  • 1970-01-01
  • 2015-05-15
  • 1970-01-01
相关资源
最近更新 更多