Claude API×GASでスプレッドシート自動化|2025年版コピペで動く設定手順
Claude APIをGASで動かそうとして詰まっていないか
スプレッドシートにAI分析を組み込もうと調べると、古いコードがたくさん出てくる。コピペして実行したら400 Bad Request。モデル名を変えても動かない。そのまま半日が消える。
正直なところ、2025年時点でそのパターンにハマる人は多い。旧エンドポイントや廃止済みモデル名を使ったコードが今もネット上に溢れているからだ。
この記事では、2025年時点で実際に動くGASコードを軸に、APIキーの安全な管理方法・バッチ処理の設計・実務ユースケースまでをまとめて解説する。
💡 関連教材: ChatGPT業務自動化 実践テンプレート集(¥1,480) — API・スプレッドシート・メール・議事録・請求書をコピペで自動化する実装特化型テンプレート集(全22ページ)
Claude APIをGASで使う前に確認|2025年時点の「落とし穴」3つ
落とし穴①:エンドポイントが変わっている
古い記事のほとんどが/v1/completeを使っている。これはText Completions APIと呼ばれる旧エンドポイントで、すでに非推奨扱いだ。
現在の正解は/v1/messages。リクエストの構造が別物なので、旧コードをそのままコピペしても動かない。
旧エンドポイント(動かない)
// ❌ これは非推奨
const url = 'https://api.anthropic.com/v1/complete';
const payload = {
model: 'claude-2',
prompt: '\n\nHuman: ' + userInput + '\n\nAssistant:',
max_tokens_to_sample: 1000
};
現行エンドポイント(2025年対応)
// ✅ これが正しい
const url = 'https://api.anthropic.com/v1/messages';
const payload = {
model: 'claude-3-5-sonnet-20241022',
max_tokens: 1024,
messages: [{ role: 'user', content: userInput }]
};
リクエストキー名もprompt→messages、max_tokens_to_sample→max_tokensと変わっている。細かいが、ここを直さないと何をやっても動かない。
落とし穴②:モデル名に日付が必要になった
claude-2やclaude-instant-1といったエイリアスは廃止・変更が進んでいる。2025年時点では日付付きの正確な文字列が必要だ。
主要モデルの現行名称はこうなっている。
| モデル | 正しいmodel名 |
|---|---|
| Claude 3.5 Sonnet | claude-3-5-sonnet-20241022 |
| Claude 3.7 Sonnet | claude-3-7-sonnet-20250219 |
| Claude 3 Haiku | claude-3-haiku-20240307 |
コスト感も把握しておく。Claude 3.5 / 3.7 Sonnetはどちらも入力$3・出力$15(1Mトークンあたり)。日本語は英語の2〜3倍トークンを消費するので、日本語で大量処理するときは試算を多めに見ておくこと。
落とし穴③:GAS固有の制約を知らずに設計する
GASには見落としやすい制約が3つある。
- URLフェッチのタイムアウト:30秒固定(長文生成は設計が必要)
- スクリプトの実行時間上限:6分(大量行のループは分割が必須)
- 1日のURLフェッチ呼び出し上限:20,000回(無料アカウント)
「1,000行まとめて処理しよう」と思って素朴にループを書くと、6分で強制終了される。後述するバッチ処理パターンで対処する。
GeminiのスプレッドシートネイティブAI関数との使い分け
Google スプレッドシートには=GEMINI()関数(Google AI Studio連携)が使えるケースがある。これで十分な場面も多い。
Claudeをわざわざ使う理由は主に2つだ。
- 長文の品質と一貫性:メール文案・商品説明など数百字を要するテキスト生成はClaudeが強い
- システムプロンプトの細かい制御:役割・出力形式・トーンを厳密に指定したいとき
単セルでの簡単な言い換えや要約ならGemini関数の方が手軽。用途で使い分けるのが実務的な判断だ。
APIキー取得〜GASへの設定|セキュアな初期設定手順
ステップ1:Anthropic ConsoleでAPIキーを発行する
- console.anthropic.com にアクセスしてアカウントを作成
- 左メニューの「API Keys」を開く
- 「Create Key」ボタンをクリック
- キー名を入力(例:
spreadsheet-gas)して作成 - 表示された
sk-ant-api03-...の文字列をコピー(この画面を閉じると二度と表示されない)
2025年時点では、新規アカウントの無料試用クレジットは条件が変更されている。最初にクレジットカードを登録してから利用開始するフローになっているケースが多い。
ステップ2:GASのスクリプトプロパティに保存する
APIキーをコード内にベタ書きするのは絶対にやめる。GitHubに誤ってpushした瞬間にキーが漏洩する。
PropertiesServiceを使えばスクリプト外に安全に保存できる。
設定手順(一度だけ実行するコード)
function setApiKey() {
PropertiesService.getScriptProperties()
.setProperty('ANTHROPIC_API_KEY', 'sk-ant-api03-ここに貼る');
Logger.log('APIキーを保存しました');
}
この関数を一度だけ実行したら、コード内の実際のキー文字列は削除していい。以降はこう呼び出す。
const apiKey = PropertiesService.getScriptProperties()
.getProperty('ANTHROPIC_API_KEY');
GASエディタでの設定画面から直接入力する方法もある。
GASエディタ左メニュー「プロジェクトの設定」→「スクリプト プロパティ」→「プロパティを追加」から、プロパティ名ANTHROPIC_API_KEY・値にキーを貼り付けて保存。こちらの方が確実だ。
ステップ3:動作確認用の最小コードを実行する
設定できたら、まず1セルだけで動作確認する。
function testClaudeApi() {
const apiKey = PropertiesService.getScriptProperties()
.getProperty('ANTHROPIC_API_KEY');
const url = 'https://api.anthropic.com/v1/messages';
const payload = {
model: 'claude-3-5-sonnet-20241022',
max_tokens: 256,
messages: [{
role: 'user',
content: 'こんにちは。一言だけ返してください。'
}]
};
const options = {
method: 'post',
contentType: 'application/json',
headers: {
'x-api-key': apiKey,
'anthropic-version': '2023-06-01'
},
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(url, options);
const result = JSON.parse(response.getContentText());
Logger.log(result.content[0].text);
}
ログに返答が表示されれば接続成功だ。muteHttpExceptions: trueを入れておくと、エラー時にも中断せずにレスポンスの中身を確認できる。
実務で使えるサンプルコード2選|AI分析と文章生成
ユースケース①:顧客レビューの感情分析
A列にレビューテキストが入っていて、B列に「ポジティブ/ネガティブ/中立」を自動で入れる構成だ。
function analyzeSentiment() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastRow = sheet.getLastRow();
const apiKey = PropertiesService.getScriptProperties()
.getProperty('ANTHROPIC_API_KEY');
for (let i = 2; i <= lastRow; i++) {
const reviewText = sheet.getRange(i, 1).getValue();
if (!reviewText) continue;
// すでに処理済みの行はスキップ
if (sheet.getRange(i, 2).getValue()) continue;
const result = callClaude(
apiKey,
'あなたはレビュー分析AIです。以下のレビューを「ポジティブ」「ネガティブ」「中立」の3択で分類してください。理由は不要です。1語だけ答えてください。',
reviewText,
0.1 // 分類タスクはtemperatureを低くする
);
sheet.getRange(i, 2).setValue(result);
Utilities.sleep(1200); // レート制限対策:1.2秒待機
}
}
function callClaude(apiKey, systemPrompt, userMessage, temperature) {
const url = 'https://api.anthropic.com/v1/messages';
const payload = {
model: 'claude-3-5-sonnet-20241022',
max_tokens: 64,
temperature: temperature || 0.5,
system: systemPrompt,
messages: [{ role: 'user', content: userMessage }]
};
const options = {
method: 'post',
contentType: 'application/json',
headers: {
'x-api-key': apiKey,
'anthropic-version': '2023-06-01'
},
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
try {
const response = UrlFetchApp.fetch(url, options);
const result = JSON.parse(response.getContentText());
return result.content[0].text.trim();
} catch (e) {
Logger.log('エラー: ' + e.message);
return 'ERROR';
}
}
ポイントは3つ。
systemパラメータで役割を定義:出力を1語に絞る指示をここに書くtemperature: 0.1:分類タスクは低くする。高いとブレるUtilities.sleep(1200):1秒以上空けてTier1のレート制限(50RPM)に引っかからないようにする
ユースケース②:商品情報から説明文を一括生成
A列に商品名・B列に特徴キーワード・C列に生成した説明文が入る構成。
function generateProductDescription() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const lastRow = sheet.getLastRow();
const apiKey = PropertiesService.getScriptProperties()
.getProperty('ANTHROPIC_API_KEY');
const systemPrompt = [
'あなたはECサイトのコピーライターです。',
'商品名と特徴を渡すので、購買意欲を高める説明文を150字程度で作成してください。',
'箇条書きは使わず、読み手に語りかける自然な文体で書いてください。'
].join('');
for (let i = 2; i <= lastRow; i++) {
const productName = sheet.getRange(i, 1).getValue();
const features = sheet.getRange(i, 2).getValue();
if (!productName) continue;
if (sheet.getRange(i, 3).getValue()) continue;
const userMessage = `商品名:${productName}\n特徴:${features}`;
const description = callClaude(apiKey, systemPrompt, userMessage, 0.7);
sheet.getRange(i, 3).setValue(description);
Utilities.sleep(1500);
}
}
文章生成はtemperature: 0.7前後が自然なバリエーションを出しやすい。max_tokensは出力が150字なら日本語換算で300〜450トークン程度を見込んでおく。
100行以上を安定処理するバッチ設計|タイムアウトを回避する方法
素朴なforループで1,000行を処理しようとすると、GASの6分制限で強制終了される。処理の途中で止まると「どこまで終わったか」もわからなくなる。
実務で使えるパターンは「処理済み行をフラグ管理 + 時間ベースのトリガーで再実行」だ。
function batchAnalyzeWithResume() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const apiKey = PropertiesService.getScriptProperties()
.getProperty('ANTHROPIC_API_KEY');
const startTime = Date.now();
const timeLimit = 5 * 60 * 1000; // 5分で自主的に停止(6分制限の手前)
const lastRow = sheet.getLastRow();
for (let i = 2; i <= lastRow; i++) {
// 5分経過したら終了(次回トリガーに委ねる)
if (Date.now() - startTime > timeLimit) {
Logger.log(`行 ${i} で時間切れ。次回は続きから再開します。`);
break;
}
const inputText = sheet.getRange(i, 1).getValue();
const status = sheet.getRange(i, 3).getValue(); // C列をステータスフラグに使う
if (!inputText || status === '完了') continue;
const result = callClaude(apiKey, 'テキストを要約してください。', inputText, 0.3);
sheet.getRange(i, 2).setValue(result);
sheet.getRange(i, 3).setValue('完了'); // 処理済みフラグ
Utilities.sleep(1200);
}
}
これを時間ベースのトリガー(5〜10分おき)に設定すれば、何千行でも自動で続きから処理できる。GASエディタの「トリガー」メニューから設定する。
もう一点、これ意外と知られていないんだが、muteHttpExceptions: trueを入れると30秒タイムアウトでクラッシュする代わりにエラーレスポンスを受け取れる。エラー行にERRORを書いておけば後で再処理もできる。
今日やるべき1つのアクション
まずAPIキーをGASのスクリプトプロパティに保存して、testClaudeApi()の動作確認を通すところまでやってみてほしい。
コードのコピペから接続確認まで、早ければ15分で終わる。動いた瞬間に「何を分析・生成させようか」という具体的なアイデアが一気に出てくる。そこからが本番だ。
Claude APIの料金体系やトークン節約の詳しい方法は「Claude API料金を最大90%削減する方法」で別途まとめているので、大量処理を考えているなら合わせて読んでおくといい。
関連記事
- ChatGPT API×スプレッドシート連携|GAS初心者向け設定と自動化手順
- ChatGPT×Googleカレンダー連携|GASで予定自動登録・リマインド通知を設定する方法
- AIツールおすすめ2026年版|用途別に選ぶ最新10選と活用法
📘 もっと深く学びたい方へ
この記事で紹介した内容を、さらに体系的に・実務レベルで習得できる教材を販売中です。
ChatGPT業務自動化 実践テンプレート集(¥1,480)
API・スプレッドシート・メール・議事録・請求書をコピペで自動化する実装特化型テンプレート集(全22ページ)
- 動くGASコード・API設定手順・プロンプトをワンセット収録
- スプレッドシート連携/メール/議事録/請求書を実務レベルで自動化
- コピペで即動く実装コード(Python / GAS)付き
👉 今すぐ購入する
ChatGPT&Claude AIプロンプト集50選(¥980)
コピペで即使える実践プロンプト50種を全24ページに凝縮
- ビジネスメール・企画書・分析・コーディング等 8カテゴリ網羅
- ChatGPT / Claude / Gemini 全対応
- 変数を埋めるだけで即実務投入
👉 今すぐ購入する
関連ツール紹介
ブログ記事を効率的に量産するなら → Value AI Writer byGMOがSEO記事の自動生成に使える。月額1,650円から利用可能。![]()
おすすめツールの一覧はこちらにまとめている。