サードパーティ API

Google 広告スクリプトの強力な機能の 1 つに、サードパーティ 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]

この URL は、認可の最初の例を示しています。パラメータ 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 広告スクリプトのログ ウィンドウに長い JSON テキストが書き込まれます。

次のステップでは、これをスクリプト内で使用できる形式に変換します。

JSON データ

多くの API は JSON 形式でレスポンスを提供します。これは JavaScript オブジェクトの単純なシリアル化を表します。オブジェクト、配列、基本型を文字列として表して転送できます。

OpenWeatherMap から返された JSON 文字列を JavaScript オブジェクトに変換するには、組み込みの JSON.parse メソッドを使用します。上記の例を続けると、次のようになります。

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

JSON.parse メソッドは、文字列を name プロパティを持つオブジェクトに変換します。

さまざまな形式の API レスポンスの処理について詳しくは、レスポンスを解析するをご覧ください。

エラー処理

サードパーティ API は頻繁に変更され、予期しないレスポンス値を生成することが多いため、スクリプトでサードパーティ API を使用する場合は、エラー処理を考慮することが重要です。たとえば、次のような場合です。

  • API の URL やパラメータが、ユーザーの知らないうちに変更される可能性があります。
  • 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 で POST データを送信する

OpenWeatherMap を使用した入門用の例では、データを取得しただけでした。通常、リモート サーバーで状態を変更しない API 呼び出しは HTTP GET メソッドを使用します。

GET メソッドは UrlFetchApp のデフォルトです。ただし、SMS メッセージを送信するサービスへの呼び出しなど、一部の API 呼び出しでは、POSTPUT などの別の方法が必要になります。

UrlFetchAppPOST 呼び出しを使用する例として、次の例では、コラボレーション メッセージング アプリケーションである Slack との統合を示し、Slack ユーザーとグループに Slack メッセージを送信します。

Slack を設定する

このガイドは、Slack アカウントにすでに登録していることを前提としています。

前の例の OpenWeatherMap と同様に、メッセージの送信を有効にするにはトークンを取得する必要があります。Slack には、チームにメッセージを送信できる一意の URL(受信 Webhook)があります。

[Add Incoming WebHooks Integration] をクリックして手順に沿って操作し、受信 Webhook を設定します。プロセスは、メッセージの送受信に使用する URL を発行する必要があります。

POST リクエストを行う

着信 Webhook を設定したら、POST リクエストを行うには、UrlFetchApp.fetch に渡される options パラメータでいくつかの追加プロパティを使用するだけです。

  • method: 前述のように、デフォルトは GET ですが、ここではオーバーライドして POST に設定します。
  • payload: POST リクエストの一部としてサーバーに送信されるデータです。この例では、Slack は Slack ドキュメントに記載されているように、JSON 形式にシリアル化されたオブジェクトを想定しています。これには、JSON.stringify メソッドを使用し、Content-Typeapplication/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 ドキュメントのメッセージのフォーマットをご覧ください。

フォームデータ

上記の例では、POST リクエストの payload プロパティとして JSON 文字列を使用する方法を示しました。

payload の形式に応じて、UrlFetchAppPOST リクエストの構築に異なるアプローチを使用します。

  • payload が文字列の場合、文字列引数はリクエストの本文として送信されます。
  • payload がオブジェクトの場合(値のマップなど):

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

    Key-Value ペアは form-data に変換されます。

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

    また、リクエストの Content-Type ヘッダーが application/x-www-form-urlencoded に設定されています。

一部の API では、POST リクエストを送信する際にフォームデータを使用する必要があります。そのため、JavaScript オブジェクトからフォームデータへの自動変換を覚えておくと便利です。

HTTP 基本認証

HTTP 基本認証は、最もシンプルな認証形式の 1 つであり、多くの API で使用されています。

認証は、各リクエストの HTTP ヘッダーにエンコードされたユーザー名とパスワードを付加することで実現されます。

HTTP 基本認証

