如何修复来自 Google Ads API 的无效 JSON 负载错误
Posted
技术标签:
【中文标题】如何修复来自 Google Ads API 的无效 JSON 负载错误【英文标题】:How to fix Invalid JSON payload error from the Google Ads API 【发布时间】:2020-08-27 09:56:35 【问题描述】:我正在尝试将 Google Ads API 中的报告提取到 Google 表格中,但我无法让 API 将我的查询识别为查询
这是我得到的代码和错误:
function basicReport()
var query =
"query" : "SELECT campaign.name, campaign.status FROM campaign ORDER BY campaign.id"
;
var body = JSON.stringify(query);
var head =
'Developer-token' : "<Dev token>",
'login-customer-id' : <Manager ID>,
'Authorization' : "Bearer <Auth token>",
;
var options =
'method' : 'POST',
'content-type': 'application/json',
'headers' : head,
'payload' : body,
'muteHttpExceptions' : true
;
var response = UrlFetchApp.fetch('https://googleads.googleapis.com/v4/customers/<Customer ID>/googleAds:searchStream', options);
var json = response.getContentText();
var data = JSON.parse(json);
但我经常收到错误:
"error":
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"\"query\":\"SELECT campaign.name, campaign.status FROM campaign ORDER BY campaign.id\"\": Cannot bind query parameter. Field '\"query\":\"SELECT campaign' could not be found in request message.",
"status": "INVALID_ARGUMENT",
"details": [
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
"description": "Invalid JSON payload received. Unknown name \"\"query\":\"SELECT campaign.name, campaign.status FROM campaign ORDER BY campaign.id\"\": Cannot bind query parameter. Field '\"query\":\"SELECT campaign' could not be found in request message."
我已经在 OAuth 游乐场 (https://developers.google.com/oauthplayground) 中运行了查询,它在那里工作,所以我知道查询没问题。
我尝试将正文作为对象而不是字符串传递,但随后出现 500 错误。
【问题讨论】:
您会感到惊讶(但可能很久以前就已经解决了),但问题在于content-type
选项。没有这样的选项 - 正确的选项是 contentType
,否则负载类型默认为 application/x-www-form-urlencoded
。您对有效负载进行字符串化也是正确的 - 它始终作为字符串传递。但是当 content-type 标头设置为默认值(urlencoded)时,UrlFetchApp
允许您传递一个对象并在后台将其字符串化,但是对于查询,导致 Ads API 服务器无法处理有效负载(因此500 错误)
它确实适用于内容类型(可能两者都适用?但肯定适用于内容类型)。我确实解决了它,所以在下面发布了完整的解决方案。感谢您提醒我跟进!
这很奇怪,参数不能正常工作(除非 API 也接受表单编码的主体,坦率地说,我没有测试)。回复:解决方案 - 你绝对可以删除“查询”部分 - 没关系,在 JS 中,带引号和不带引号的键之间存在 0 差异 - 它们被字符串化相同。我认为该解决方案有效,因为您将内容类型移动到标题 - 它是一个有效的标题(基本上,contentType
选项将此标题设置在幕后)。开发令牌大写也可能导致了这个问题 - 看起来 API 是区分大小写的。
谢谢!我刚刚测试过,你是对的,contentType 是在 options 中设置的,Content-Type 是在 headers 中设置的。设置任何一个都可以使其工作,但它们不可互换。还测试了“查询”的引号和开发者令牌的大写 - 都不重要。
很高兴您检查了 - 一切都符合预期。引用 100% 与规范无关,contentType
拼写很重要,因为这是一个参数,并且 HTTP 标头在定义上不区分大小写(尽管由于用户代码通常会解释它们,我总是尝试遵循确切的大小写)跨度>
【参考方案1】:
如果其他人正在寻找这个 - 我确实解决了它。
在 header 中设置时,Content-Type 有破折号,在选项中设置时,contentType 没有。
function basicReport()
var query =
"query" : "SELECT campaign.name, campaign.status FROM campaign ORDER BY campaign.id"
;
var body = JSON.stringify(query);
var head =
'developer-token' : "<Dev token>",
'login-customer-id' : "<Manager ID>",
'authorization' : "Bearer <Auth token>",
'accept' : 'application/json'
'Content-Type': 'application/json',
;
var options =
'method' : 'POST',
'headers' : head,
'payload' : body,
'muteHttpExceptions' : true
;
var response = UrlFetchApp.fetch('https://googleads.googleapis.com/v4/customers/<Customer ID>/googleAds:searchStream', options);
var json = response.getContentText();
var data = JSON.parse(json);
Logger.log(data);
【讨论】:
以上是关于如何修复来自 Google Ads API 的无效 JSON 负载错误的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 Google Analytics API 获取 Google Ads 关键字和广告内容