【初心者向け】GASでスプレッドシートとAPI連携する方法|基礎から実践まで

kento_morota 25分で読めます

GASとスプレッドシートのAPI連携とは

「毎日の受注データを手入力している」「複数のツールを行き来してデータをコピペしている」――そんな作業に時間を取られていませんか?

Google Apps Script(GAS)を使えば、スプレッドシートと外部サービスを自動的につなげて、こうした手作業を大幅に削減できます。Googleアカウントさえあれば、すべて無料で始められます

この記事では、プログラミング経験が浅い方でも実践できるように、GAS スプレッドシート API 連携の基礎から実践的な活用方法まで、ステップバイステップで解説します。

API連携の基本概念

API連携とは、異なるシステム同士が自動的にデータをやり取りする仕組みです。たとえば、会計ソフトの売上データをスプレッドシートに自動で取り込んだり、スプレッドシートの情報をチャットツールに通知したりできます。

GASは、Googleが提供するJavaScriptベースのプログラミング環境で、スプレッドシートに標準で組み込まれています。難しい環境構築は不要で、ブラウザだけで開発から実行まで完結します。

できること:

  • 外部サービスのデータを定期的にスプレッドシートに取り込む
  • スプレッドシートのデータを他のシステムに自動送信する
  • 特定の条件を満たしたときに通知を送る
  • 手作業でのデータ入力ミスを削減する

主な制限:

  • 1回の実行で6分の時間制限
  • リアルタイム性が求められる処理には不向き
  • APIを提供していないシステムとは連携不可

ただし、中小企業の日常業務であれば、これらの制限に引っかかるケースはほとんどありません。

GASを選ぶべき理由

1. 初期費用ゼロ
専用サーバーやソフトウェアライセンスが不要です。

2. 環境構築が不要
スプレッドシートを開けば、すぐにコードを書き始められます。

3. クラウドで自動実行
パソコンを閉じていても、クラウド上で自動的にスクリプトが実行されます。

4. Googleサービスとの親和性
Gmail、Googleカレンダーなど、既存のツールとシームレスに連携できます。

活用できる業務シーン

営業・マーケティング
- 問い合わせフォームの内容を自動的にSlackに通知
- 広告の配信データを毎日自動取得

経理・財務
- 会計ソフトから仕訳データを自動取得
- 請求書発行データの一元管理

EC・物流
- 受注データの自動取り込みと在庫連携
- 売上データの日次集計

これらに共通するのは、「定型的で繰り返しが多い」「複数のツールを跨ぐ」という特徴です。

必要なスキルレベル

最低限必要な知識:
- スプレッドシートの基本操作
- コピー&ペーストができること

あると望ましい知識:
- JavaScriptの基礎(変数、関数など)
- JSONデータ形式の概念

プログラミング経験がなくても、本記事のサンプルコードをコピー&ペーストで動かしながら、徐々に理解を深めていけます。

事前準備:環境設定と安全な実行

実際にAPI連携を始める前に、安全に作業できる環境を整えましょう。

GASエディタの開き方

  1. 新しいGoogleスプレッドシートを作成
  2. メニューバーから「拡張機能」→「Apps Script」を選択

これだけで、GASのスクリプトエディタが新しいタブで開きます。

エディタの基本操作

主要な画面要素:
- コードエディタ(中央):実際にコードを書く場所
- 実行ボタン(上部):コードを実行します
- ログビューア(下部):実行結果やエラーメッセージを確認

基本操作:
- 保存:Ctrl+S(Mac: Cmd+S)
- 実行:実行したい関数を選択して実行ボタンをクリック
- プロジェクト名:左上の「無題のプロジェクト」から変更可能

APIキーの準備と安全な保管

API連携には、接続先サービスから以下の情報を取得する必要があります。

必要な情報:
- APIエンドポイント(URL)
- APIキーまたはトークン
- APIドキュメント

APIキーの安全な保存方法:

// APIキーを保存(一度だけ実行)
function setApiKey() {
  PropertiesService.getScriptProperties()
    .setProperty('API_KEY', 'ここにAPIキーを入力');
}

// APIキーを取得して使用
function getApiKey() {
  return PropertiesService.getScriptProperties()
    .getProperty('API_KEY');
}

重要: コード内に直接APIキーを書かず、必ずスクリプトプロパティに保存してください。

テスト環境の作成

本番データを壊さないために、必ずテスト環境で練習しましょう。

安全な実行のチェックリスト:
- [ ] テスト用のスプレッドシートで作業している
- [ ] 本番データのバックアップを取っている
- [ ] 最初は少量データで動作確認する

