Web API連携の基礎(UrlFetchApp)

Web API連携の基礎(UrlFetchApp)を説明する女性
目次

クローズドな環境からオープンなWebの世界へ:API連携の意義と可能性

これまでの章では、スプレッドシート内のデータ操作や、Google Workspace内のサービス間連携を中心に、閉じた環境での自動化技術を磨いてきました。しかし、現代のシステム開発において、自身の環境にあるデータだけで完結する業務は稀です。天気予報、株価、為替レート、最新のニュース、そして高度なAIによる推論など、ビジネスに必要な情報の多くは外部のWeb上に存在しています。これらの膨大なリソースにプログラムからアクセスし、自社のシステムの一部として取り込む技術が「API連携」です。

APIとはApplication Programming Interfaceの略であり、外部のアプリケーションやデータを、自身のプログラムから利用するための接続口を指します。Google Apps Script(GAS)において、このAPI連携の中核を担うのが「UrlFetchApp」クラスです。このクラスを使いこなすことは、Googleのサーバーからインターネット上のあらゆるサーバーへリクエストを投げ、応答を受け取る能力を手に入れることを意味します。

これにより、あなたのスクリプトは単なる表計算の補助ツールから、世界中のデータと接続し、複合的な処理を行う「ハブ」としての役割を果たすアプリケーションへと進化します。本章では、HTTP通信の基礎から、GASにおける具体的な実装方法、そして開発者が意識すべきセキュリティとエラーハンドリングまで、API連携に必要な知識を包括的に解説します

HTTP通信のメカニズム:リクエストとレスポンスの構造的理解

Web APIを利用するためには、Webの基本プロトコルであるHTTP(Hypertext Transfer Protocol)の仕組みを理解しておく必要があります。私たちが普段ブラウザでWebページを閲覧する際、ブラウザはWebサーバーに対して「このページを見せてほしい」という依頼(リクエスト)を送り、サーバーはその依頼に応じてHTMLデータなどの結果(レスポンス)を返します。API連携もこれと全く同じ構造で行われます。

ただし、人間が読むためのHTMLではなく、プログラムが処理しやすいデータ形式(主にJSON)でやり取りが行われる点が異なります。GASの開発者としてAPIを扱う際、意識すべきはリクエストの「メソッド」「ヘッダー」「ボディ」という3つの要素です。メソッドは「何をしたいか(取得、送信、削除など)」を定義し、ヘッダーは「どのような形式でデータを送るか、認証情報は何か」といったメタ情報を格納し、ボディには「実際に送るデータの中身」を記述します。

UrlFetchAppは、これらの要素を組み立て、Googleのサーバーを経由して対象のAPIサーバーへと送信し、返ってきたレスポンスを受け取る機能を提供します。この通信は同期的に行われるため、リクエストを送ってからレスポンスが返ってくるまでの間、スクリプトの処理は一時停止します。この挙動を理解しておくことは、後のタイムアウト対策やパフォーマンスチューニングにおいて重要となります。

UrlFetchAppクラスの基本操作:fetchメソッドの仕様

GASでHTTPリクエストを行うための主要なメソッドが UrlFetchApp.fetch(url, params) です。第一引数にはアクセス先のURLを文字列で指定し、第二引数にはオプションパラメータをオブジェクト形式で渡します。最も単純なGETリクエスト(データを取得する場合)であれば、URLを指定するだけで動作しますが、開発者としてAPIを扱う場合は、第二引数の params を適切に構成するスキルが求められます。

この params オブジェクトには、HTTPメソッドを指定する method、送信データを含める payload、認証情報などを記述する headers、コンテンツの種類を指定する contentType などを設定します。fetch メソッドを実行すると、サーバーからの応答が HTTPResponse オブジェクトとして返されます。このオブジェクトからは、レスポンスの本文(ボディ)を取得する getContentText()、HTTPステータスコードを取得する getResponseCode()、レスポンスヘッダーを取得する getHeaders() などのメソッドを利用できます。初心者は単に getContentText() で中身を取り出して終わりにしてしまいがちですが、堅牢なシステムを構築するためには、ステータスコードやヘッダー情報も含めて検証し、通信が正常に行われたかを厳密に判断する実装が必要です。

HTTPメソッドの使い分け:GETによる取得とPOSTによる送信

HTTPメソッドにはいくつかの種類がありますが、API連携において頻繁に使用されるのは「GET」と「POST」の2つです。GETリクエストは、サーバーから情報を「取得」するために使用されます。例えば、天気予報APIから明日の天気を取得したり、株価APIから現在の値を取得したりする場合です。

