SECTION 09

GAS x Gemini API 連携

スプレッドシートにAIの頭脳を組み込む

LCREATOR.Inc Google AI 研修プログラム

SECTION 09

GAS x AI の可能性

OVERVIEW

スプレッドシートの全行をAIが処理し、人間は結果を確認するだけ。これが GAS x Gemini の世界です。

実現できること

  • 問い合わせメール500件を自動分類
  • 商品レビュー1,000件を感情分析
  • 議事録から要点を自動要約
  • 多言語テキストの一括翻訳
  • 自由回答アンケートの自動集計
bar_chart スプレッドシートのデータ(A列)
smart_toy GAS が Gemini API を呼び出し
check_circle 結果をB列に自動書き込み
lightbulb
人間がやると1件5分 x 500件 = 約42時間。GASなら数分で完了します。

SECTION 09

Vertex AI vs Google AI Studio

COMPARE
企業向け

Vertex AI

  • Google Cloud Platform 上のサービス
  • データの地域指定、SLA保証
  • 組織のセキュリティポリシーに準拠
  • 従量課金(トークン単位)
  • 本番環境での運用に最適
開発者・学習向け

Google AI Studio

  • APIキー1つですぐに使える
  • 無料枠が充実(学習に最適)
  • プロンプトのテスト・調整が簡単
  • セットアップが非常に簡単
  • プロトタイプ開発に最適

本研修では Google AI Studio を使用します。 セットアップが簡単で、無料枠で十分に学習できます。本番環境への移行時は Vertex AI を検討してください。

SECTION 09

Google Cloud Console の準備

SETUP 01
1

Google Cloud Console にアクセス

console.cloud.google.com にアクセスし、Googleアカウントでログイン。

2

新しいプロジェクトを作成

ヘッダーのプロジェクト選択 → 「新しいプロジェクト」をクリック。

3

Generative Language API を有効化

「APIとサービス」→「ライブラリ」で「Generative Language API」を検索して有効化。

4

APIキーを作成

「APIとサービス」→「認証情報」→「認証情報を作成」→「APIキー」。

console.cloud.google.com
Google Cloud Console の API 有効化画面

SECTION 09

APIキーの取得と設定

SETUP 02

AI Studio でのキー取得(簡単な方法)

1

AI Studio にアクセス

aistudio.google.com を開く。

2

「Get API key」をクリック

左メニューの「Get API key」を選択。

3

「Create API key」でキーを生成

プロジェクトを選択してキーを作成。

lock
APIキーは他人に共有しないでください。漏洩した場合は即座に無効化し、新しいキーを作成してください。
aistudio.google.com/apikey
AI Studio の API キー取得画面

SECTION 09

PropertiesService でキーを安全に保管

SETUP 03

スクリプトプロパティへの保存

1

エディタの歯車アイコン(プロジェクトの設定)を開く

2

「スクリプトプロパティを追加」をクリック

3

プロパティ名: GCP_PROJECT_ID

値: 取得したAPIキーを貼り付け

check_circle
セクション08で学んだ PropertiesService を活用します。コードにキーを直接書くのは絶対にNGです。

コードからの取得方法

GAS // APIキーをスクリプトプロパティから取得 function getApiKey() { const key = PropertiesService .getScriptProperties() .getProperty("GCP_PROJECT_ID"); if (!key) { throw new Error( "APIキーが設定されていません。" + "プロジェクトの設定から" + "GCP_PROJECT_ID を追加してください。" ); } return key; }

SECTION 09

最初の Gemini API 呼び出し

CODE 01
GAS function callGemini(prompt) { const API_KEY = PropertiesService.getScriptProperties().getProperty("GCP_PROJECT_ID"); const url = "https://us-central1-aiplatform.googleapis.com/v1/projects/YOUR_PROJECT_ID/locations/us-central1/publishers/google/models/gemini-2.5-flash:generateContent"; const payload = { contents: [{ parts: [{ text: prompt }] }] }; const options = { method: "post", contentType: "application/json", payload: JSON.stringify(payload), muteHttpExceptions: true }; const response = UrlFetchApp.fetch(url, options); const json = JSON.parse(response.getContentText()); return json.candidates[0].content.parts[0].text; } // テスト実行 function testGemini() { const result = callGemini("日本の首都はどこですか?一言で答えてください。"); Logger.log(result); // → "東京です。" }
lightbulb
UrlFetchApp.fetch() はGASから外部APIを呼び出すための標準メソッドです。HTTPリクエストを送信し、レスポンスを受け取ります。

SECTION 09

レスポンスの解析

CODE 02

Gemini APIのレスポンス構造

