GEMINI LABEN
NANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定ですNANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定です
記事一覧/API / SDK
API / SDK/2026-07-09中級

Google Sheets API × Gemini API でつくるデータ処理パイプライン — Apps Script 不要の Python 自動化

サービスアカウントを使った Google Sheets API の認証から、Gemini API でのデータ分析・分類・要約まで、Python だけで完結するスプレッドシート AI 自動化パイプラインを解説します。

Gemini API191Google Sheets4Python38自動化26データ処理AI10スプレッドシート3

Apps Script で「できない」壁にぶつかったことはありませんか

Google Workspace で AI 自動化を試みるとき、多くの方が最初に選ぶのは Apps Script です。手軽に始められるし、Gemini との統合機能も Google が用意してくれています。

ただ、少し複雑なことをしようとした瞬間に限界が見えてきます。外部ライブラリが使えない、実行時間の上限が 6 分、エラーハンドリングが不自由、ローカルでのデバッグが難しい——こういった制約に何度かぶつかってきた方も多いのではないでしょうか。

Apps Script を一切使わず、Python だけで Google Sheets の読み書きと Gemini API による AI 処理を連携させる方法を順を追って整理していきます。スケジューラに乗せてバッチ実行したり、FastAPI サーバーのエンドポイントとして組み込んだりと、自由度が一気に広がります。

実用例として、顧客フィードバック(自由記述テキスト)をシートから読み取り、Gemini がカテゴリ分類・感情分析・改善提案を行い、結果を同じシートに書き戻すパイプラインを構築します。

必要なもの・全体構成

必要なものを先に整理しておきます。

  • Google Cloud プロジェクト(無料枠でOK)
  • サービスアカウントと認証 JSON ファイル
  • Google Sheets API の有効化
  • Gemini API キー(Google AI Studio から取得)
  • Python 3.10 以上

全体の流れはこうなります。

  1. サービスアカウントの作成と権限設定
  2. 対象スプレッドシートをサービスアカウントと共有
  3. Python で Sheets API 認証とデータ読み取り
  4. Gemini API で AI 処理(分類・要約・抽出)
  5. 結果をシートに書き戻す

サービスアカウントのセットアップ

Google Cloud Console(console.cloud.google.com)にアクセスし、プロジェクトを選択または新規作成します。

API の有効化

「API とサービス」→「ライブラリ」から以下を有効化します。

  • Google Sheets API
  • Google Drive API(共有ファイルへのアクセスに必要)

サービスアカウントの作成

「API とサービス」→「認証情報」→「認証情報を作成」→「サービスアカウント」と進みます。

名前は何でも構いません。ロールは「編集者」を付与しておくと Sheets の読み書き両方ができます。作成後、「キー」タブから「鍵を追加」→「JSON」を選択してキーファイルをダウンロードします。このファイルは .gitignore に追加して、絶対に Git にコミットしないようにしてください。

スプレッドシートとの共有

ダウンロードした JSON ファイルを開き、client_email の値(xxx@your-project.iam.gserviceaccount.com の形式)をコピーします。処理対象の Google スプレッドシートを開き、「共有」からそのメールアドレスを追加します。「編集者」権限で追加します。

Python 環境の構築

pip install google-auth google-auth-oauthlib google-api-python-client google-generativeai

プロジェクトディレクトリ構成はこのようにします。

sheets-gemini-pipeline/
├── credentials.json      # サービスアカウントキー(gitignore必須)
├── pipeline.py           # メイン処理
└── .env                  # GEMINI_API_KEY を記載

スプレッドシートからデータを読み取る

まず、Sheets API の認証とデータ読み取りを実装します。

import os
from google.oauth2 import service_account
from googleapiclient.discovery import build
 
# サービスアカウント認証
SCOPES = [
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/drive.readonly",
]
 
def get_sheets_service():
    """Google Sheets API サービスオブジェクトを取得する"""
    credentials = service_account.Credentials.from_service_account_file(
        "credentials.json",
        scopes=SCOPES,
    )
    return build("sheets", "v4", credentials=credentials)
 
