第三方 API

Google Ads 脚本的一项强大功能是能够与第三方 API 的数据和服务集成。

本指南介绍了以下概念,可帮助您编写脚本以连接到其他服务:

  • 发出 HTTP 请求:如何使用 UrlFetchApp 访问外部 API。
  • 身份验证:我们涵盖了一些常见的身份验证场景。
  • 解析响应:如何处理返回的 JSON 和 XML 数据。

我们还提供了一些热门 API 的示例,用于说明这些概念。

使用 UrlFetchApp 提取数据

UrlFetchApp 提供与第三方 API 交互所需的核心功能。

以下示例展示了如何从 OpenWeatherMap 获取天气数据。我们之所以选择 OpenWeatherMap,是因为其授权方案和 API 相对简单。

发出请求

OpenWeatherMap 文档指定了请求当前天气的格式,如下所示:

http://api.openweathermap.org/data/2.5/weather?q=[location]&apikey=[apikey]

此网址提供了我们的第一个授权示例:参数 apikey 是必需的,并且每个用户的值都是唯一的。此密钥通过注册获得。

注册后,可以使用该密钥发出请求,如下所示:

const location = 'London,uk';
const apikey = 'da.......................81'; // Replace with your API key
const currentWeatherUrl = `http://api.openweathermap.org/data/2.5/weather?q=${location}&apiKey=${apiKey}`;
const response = UrlFetchApp.fetch(currentWeatherUrl);
console.log(response.getContentText());

执行此代码后,系统会在 Google Ads 脚本的日志记录窗口中写入一个长长的 JSON 文本字符串。

下一步是将此内容转换为可在脚本中使用的格式。

JSON 数据

许多 API 都以 JSON 格式提供响应。这表示 JavaScript 对象的简单序列化,以便对象、数组和基本类型可以表示为字符串并进行传输。

如需将 JSON 字符串(例如从 OpenWeatherMap 返回的字符串)转换回 JavaScript 对象,请使用内置的 JSON.parse 方法。继续沿用上述示例:

const json = response.getContentText();
const weatherData = JSON.parse(json);
console.log(weatherData.name);
//  "London"

JSON.parse 方法会将字符串转换为具有属性 name 的对象。

如需详细了解如何处理不同格式的 API 响应,请参阅解析响应部分。

错误处理

在脚本中使用第三方 API 时,错误处理是一项重要的考虑因素,因为第三方 API 经常会发生变化,并生成意外的响应值,例如:

  • API 的网址或参数可能会在您不知情的情况下发生变化。
  • 您的 API 密钥(或其他用户凭据)可能会过期。
  • 回答的格式可能会发生变化,恕不另行通知。

HTTP 状态代码

由于可能会出现意外响应,您应检查 HTTP 状态代码。默认情况下,如果遇到 HTTP 错误代码,UrlFetchApp 会抛出异常。如需更改此行为,必须传递一个可选参数,如以下示例所示:

const options = {
  muteHttpExceptions: true
}
const response = UrlFetchApp.fetch(url, options);
// Any status code greater or equal to 400 is either a client or server error.
if (response.getResponseCode() >= 400) {
  // Error encountered, send an email alert to the developer
  sendFailureEmail();
}

响应结构

当第三方 API 发生变化时,开发者通常不会立即意识到这些变化可能会影响其脚本。例如,如果将 OpenWeatherMap 示例中返回的 name 属性更改为 locationName,则使用此属性的脚本将失败。

因此,测试返回的结构是否符合预期可能很有用,例如:

const weatherData = JSON.parse(json);
if (weatherData && weatherData.name) {
  console.log('Location is : ' + name);
} else {
  console.log('Data not in expected format');
}

使用 UrlFetchApp 发布数据

使用 OpenWeatherMap 的入门示例仅提取了数据。通常,不会更改远程服务器状态的 API 调用会使用 HTTP GET 方法。

GET 方法是 UrlFetchApp 的默认方法。不过,某些 API 调用(例如对发送短信的服务进行的调用)将需要其他方法,例如 POSTPUT

为了说明如何将 POST 调用与 UrlFetchApp 搭配使用,以下示例演示了如何与协作消息应用 Slack 集成,以向 Slack 用户和群组发送 Slack 消息。

设置 Slack

本指南假定您已注册 Slack 账号。