初回実行時の承認:
GASを初めて実行すると「承認が必要です」と表示されます。これは正常な動作です。画面の指示に従って、スクリプトがスプレッドシートにアクセスする許可を与えてください。

GASでAPI連携する基本コード

GASで外部APIと通信するための核となるのが、UrlFetchAppです。

UrlFetchAppの基本構文

function simpleApiCall() {
  const url = 'https://api.example.com/data';
  const response = UrlFetchApp.fetch(url);
  Logger.log(response.getContentText());
}

基本構文:

UrlFetchApp.fetch(url, options)
  • url:アクセス先のURL(必須)
  • options:リクエストの詳細設定(省略可能)

optionsの主な項目:

const options = {
  'method': 'GET',  // HTTPメソッド
  'headers': {      // リクエストヘッダー
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  'payload': JSON.stringify(data),  // 送信データ
  'muteHttpExceptions': true  // エラー時も例外を投げない
};

GETリクエスト:データを取得する

GETリクエストは、サーバーからデータを取得する最も基本的な方法です。

function getWeatherData() {
  const apiKey = PropertiesService.getScriptProperties()
    .getProperty('WEATHER_API_KEY');
  const city = 'Tokyo';
  const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&lang=ja&units=metric`;

  try {
    const response = UrlFetchApp.fetch(url);
    const data = JSON.parse(response.getContentText());

    Logger.log('都市: ' + data.name);
    Logger.log('気温: ' + data.main.temp + '℃');

    return data;
  } catch (error) {
    Logger.log('エラー: ' + error);
  }
}

ポイント:
- APIキーは必ずスクリプトプロパティから取得
- エラーハンドリング(try-catch)を必ず入れる

POSTリクエスト:データを送信する

POSTリクエストは、サーバーにデータを送信するときに使います。

function sendDataToApi() {
  const url = 'https://api.example.com/users';

  const data = {
    name: '山田太郎',
    email: 'yamada@example.com'
  };

  const options = {
    'method': 'POST',
    'contentType': 'application/json',
    'headers': {
      'Authorization': 'Bearer YOUR_API_KEY'
    },
    'payload': JSON.stringify(data),
    'muteHttpExceptions': true
  };

  try {
    const response = UrlFetchApp.fetch(url, options);
    const responseCode = response.getResponseCode();

    if (responseCode === 200 || responseCode === 201) {
      Logger.log('データ送信成功');
    } else {
      Logger.log('エラー: ' + responseCode);
    }
  } catch (error) {
    Logger.log('送信エラー: ' + error);
  }
}

JSONデータの扱い方

APIから返ってくるデータは、多くの場合JSON形式です。

JSONデータの解析:

function parseJsonResponse() {
  const url = 'https://api.example.com/data';
  const response = UrlFetchApp.fetch(url);

  // JSON文字列をJavaScriptオブジェクトに変換
  const jsonData = JSON.parse(response.getContentText());

  // データへのアクセス
  Logger.log('ID: ' + jsonData.data.id);
  Logger.log('名前: ' + jsonData.data.name);

  // 配列データの処理
  jsonData.data.items.forEach(function(item) {
    Logger.log(item.product + ': ' + item.price + '円');
  });
}

重要な関数:
- JSON.parse():JSON文字列 → JavaScriptオブジェクト(受信時)
- JSON.stringify():JavaScriptオブジェクト → JSON文字列(送信時)

実践例:API連携の具体的な実装

ここからは、実際に動くコードで具体的な連携方法を学びましょう。

例1:天気データの自動記録

OpenWeatherMap APIを使って、毎日の天気情報をスプレッドシートに記録します。

事前準備:
1. OpenWeatherMapで無料アカウントを作成してAPIキーを取得
2. スプレッドシートに「天気記録」というシートを作成

// 天気データを取得してスプレッドシートに記録
function recordWeatherData() {
  const apiKey = PropertiesService.getScriptProperties()
    .getProperty('WEATHER_API_KEY');
  const city = 'Tokyo';
  const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&lang=ja&units=metric`;

  try {
    const response = UrlFetchApp.fetch(url);
    const weather = JSON.parse(response.getContentText());

    const sheet = SpreadsheetApp.getActiveSpreadsheet()
      .getSheetByName('天気記録');

    // ヘッダーがなければ作成
    if (sheet.getLastRow() === 0) {
      sheet.appendRow(['日時', '都市', '気温', '湿度', '天気']);
    }

    // データを追加
    sheet.appendRow([
      new Date(),
      weather.name,
      weather.main.temp,
      weather.main.humidity,
      weather.weather[0].description
    ]);

    Logger.log('天気データを記録しました');
  } catch (error) {
    Logger.log('エラー: ' + error);
  }
}

例2:会計データの取得

freee APIを使って、仕訳データをスプレッドシートに取り込みます。

// 仕訳データを取得
function getFreeeDeals() {
  const props = PropertiesService.getScriptProperties();
  const accessToken = props.getProperty('FREEE_ACCESS_TOKEN');
  const companyId = props.getProperty('FREEE_COMPANY_ID');

  // 取得期間を設定(過去30日間)
  const today = new Date();
  const from = new Date(today.getTime() - 30 * 24 * 60 * 60 * 1000);
  const fromDate = Utilities.formatDate(from, 'JST', 'yyyy-MM-dd');
  const toDate = Utilities.formatDate(today, 'JST', 'yyyy-MM-dd');

  const url = `https://api.freee.co.jp/api/1/deals?company_id=${companyId}&start_issue_date=${fromDate}&end_issue_date=${toDate}`;

  const options = {
    'method': 'GET',
    'headers': {
      'Authorization': `Bearer ${accessToken}`
    },
    'muteHttpExceptions': true
  };

  try {
    const response = UrlFetchApp.fetch(url, options);
    const data = JSON.parse(response.getContentText());

    if (response.getResponseCode() !== 200) {
      throw new Error(`API Error: ${data.message}`);
    }

    writeDealsToSheet(data.deals);
  } catch (error) {
    Logger.log('freee API エラー: ' + error);
  }
}

// 仕訳データをシートに書き込む
function writeDealsToSheet(deals) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName('仕訳データ');

  // ヘッダー作成
  if (sheet.getLastRow() === 0) {
    sheet.appendRow(['取引日', '取引No', '勘定科目', '金額']);
  }

  // データ書き込み
  const rows = [];
  deals.forEach(function(deal) {
    deal.details.forEach(function(detail) {
      rows.push([
        deal.issue_date,
        deal.id,
        detail.account_item_name,
        detail.amount
      ]);
    });
  });

  if (rows.length > 0) {
    sheet.getRange(sheet.getLastRow() + 1, 1, rows.length, 4)
      .setValues(rows);
    Logger.log(`${rows.length}件のデータを書き込みました`);
  }
}