def read_sheet(spreadsheet_id: str, range_name: str) -> list[list[str]]:
    """
    スプレッドシートから指定範囲のデータを読み取る
 
    Args:
        spreadsheet_id: URL の /d/{ID}/ 部分
        range_name: 例 "Sheet1\!A2:C100"(ヘッダー行を除いた範囲)
 
    Returns:
        2次元リスト。空の場合は []
    """
    service = get_sheets_service()
    result = (
        service.spreadsheets()
        .values()
        .get(spreadsheetId=spreadsheet_id, range=range_name)
        .execute()
    )
    return result.get("values", [])

spreadsheet_id は、スプレッドシートの URL https://docs.google.com/spreadsheets/d/{ここの部分}/edit から取得できます。

Gemini API で AI 処理を実装する

次に、Gemini API を使った分析処理を実装します。ここでは顧客フィードバックを例に、カテゴリ分類と感情分析を行います。

import json
import google.generativeai as genai
import typing_extensions as typing
 
# 環境変数から API キーを読み込む
genai.configure(api_key=os.environ["GEMINI_API_KEY"])
model = genai.GenerativeModel("gemini-2.5-flash-preview")
 
# 出力スキーマを定義(TypedDict で型安全に)
class FeedbackAnalysis(typing.TypedDict):
    category: str          # バグ報告 / 機能要望 / 使い方の質問 / 称賛 / その他
    sentiment: str         # positive / neutral / negative
    urgency: str           # high / medium / low
    summary: str           # 30文字以内の要約
    suggestion: str        # 改善提案(簡潔に)
 
def analyze_feedback(feedback_text: str) -> FeedbackAnalysis:
    """
    顧客フィードバックを Gemini で分析する
 
    Args:
        feedback_text: 分析対象のフィードバックテキスト
 
    Returns:
        FeedbackAnalysis 型の辞書
 
    Raises:
        ValueError: Gemini の応答が JSON パースできない場合
    """
    prompt = f"""以下の顧客フィードバックを分析してください。
 
フィードバック:
{feedback_text}
 
分類ルール:
- category: バグ報告 / 機能要望 / 使い方の質問 / 称賛 / その他 のいずれか
- sentiment: positive / neutral / negative のいずれか
- urgency: high(即対応必要) / medium(近いうちに対応) / low(余裕あり)
- summary: 30文字以内で内容を要約
- suggestion: 具体的な改善提案(改善不要なら「対応不要」)"""
 
    response = model.generate_content(
        prompt,
        generation_config=genai.GenerationConfig(
            response_mime_type="application/json",
            response_schema=FeedbackAnalysis,
        ),
    )
 
    return json.loads(response.text)

response_schemaFeedbackAnalysis を指定することで、Gemini の出力が必ずこのスキーマに従った JSON になります。json.loads() でパースエラーが起きることがほぼなくなるため、パイプラインの信頼性が格段に上がります。

結果をシートに書き戻す

分析結果を元のスプレッドシートの別列に書き込みます。

def write_results(
    spreadsheet_id: str,
    results: list[FeedbackAnalysis],
    start_row: int = 2,
    start_col: str = "D",
) -> None:
    """
    分析結果をスプレッドシートに書き込む
 
    Args:
        spreadsheet_id: 書き込み先のスプレッドシート ID
        results: analyze_feedback() の結果リスト
        start_row: データ書き込み開始行(デフォルト 2 = ヘッダー行の次)
        start_col: 書き込み開始列(デフォルト D 列)
    """
    service = get_sheets_service()
 
    # 2次元リストに変換(API の expects する形式)
    values = [
        [
            r["category"],
            r["sentiment"],
            r["urgency"],
            r["summary"],
            r["suggestion"],
        ]
        for r in results
    ]
 
    end_row = start_row + len(values) - 1
    end_col = chr(ord(start_col) + 4)  # D + 4列 = H
    range_name = f"Sheet1\!{start_col}{start_row}:{end_col}{end_row}"
 
    body = {"values": values}
    service.spreadsheets().values().update(
        spreadsheetId=spreadsheet_id,
        range=range_name,
        valueInputOption="USER_ENTERED",  # 書式を Sheets が解釈する
        body=body,
    ).execute()
 
    print(f"✅ {len(values)} 件の結果を {range_name} に書き込みました")