与上例中的 OpenWeatherMap 一样,您需要获取令牌才能发送消息。Slack 提供了一个唯一的网址,让您可以向团队发送消息,该网址称为传入的 webhook

点击 Add Incoming WebHooks Integration 并按照说明设置传入网络钩子。该进程应发布一个用于消息传递的网址。

发出 POST 请求

设置好传入 Webhook 后,只需在传递给 UrlFetchApp.fetchoptions 参数中使用一些额外的属性,即可发出 POST 请求:

  • method:如上所述,此值默认为 GET,但在此处我们将其替换为 POST
  • payload:这是要作为 POST 请求的一部分发送到服务器的数据。在此示例中,Slack 需要一个序列化为 JSON 格式的对象,如 Slack 文档中所述。 为此,请使用 JSON.stringify 方法,并将 Content-Type 设置为 application/json

      // Change the URL for the one issued to you from 'Setting up Slack'.
      const SLACK_URL = 'https://hooks.slack.com/services/AAAA/BBBB/CCCCCCCCCC';
      const slackMessage = {
        text: 'Hello, slack!'
      };
    
      const options = {
        method: 'POST',
        contentType: 'application/json',
        payload: JSON.stringify(slackMessage)
      };
      UrlFetchApp.fetch(SLACK_URL, options);
    

扩展的 Slack 示例

上述示例展示了启用 Slack 接收消息所需的最低限度。一个扩展的示例演示了如何创建广告系列效果报告并将其发送给群组,以及一些格式设置和显示选项。

收到的消息

如需详细了解 Slack 消息,请参阅 Slack 文档中的消息格式设置

表单数据

上面的示例演示了如何使用 JSON 字符串作为 POST 请求的 payload 属性。

根据 payload 的格式,UrlFetchApp 会采用不同的方法来构建 POST 请求:

  • 如果 payload 是字符串,则字符串实参会作为请求的正文发送。
  • payload 是一个对象(例如值映射)时:

    {to: 'mail@example.com', subject:'Test', body:'Hello, World!'}
    

    键值对会转换为 form-data:

    subject=Test&to=mail@example.com&body=Hello,+World!
    

    此外,请求的 Content-Type 标头设置为 application/x-www-form-urlencoded

某些 API 在提交 POST 请求时需要使用表单数据,因此请务必记住,JavaScript 对象会自动转换为表单数据

HTTP 基本身份验证

HTTP 基本身份验证是最简单的身份验证形式之一,许多 API 都使用这种身份验证。

通过在每个请求中将编码的用户名和密码附加到 HTTP 标头来实现身份验证。

HTTP 基本身份验证

构建请求

如需生成经过身份验证的请求,必须执行以下步骤:

  1. 通过将用户名和密码与英文冒号连接起来,形成口令,例如 username:password
  2. 对口令进行 Base64 编码,例如 username:password 变为 dXNlcm5hbWU6cGFzc3dvcmQ=
  3. Authorization 标头附加到请求中,格式为 Authorization: Basic <encoded passphrase>

以下代码段展示了如何在 Google Ads 脚本中实现此目的:

const USERNAME = 'your_username';
const PASSWORD = 'your_password';
const API_URL = 'http://<place_api_url_here>';

const authHeader = 'Basic ' + Utilities.base64Encode(USERNAME + ':' + PASSWORD);
const options = {
  headers: {Authorization: authHeader}
}
// Include 'options' object in every request
const response = UrlFetchApp.fetch(API_URL, options);

基本身份验证示例

代码示例部分包含两个示例,展示了如何使用 HTTP 基本身份验证:

Plivo

Plivo 是一项服务,可使用其 API 帮助您发送和接收短信。此示例说明了如何发送消息。

  1. Plivo 注册。
  2. 示例脚本粘贴到 Google Ads 中的新脚本中。
  3. PLIVO_ACCOUNT_AUTHIDPLIVO_ACCOUNT_AUTHTOKEN 值替换为管理信息中心中的值。
  4. 按照脚本中的指定插入您的电子邮件地址,以便接收错误通知。
  5. 如需使用 Plivo,您必须购买号码或向试用账号添加号码。添加可与试用账号搭配使用的沙盒号码
  6. 添加将显示为发件人的号码和收件人号码。
  7. 将脚本中的 PLIVO_SRC_PHONE_NUMBER 更新为刚刚注册的沙盒号码之一。这应包含国际国家/地区代码,例如英国号码的 447777123456

Twilio

Twilio 是另一项服务,可使用其 API 轻松发送和接收短信。此示例说明了如何发送消息。

  1. Twillio 注册。
  2. 示例脚本粘贴到 Google Ads 中的新脚本中。
  3. TWILIO_ACCOUNT_SIDTWILIO_ACCOUNT_AUTHTOKEN 值替换为账号控制台页面上显示的值。
  4. TWILIO_SRC_PHONE_NUMBER 替换为信息中心中的号码,这是 Twilio 授权用于发送消息的号码。

OAuth 1.0

许多热门服务都使用 OAuth 进行身份验证。OAuth 有多种风格和版本。

而使用 HTTP 基本身份验证时,用户只有一个用户名和密码,OAuth 则允许使用特定于第三方应用的凭据向第三方应用授予对用户账号和数据的访问权限。此外,访问权限的范围也将特定于该应用。

如需了解 OAuth 1.0 的背景信息,请参阅 OAuth 核心指南。 具体而言,请参阅 6. 使用 OAuth 进行身份验证。在完整的三方 OAuth 1.0 中,流程如下:

  1. 应用(“消费者”)获取请求令牌。
  2. 用户授权请求令牌。
  3. 应用将请求令牌兑换为访问令牌。
  4. 对于所有后续资源请求,访问令牌都用于签名请求中。

如果第三方服务要使用 OAuth 1.0 而无需用户互动(例如 Google Ads 脚本需要这样做),则无法执行第 1 步、第 2 步和第 3 步。因此,某些服务会从其配置控制台中颁发访问令牌,从而允许应用直接进入第 4 步。这称为单方模式 OAuth 1.0。

OAuth1

Google Ads 脚本中的 OAuth 1.0

对于 Google Ads 脚本,每个脚本通常会被解读为一种应用。通过控制台或服务的管理设置页面,通常需要执行以下操作:

  • 设置应用配置以表示脚本。
  • 指定要向脚本扩展哪些权限。
  • 获取使用方密钥、使用方密钥、访问令牌和访问密钥,以便与单腿 OAuth 搭配使用。

OAuth 2.0

OAuth 2.0 在热门 API 中用于提供对用户数据的访问权限。特定第三方服务的账号所有者向特定应用授予权限,以允许这些应用访问用户数据。优势在于,所有者:

  • 无需与应用分享其账号凭据。
  • 可以单独控制哪些应用可以访问数据以及访问权限的范围。(例如,授予的访问权限可能是只读权限,或者仅限于部分数据。)

如需在 Google Ads 脚本中使用启用 OAuth 2.0 的服务,您需要执行以下几个步骤:

脚本之外

授予 Google Ads 脚本通过第三方 API 访问您的用户数据的授权。在大多数情况下,这需要您在第三方服务的控制台中设置应用。此应用代表您的 Google Ads 脚本。

您需要指定应向 Google Ads 脚本应用授予哪些访问权限,该应用通常会被分配一个客户端 ID。这样一来,您就可以通过 OAuth 2.0 控制哪些应用可以访问第三方服务中的数据,以及这些应用可以查看或修改哪些方面的数据。

在脚本中

使用远程服务器进行授权。根据服务器允许的授权类型,需要遵循一组不同的步骤(称为流程),但最终都会生成一个访问令牌,该令牌将用于相应会话的所有后续请求。

发出 API 请求。在每个请求中传递访问令牌

授权流程

每种授权类型和相应流程都适用于不同的使用场景。例如,当用户参与互动会话时,系统会使用不同的流程,这与需要应用在后台运行且没有用户在场的情况形成对比。

API 提供方将决定接受哪些授权类型,这将指导用户如何继续集成其 API。

实现

对于所有不同的 OAuth 流程,目标都是获取访问令牌,然后可以在会话的剩余时间内使用该令牌对请求进行身份验证。

示例库,用于说明如何针对每种不同的流程类型进行身份验证。这些方法中的每一种都会返回一个用于获取和存储访问令牌的对象,并有助于进行身份验证的请求。

一般使用模式如下:

// Authenticate using chosen flow type
const urlFetchObj = OAuth2.<flow method>(args);
// Make request(s) using obtained object.
const response1 = urlFetchObj.fetch(url1);
const response2 = urlFetchObj.fetch(url2, options);

客户端凭据授权