リクエストを作成する

認証済みリクエストを生成するには、次の手順が必要です。

  1. ユーザー名とパスワードをコロンで結合して、パスフレーズを作成します(例: username:password)。
  2. パスフレーズを Base64 でエンコードします(例: username:passworddXNlcm5hbWU6cGFzc3dvcmQ= になります)。
  3. リクエストに Authorization ヘッダーを Authorization: Basic <encoded passphrase> 形式で付加します。

次のスニペットは、Google 広告スクリプトでこれを実現する方法を示しています。

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 Basic 認証の使用方法を示す 2 つのサンプルが含まれています。

Plivo

Plivo は、API を使用して SMS メッセージの送受信を容易にするサービスです。このサンプルは、メッセージの送信を示しています。

  1. Plivo に登録します。
  2. サンプル スクリプトを Google 広告の新しいスクリプトに貼り付けます。
  3. PLIVO_ACCOUNT_AUTHIDPLIVO_ACCOUNT_AUTHTOKEN の値を管理ダッシュボードの値に置き換えます。
  4. エラー通知のスクリプトで指定されているメールアドレスを挿入します。
  5. Plivo を使用するには、番号を購入するか、トライアル アカウントに番号を追加する必要があります。試用アカウントで使用できるサンドボックス番号を追加します。
  6. 送信者として表示される番号と受信者の番号の両方を追加します。
  7. スクリプトの PLIVO_SRC_PHONE_NUMBER を、登録したサンドボックス番号のいずれかに更新します。これには、国際国コードを含める必要があります(英国の電話番号の場合は 447777123456 など)。

Twilio

Twilio は、API を使用して SMS メッセージの送受信を容易にする別のサービスです。このサンプルは、メッセージの送信を示しています。

  1. Twillio に登録します。
  2. サンプル スクリプトを Google 広告の新しいスクリプトに貼り付けます。
  3. TWILIO_ACCOUNT_SIDTWILIO_ACCOUNT_AUTHTOKEN の値は、アカウント コンソール ページに表示されている値に置き換えます。
  4. TWILIO_SRC_PHONE_NUMBER は、ダッシュボードの番号に置き換えます。これは、Twilio がメッセージの送信を承認した番号です。

OAuth 1.0

多くの人気サービスでは、認証に OAuth が使用されています。OAuth には、さまざまなフレーバーとバージョンがあります。

HTTP 基本認証では、ユーザーは 1 つのユーザー名とパスワードしか持っていませんが、OAuth では、サードパーティ製アプリケーションに固有の認証情報を使用して、ユーザーのアカウントとデータへのアクセス権をサードパーティ製アプリケーションに付与できます。また、アクセス権の範囲もそのアプリケーションに固有のものになります。

OAuth 1.0 の背景については、OAuth Core ガイドをご覧ください。特に、6. OAuth を使用した認証。完全な 3 レッグ OAuth 1.0 では、プロセスは次のようになります。

  1. アプリケーション(「コンシューマー」)がリクエスト トークンを取得します。
  2. ユーザーがリクエスト トークンを承認します。
  3. アプリケーションがリクエスト トークンをアクセス トークンと交換します。
  4. 後続のすべてのリソース リクエストでは、アクセス トークンが署名付きリクエストで使用されます。

サードパーティ サービスがユーザー操作なしで OAuth 1.0 を使用する場合(Google 広告スクリプトで必要な場合など)、ステップ 1、2、3 は実行できません。そのため、一部のサービスでは構成コンソールからアクセス トークンを発行し、アプリケーションが直接ステップ 4 に進むことができます。これは、1 レッグ OAuth 1.0 と呼ばれます。

OAuth1

Google 広告スクリプトの OAuth 1.0

Google 広告スクリプトの場合、通常、各スクリプトはアプリケーションとして解釈されます。通常、サービスのコンソールまたは管理設定ページで次の操作を行う必要があります。

  • スクリプトを表すアプリケーション構成を設定します。
  • スクリプトに拡張する権限を指定します。
  • ワンレッグ OAuth で使用するコンシューマ キー、コンシューマ シークレット、アクセス トークン、アクセス シークレットを取得します。