パイプライン全体を組み合わせる

個々の関数をつないで、エラーハンドリングを含む実用的なパイプラインに仕上げます。

import time
 
SPREADSHEET_ID = "あなたのスプレッドシートID"
INPUT_RANGE = "Sheet1\!C2:C1000"  # C列: フィードバックテキスト
 
def run_pipeline() -> None:
    """フィードバック分析パイプラインのメイン処理"""
 
    print("📊 スプレッドシートからデータを読み取り中...")
    rows = read_sheet(SPREADSHEET_ID, INPUT_RANGE)
 
    if not rows:
        print("処理対象データがありませんでした")
        return
 
    # 空セルをスキップ
    feedback_texts = [row[0].strip() for row in rows if row and row[0].strip()]
    print(f"📝 {len(feedback_texts)} 件のフィードバックを処理します")
 
    results = []
    for i, text in enumerate(feedback_texts, 1):
        print(f"  [{i}/{len(feedback_texts)}] 処理中: {text[:30]}...")
        try:
            analysis = analyze_feedback(text)
            results.append(analysis)
        except Exception as e:
            # 1件失敗しても全体を止めない
            print(f"  ⚠️ エラー(行 {i + 1}): {e}")
            results.append({
                "category": "エラー",
                "sentiment": "unknown",
                "urgency": "low",
                "summary": "処理エラー",
                "suggestion": str(e)[:50],
            })
 
        # レート制限対策: 1秒待機(60rpm の無料枠を超えないように)
        if i % 10 == 0:
            time.sleep(1)
 
    print("📤 結果をスプレッドシートに書き込み中...")
    write_results(SPREADSHEET_ID, results)
    print("🎉 パイプライン完了!")
 
if __name__ == "__main__":
    run_pipeline()

実際に実行すると、スプレッドシートの D〜H 列にカテゴリ・感情・緊急度・要約・改善提案が自動で埋まっていきます。100件のフィードバックであれば 2〜3 分程度で完了します。

よくある実装上の詰まりポイント

認証エラー「Request had invalid authentication credentials」

サービスアカウントをスプレッドシートに共有するのを忘れているケースが大半です。credentials.jsonclient_email を確認し、対象シートの「共有」に追加されているか確認してください。

もう一つよくある原因は、SCOPES に Sheets API のスコープしか含めず、Drive API のスコープを省略しているケースです。共有ドライブ上のファイルにアクセスする場合は https://www.googleapis.com/auth/drive.readonly が必要になります。

Gemini のレスポンスが稀に崩れる

response_schema を指定していても、複雑なプロンプトでは稀にスキーマ外の応答が返ることがあります。json.loads() の周りを try/except で囲み、パースに失敗した行はスキップしてリトライキューに入れるのが安全です。

try:
    result = json.loads(response.text)
except json.JSONDecodeError:
    # フォールバック: テキストから手動パース or スキップ
    result = {"category": "パースエラー", "sentiment": "unknown", ...}

429 エラー(レート制限)

無料枠では 60 rpm(リクエスト/分)の制限があります。フィードバックが数百件ある場合は、10 件ごとに time.sleep(1) を挟むか、google-genai SDK の指数バックオフ機能を使うのが現実的です。

レート制限の詳細はGemini API 料金・クォータ管理ガイドも参考にしてください。

応用:スケジュール実行・サーバー統合

このスクリプトをそのまま cron や Cloud Scheduler に乗せれば、毎日自動で実行される定期バッチになります。