客户端凭据授权是 OAuth2 流程中较为简单的一种形式,其中应用会交换应用特有的 ID 和 Secret,以换取时限有限的访问令牌

客户端凭据

// Access token is obtained and cached.
const authUrlFetch = OAuth2.withClientCredentials(
    tokenUrl, clientId, clientSecret, optionalScope));
// Use access token in each request
const response = authUrlFetch.fetch(url);
// ... use response

刷新令牌授权

刷新令牌授权与客户端凭据授权类似,因为向服务器发送简单请求即可返回可在会话中使用的访问令牌

刷新令牌

获取刷新令牌

与刷新令牌授权的不同之处在于,客户端凭据授权所需的详细信息来自应用配置(例如,在服务的控制面板中),而刷新令牌是作为更复杂流程(例如授权码授权)的一部分授予的,这需要用户互动:

授权代码

使用 OAuth Playground 获取刷新令牌

OAuth2 Playground 提供了一个界面,用户可以通过该界面逐步完成授权代码授予流程,以获取刷新令牌。

通过右上角的“设置”按钮,您可以定义 OAuth 流程中要使用的所有参数,包括:

  • 授权端点:用作授权流程的起点。
  • 令牌端点:与刷新令牌搭配使用,以获取访问令牌。
  • 客户端 ID 和密钥:应用的凭据。

OAuth Playground

刷新令牌使用情况

完成初始授权后,服务可以颁发刷新令牌,然后可以像客户端凭据流程一样使用该令牌。下面给出了两个示例:

const authUrlFetch = OAuth2.withRefreshToken(tokenUrl, clientId, clientSecret,
    refreshToken, optionalScope);
const response = authUrlFetch.fetch(url);
// ... use response

Search Ads 360 示例

Search Ads 360 是可与刷新令牌搭配使用的 API 的一个示例。 在此示例中,脚本生成并返回报告。 如需详细了解可执行的其他操作,请参阅 Search Ads 360 API 参考

创建脚本
  1. API 控制台中创建一个新项目,然后按照 Search Ads 360 指南中的步骤获取客户端 ID、客户端密钥和刷新令牌,确保您已启用 Search Ads 360 API。
  2. 示例脚本粘贴到 Google Ads 中的新脚本中。
  3. 示例 OAuth2 库粘贴到代码列表下方。
  4. 修改脚本,使其包含客户端 ID、客户端密钥和刷新令牌的正确值。

Apps Script Execution API 示例

此示例展示了如何使用 Apps Script Execution API 在 Apps 脚本中执行函数。这样,您就可以从 Google Ads 脚本调用 Apps 脚本。

创建 Apps 脚本脚本

创建新脚本。以下示例将列出云端硬盘中的 10 个文件:

function listFiles() {
  const limit = 10;
  const files = [];
  const fileIterator = DriveApp.getFiles();
  while (fileIterator.hasNext() && limit) {
    files.push(fileIterator.next().getName());
    limit--;
  }
  return files;
}
配置 Apps 脚本以供执行
  1. 保存脚本。
  2. 依次点击资源 > Cloud Platform 项目
  3. 点击项目名称以导航到 API 控制台。
  4. 前往 API 和服务
  5. 启用相应的 API,在本例中为 Drive APIApps 脚本执行 API
  6. 通过菜单中的凭据项创建 OAuth 凭据。
  7. 返回到脚本中,依次选择发布 > 部署为 API 可执行文件,发布脚本以供执行。
创建 Google Ads 脚本
  1. 示例脚本粘贴到 Google Ads 中的新脚本中。
  2. 此外,请将示例 OAuth2 库粘贴到代码清单下方。
  3. 修改脚本,使其包含客户端 ID、客户端密钥和刷新令牌的正确值。

服务账号

上述授权类型的替代方案是服务账号的概念。

服务账号与上述账号的不同之处在于,它们不用于访问用户数据:身份验证后,请求由服务账号代表应用发出,而不是以可能拥有项目的用户的身份发出。例如,如果服务账号使用 Drive API 创建文件,则该文件属于服务账号,并且默认情况下项目所有者无法访问该文件。

Google Natural Language API 示例

Natural Language API 可为文本提供情感分析实体分析

此示例展示了如何计算广告文字(包括标题或广告内容描述)的情感基调。这可用于衡量消息的正面程度和重要程度:我们销售蛋糕和我们销售伦敦最好的蛋糕,哪个更好?立即购买!