JSON { "candidates": [{ "content": { "parts": [{ "text": "AIの回答テキスト" }], "role": "model" }, "finishReason": "STOP" }], "usageMetadata": { "promptTokenCount": 15, "candidatesTokenCount": 42, "totalTokenCount": 57 } }

テキストの取り出し方

GAS const json = JSON.parse( response.getContentText() ); // 回答テキストを取得 const text = json .candidates[0] .content .parts[0] .text; // トークン数を確認 const tokens = json .usageMetadata .totalTokenCount;
warning
candidates が空の場合があります(安全フィルターでブロックされた場合など)。本番コードでは必ずチェックしましょう。

SECTION 09

GAS内でのプロンプト設計

CODE 03

テンプレートリテラルの活用

GAS function summarizeText(text) { // バッククォートで複数行プロンプト const prompt = `以下のテキストを3行以内で要約してください。 【テキスト】 ${text} 【出力ルール】 - 箇条書きで3点にまとめる - 各項目は30文字以内 - 敬体(です・ます)で記述`; return callGemini(prompt); }

プロンプト設計の3原則

1

役割を明示する

「あなたはビジネスメールの専門家です」のように、AIの立場を指定します。

2

出力形式を指定する

「JSON形式で」「箇条書きで」など、期待する出力形式を明記します。

3

具体例を示す

入力と出力の例を1〜2個示すと、精度が大幅に向上します(Few-shot)。

実践的な連携パターン

業務で今すぐ使える GAS x Gemini の4つの型

SECTION 09

パターン1: 一括AI要約

PATTERN 01

A列の長文テキストをGeminiで要約し、B列に結果を書き込みます。

GAS function batchSummarize() { const sheet = SpreadsheetApp .getActiveSpreadsheet() .getActiveSheet(); const data = sheet.getDataRange().getValues(); for (let i = 1; i < data.length; i++) { const text = data[i][0]; // A列: 原文 const status = data[i][2]; // C列: ステータス if (status === "完了" || !text) continue; const prompt = `以下を50文字以内で要約: ${text}`; const summary = callGemini(prompt); sheet.getRange(i+1, 2).setValue(summary); sheet.getRange(i+1, 3).setValue("完了"); // API制限対策: 1秒待機 Utilities.sleep(1000); } }

シートのイメージ

A: 原文B: 要約C: ステータス
長い議事録テキスト...予算承認と新製品...完了
お客様からの問い合わせ...納期確認の依頼...完了
来週のイベント企画...(処理中...)

ポイント: ステータス列で処理済みを管理。途中でエラーが起きても、再実行すれば未処理分だけ処理されます。

warning
Utilities.sleep(1000) は必須です。APIへの連続アクセスを防ぎ、レート制限エラーを回避します。

SECTION 09

パターン2: AI分類・タグ付け

PATTERN 02
GAS function classifyInquiries() { const sheet = SpreadsheetApp .getActiveSpreadsheet() .getActiveSheet(); const data = sheet.getDataRange().getValues(); for (let i = 1; i < data.length; i++) { const inquiry = data[i][0]; if (data[i][1]) continue; const prompt = `以下の問い合わせを分類してください。 カテゴリは以下のいずれか1つだけ回答: - 製品問い合わせ - クレーム - 見積もり依頼 - 技術サポート - その他 問い合わせ: ${inquiry}`; const category = callGemini(prompt) .trim(); sheet.getRange(i+1, 2).setValue(category); Utilities.sleep(1000); } }

分類結果のイメージ

A: 問い合わせ内容B: カテゴリ
商品Xの在庫はありますか?製品問い合わせ
先日届いた商品が破損して...クレーム
100個注文した場合の価格は?見積もり依頼
ログインできなくなりました技術サポート
lightbulb
精度を上げるコツ: カテゴリの選択肢を明示し、「1つだけ」と指定することで、安定した出力が得られます。

SECTION 09

パターン3: AI翻訳バッチ

PATTERN 03
GAS function batchTranslate() { const sheet = SpreadsheetApp .getActiveSpreadsheet() .getActiveSheet(); const data = sheet.getDataRange().getValues(); for (let i = 1; i < data.length; i++) { const japanese = data[i][0]; if (data[i][1] || !japanese) continue; const prompt = `以下の日本語を自然な英語に翻訳してください。 翻訳文のみ出力し、説明は不要です。 日本語: ${japanese}`; const english = callGemini(prompt) .trim(); sheet.getRange(i+1, 2).setValue(english); Utilities.sleep(1000); } }

翻訳結果のイメージ

A: 日本語B: English
お世話になっておりますThank you for your continued support
ご確認をお願いいたしますPlease review and confirm
来週の会議に出席可能ですI am available to attend next week's meeting

Google翻訳との違い: Geminiは文脈を理解した自然な翻訳ができます。ビジネス文書の翻訳では特に差が出ます。

SECTION 09

パターン4: AIデータ抽出(JSON出力)

PATTERN 04
GAS function extractData() { const sheet = SpreadsheetApp .getActiveSpreadsheet() .getActiveSheet(); const data = sheet.getDataRange().getValues(); for (let i = 1; i < data.length; i++) { const text = data[i][0]; if (data[i][1] || !text) continue; const prompt = `以下のテキストから情報を抽出し、 JSON形式で返してください。JSONのみ出力。 {"name":"氏名","company":"会社名", "email":"メールアドレス","phone":"電話番号"} テキスト: ${text}`; const result = callGemini(prompt); const cleaned = result .replace(/```json\n?/g, "") .replace(/```/g, "").trim(); const obj = JSON.parse(cleaned); sheet.getRange(i+1,2).setValue(obj.name); sheet.getRange(i+1,3).setValue(obj.company); sheet.getRange(i+1,4).setValue(obj.email); Utilities.sleep(1000); } }

入力と出力

入力(A列)

"株式会社ABCの田中太郎です。メールはtanaka@abc.co.jpまでお願いします。電話は03-1234-5678です。"

出力(B〜D列)

B: 氏名C: 会社名D: メール
田中太郎株式会社ABCtanaka@abc.co.jp
lightbulb
非構造化テキストから構造化データを抽出するのは、AIの得意技です。名刺情報、契約書、メールなどに活用できます。

エラー対応と品質管理

本番運用で困らないための必須テクニック

SECTION 09

APIエラーコード解説

ERROR 01
コード 意味 よくある原因 対策
400 Bad Request リクエストの形式が不正、プロンプトが長すぎる JSONの構造を確認、プロンプトを短くする
403 Forbidden APIキーが無効、APIが未有効化 APIキーの再確認、APIの有効化を確認
429 Too Many Requests レート制限に到達(短時間に大量リクエスト) Utilities.sleep() で待機時間を追加
500 Internal Error Google側のサーバーエラー 時間をおいてリトライ
local_fire_department
最も遭遇しやすいのは 429 エラーです。 無料枠ではRPM(1分あたりのリクエスト数)に制限があります。Utilities.sleep() で適切な待機時間を設けることが必須です。

SECTION 09

指数バックオフ(リトライ実装)

ERROR 02
GAS function callGeminiWithRetry(prompt, maxRetries) { maxRetries = maxRetries || 3; for (let attempt = 0; attempt < maxRetries; attempt++) { try { const result = callGemini(prompt); return result; // 成功したら即返却 } catch (e) { Logger.log( `試行 ${attempt + 1} 失敗: ${e.message}` ); if (attempt < maxRetries - 1) { // 待機時間を指数的に増加 // 1回目: 2秒, 2回目: 4秒, 3回目: 8秒 const waitMs = Math.pow(2, attempt + 1) * 1000; Logger.log(`${waitMs/1000}秒 待機中...`); Utilities.sleep(waitMs); } } } return "エラー: API呼び出し失敗"; }

指数バックオフとは

1⃣ 1回目失敗 → 2秒待機
2⃣ 2回目失敗 → 4秒待機
3⃣ 3回目失敗 → エラーとして記録

なぜ指数的に増やすのか? サーバーが混雑しているとき、すぐにリトライすると状況が悪化します。待機時間を倍々に増やすことで、サーバーの回復を待ちつつ確実にリトライできます。

SECTION 09

レート制限への対応

ERROR 03

Gemini API の主な制限

制限項目無料枠
RPM(1分あたりリクエスト)15 RPM
RPD(1日あたりリクエスト)1,500 RPD
TPM(1分あたりトークン)100万 TPM
warning
15 RPM = 4秒に1回。大量データ処理では Utilities.sleep(4000) 以上の待機が安全です。

大量データ処理のテクニック

GAS function processBatch() { const BATCH_SIZE = 10; // 1回に処理する件数 const WAIT_MS = 4000; // 4秒待機 const sheet = SpreadsheetApp .getActiveSpreadsheet().getActiveSheet(); const data = sheet.getDataRange().getValues(); let processed = 0; for (let i = 1; i < data.length; i++) { if (data[i][2] === "完了") continue; if (processed >= BATCH_SIZE) { Logger.log(`${BATCH_SIZE}件処理完了。`); break; // 次回に続きから } // ... API呼び出し処理 ... processed++; Utilities.sleep(WAIT_MS); } }

SECTION 09

出力品質の安定化

QUALITY

温度パラメータ(temperature)

GAS const payload = { contents: [{ parts: [{ text: prompt }] }], generationConfig: { temperature: 0.2, // 低い=安定 maxOutputTokens: 500 } };
温度特徴用途
0.0〜0.3安定・決定的分類、抽出、翻訳
0.4〜0.7バランス型要約、文章生成
0.8〜1.0創造的・多様アイデア出し

出力検証の実装

GAS function classifyWithValidation(text) { const validCategories = [ "製品問い合わせ", "クレーム", "見積もり依頼", "技術サポート", "その他" ]; const result = callGemini( `分類: ${text}` ).trim(); // AIの出力が期待値に含まれるか確認 if (validCategories.includes(result)) { return result; } return "分類失敗(要確認)"; }
check_circle
AIの出力は必ずしも期待通りではありません。出力を検証し、異常値を検出する仕組みを入れましょう。

SECTION 09

トークン管理とコスト

COST

トークンとは?

トークンはAIが処理するテキストの単位です。日本語では約1文字 = 1〜2トークンが目安です。

入力
プロンプト + データ
出力
AIの回答
lightbulb
Gemini 2.0 Flash は無料枠が大きく、学習用途では料金を心配する必要はほぼありません。

コスト見積もりの例

処理内容件数月額目安
短文要約100件/日無料枠内
メール分類500件/日〜$5
長文翻訳1,000件/日〜$20

コスト削減のコツ:

  • プロンプトは必要最小限に
  • maxOutputTokens を設定して出力を制限
  • 同じ入力の結果はキャッシュする

ハンズオン

GAS x Gemini を実際に動かしてみよう

SECTION 09

ハンズオン 1: Gemini API を呼び出す

HANDS-ON
1

スクリプトプロパティに APIキーを設定

プロパティ名: GCP_PROJECT_ID

2

右のコードをエディタにコピー

3

testGemini 関数を実行

実行する関数のドロップダウンで testGemini を選択。

4

ログに回答が表示されれば成功

GAS function callGemini(prompt) { const API_KEY = PropertiesService .getScriptProperties() .getProperty("GCP_PROJECT_ID"); const url = "https://us-central1-aiplatform.googleapis.com/v1/projects/YOUR_PROJECT_ID/locations/us-central1/publishers/google/models/gemini-2.5-flash:generateContent"; const res = UrlFetchApp.fetch(url, { method: "post", contentType: "application/json", payload: JSON.stringify({ contents: [{parts: [{text: prompt}]}] }), muteHttpExceptions: true }); const json = JSON.parse(res.getContentText()); return json.candidates[0].content.parts[0].text; } function testGemini() { const answer = callGemini( "こんにちは!一言で挨拶してください。" ); Logger.log(answer); }

SECTION 09

ハンズオン 2: シートデータをAI処理

HANDS-ON

準備: A列に5件のテキストを入力

A列: テキスト
今日の会議で来月の予算が承認されました
新しいプロジェクトの立ち上げが決定しました
顧客満足度調査の結果が大幅に改善しました
サーバーの移行作業が来週に延期されました
営業チームの四半期目標を達成しました
GAS function summarizeSheet() { const sheet = SpreadsheetApp .getActiveSpreadsheet().getActiveSheet(); const data = sheet.getDataRange().getValues(); for (let i = 0; i < data.length; i++) { const text = data[i][0]; if (!text || data[i][1]) continue; const summary = callGemini( `10文字以内で要約: ${text}` ); sheet.getRange(i+1, 2) .setValue(summary.trim()); Utilities.sleep(2000); } Browser.msgBox("要約完了!"); }
check_circle
B列に各テキストの10文字要約が表示されれば成功です。

SECTION 09

ハンズオン 3: エラーハンドリングを追加

HANDS-ON

ハンズオン2のコードに try-catch とリトライを追加します。

GAS function callGeminiSafe(prompt) { const MAX_RETRIES = 3; for (let attempt = 0; attempt < MAX_RETRIES; attempt++) { try { return callGemini(prompt); } catch (e) { Logger.log(`リトライ ${attempt+1}: ${e}`); if (attempt < MAX_RETRIES - 1) { Utilities.sleep( Math.pow(2, attempt+1) * 1000 ); } } } return "ERROR"; } function summarizeSafe() { const sheet = SpreadsheetApp .getActiveSpreadsheet().getActiveSheet(); const data = sheet.getDataRange().getValues(); for (let i = 0; i < data.length; i++) { if (!data[i][0] || data[i][1]) continue; const result = callGeminiSafe( `10文字以内で要約: ${data[i][0]}` ); sheet.getRange(i+1,2).setValue(result.trim()); Utilities.sleep(2000); } }

追加したポイント

shield

try-catch でエラー捕捉

APIエラーでスクリプト全体が止まるのを防ぎます。

sync

最大3回リトライ

一時的なエラーなら自動で復旧します。

hourglass_empty

指数バックオフ待機

2秒 → 4秒 → 8秒と待機時間を増やします。

edit_note

エラーログ記録

失敗した場合「ERROR」と記録し、後で確認できます。

SECTION 09

ハンズオン 4: カスタムメニューでAI処理

HANDS-ON
GAS function onOpen() { SpreadsheetApp.getUi() .createMenu(' AI処理') .addItem('一括要約', 'summarizeSafe') .addItem('一括分類', 'classifyAll') .addSeparator() .addItem('結果クリア', 'clearResults') .addToUi(); } function classifyAll() { const sheet = SpreadsheetApp .getActiveSpreadsheet().getActiveSheet(); const data = sheet.getDataRange().getValues(); for (let i = 0; i < data.length; i++) { if (!data[i][0] || data[i][1]) continue; const cat = callGeminiSafe(`以下を「ポジティブ」「ネガティブ」「中立」のいずれか1語で分類: ${data[i][0]}`); sheet.getRange(i+1,2).setValue(cat.trim()); Utilities.sleep(2000); } Browser.msgBox("分類完了!"); } function clearResults() { const sheet = SpreadsheetApp .getActiveSpreadsheet().getActiveSheet(); const lastRow = sheet.getLastRow(); if (lastRow > 0) { sheet.getRange(1,2,lastRow,1).clearContent(); } }

完成イメージ

docs.google.com/spreadsheets/d/...
研修資料イメージ

到達点: 非エンジニアでもメニューから「一括要約」を選ぶだけでAI処理が実行できる環境が完成しました。

SECTION 09

運用のベストプラクティス

BEST PRACTICE
assignment

ログ管理

処理結果・エラーをログシートに記録。問題発生時の原因特定を容易にします。

schedule

定期実行(トリガー)

毎朝9時にデータ処理、毎週月曜にレポート生成など、トリガーで完全自動化。

payments

コスト監視

usageMetadata のトークン数を記録し、想定外のコスト増を早期検知します。

lock

APIキーのローテーション

定期的にキーを再生成し、古いキーを無効化。セキュリティリスクを最小化します。

bar_chart

処理件数の制限

1回のバッチ処理を50件までに制限。GASの実行時間制限(6分)に対応。

science

テスト用シートで検証

本番データに触る前に、少量のテストデータで動作確認を必ず行いましょう。

SECTION 09

次のステップ: ワークフロー構築へ

NEXT

ここまでで身につけたスキル

SEC 08: GAS基礎(シート操作・メニュー・トリガー)
SEC 09: GAS x Gemini(API連携・バッチ処理・エラー対応)
SEC 10: Gmail自動化(メール × AI の実践ワークフロー)

次のセクションで学ぶこと

  • GmailApp でメールの取得・送信を自動化
  • 受信メールをAIで自動分類・返信ドラフト作成
  • スプレッドシートとGmailの連携ワークフロー
  • フォーム送信をトリガーにした自動処理

GASの基礎 + AI連携を身につけた今、あらゆるGoogleサービスを自動化する準備が整いました。

SECTION 09

まとめ: GAS x Gemini 連携チェックリスト

SUMMARY

API連携の基本

  • Vertex AI 経由でGemini APIにアクセス
  • ScriptApp.getOAuthToken() で認証
  • UrlFetchApp.fetch() でAPI呼び出し
  • レスポンスからテキストを抽出できる

実践パターン

  • 一括要約・分類・翻訳・データ抽出
  • ステータス列で処理済み管理
  • プロンプト設計の3原則

エラー対応・品質管理

  • APIエラーコード(400/403/429/500)を理解
  • try-catch + 指数バックオフでリトライ
  • Utilities.sleep() でレート制限対策
  • 温度パラメータで出力品質を制御
  • 出力の検証ロジックを実装

「シートのデータをAIで処理し、結果をシートに戻す」-- この基本パターンを応用すれば、あらゆる業務を自動化できます。

セクション09 完了

お疲れさまでした!次はGmailの自動化ワークフローに進みます。

次へ → セクション10: Gmail自動化ワークフロー
学習項目
10
ハンズオン
4
所要時間
50分
🏠 研修ポータル ▶ この章の動画 📺 動画一覧