ポイント:
- 大量データは配列化してからsetValues()で一括書き込みすると高速
- 日付のフォーマットはUtilities.formatDate()を使用

例3:Slack通知の送信

スプレッドシートの特定条件を満たしたら、Slackに通知を送ります。

// Slackに通知を送信
function sendSlackNotification(message) {
  const webhookUrl = PropertiesService.getScriptProperties()
    .getProperty('SLACK_WEBHOOK');

  const payload = {
    'text': message,
    'username': 'スプレッドシート通知',
    'icon_emoji': ':clipboard:'
  };

  const options = {
    'method': 'POST',
    'contentType': 'application/json',
    'payload': JSON.stringify(payload)
  };

  try {
    UrlFetchApp.fetch(webhookUrl, options);
    Logger.log('Slack通知を送信しました');
  } catch (error) {
    Logger.log('送信エラー: ' + error);
  }
}

// 在庫が少なくなったら通知
function checkInventoryAndNotify() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName('在庫管理');
  const data = sheet.getDataRange().getValues();

  const lowStockItems = [];
  for (let i = 1; i < data.length; i++) {
    const itemName = data[i][0];
    const stock = data[i][1];
    const threshold = data[i][2];

    if (stock < threshold) {
      lowStockItems.push(`${itemName}: 残り${stock}個`);
    }
  }

  if (lowStockItems.length > 0) {
    const message = '⚠️ 在庫が少なくなっています\n' + 
                    lowStockItems.join('\n');
    sendSlackNotification(message);
  }
}

スプレッドシートをAPIとして公開する

GASを使えば、スプレッドシートのデータをREST APIとして外部に公開できます。

Web APIの基本構造

GASでWeb APIを作成するには、doGet()またはdoPost()関数を使用します。

// GETリクエストを受け取る
function doGet(e) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName('商品マスタ');
  const data = sheet.getDataRange().getValues();

  // ヘッダーを除いてJSON形式に変換
  const headers = data[0];
  const rows = data.slice(1).map(row => {
    const obj = {};
    headers.forEach((header, index) => {
      obj[header] = row[index];
    });
    return obj;
  });

  return ContentService.createTextOutput(JSON.stringify(rows))
    .setMimeType(ContentService.MimeType.JSON);
}