设置脚本
  1. API 控制台中创建新项目
  2. 启用 Natural Language API
  3. 为项目启用结算功能。
  4. 创建服务账号。 下载凭据 JSON 文件。
  5. 示例脚本粘贴到 Google Ads 中的新脚本中。
  6. 此外,请将示例 OAuth2 库粘贴到代码清单下方。
  7. 替换必要的值:
    • serviceAccount:服务账号的电子邮件地址,例如 xxxxx@yyyy.iam.gserviceaccount.com
    • key:创建服务账号时下载的 JSON 文件中的密钥。开始时间为 -----BEGIN PRIVATE KEY...,结束时间为 ...END PRIVATE KEY-----\n

API 响应

API 可以返回多种格式的数据。其中最值得注意的是 XML 和 JSON。

JSON

作为响应格式,JSON 通常比 XML 更易于使用。不过,仍可能会出现一些问题。

回复验证

从 API 调用中获得成功响应后,典型的下一步是使用 JSON.parse 将 JSON 字符串转换为 JavaScript 对象。此时,最好处理解析失败的情况:

const json = response.getContentText();
try {
  const data = JSON.parse(json);
  return data;
} catch(e) {
  // Parsing of JSON failed - handle error.
}

此外,如果 API 不受您控制,请考虑响应的结构可能会发生变化,并且属性可能不再存在:

// Less good approach
// Assumes JSON was in form {"queryResponse": ...} when parsed.
const answer = data.queryResponse;

// Better approach
if (data && data.queryResponse) {
  const answer = data.queryResponse;
} else {
  // Format of API response has changed - alert developer or handle accordingly
}

XML

验证

XML 仍然是构建 API 的常用格式。可以使用 XmlService parse 方法解析 API 调用的响应:

const responseText = response.getContentText();
try {
  const document = XmlService.parse(responseText);
} catch(e) {
  // Error in XML representation - handle accordingly.
}

虽然 XmlService.parse 可以检测 XML 中的错误并相应地抛出异常,但它无法根据架构验证 XML。

根元素

如果成功解析 XML 文档,则可以使用 getRootElement() 方法获取根元素:

const document = XmlService.parse(responseText);
const rootElement = document.getRootElement();

命名空间

在以下示例中,Sportradar API 用于获取所选比赛的足球赛果。XML 响应采用以下格式:

<schedule xmlns="http://feed.elasticstats.com/schema/soccer/sr/v2/matches-schedule.xsd">
  <matches>
     ...
  </matches>
</schedule>

请注意如何在根元素中指定命名空间。因此,您需要执行以下操作:

  • 从文档中提取命名空间属性。
  • 在遍历和访问子元素时使用此命名空间。

以下示例展示了如何访问上述文档代码段中的 <matches> 元素:

const document = XmlService.parse(xmlText);
const scheduleElement = document.getRootElement();
// The namespace is required for accessing child elements in the schema.
const namespace = scheduleElement.getNamespace();
const matchesElement = scheduleElement.getChild('matches', namespace);

获取值

假设有以下橄榄球赛程示例:

<match status="..." category="..." ... >
  ...
</match>

例如,可以检索以下属性:

const status = matchElement.getAttribute('status').getValue();

可以使用 getText() 读取元素中包含的文本,但如果元素的文本子级有多个,这些文本将会串联在一起。如果可能存在多个文本子级,请考虑使用 getChildren() 并遍历每个子级。

Sportradar 示例

此完整的 Sportradar 示例演示了如何检索足球比赛(尤其是英格兰足球超级联赛比赛)的详细信息。Soccer API 是 Sportradar 提供的众多体育信息源之一。

设置 Sportradar 账号
  1. 前往 Sportradar 开发者网站
  2. 注册试用账号
  3. 注册完成后,登录您的账号。
  4. 登录后,前往MyAccount

Sportradar 将不同的体育项目分为不同的 API。例如,您可能购买了对 Soccer API 的访问权限,但没有购买对 Tennis API 的访问权限。您创建的每个应用都可以关联不同的运动项目和不同的密钥。

  1. 在“应用”下,点击创建新应用。为应用提供名称和说明,并忽略网站字段。
  2. 仅选择 Issue a new key for Soccer Trial Europe v2
  3. 点击注册应用