GETリクエストの特徴は、必要なパラメータをURLの末尾にクエリパラメータ(?key=value&…の形式)として付与する点です。UrlFetchAppでは、method オプションを省略するとデフォルトでGETリクエストとして扱われます。一方、POSTリクエストは、サーバーに対してデータを「送信」し、何らかの処理を依頼したり、データを登録したりする場合に使用されます。例えば、チャットツールにメッセージを通知したり、AIにプロンプトを送って回答を生成させたりする場合です。

POSTリクエストでは、送信するデータはURLではなく、リクエストの「ボディ(payload)」に含まれます。GASでPOSTリクエストを送る場合は、options オブジェクトの method プロパティに “post” を指定し、payload プロパティに送信データを設定します。APIによってはPUT(更新)やDELETE(削除)などのメソッドを使用する場合もありますが、基本となるGETとPOSTの挙動とデータの渡し方を確実に理解しておくことが、あらゆるAPIを扱うための第一歩です。

データ交換の標準フォーマット:JSONの構造とパース処理

現代のWeb APIにおいて、データの受け渡し形式として事実上の標準となっているのがJSON(JavaScript Object Notation)です。JSONは、テキストベースの軽量なデータ記述言語であり、JavaScriptのオブジェクト記法とほぼ同じ構文を持っています。APIから返ってくるデータ(レスポンスボディ)は、多くの場合、巨大なJSON文字列です。GASの response.getContentText() で取得できるのはあくまで「文字列」としてのJSONであるため、そのままではプログラム内で「名前」や「価格」といった特定の項目を取り出すことができません。

そこで必要になるのが「パース(解析)」という処理です。GAS(JavaScript)には標準で JSON オブジェクトが用意されており、JSON.parse(jsonString) メソッドを使用することで、JSON文字列をGASで扱えるオブジェクトや配列に変換できます。逆に、POSTリクエストでデータを送信する際は、GASのオブジェクトを JSON.stringify(object) メソッドを使ってJSON文字列に変換してから payload に設定する必要があります。

API連携において発生するトラブルの多くは、このJSONのパースや文字列化のミス、あるいは想定していたJSONの構造と実際のレスポンスが異なっていたことに起因します。開発者は、APIドキュメントを読み込み、返却されるJSONがどのような階層構造(オブジェクトの入れ子や配列)になっているかを正確に把握し、適切なプロパティにアクセスするコードを書く能力が求められます。

認証とセキュリティ:APIキーとアクセストークンの安全な管理

多くの有用なWeb APIは、誰でも無制限に使えるわけではなく、利用者を識別し、権限を確認するための「認証」を必要とします。認証方式には、URLにパラメータとして付与するシンプルなAPIキー方式や、HTTPヘッダーに「Bearer トークン」として含める方式、さらにはOAuth 2.0を用いた複雑な認可フローなどがあります。

どのような方式であれ、APIキーやアクセストークンは、外部サービスを利用するための「パスワード」と同等の機密情報です。これらをスクリプトのコード内に直接文字列として書き込む(ハードコーディングする)ことは、セキュリティ上、絶対に行ってはいけません。スクリプトが共有されたり、スクリーンショットに映り込んだりした際に、キーが流出し、悪用されるリスクがあるからです。GAS開発者としての正しい作法は、PropertiesService(スクリプトプロパティ)を利用することです。スクリプトエディタのプロジェクト設定から、キーと値のペアとして認証情報を保存し、コード内では PropertiesService.getScriptProperties().getProperty('API_KEY') のように呼び出します。

これにより、コード上からは機密情報を排除しつつ、プログラム実行時のみ安全に値を取得する仕組みを構築できます。APIを利用する際は、機能の実装と同じくらい、このセキュリティ管理に意識を向ける必要があります。

HTTPステータスコードの理解とエラーハンドリングの実装

APIリクエスト送信後、サーバーからはデータと共に「HTTPステータスコード」という3桁の数字が返されます。これはリクエストの結果を表す重要な信号です。代表的なものに、成功を表す「200 OK」、リクエスト内容に誤りがある「400 Bad Request」、認証に失敗した「401 Unauthorized」、リソースが見つからない「404 Not Found」、サーバー側でエラーが発生した「500 Internal Server Error」などがあります。

UrlFetchAppのデフォルトの挙動では、200番台以外のステータスコード(エラー)が返されると、スクリプト全体がそこで例外を投げて停止してしまいます。しかし、実運用では「エラーならログに残して次の処理に進む」といった柔軟な対応が必要な場合があります。これを実現するために、fetch メソッドのオプションに muteHttpExceptions: true を設定します。これを有効にすると、エラー時でも例外が発生せず、エラー内容を含んだレスポンスオブジェクトが返されます。