// POSTリクエストを受け取る
function doPost(e) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName('受注データ');

  try {
    const data = JSON.parse(e.postData.contents);
    sheet.appendRow([
      new Date(),
      data.orderId,
      data.customerName,
      data.amount
    ]);

    return ContentService.createTextOutput(
      JSON.stringify({status: 'success'})
    ).setMimeType(ContentService.MimeType.JSON);
  } catch (error) {
    return ContentService.createTextOutput(
      JSON.stringify({status: 'error', message: error.toString()})
    ).setMimeType(ContentService.MimeType.JSON);
  }
}

APIの公開と認証

公開手順:
1. スクリプトエディタで「デプロイ」→「新しいデプロイ」をクリック
2. 「種類の選択」で「ウェブアプリ」を選択
3. 「アクセスできるユーザー」を「全員」に設定
4. 「デプロイ」をクリックしてURLを取得

簡易的な認証の実装:

function doGet(e) {
  // APIキーの検証
  const validApiKey = PropertiesService.getScriptProperties()
    .getProperty('VALID_API_KEY');

  if (e.parameter.apikey !== validApiKey) {
    return ContentService.createTextOutput(
      JSON.stringify({error: '認証エラー'})
    ).setMimeType(ContentService.MimeType.JSON);
  }

  // 正常な処理
  // ...
}

セキュリティの注意点:
- 機密情報を扱う場合は、より強固な認証を実装する
- APIキーは定期的に更新する
- アクセスログを記録して監視する

トラブルシューティング

よくあるエラーと解決方法を紹介します。

API接続エラー

エラー例: Exception: Request failed for https://... returned code 401

原因と対処法:
- APIキーが間違っている → 再度確認して設定し直す
- APIキーの有効期限切れ → 新しいキーを発行
- エンドポイントURLが間違っている → APIドキュメントで確認

データが取得できない

確認ポイント:

function debugApiCall() {
  const url = 'https://api.example.com/data';
  const response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true});

  Logger.log('ステータスコード: ' + response.getResponseCode());
  Logger.log('レスポンス内容: ' + response.getContentText());
}
  • ステータスコードを確認(200が正常)
  • レスポンス内容を確認してJSON構造を把握
  • APIドキュメントと照らし合わせる

実行時間制限エラー

エラー例: Exceeded maximum execution time

対処法:

// 大量データは分割処理
function processLargeData() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName('データ');
  const lastProcessed = PropertiesService.getScriptProperties()
    .getProperty('LAST_ROW') || '1';

  const startRow = parseInt(lastProcessed) + 1;
  const batchSize = 100;  // 一度に処理する件数

  const data = sheet.getRange(startRow, 1, batchSize, sheet.getLastColumn())
    .getValues();

  // データ処理
  // ...

  // 次回の開始位置を保存
  PropertiesService.getScriptProperties()
    .setProperty('LAST_ROW', (startRow + batchSize - 1).toString());
}

運用のコツと次のステップ

定期実行の設定

トリガーを設定して、スクリプトを自動実行できます。

設定手順:
1. スクリプトエディタで「トリガー」アイコンをクリック
2. 「トリガーを追加」をクリック
3. 実行する関数、イベントソース、実行頻度を選択
4. 「保存」をクリック

推奨設定:
- 毎日実行する場合:「時間主導型」→「日タイマー」
- 毎時実行する場合:「時間主導型」→「時間ベースのタイマー」

メンテナンスしやすいコードの書き方

// 設定を一箇所にまとめる
const CONFIG = {
  SHEET_NAME: '受注データ',
  API_ENDPOINT: 'https://api.example.com/orders',
  BATCH_SIZE: 100
};

// 関数を小さく分割する
function main() {
  const data = fetchApiData();
  const processedData = processData(data);
  writeToSheet(processedData);
}

function fetchApiData() {
  // API呼び出し処理
}

function processData(data) {
  // データ加工処理
}

function writeToSheet(data) {
  // シート書き込み処理
}

ドキュメント作成のポイント

記録すべき内容:
- スクリプトの目的と概要
- 使用しているAPI情報
- トリガー設定内容
- エラー時の対応手順
- 更新履歴

スプレッドシート内に「README」シートを作成して、これらの情報を記載しておくと、チーム内での引き継ぎがスムーズになります。

さらに学ぶために

GAS スプレッドシート API 連携をマスターしたら、以下のステップに進みましょう。

  • 複数のAPIを組み合わせた高度な自動化
  • Google Workspace全体の連携(Gmail、カレンダーなど)
  • カスタムメニューやサイドバーの作成

本記事で紹介した基本を押さえれば、自社の業務に合わせた柔軟な自動化が実現できます。まずは小さく始めて、徐々に拡張していきましょう。

#GAS#スプレッドシート#API
共有:

ちょっとした業務の悩みも、気軽にご相談ください。

まずは話だけ聞いてもらう