OAuth 2.0

OAuth 2.0 は、ユーザーデータへのアクセスを提供するために一般的な API で使用されています。特定のサードパーティ サービスのオーナーが、特定のアプリケーションにユーザーデータへのアクセスを許可します。オーナーのメリットは次のとおりです。

  • アカウント認証情報をアプリケーションと共有する必要がない。
  • どのアプリケーションがデータにアクセスできるか、どの程度アクセスできるかを個別に制御できます。(たとえば、付与されるアクセス権が読み取り専用である場合や、データのサブセットのみにアクセスできる場合があります)。

Google Ads スクリプトで OAuth 2.0 対応サービスを使用するには、次の手順を行います。

スクリプトの外部

Google 広告スクリプトがサードパーティ API を介してユーザーデータにアクセスするための承認を付与します。ほとんどの場合、サードパーティ サービスのコンソールでアプリケーションを設定する必要があります。このアプリケーションは、Google 広告スクリプトを表します。

Google 広告スクリプトのアプリケーションに付与するアクセス権を指定します。通常は、クライアント 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 フローのよりシンプルな形式の 1 つです。この形式では、アプリケーションがアプリケーション固有の ID とシークレットを交換して、有効期限付きのアクセス トークンの発行を受けます。

クライアント認証情報

// 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 には、ユーザーが認可コード付与をステップ実行して更新トークンを取得できる UI が用意されています。

右上にある設定ボタンを使用すると、OAuth フローで使用するすべてのパラメータ(以下を含む)を定義できます。

  • 認証エンドポイント: 認証フローの開始点として使用されます。
  • トークン エンドポイント: 更新トークンとともに使用して、アクセス トークンを取得します。
  • クライアント ID とシークレット: アプリケーションの認証情報。

OAuth2 Playground

更新トークンの使用状況

初期承認が完了すると、サービスは更新トークンを発行できます。このトークンは、クライアント認証情報フローと同様の方法で使用できます。以下に 2 つの例を示します。

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

検索広告 360 の例

検索広告 360 は、更新トークンで使用できる API の一例です。このサンプルでは、スクリプトがレポートを生成して返します。実行できるその他のアクションの詳細については、検索広告 360 API リファレンスをご覧ください。

スクリプトを作成する
  1. API Console で新しいプロジェクトを作成し、検索広告 360 ガイドの手順に沿ってクライアント ID、クライアント シークレット、更新トークンを取得します。このとき、検索広告 360 API が有効になっていることを確認してください。
  2. サンプル スクリプトを Google 広告の新しいスクリプトに貼り付けます。
  3. コードリストの下にサンプル OAuth2 ライブラリを貼り付けます。
  4. クライアント ID、クライアント シークレット、更新トークンの正しい値を含むようにスクリプトを修正します。

Apps Script Execution API の例

この例では、Apps Script Execution API を使用して Apps Script で関数を実行する方法を示します。これにより、Google 広告スクリプトから Apps Script を呼び出すことができます。

Apps Script スクリプトを作成する

新しいスクリプトを作成する。次のサンプルは、ドライブから 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 Script を構成する
  1. スクリプトを保存します。
  2. [リソース] > [Cloud Platform プロジェクト] をクリックします。
  3. プロジェクト名をクリックして、API Console に移動します。
  4. [API とサービス] に移動します。
  5. 適切な API(この場合は Drive APIApps Script 実行 API)を有効にします。
  6. メニューの [認証情報] 項目から OAuth 認証情報を作成します。
  7. スクリプトに戻り、[公開] > [API 実行可能ファイルとしてデプロイ] から実行するスクリプトを公開します。
