GASから外部のWebページやAPIへリクエストを送るときは、UrlFetchApp.fetchを使います。取得結果は文字列そのものではなくHTTPResponseとして返るため、ステータスコードと本文を分けて取り出すのが基本です。
「実行は終わったのにデータが取れない」ときは、通信先のURL、HTTPの応答、本文の形式を順に確認します。最初からスプレッドシートへの書き込みまで組み込まず、取得だけを確認すると原因を追いやすくなります。
まずGETでページを取得する
次の例はexample.comのHTMLを取得し、HTTPステータスと本文の文字数だけをログへ出します。外部サービスへのデータ登録や、スプレッドシートの更新は行いません。
function fetchDemoPage() {
const response = UrlFetchApp.fetch('https://www.example.com/', {
method: 'get',
muteHttpExceptions: true
});
const status = response.getResponseCode();
const text = response.getContentText();
console.log('HTTP ' + status);
console.log('本文の文字数: ' + text.length);
if (status < 200 || status >= 300) {
throw new Error('取得に失敗しました: HTTP ' + status);
}
return text;
}
- Apps Scriptの練習用プロジェクトにコードを保存します。
- 関数一覧からfetchDemoPageを選んで実行します。
- 初回に認可を求められたら、使用するアカウントと要求内容を確認します。
- 実行ログでHTTPステータスと文字数を確認します。
取得先がHTMLページなので、この結果をそのままJSON.parseへ渡してもJSONデータにはなりません。ページを取得できたことと、APIとして使える形式のデータが返ったことは分けて判断します。
UrlFetchAppのオプションと必要な認可範囲はGoogle公式リファレンスで確認できます。マニフェストにスコープを明示しているプロジェクトでは、外部リクエスト用のスコープも確認してください。
JSONを返すAPIでは、HTTPを確認してから解析する
次の関数には、利用するAPIの公式資料で確認したHTTPSのURLを渡します。関数を定義しただけでは通信は発生しません。認証が必要なAPIでは、提供元の指定に合わせたヘッダーなどを追加する必要があります。
function fetchJsonGet(url) {
if (typeof url !== 'string' || !url.startsWith('https://')) {
throw new Error('APIのHTTPS URLを指定してください');
}
const response = UrlFetchApp.fetch(url, {
method: 'get',
headers: { Accept: 'application/json' },
muteHttpExceptions: true
});
const status = response.getResponseCode();
if (status < 200 || status >= 300) {
throw new Error('APIがエラーを返しました: HTTP ' + status);
}
const text = response.getContentText();
if (text.trim() === '') return null;
try {
return JSON.parse(text);
} catch (error) {
throw new Error('応答は成功しましたが、本文がJSONではありません');
}
}
Acceptヘッダーは、JSON形式の応答を希望することを伝える設定です。HTMLしか返さないURLをJSONへ変換する機能ではありません。ログイン画面やエラーページがHTTP 200で返るサービスもあるため、成功コードだけで判定を終えないようにします。
JSONの解析後は、必要な項目があるかも確認します。たとえば配列を想定しているならArray.isArrayで調べ、空の配列を「通信失敗」と決めつけず、検索結果が0件だった可能性も分けて扱います。
muteHttpExceptionsはエラーを成功に変える設定ではない
muteHttpExceptionsをtrueにすると、HTTPエラーの応答も取得して確認できます。その後でgetResponseCodeを調べ、失敗時の処理を自分で書きます。URLの解決や通信自体の失敗など、すべての例外を抑える設定ではありません。
| 応答の例 | 先に確認する項目 |
|---|---|
| 401・403 | 認証情報、権限、接続元制限 |
| 404 | APIのパス、バージョン、リソースID |
| 429 | 提供元のレート制限と再試行条件 |
| 5xx | 提供元の障害情報、時間を空けた再試行の可否 |
本文やヘッダーの取得方法はHTTPResponseの公式リファレンスを参照できます。エラー本文に個人情報やトークンが含まれることもあるため、本文全体を常にログへ出す作りは避け、必要な項目だけを記録します。
POSTでJSONを送る場合に変えるところ
APIがJSONのPOSTを要求するなら、methodをpost、contentTypeをapplication/jsonにし、payloadにはJSON.stringifyで変換した文字列を渡します。フォーム形式を要求するAPIへ同じ設定を流用すると、相手が本文を解釈できない場合があります。
POSTはデータを作成・更新することがあります。まず提供元のテスト環境やテスト用データで確認し、失敗したからと即座に同じ要求を繰り返さないようにします。通信が途切れても相手側では登録が完了している場合があるため、重複防止の仕組みがあるか確認します。
ブラウザでは見られるのにGASから取得できない場合
UrlFetchAppはGoogleの実行環境からアクセスします。手元のブラウザでログイン済みでも、そのCookieが自動でGASへ引き継がれるわけではありません。ブラウザ用の画面URLではなく、サービスが用意するAPIと認証方法を使います。
また、接続元IPの制限、外部アクセスの制限、実行回数や時間の上限も確認対象です。まず1回のGETを成功させ、次にJSONの項目を確認し、最後にシートへの保存などを加える順番なら、どこで失敗したかを把握しやすくなります。
