サードパーティ API

Google 広告スクリプトの強力な機能の 1 つは、サードパーティ API のデータやサービスと統合できることです。

このガイドでは、他のサービスに接続するスクリプトを作成する際に役立つ次のコンセプトについて説明します。

  • HTTP リクエストの送信: UrlFetchApp を使用して外部 API にアクセスする方法。
  • 認証: 一般的な認証シナリオについて説明します。
  • レスポンスの解析: 返された JSON データと XML データを処理する方法。

また、これらのコンセプトを示す一般的な API のサンプルも含まれています。

UrlFetchApp でデータを取得する

UrlFetchApp は、サードパーティ API の操作に必要なコア機能を提供します。

次の例は、OpenWeatherMap から天気データを取得する方法を示しています。認可スキームと API が比較的シンプルであるため、OpenWeatherMap を選択しました。

リクエストを作成する

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());

このコードを実行すると、長い JSON テキスト文字列が Google 広告スクリプトのログウィンドウに書き込まれます。

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

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 のドキュメントで説明されているように、JSON 形式にシリアル化されたオブジェクトが Slack に送信されます。これには 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 ペアはフォームデータに変換されます。

    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: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 Authentication の使用を示す 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 に直接進むことができます。これは、ワンレッグ OAuth 1.0 と呼ばれます。

OAuth1

Google 広告スクリプトにおける OAuth 1.0

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

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

OAuth 2.0

OAuth 2.0 は、一般的な API でユーザーデータへのアクセスを提供するために使用されます。特定のサードパーティ サービスのアカウントのオーナーは、特定のアプリにユーザーデータへのアクセスを許可する権限を付与します。メリットは、オーナーが次のことができることです。

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

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

スクリプト以外

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

Google 広告スクリプト アプリケーションに付与するアクセス権を指定します。通常は、クライアント ID が割り当てられます。これにより、OAuth 2 を使用して、サードパーティ サービス内のユーザーデータにアクセスできるアプリケーションと、そのデータのどの部分を表示または変更できるかを制御できます。

スクリプト内

リモート サーバーで承認する。サーバーが許可した付与タイプに応じて、フローと呼ばれる異なる一連の手順に従う必要がありますが、最終的には、後続のすべてのリクエストでそのセッションに使用されるアクセス トークンが発行されます。

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 の例

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

スクリプトを作成する
  1. API Console で新しいプロジェクトを作成し、DoubleClick ガイドの手順に沿ってクライアント ID、クライアント シークレット、更新トークンを取得します。必ず DoubleClick Search 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 Execution API)を有効にします。
  6. メニューの [認証情報] 項目から OAuth 認証情報を作成します。
  7. スクリプトに戻り、[公開] > [Execution 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

通常、レスポンス形式として使用する場合は、XML よりも JSON のほうが簡単です。ただし、発生する可能性がある問題がいくつかあります。

回答の検証

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 呼び出しからのレスポンスを解析するには、XmlServiceparse メソッドを使用します。

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 に分離しています。たとえば、Soccer API へのアクセスを購入しても、Tennis API へのアクセスは購入しない場合があります。作成する各アプリケーションには、異なるスポーツと異なるキーを関連付けることができます。

  1. [Applications] で [Create a new Application] をクリックします。アプリケーションに名前と説明を付け、ウェブサイト フィールドは無視します。
  2. [サッカー トライアル ヨーロッパ 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() があります。

このメソッドは、サーバーにリクエストを送信する代わりに、送信されたリクエストを作成して返します。これにより、ユーザーはリクエストの要素を検査して、リクエストが正しいことを確認できます。

たとえば、リクエスト内のフォームデータが連結された多くの文字列で構成されている場合、そのフォームデータを生成するために作成した関数にエラーがある可能性があります。簡単に言うと:

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;
    }
    

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