# crontab -e で設定例(毎日 9:00 JST に実行)
0 0 * * * cd /path/to/project && python pipeline.py >> logs/pipeline.log 2>&1

FastAPI との組み合わせも自然です。

from fastapi import FastAPI, BackgroundTasks
 
app = FastAPI()
 
@app.post("/analyze")
async def trigger_analysis(background_tasks: BackgroundTasks):
    background_tasks.add_task(run_pipeline)
    return {"status": "started"}

Webhook を受け取るたびに処理を走らせる、といった使い方も同じパターンで対応できます。Gemini API × FastAPI バックエンド実装ガイドでは、より本格的なサーバー構成を解説しています。

行数が増えたときに最初に壊れる場所

このパイプラインは数百行のシートでは快適に動きますが、数千行を超えたあたりから別の問題が出てきます。私が最初に踏んだのは、Gemini API のレート制限ではなく、Sheets API 側の書き込み回数の上限でした。

個人開発で書いた初版がまさにこれで、1行ずつ update を呼ぶ実装は、行数がそのままリクエスト数になります。処理そのものは成功していても、途中で 429 が返り、再実行すると最初の数百行を二重に処理することになります。

私自身が実際に効果を確認できたのは、次の3点です。

  1. 書き込みを batchUpdate にまとめる。100行ごとにまとめるだけで、リクエスト数は 1/100 になります
  2. 処理済み行にマーカー列を持たせる。再実行時にスキップできるようにしておくと、途中で落ちても安全です
  3. Gemini API 側の呼び出しには指数バックオフを入れる。単純な sleep(1) の固定待機では、混雑時に抜けられません

このうち、実務でいちばん効いたのは2番目のマーカー列でした。冪等性が確保できていれば、途中で落ちること自体は怖くありません。個人開発では監視を手厚くできないぶん、「落ちても壊れない」設計に寄せるほうが結果的に楽になります。

システム指示の設計そのものを見直したい場合は「Gemini API のシステム指示とプロンプト設計」も参考になるはずです。

Apps Script と Python の使い分け

どちらが優れているというわけではなく、ユースケースによって使い分けるのが現実的だと思っています。

スプレッドシートを「主役」として人が手動で操作しながら AI を補助的に使うなら、Apps Script の方が断然楽です。セットアップも不要ですし、スプレッドシートのメニューから直接呼び出せます。

一方、スプレッドシートをデータストアとして扱い、AI 処理がメインの場合は Python が向いています。複数の外部 API を組み合わせる、処理時間が長い、エラーリカバリが必要、ローカルでのデバッグを繰り返したい——こういった場面では Python の自由度が活きてきます。

最初から完璧な設計を目指さず、まずシンプルなスクリプトで動かして、必要に応じてサーバー化・スケジュール化していくのが、個人開発者には現実的なアプローチではないでしょうか。

run_pipeline()python pipeline.py で一度動かしてみることから始めてみてください。

シェア

お読みいただきありがとうございます

Gemini Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

API / SDK2026-03-14
Gemini Code Execution API — AIにコードを書かせて実行する
Gemini Code Execution APIの使い方。AIが生成したコードを安全に実行し、数学計算、データ処理、複雑な分析をAIに任せる方法を解説します。
API / SDK2026-07-16
Gemini にスクリーンショットを採点させたら、全部78〜85点だった — 絶対スコアを捨ててペア比較に切り替えるまで
Gemini Vision に App Store スクリーンショットを100点満点で採点させると、良い案も崩した案も78〜85点に潰れます。弁別能を実測して絶対スコアを捨て、位置バイアスを除いたペア比較でランキングを作るまでの実装記録です。
API / SDK2026-06-29
Gemini APIのレスポンスをCIで守る — スナップショットと意味的回帰の検知設計
生成AIの非決定的なレスポンスを、pytestのスナップショットテストとembeddingベースの意味的回帰検知で守る実装手順。CI組み込み・flakyと本物の回帰の切り分け・スナップショット更新のガバナンスまでを実コードで解説します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →