Google スプレッドシートとChatGPT APIで日報を自動要約する方法
日報は社員の行動を記録し、業務改善に役立つ情報を残すために欠かせません。しかし、毎日数千文字を手入力したり、集計・確認したりする作業は想像以上に時間と労力がかかります。「忙しくて日報を読む暇がない」「要点だけ分かればいいのに」と感じたことはないでしょうか。そこで役立つのが生成AIを用いた自動要約です。本記事では、Google スプレッドシートとOpenAIのChatGPT APIを組み合わせ、**「入力された日報を自動で要約し、別シートへ保存するシステム」**を構築する方法を解説します。Google Apps Script(GAS)による自動処理から最新モデルの選び方まで、SEOを意識しながら詳しく紹介します。
全体の仕組みとメリット
今回のシステムは以下の流れで動作します。
- 従業員がGoogle スプレッドシートの指定列に日報を入力する。
- GASが新規入力を検知してChatGPT APIにテキストを送信する。
- ChatGPTが入力内容を要約し、結果を受信する。
- 要約結果を別シートや同じ行の「要約」列に自動で書き込む。
この仕組みにより、管理者は長文を逐一読む必要がなくなり、要約済みデータを基に月次報告や分析が容易になります。従業員は自由な文章で記録できるため従来のフォームより負担が少なく、情報量は減らさずに確認・共有の効率が高まります。
準備するもの
実装に必要な準備は以下の通りです。
- Google アカウント – スプレッドシートとApps Scriptを利用するため。
- Google スプレッドシート – 日報データの保存先。新しいシートを作るか既存のシートを使用します。
- OpenAI アカウントとAPIキー – ChatGPT APIを利用するため。OpenAIのダッシュボードからAPIキーを作成してコピーします。取得手順はOpenAIのAPIページで公開されており、ダッシュボードの「API keys」タブから新しいキーを作成して保存します。
- インターネット接続 – GASから外部APIへアクセスするため。
スプレッドシートの構成例
まずは日報を入力するスプレッドシートを用意します。ここでは基本例として4列で構成しました。
A列:日付 | B列:氏名 | C列:業務内容(本文) | D列:要約(自動生成) |
---|---|---|---|
2025/08/25 | 山田太郎 | 顧客対応3件、請求書修正、新プロジェクトのキックオフ会議に参加 | (空白)→後で要約が入る |
要約列は初めは空欄にしておき、Apps Scriptが自動で書き込みます。日付や氏名の列は自由にカスタマイズできますが、本文列がどの列かをScript側で指定する必要があります。
GASでChatGPT APIと連携する
次に、スプレッドシートの「拡張機能 → Apps Script」を開き、APIに接続して要約を実行するコードを作成します。以下のサンプルはChatGPTに安全にアクセスしつつ、エラー処理や再利用性も考慮したオリジナルの実装例です。
1. APIキーを安全に管理する
APIキーをソースコードにハードコードするのはセキュリティ上好ましくありません。Apps ScriptにはPropertiesService
があり、キーをスクリプトプロパティに保存できます。
/**
* 初回実行時にAPIキーをスクリプトプロパティに保存します。
* 管理者が手動で一度だけ実行してください。
*/
function saveApiKey() {
const key = Browser.inputBox('OpenAI APIキーを入力してください');
PropertiesService.getScriptProperties().setProperty('OPENAI_API_KEY', key.trim());
}
/**
* スクリプトプロパティからAPIキーを取得します。
*/
function getApiKey() {
const key = PropertiesService.getScriptProperties().getProperty('OPENAI_API_KEY');
if (!key) {
throw new Error('APIキーが設定されていません。saveApiKey()を先に実行してください。');
}
return key;
}
ユーザーが初回にsaveApiKey()
を実行しAPIキーを入力すれば、その後はコードから直接キーを取得できるため、ソースにキーを記載せずに済みます。
2. ChatGPT APIを呼び出すユーティリティ関数
OpenAIのChatGPT APIはHTTP POSTリクエストで利用します。Apps ScriptのUrlFetchApp
を使ってAPIにアクセスし、応答を処理します。以下の関数は、汎用的なプロンプトを受け取り要約結果を返すものです。
/**
* ChatGPT APIにテキストを送り要約を取得する関数。
* @param {string} text 要約したい本文
* @param {string} [model] 使用するモデルID(省略時はgpt-4o-mini)
* @param {number} [maxTokens] 生成する最大トークン数
* @return {string} 要約テキスト
*/
function summarizeWithChatGPT(text, model = 'gpt-4o-mini', maxTokens = 200) {
const apiKey = getApiKey();
const url = 'https://api.openai.com/v1/chat/completions';
const payload = {
model: model,
messages: [
{ role: 'system', content: 'あなたは熟練した日本語の要約アシスタントです。入力文を簡潔に箇条書きで要約してください。' },
{ role: 'user', content: text }
],
max_tokens: maxTokens,
temperature: 0.3
};
const options = {
method: 'POST',
headers: {
Authorization: 'Bearer ' + apiKey,
'Content-Type': 'application/json'
},
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(url, options);
const code = response.getResponseCode();
if (code !== 200) {
console.warn('OpenAI APIエラー: ' + response.getContentText());
throw new Error('ChatGPT API呼び出しに失敗しました');
}
const data = JSON.parse(response.getContentText());
return data.choices[0].message.content.trim();
}
summarizeWithChatGPT()
はモデル名や最大トークン数を引数で指定できるため、用途に応じてgpt-4o-mini
やgpt-4o
などを簡単に切り替えられます。エラー時には例外を投げてログに詳細を出力します。
3. スプレッドシートへの自動書き込み
新しい日報が入力された際に要約を生成するには、onEdit(e)
トリガーを利用します。次の例では3列目(C列)の本文が変更されたときだけ処理し、要約列に既に値がある場合は上書きを避けます。
/**
* シートの編集イベントを監視し、本文が入力されたら要約を生成します。
* @param {Event} e 編集イベントオブジェクト
*/
function onEdit(e) {
const sheet = e.range.getSheet();
const row = e.range.getRow();
const col = e.range.getColumn();
// 見出し行を除外し、業務内容列(C列=3)に入力されたときのみ処理
if (row > 1 && col === 3) {
const text = sheet.getRange(row, 3).getValue();
const summaryCell = sheet.getRange(row, 4);
if (text && summaryCell.getValue() === '') {
try {
const summary = summarizeWithChatGPT(text);
summaryCell.setValue(summary);
} catch (error) {
// エラー発生時はセルにエラーメッセージを入れる
summaryCell.setValue('要約に失敗しました');
Logger.log(error);
}
}
}
}
上記コードを保存すると、自動的に要約が生成されるようになります。ただしonEdit
はユーザーの手入力しか検知できないため、フォーム送信や既存データの一括要約には別関数が必要です。次の関数を手動で実行するかタイムドリガーを設定することで、未要約の行をまとめて処理できます。
/**
* 現在のシートの未要約データをすべて処理して要約を埋める関数。
*/
function summarizeAllRows() {
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getDataRange().getValues();
// 1行目は見出しのため開始を1に設定
for (let i = 1; i < data.length; i++) {
const text = data[i][2];
const summary = data[i][3];
if (text && !summary) {
try {
const result = summarizeWithChatGPT(text);
sheet.getRange(i + 1, 4).setValue(result);
Utilities.sleep(1000); // API呼び出しの間隔を空けてレート制限を回避
} catch (e) {
sheet.getRange(i + 1, 4).setValue('要約エラー');
Logger.log(e);
}
}
}
}
このsummaryAllRows()
関数を1日1回や1時間ごとに自動実行するタイムトリガーを設定すれば、まとめて要約が反映されます。Apps Scriptの「トリガー」を開き、関数名と実行間隔を選択してください。
4. APIの選択とコストへの配慮
2024年にOpenAIは「GPT‑4o Mini」モデルを発表しました。GPT‑4o Miniは、従来モデルより速度とコスト効率を重視した設計で、テキストと画像入力に対応し、最大128,000トークンのコンテキストウィンドウを処理できます。価格は入力トークン100万あたり0.15ドル、出力トークン100万あたり0.60ドルとされ、上位モデルと同じ料金ながらも高速性に優れるためチャットボットやコンテンツ生成など大量処理に適しています。さらに4o Miniは一般的な推論ベンチマークで82%のMMLUスコアを記録し、他の小型モデルより高い性能を示しています。日報の要約は1件につき数百文字程度のテキストなので、4o Miniの性能で十分に処理できます。より高度な会議議事録の要約や分析を行いたい場合は、上位モデル「GPT‑4o」や「GPT‑5」を検討してみましょう。
APIコストはトークン数に比例して増えます。要約だけであれば最大トークン数を200程度に設定すると十分です。コード中のmaxTokens
引数を必要に応じて下げることでコストを削減できます。また、同じ内容を複数回APIに送ると料金が無駄になるため、セルに既に要約が存在するかを確認してから呼び出す仕組みを作っています。
実際の動作例
例えば、次のような日報が入力されたとします。
顧客対応で3件の問い合わせに回答。請求書の修正を実施。午後は新プロジェクトのキックオフ会議に参加。
summarizeWithChatGPT()
は「箇条書きで要約してください」と指示しているため、以下のような結果が得られます。
・顧客からの問い合わせ3件に対応
・請求書の修正を実施
・午後は新プロジェクトのキックオフ会議に参加
このように重要なタスクが3行でまとまり、管理者は一目で内容を把握できます。要約のフォーマットはプロンプトを変更することで柔軟に調整できます。例えば「ポイントごとに改行せず1文でまとめて」と指示すれば1行の要約が返ってきます。
要約精度を上げるための工夫
ChatGPTによる要約はプロンプト設計次第で結果が変わります。以下の点を意識すると精度が向上します。
- 具体的な指示を出す – 「箇条書きで3〜5項目」「重要な数字や件数を含める」など、期待する形式を明確に伝えます。システムコンテンツに要約条件を記載し、API呼び出し時の
systemContent
に入れるとよいでしょう。 - 不要な情報を含めない – 長すぎる文はトークン数が増えコストも上がります。日報入力欄にチェックボックスやプルダウンでカテゴリを追加し、本文では詳細のみを書くよう促すと良いでしょう。
- 温度(temperature)の調整 – コード例では
temperature: 0.3
と低めに設定し、結果の揺らぎを抑えています。創造的な要約が欲しい場合は0.7程度に上げます。 - モデルの選定 – 前述したようにGPT‑4o Miniはコストと速度のバランスが良く、小規模な業務要約に適しています。一方、長文や専門的な要約には上位モデル(GPT‑4oやGPT‑5)の方が適切です。128,000トークンの長いコンテキストウィンドウを活用すれば、会議議事録や研究レポートなど大型文書も扱えます。
応用例と拡張アイデア
日報要約の仕組みは他の業務にも応用できます。例えば:
- 会議議事録の要約 – 参加者が議事録をスプレッドシートに貼り付け、重要な決定事項やアクションアイテムを自動抽出します。長文の場合は最大トークン数を増やすか、段落ごとに分割して要約します。
- 営業日報の分析 – 営業担当が入力した訪問内容や受注状況を要約し、抽出したキーワードから注力分野を可視化します。要約後のデータを集計用の別シートにコピーしてピボットテーブルやグラフを作成することで、今週の活動量や重点顧客が一目で分かります。
- 質問回答テンプレート生成 – ヘルプデスクの問合せ内容を要約し、FAQの下書きを自動生成します。似た要約の履歴を活用すればテンプレートが充実します。
- 多言語翻訳・要約 –
messages
に複数のユーザーロールを使い、同時に「英語に翻訳して要約する」「箇条書きでまとめて中国語に翻訳する」などの処理も可能です。
トラブルシューティングと注意点
レート制限やエラーへの対応
OpenAI APIには1分あたりのリクエスト数上限があります。無料プランでは3回/分の制限があり、超過するとエラーが返ります。まとめて要約を実行する場合は1秒間隔で待機 (Utilities.sleep(1000)
) したり、バッチ処理ごとに一定の時間を空ける工夫が必要です。
エラーが発生した際にスクリプトが止まってしまうと後続処理が行われません。コード例では例外をキャッチしセルに「要約エラー」と記入することで、どの行で失敗したかが分かるようにしています。原因がAPIの上限なのか、テキストに問題があったのかをログで確認し、必要に応じて再実行してください。
個人情報とプライバシー
ChatGPTに送信する内容はOpenAI側で学習に利用される可能性があります。業務で扱う機密情報を送信しないように注意し、必要に応じて要約前にテキストをマスクする処理を加えましょう。また、OpenAIはエンタープライズ向けに会話ログ管理やアクセス制御などコンプライアンス機能を提供しており、企業での導入を検討する際は契約形態を確認すると安心です。
まとめ
Google スプレッドシートとChatGPT APIを組み合わせることで、日報や議事録といった長文を自動で要約する仕組みを簡単に構築できます。Apps Scriptを使えば新規入力の検知からAPI呼び出し、要約結果の書き込みまで全自動で行えます。この記事では、スクリプトプロパティによるAPIキー管理、汎用的な要約関数、バッチ処理関数などを紹介し、実務に使えるように最適化しました。さらに、2024年に登場したコスト効率の高いGPT‑4o Miniの特徴や、トークン数を抑える設定、レート制限への対応方法も解説しました。
今回紹介した仕組みを応用すれば、会議議事録の要約や営業報告の分析など様々な業務を自動化できます。生成AIの活用で情報共有のスピードと品質を向上させ、空いた時間をより創造的な仕事に充てましょう。