「GASから外部のAPIを呼べるらしい」と聞いて調べてみたものの、UrlFetchApp とか JSON.parse とか、いきなり知らない単語が並んで手が止まってしまった……。私も最初はそうでした。
しかも、コードをコピペして動かしたのに、エラーも出ないのにシートが空のまま。「何が起きているの?」となるのが、API初心者のあるあるですよね。
この記事では、APIキーがいらない公開APIを使って、GASでデータを取得し、スプレッドシートに書き込むまでを、小さなコードで一緒にやってみましょう。最後に、失敗したときに原因が分かるよう、エラーの確認方法もつけます。
-
UrlFetchAppでGET通信する基本形 - JSONを
JSON.parseで扱う方法 - 取得したデータをシートに書き込む方法
- レスポンスコードの確認と
try/catchでのエラー処理 - よくあるつまずきと確認ポイント
結論:UrlFetchAppで取得し、JSON.parseで読めばいい
先に結論です。
- 外部のURLにアクセスするには、GASの
UrlFetchApp.fetch(url)を使います - 返ってきた文字列は、
getContentText()で取り出し、JSON.parse()でJavaScriptの配列やオブジェクトに変換します - 変換できたら、あとは普通の配列として、シートに書き込めます
- 失敗に気づけるよう、レスポンスコードの確認と
try/catchを入れておきます
準備:使う公開APIとシートを用意する
今回は、練習用に公開されている JSONPlaceholder の投稿データAPIを使います。APIキーの登録は不要なので、すぐに試せます。
- 1
https://jsonplaceholder.typicode.com/posts?_limit=5このURLをブラウザで開くと、投稿データが5件、JSONで表示されます。形は次のような配列です(値は省略しています)。
- 1
- 2
- 3
- 4
[
{ "userId": 1, "id": 1, "title": "(タイトルの文字列)", "body": "(本文の文字列)" },
{ "userId": 1, "id": 2, "title": "(タイトルの文字列)", "body": "(本文の文字列)" }
]別のAPIを使うときは、そのサービスの利用規約や、キーの要否を事前に確認してください。この記事の例は、練習用のAPIだけを使っています。
シートの準備はこの2つです。
- Googleスプレッドシートを新しく作り、シート名を
postsにします - 「拡張機能」→「Apps Script」を開きます
エディタの開き方に不安があれば、Googleスプレッドシートを開くための手順も見ておきましょう。
まずはGETして、中身をログで見てみる
いきなりシートに書くのではなく、最初は「ちゃんと取れているか」をログで見るところから始めましょう。
- 1
- 2
- 3
- 4
- 5
function fetchTest() {
const response = UrlFetchApp.fetch('https://jsonplaceholder.typicode.com/posts?_limit=5');
console.log(response.getResponseCode());
console.log(response.getContentText());
}- 上のコードを貼って保存し、
fetchTestを選んで「実行」します - 初回は承認を求める画面が出るので、案内に従って許可します
- 画面下の実行ログに、
200と、JSONの文字列が出ていれば成功です
200 はHTTPのステータスコードで、「正常に取得できた」という意味です。getContentText() で返ってくるのは、まだただの文字列です。ここがポイントなので、次で変換します。
JSON.parseで配列にして、シートに書き込む
文字列のままではシートに書けないので、JSON.parse() でJavaScriptの配列に変換します。変換後は、post.id や post.title のように、キーの名前で値を取り出せます。
次が、シートへの書き込みまで含めたコードです。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
const API_URL = 'https://jsonplaceholder.typicode.com/posts?_limit=5';
const SHEET_NAME = 'posts';
function importPosts() {
const response = UrlFetchApp.fetch(API_URL);
const posts = JSON.parse(response.getContentText());
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
const rows = posts.map(post => [post.id, post.userId, post.title]);
sheet.clearContents();
sheet.getRange(1, 1, 1, 3).setValues([['id', 'userId', 'title']]);
sheet.getRange(2, 1, rows.length, 3).setValues(rows);
}流れを分けて見てみましょう。
| 処理 | 使っているもの |
|---|---|
| APIにアクセスする | UrlFetchApp.fetch(API_URL) |
| 文字列を配列に変換する | JSON.parse(response.getContentText()) |
| 必要な項目だけを取り出す | posts.map(post => [post.id, post.userId, post.title]) |
| シートを一度空にする | sheet.clearContents() |
| 見出しとデータを書く | getRange(...).setValues(...) |
setValues() には、「行の配列の配列」を渡す必要があります。map で [[1, 1, 'タイトル'], ...] の形にしているのは、そのためです。
実行して、シートに見出しと5行のデータが入れば成功です。コードの実行方法に迷ったら、GoogleAppsScriptのコードを実行する方法を見てみてください。
エラーに気づけるようにする(レスポンスコードと try/catch)
ここまでのコードは、うまくいく前提で書いています。ただ、現実にはURLを打ち間違えたり、相手のサービスが止まっていたりします。そこで、失敗に気づける形に書き直します。
UrlFetchApp.fetch() は、既定ではHTTPエラー(4xxや5xx)のときに例外を投げて止まります。一方、オプションの muteHttpExceptions: true を付けると、エラーでも例外にならず、レスポンスコードを自分で確認できます。今回はこちらを使って、コードを自分で見て判断します。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
const API_URL = 'https://jsonplaceholder.typicode.com/posts?_limit=5';
const SHEET_NAME = 'posts';
function importPosts() {
try {
const response = UrlFetchApp.fetch(API_URL, { muteHttpExceptions: true });
const code = response.getResponseCode();
if (code !== 200) {
throw new Error(`APIがエラーを返しました(HTTP ${code})`);
}
const posts = JSON.parse(response.getContentText());
if (posts.length === 0) {
throw new Error('取得できたデータが0件でした');
}
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
if (!sheet) {
throw new Error(`シート「${SHEET_NAME}」が見つかりません`);
}
const rows = posts.map(post => [post.id, post.userId, post.title]);
sheet.clearContents();
sheet.getRange(1, 1, 1, 3).setValues([['id', 'userId', 'title']]);
sheet.getRange(2, 1, rows.length, 3).setValues(rows);
console.log(`${rows.length}件を書き込みました`);
} catch (e) {
console.error(e.message);
throw e;
}
}確認しているポイントは3つです。
- レスポンスコードが200かどうか
- データが0件ではないか
- シートが存在するか
catch の中では、メッセージをログに出したうえで、throw e で改めてエラーにしています。こうしておくと、実行ログに「失敗」として残ります。握りつぶしてしまうと、失敗しているのに成功に見えてしまうので気をつけましょう。
試しに、API_URL の posts を postss のように間違えて実行してみてください。404が返ってきて、ログに「APIがエラーを返しました」と出るはずです。
よくあるつまずき
| 症状 | よくある原因 | 確認すること |
|---|---|---|
Cannot read properties of null が出る | シート名が違う、または単体のスクリプトで getActiveSpreadsheet() を使っている | シート名が posts か。スプレッドシートの「拡張機能」→「Apps Script」から開いたか |
| シートが空のまま | 実行に失敗している、または別のシートを見ている | 実行ログのエラーを確認する |
| HTTP 404 が返る | URLの打ち間違い | ブラウザで同じURLを開いて確認する |
SyntaxError が出る | 返ってきたものがJSONではない(HTMLなど) | console.log(response.getContentText()) で中身を見る |
| 承認の画面が出る | 初回に外部へ接続する許可が必要 | 内容を確認して、許可する |
| 前回のデータが残っている | シートを空にしていない | clearContents() を入れているか確認する |
APIまわりで困ったら、まず「ステータスコード」と「返ってきた文字列」をログに出すことをおすすめします。原因の半分は、これで分かります。
次の一歩
公開APIで1回できたら、次は応用です。
- URLの
?_limit=5を変えて、取得件数を変えてみる - シートに書く列を増やして、
bodyも取り出してみる - 時間主導型トリガーを付けて、毎日自動で取得する(GASを毎日自動で動かす|時間主導型トリガーの設定手順)
GAS全体の学ぶ順番を整理したい方は、GAS学習の進め方|既存記事をつなぐ学習マップが参考になります。
また、GASではなく「何かが起きたらAPIで通知を受け取って動かす」方向に進みたい方は、n8nのトリガー設計|Webhookで始める「起きたら動く」自動化も読んでみてください。
関連する本・記事
本:『Google Apps Script × 生成AI 全自動仕事術』
GASで日々の作業を自動化する流れを、生成AIに頼みながら進める本です。コードを一から書くのが不安な方に向いています。
記事:
- GAS学習の進め方|既存記事をつなぐ学習マップ:GASの記事を、学ぶ順番にまとめたマップです
- n8nのトリガー設計|Webhookで始める「起きたら動く」自動化:APIやWebhookを使った別の自動化の入口です
- GASを毎日自動で動かす|時間主導型トリガーの設定手順:取得処理を定期実行したいときに