開発者は response.getResponseCode() でステータスコードを確認し、「もし200なら正常処理、それ以外ならエラー通知を送る」といった条件分岐(if文)を記述することで、予期せぬエラーでシステム全体がダウンすることを防ぐ、堅牢なエラーハンドリングを実装することができます。

実践:GETリクエストによる外部データの取得とスプレッドシートへの反映

理論を学んだところで、実際のコード構造をイメージしてみましょう。ここでは、公開されている天気予報APIからデータを取得し、スプレッドシートに書き込むシナリオを想定します。

まず、UrlFetchApp.fetch(url) でリクエストを送信します。この際、URLには必要なクエリパラメータ(地域IDやAPIキーなど)を含めておきます。次に、取得したレスポンスに対して getResponseCode() で200であることを確認します。

正常であれば、getContentText() でレスポンスボディ(JSON文字列)を取得し、JSON.parse() でオブジェクト化します。変換されたオブジェクトから、例えば weatherData.forecasts.temperature のように必要なデータ(明日の気温など)をピンポイントで抽出します。

最後に、抽出したデータを sheet.getRange().setValue() を使ってスプレッドシートの指定セルに書き込みます。この一連の流れが、API連携の基本パターンです。APIによっては、データが配列形式で返ってくる場合もあるため、前章で学んだループ処理と組み合わせることで、週間天気予報のような複数行にわたるデータを一括で処理することも可能になります。

実践:POSTリクエストによるデータ送信とAI連携の基礎

次に、データを送信するPOSTリクエストの実装を考えます。例として、スプレッドシート上のテキストを外部のAI APIに送信し、要約させるケースを想定します。まず、送信したいデータ(プロンプトなど)を含むオブジェクトを作成し、JSON.stringify() でJSON文字列に変換します。

これがリクエストの payload になります。次に、options オブジェクトを作成し、method に “post”、contentType に “application/json”、payload に先ほどのJSON文字列、そして headers に認証トークンを設定します。準備ができたら UrlFetchApp.fetch(endpoint, options) を実行します。

POSTリクエストの場合も、サーバーからは処理結果(要約されたテキストなど)がレスポンスとして返ってくるため、GETの時と同様にパースして抽出します。この「データを加工してJSON化し、適切なヘッダーと共に投げ、結果を受け取る」という手順は、Slackへの通知や、データベースへの登録など、あらゆる送信系APIで共通する汎用的なスキルです。特にAI連携においては、パラメータ(Temperatureなど)の調整によって応答が変わるため、オプションの設定が非常に重要になります。

APIの利用制限(レートリミット)とQuotasへの対策

外部APIを利用する際、開発者が常に意識しなければならないのが「レートリミット(利用制限)」です。多くのAPIには「1分間に60回まで」「1日1000回まで」といったアクセス頻度や回数の上限が設けられています。これを超えてリクエストを送ると、サーバーは「429 Too Many Requests」というエラーを返し、アクセスを遮断します。

また、GAS側にも UrlFetchApp の利用回数や実行時間に制限(Quotas)が存在します。例えば、forループの中でAPIリクエストを1行ごとに送信するようなコードは、すぐに制限に達してしまうだけでなく、処理速度も著しく低下します。これを回避するための対策として、可能な場合は「一括取得(Bulk API)」を利用する、リクエスト間に Utilities.sleep(1000) などを挟んでアクセス頻度を調整する、あるいは取得したデータを CacheService やスプレッドシートに一時保存して無駄なリクエストを減らすといった工夫が必要です。

開発者は、単に「動くコード」を書くだけでなく、APIプロバイダの制限とGASの制限の両方を考慮し、持続可能で効率的なシステムを設計する責任があります。

開発者としての視点:APIドキュメントを読み解く力

API連携の実装において、最も重要な資料は「APIドキュメント(仕様書)」です。ここには、エンドポイントのURL、使用可能なHTTPメソッド、必須および任意のパラメータ、認証方法、レスポンスのデータ構造、エラーコードの意味など、連携に必要なすべての情報が記載されています。

AIにコードを書かせる場合でも、AIは最新のAPI仕様や特定のマイナーなAPIの仕様を知らない可能性があります。そのため、開発者自身がドキュメントを読み、「どのURLに」「何をヘッダーに入れて」「どんなJSONを送ればよいか」を正確に把握し、AIの出力したコードが仕様に合致しているかをレビューする能力が不可欠です。

API連携は、外部システムとの対話です。相手(API)の言葉(仕様)を理解し、正しい作法(プロトコル)で話しかけること。このコミュニケーション能力こそが、API連携を成功させる鍵となります。次章では、APIから取得したデータの加工や、より複雑なテキスト処理に役立つ「正規表現」の世界へと足を踏み入れます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次