【发布时间】: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 标头在定义上不区分大小写(尽管由于用户代码通常会解释它们,我总是尝试遵循确切的大小写)跨度>
标签: google-apps-script google-api google-ads-api