成功后,系统会显示一个包含新 API 密钥的页面。

  1. 示例脚本粘贴到 Google Ads 中的新脚本中。
  2. 将清单中的 API 密钥替换为上述获取的密钥,并修改电子邮件地址字段。

问题排查

在使用第三方 API 时,可能会因多种原因而发生错误,例如:

  • 客户端向服务器发出的请求的格式与 API 预期的格式不符。
  • 客户端期望的响应格式与实际遇到的格式不同。
  • 使用无效令牌或密钥的客户,或将值保留为占位符的客户。
  • 客户端达到使用量上限。
  • 提供无效参数的客户端。

在所有这些情况以及其他情况下,确定问题原因的第一步是检查导致错误的响应的详细信息。

解析回答

默认情况下,任何返回错误(状态代码为 400 或更高)的响应都会被 Google Ads 脚本引擎抛出。

如需防止此行为,并允许检查错误和错误消息,请将可选参数的 muteHttpExceptions 属性设置为 UrlFetchApp.fetch。例如:

const params = {
  muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(url, params);
if (response.getResponseCode() >= 400) {
  // ... inspect error details...
}

常见状态代码

  • 200 OK 表示成功。如果响应不包含预期数据,请考虑以下情况:

    • 某些 API 允许指定要使用的字段和/或响应格式。如需了解详情,请参阅 API 文档。
    • 一个 API 可能有多个可调用的资源。请参阅相关文档,确定是否可以使用其他更合适的资源,并返回所需的数据。
    • 自编写代码以来,该 API 可能已发生变化。请参阅文档或咨询开发者以获取说明。
  • 400 Bad Request 通常表示发送到服务器的请求的格式或结构存在问题。检查请求并将其与 API 规范进行比较,以确保其符合预期。如需详细了解如何检查请求,请参阅检查请求

  • 401 Unauthorized 通常表示在调用 API 时未提供或未成功执行授权。

    • 如果 API 使用基本授权,请确保在请求中构建并提供 Authorization 标头。
    • 如果 API 使用 OAuth 2.0,请确保已获取访问令牌,并将其作为不记名令牌提供。
    • 对于任何其他授权变体,请确保提供请求所需的凭据。
  • 403 Forbidden 表示用户无权访问所请求的资源。

    • 确保已向用户授予必要的权限,例如在基于文件的请求中授予用户对文件的访问权限。
  • 404 Not Found 表示请求的资源不存在。

    • 检查用于 API 端点的网址是否正确。
    • 如果提取资源,请检查所引用的资源是否存在(例如,对于基于文件的 API,请检查文件是否存在)。

检查请求

当 API 响应表明请求格式有误(例如,返回 400 状态代码)时,检查请求非常有用。为了帮助检查请求,UrlFetchApp 有一个 fetch() 方法的配套方法,称为 getRequest(url, params)

此方法不会向服务器发送请求,而是构建本应发送的请求,然后返回该请求。这样,用户就可以检查请求的各个元素,确保请求看起来正确无误。

例如,如果请求中的表单数据由许多串联在一起的字符串组成,则错误可能在于您创建的用于生成该表单数据的函数。最简单的形式:

const request = UrlFetchApp.getRequest(url, params);
console.log(request);
// Now make the fetch:
const response = UrlFetchApp.fetch(url, params);
// ...

将允许您检查请求的元素。

记录请求和响应

为了帮助您完成检查第三方 API 的请求和响应的整个过程,以下辅助函数可用作 UrlFetchApp.fetch() 的替代函数,用于记录请求和响应。

  1. 将代码中的所有 UrlFetchApp.fetch() 实例替换为 logUrlFetch()

  2. 将以下函数添加到脚本的末尾。

    function logUrlFetch(url, opt_params) {
      const params = opt_params || {};
      params.muteHttpExceptions = true;
      const request = UrlFetchApp.getRequest(url, params);
      console.log('Request:       >>> ' + JSON.stringify(request));
      const response = UrlFetchApp.fetch(url, params);
      console.log('Response Code: <<< ' + response.getResponseCode());
      console.log('Response text: <<< ' + response.getContentText());
      if (response.getResponseCode() >= 400) {
        throw Error('Error in response: ' + response);
      }
      return response;
    }
    

执行脚本时,系统会将所有请求和响应的详细信息记录到控制台,以便您更轻松地进行调试。