テキストがポジティブかネガティブか、どの程度の感情の強さがあるかを判定したいケースがあります。
Google CloudのNatural Language APIで、文章に表れた感情の傾向を推定します。書き手の本心や健康状態を判定する用途ではありません。

Natural Language API の使い方
Google Apps Script(GAS)からNatural Language APIへ文章を送信し、ScoreとMagnitudeをシートに書き込みます。練習には架空の文章を使い、送信権限のない個人情報・機密情報は入力しないでください。既存画像は旧版の参考画面です。今回の本文・コードの見直しではGoogle実機でのAPI通信や課金は検証していません。
画面の案内に沿って操作し、GCPのプロジェクトを作成します。
利用するGoogle Cloudプロジェクトで請求先アカウントを設定します。登録できる支払い方法や組織の権限を確認してください。

※利用量が無料枠を超えると課金が発生します。
2026年10月23日に公式料金表を照合した時点では、感情分析は月5,000ユニットまで無料です。1リクエストのUnicode文字数を1,000文字単位で切り上げます。1,500文字なら2ユニットで、再送も利用量に含まれます。無料枠は5,000行という意味ではありません。
Google Cloudの請求レポートで対象プロジェクトの利用額を、APIの割り当て画面で利用量を確認します。予算アラートだけでAPIが自動停止するとは限りません。

対象プロジェクトでCloud Natural Language APIを有効にします。その後「APIとサービス」の「認証情報」からAPIキーを作成し、APIの制限をCloud Natural Language APIに設定します。キーの発行だけではAPIの有効化は完了しません。

キーはセルや公開コードに貼らず、Apps Scriptの「プロジェクトの設定」のスクリプトプロパティへ、名前NL_API_KEYで保存します。
スクリプトプロパティもプロジェクト編集者から秘密を守る仕組みではありません。シートとスクリプトの編集権限を限定し、漏えいしたキーは無効化して再発行してください。認証方法はGoogleのAPIキー利用手順を参照してください。

テスト用スプレッドシートを作り、「拡張機能」→「Apps Script」を開きます。このコードは、そのファイルに紐づくスクリプト用です。
「分析」シートを作り、A1に文章、B1にScore、C1にMagnitudeと入力します。A2:A11に架空の日本語文を入れ、B2:C11は出力専用として空けます。後述のコードを保存し、既存のonOpenがある場合はメニュー追加処理を統合してください。
APIキーはNL_API_KEYプロパティから読みます。
対象はA2:A11の最大10行、1行1,000文字までという練習用の上限です。
「8個まで」というAPI仕様ではありません。
B列かC列に値または数式がある行は再送せず、文章が空の行も送信しません。
空欄に見える=""などの数式も、上書きを避けるため対象外にします。
function onOpen() {
SpreadsheetApp.getUi().createMenu('感情分析').addItem('A2:A11を分析', 'main').addToUi();
}
function main() {
const lock = LockService.getScriptLock();
if (!lock.tryLock(10000)) throw new Error('同じスクリプトで処理中です');
try {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('分析');
if (!sheet) throw new Error('分析シートを作成してください');
const key = PropertiesService.getScriptProperties().getProperty('NL_API_KEY');
if (!key) throw new Error('スクリプトプロパティNL_API_KEYを設定してください');
const data = sheet.getRange('A2:C11').getValues();
const formulas = sheet.getRange('B2:C11').getFormulas();
const jobs = [];
for (let i = 0; i < data.length; i++) {
const [text, score, magnitude] = data[i];
if (text === '' || score !== '' || magnitude !== '' ||
formulas[i][0] !== '' || formulas[i][1] !== '') continue;
if (typeof text !== 'string' || !text.trim() || Array.from(text).length > 1000) {
throw new Error((i + 2) + '行目は1〜1000文字の文章にしてください');
}
jobs.push({row: i + 2, text});
}
for (const job of jobs) {
let response;
try {
response = UrlFetchApp.fetch('https://language.googleapis.com/v1/documents:analyzeSentiment', {
method: 'post', contentType: 'application/json',
headers: {'x-goog-api-key': key},
payload: JSON.stringify({document: {type: 'PLAIN_TEXT', language: 'ja', content: job.text}, encodingType: 'UTF8'}),
muteHttpExceptions: true
});
} catch (e) {
throw new Error(job.row + '行目の通信に失敗しました。課金・出力を確認してから再実行してください');
}
if (response.getResponseCode() !== 200) {
throw new Error(job.row + '行目: HTTP ' + response.getResponseCode() + '。API設定・課金・割り当てを確認してください');
}
let result;
try { result = JSON.parse(response.getContentText()).documentSentiment; }
catch (e) { throw new Error(job.row + '行目の応答を解析できません'); }
if (!result || !Number.isFinite(result.score) || result.score < -1 || result.score > 1 ||
!Number.isFinite(result.magnitude) || result.magnitude < 0) {
throw new Error(job.row + '行目の分析結果が不正です');
}
sheet.getRange(job.row, 2, 1, 2).setValues([[result.score, result.magnitude]]);
}
} finally {
try { SpreadsheetApp.flush(); }
finally { lock.releaseLock(); }
}
}スプレッドシートの画面に戻り、F5キーなどでブラウザを再読み込みします。
スプレッドシートのメニューバーに独自のカスタムメニューが追加されます。
最初はA2だけに文章を入れて実行します。シートへのアクセスと外部通信の承認が必要です。
実行中は「分析」シートの入力と出力を編集しないでください。
このロックは同じスクリプトの同時実行を抑えるもので、手作業や別プロジェクトの編集は防げません。
「感情分析」→「A2:A11を分析」を実行すると、成功した行のB・C列に結果を書き込みます。HTTPエラーや不正な応答で停止し、済んだ行は残ります。通信失敗時にもサーバー側で処理されている可能性があるため、再送前に利用量と出力を確認してください。