Google 広告スクリプトを作成する
  1. サンプル スクリプトを Google 広告の新しいスクリプトに貼り付けます。
  2. また、コードリストの下にサンプル OAuth2 ライブラリを貼り付けます。
  3. クライアント ID、クライアント シークレット、更新トークンの正しい値を含むようにスクリプトを修正します。

サービス アカウント

上記の認可タイプの代替手段として、サービス アカウントの概念があります。

サービス アカウントは、ユーザーデータへのアクセスに使用されないという点で上記とは異なります。認証後、リクエストはプロジェクトの所有者であるユーザーとしてではなく、アプリケーションの代わりにサービス アカウントによって行われます。たとえば、サービス アカウントが Drive API を使用してファイルを作成した場合、そのファイルはサービス アカウントに属し、デフォルトではプロジェクトのオーナーはアクセスできません。

Google Natural Language API の例

Natural Language API は、テキストの感情分析エンティティ分析を提供します。

この例では、広告文(見出しや説明文など)の感情を計算する方法を示します。これにより、メッセージのポジティブさとメッセージの大きさを測定できます。たとえば、「ケーキを販売しています」と「ロンドンで最高のケーキを販売しています」では、どちらが優れているでしょうか。今すぐ購入しましょう。

スクリプトを設定する
  1. API Console で新しいプロジェクトを作成する
  2. Natural Language API を有効にする
  3. プロジェクトの課金を有効にします。
  4. サービス アカウントを作成します。認証情報の JSON ファイルをダウンロードします。
  5. サンプル スクリプトを Google 広告の新しいスクリプトに貼り付けます。
  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 の構築に依然としてよく使用される形式です。API 呼び出しからのレスポンスは、XmlService parse メソッドを使用して解析できます。

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 が提供する幅広いスポーツ フィードの 1 つです。

Sportradar アカウントを設定する
  1. Sportradar デベロッパー サイトに移動します。
  2. トライアル アカウントに登録します。
  3. 登録が完了したら、アカウントにログインします。
  4. ログインしたら、[MyAccount] に移動します。

Sportradar は、さまざまなスポーツを別々の API に分離しています。たとえば、サッカー API へのアクセス権は購入しても、テニス API へのアクセス権は購入しない場合があります。作成する各アプリケーションには、異なるスポーツと異なるキーを関連付けることができます。

  1. [Applications] で [Create a new Application] をクリックします。アプリケーションに名前と説明を付け、ウェブサイト フィールドは無視します。
  2. [Issue a new key for Soccer Trial Europe v2] のみを選択します。
  3. [アプリケーションの登録] をクリックします。

成功すると、新しい API キーが表示されたページが表示されます。

  1. サンプル スクリプトを Google 広告の新しいスクリプトに貼り付けます。
  2. リスティングの API キーを上記で取得したキーに置き換え、メールアドレス フィールドを編集します。

トラブルシューティング

サードパーティ API を使用している場合、次のようなさまざまな理由でエラーが発生することがあります。

  • API で想定されていない形式でサーバーにリクエストを発行するクライアント。
  • 予期しない形式のレスポンスを受け取ったクライアント。
  • 無効なトークンやキーを使用しているクライアント、またはプレースホルダのままになっている値。
  • 使用量上限に達したクライアント。
  • クライアントが無効なパラメータを指定している。

このような場合やその他の場合、問題の原因を特定するための最初のステップは、エラーの原因となっているレスポンスの詳細を調べることです。

レスポンスを解析する

デフォルトでは、エラー(400 以上のステータス コード)を返すレスポンスは、Google 広告スクリプト エンジンによってスローされます。

この動作を防ぎ、エラーとエラー メッセージを検査できるようにするには、省略可能なパラメータの 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 エンドポイントに使用されている URL が正しいことを確認します。
    • リソースを取得する場合は、参照されているリソースが存在することを確認します(たとえば、ファイルベースの 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;
    }
    

スクリプトを実行すると、すべてのリクエストとレスポンスの詳細がコンソールに記録されるため、デバッグが容易になります。