- Score:数値が負ならネガティブ、正ならポジティブな感情を示します。
- Magnitude:0以上の感情の量です。長い文章ほど大きくなりやすく、異なる長さの文章を単純比較しません。Scoreが0付近でも、肯定と否定が混在してMagnitudeが高い場合があります。
数値だけでは傾向を把握しにくいため、条件付き書式を設定してセルに色を付けます。
- Score列B2:B11の例:0.5以上を赤、-0.5以下を青にし、その間は無着色にします。閾値は例であり、正解ラベルや信頼度ではありません。
- Magnitude列C2:C11には次の2つのカスタム数式を別々のルールとして設定します。上を赤、下を青にし、Scoreが0付近の結果は色で断定しません。
=AND(ISNUMBER($B2),ISNUMBER($C2),$B2>=0.5,$C2>=0.5)
=AND(ISNUMBER($B2),ISNUMBER($C2),$B2<=-0.5,$C2>=0.5)

元の文章と結果を並べて確認します。色だけで意味を判断せず、皮肉や文脈による誤判定も確認してください。既存画像と本文の閾値が異なる場合は、本文の数式を使ってください。

Googleスプレッドシートの関連Tipsは、まとめセクションのリンク先でも確認できます。

関連コードはGitHubのMOTOKI-LLC/cg-method-codeにもあります。本文の修正版と同じ版とは限らないため、差分を確認してください。
外部のサービスと連携する記事は、ほかにもあります。




まとめ
GCPのNatural Language APIとGoogle Apps Scriptを連携させ、文章の感情分析を行う方法を解説しました。
403ではAPI有効化・キーの制限・請求設定、429では割り当てや利用量を確認します。キーや応答本文を実行ログへ出さない構成です。
感情スコアを可視化しておくことで、アンケートやレビュー文章の傾向把握を効率化できます。
文章を変えて再分析する場合は、その行のB・C列の旧結果を控えてから両方を空にします。空にすると再送・再課金の対象になり得ます。練習を終了する場合は追加した式やコードを戻し、不要なAPIキーをGoogle Cloud側で無効化します。
値の解釈はNatural Language APIの基本仕様を参照してください。
2026年10月28日のコード見直しでは、数式のある出力行を送信しない処理とロック解除の順序を模擬試験しました。
実際のAPI通信・課金・Google Sheetsでの動作は未検証です。
スプレッドシートでの感情分析についてよくある質問
Natural Language APIの感情分析では、何がわかりますか?
文章がポジティブかネガティブか、どの程度の感情の強さがあるかを判定できます。この手法は、センチメント分析(感情分析)と呼ばれます。
ScoreとMagnitudeは、どう読めばよいですか?
Scoreは-1〜1で、負は否定的、正は肯定的な傾向です。Magnitudeは0以上の感情の量で、文章の長さにも影響されます。Scoreが0付近でも感情が混在している可能性があり、中立とは断定できません。
利用には、料金がかかりますか?
請求先の設定が必要です。2026年10月23日時点の感情分析の無料枠は月5,000ユニットで、リクエストごとの文字数を1,000文字単位で切り上げます。再送も利用量に含まれます。最新の料金は本文の公式料金表で確認してください。
利用量や金額は、どこで確認しますか?
Google Cloudの請求レポートとAPIの割り当て画面で、対象プロジェクトの利用額・利用量を確認します。
APIキーは、どこで発行しますか?
Cloud Natural Language APIを有効にしたプロジェクトで、認証情報から発行します。API制限を設定し、Apps ScriptのNL_API_KEYプロパティへ保存します。プロジェクト編集者にはアクセスできるため、編集権限も限定してください。
スクリプトを貼り付けたのに、メニューが出ません。
スプレッドシートの画面に戻り、F5キーなどでブラウザを再読み込みしてください。メニューバーに、独自のカスタムメニューが追加されます。
コードのどこを、自分の環境に合わせますか?
本文のコードは、現在のファイルの「分析」シートのA2:A11を読み、B・C列へ出力します。APIキーはスクリプトプロパティNL_API_KEYへ保存します。別のシート名や範囲へ変える場合は出力範囲も確認してください。
結果を見やすくするには?
条件付き書式の例ではScoreが0.5以上を赤、-0.5以下を青にします。閾値は用途ごとに結果を確認して調整し、色やMagnitudeを感情判定の確実さと混同しないでください。
