SECTION 10

Gmail自動化ワークフロー

毎日のメール処理をAIが代行 — 受信から返信まで自動化

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

SECTION 10

メール業務の課題

STEP 01
121通
ビジネスパーソンの1日平均受信数
2.5時間
メール処理にかかる1日の平均時間
80%削減
GAS自動化による処理時間短縮の目標

メール処理は「判断」と「作業」に分かれる。
「作業」の部分をGASで自動化し、人間は「判断」に集中する。

よくある課題: 読んだだけで返信を忘れる、重要メールが埋もれる、同じ内容の返信を何度も書く、手動転記ミス

SECTION 10

GmailApp の基本メソッド

STEP 02

GASからGmailを操作するための主要メソッド一覧です。すべて GmailApp クラスから呼び出します。

メソッド 説明 戻り値
GmailApp.search(query)検索条件に合致するスレッドを取得GmailThread[]
GmailApp.getInboxThreads()受信トレイのスレッドを取得GmailThread[]
GmailApp.sendEmail(to, subject, body)メールを送信void
GmailApp.createDraft(to, subject, body)下書きを作成GmailDraft
thread.getMessages()スレッド内のメッセージ一覧GmailMessage[]
message.getSubject()件名を取得String
message.getBody()本文(HTML)を取得String
message.getPlainBody()本文(プレーンテキスト)を取得String
message.getFrom()送信者を取得String
thread.addLabel(label)スレッドにラベルを付与GmailThread

SECTION 10

メール検索: GmailApp.search()

STEP 03

検索演算子の活用

演算子意味
is:unread未読メール"is:unread"
from:送信元で絞り込み"from:boss@example.com"
subject:件名で絞り込み"subject:請求書"
newer_than:期間指定"newer_than:1d"
has:attachment添付ファイル付き"has:attachment"
label:ラベル指定"label:重要"

コード例: 条件検索

GAS function searchEmails() { // 過去24時間の未読メールを検索 const query = 'is:unread newer_than:1d'; const threads = GmailApp.search(query); threads.forEach(thread => { const msgs = thread.getMessages(); const latest = msgs[msgs.length - 1]; Logger.log( latest.getFrom() + ': ' + latest.getSubject() ); }); }
💡
複数条件はスペースで AND 結合できます。OR は {条件1 条件2} で指定します。

SECTION 10

メール取得と解析

STEP 04
GAS function analyzeEmails() { const threads = GmailApp.search( 'is:unread newer_than:1d', 0, 10 ); const results = []; threads.forEach(thread => { const msg = thread.getMessages()[0]; results.push({ from: msg.getFrom(), subject: msg.getSubject(), date: msg.getDate(), body: msg.getPlainBody() .substring(0, 200), hasAttach: msg.getAttachments() .length > 0 }); }); // スプレッドシートに書き出し const ss = SpreadsheetApp .getActiveSpreadsheet(); const sheet = ss.getSheetByName( 'メール一覧' ); results.forEach((r, i) => { sheet.getRange(i+2, 1, 1, 5) .setValues([[ r.from, r.subject, r.date, r.body, r.hasAttach ]]); }); }

主要な解析メソッド

getFrom() / getTo()

送信者・受信者のメールアドレスを文字列で返す

getSubject()

件名を取得。フィルタリングやカテゴリ分類に使用

getPlainBody() / getBody()

本文をプレーンテキスト/HTMLで取得。AI処理にはPlainBody推奨

getAttachments()

添付ファイルの配列を返す。Blob形式でDriveに保存可能

自動化パターン

GAS + Gemini API で実現する5つの実践パターン

SECTION 10 — 自動化パターン

パターン1: 受信メール自動分類

PATTERN 01
📧新着メール受信
🤖Gemini APIでカテゴリ判定
🏷ラベル自動付与
GAS function classifyEmails() { const threads = GmailApp.search( 'is:unread -label:classified' ); threads.forEach(thread => { const msg = thread.getMessages()[0]; const subject = msg.getSubject(); const body = msg.getPlainBody() .substring(0, 500); // Gemini APIでカテゴリ判定 const category = callGemini( `以下のメールを分類してください。 カテゴリ: 請求, 問合せ, 社内連絡, 営業, その他 件名: ${subject} 本文: ${body} 回答はカテゴリ名のみ:` ); // ラベルを取得or作成して付与 let label = GmailApp .getUserLabelByName(category); if (!label) { label = GmailApp .createLabel(category); } thread.addLabel(label); }); }

SECTION 10 — 自動化パターン

パターン2: 返信テンプレート自動生成

PATTERN 02

仕組み

  • 問い合わせメールを受信
  • Gemini APIがメール内容を分析
  • 過去の対応パターンを参照して返信文を生成
  • 下書き(Draft)として保存
  • 人間が確認して送信
ポイント: 自動送信ではなく「下書き保存」にすることで、人間の最終チェックを確保
GAS function generateReplyDraft() { const threads = GmailApp.search( 'is:unread label:問合せ' ); threads.forEach(thread => { const msg = thread.getMessages()[0]; const from = msg.getFrom(); const body = msg.getPlainBody(); // AIで返信文を生成 const reply = callGemini( `以下の問い合わせメールに対する 丁寧な返信文を作成してください。 署名は「株式会社○○ カスタマー サポート」としてください。 問い合わせ内容: ${body}` ); // 下書きとして保存 thread.createDraftReply(reply); Logger.log( '下書き作成: ' + from ); }); }

SECTION 10 — 自動化パターン

パターン3: 日次メールサマリー

PATTERN 03

概要

毎朝、未読メールの要約をSlackやChatworkに自動通知。
出社前にスマホで重要メールを把握できます。

GAS function dailySummary() { const threads = GmailApp.search( 'is:unread newer_than:1d' ); let summaryText = ''; threads.forEach(thread => { const msg = thread.getMessages()[0]; summaryText += `- ${msg.getFrom()}: ` + `${msg.getSubject()}\n`; }); // Gemini APIで要約 const summary = callGemini( `以下のメール一覧を重要度順に 要約してください:\n${summaryText}` ); // Chatworkに通知 sendToChatwork(summary); }

通知先の選択肢

💬

Chatwork

社内標準チャットへの通知。ルーム指定で部署別配信も可能

📢

Slack

Incoming Webhookで専用チャンネルに投稿

📱

LINE Notify

個人のスマホにプッシュ通知

📧

メール(自分宛)

要約結果を自分宛に送信(最もシンプル)

SECTION 10 — 自動化パターン

パターン4: 承認フロー自動化

PATTERN 04
📨申請メール受信
📊スプレッドシートに記録
📤承認者にメール転送
承認/却下を記録
GAS function processApprovalEmail() { const threads = GmailApp.search( 'subject:申請 is:unread' ); const sheet = SpreadsheetApp .getActiveSpreadsheet() .getSheetByName('承認管理'); const APPROVER = 'manager@example.com'; threads.forEach(thread => { const msg = thread.getMessages()[0]; // スプレッドシートに記録 sheet.appendRow([ new Date(), msg.getFrom(), msg.getSubject(), '未承認', msg.getPlainBody() .substring(0, 300) ]); // 承認者に転送 GmailApp.sendEmail( APPROVER, '[要承認] ' + msg.getSubject(), msg.getPlainBody() ); thread.markRead(); }); }

SECTION 10 — 自動化パターン

パターン5: メール→スプレッドシート自動転記

PATTERN 05

ユースケース

注文確認メール、問い合わせメール、申込メールなどの定型メールから必要な情報をAIで抽出し、スプレッドシートに自動記録

GAS function extractOrderData() { const threads = GmailApp.search( 'subject:注文確認 is:unread' ); threads.forEach(thread => { const msg = thread.getMessages()[0]; const body = msg.getPlainBody(); // Gemini APIでデータ抽出 const json = callGemini( `以下のメールから情報を抽出し JSON形式で返してください: {商品名, 数量, 金額, 顧客名, 日付} メール本文: ${body}` ); const data = JSON.parse(json); const sheet = SpreadsheetApp .getActiveSpreadsheet() .getSheetByName('注文一覧'); sheet.appendRow([ data.日付, data.顧客名, data.商品名, data.数量, data.金額 ]); }); }
docs.google.com/spreadsheets
自動転記されたスプレッドシート画面
💡
Tips: Geminiに「JSON形式で返して」と指示することで、プログラムで扱いやすい構造化データを取得できます。

外部サービス連携

GASからChatwork / Slack / LINE に通知を飛ばす

SECTION 10 — 外部連携

Chatwork連携

API

Chatwork API でメッセージ送信

Chatwork APIトークンを取得し、GASからHTTPリクエストでメッセージを投稿します。

GAS function sendToChatwork(message) { const TOKEN = PropertiesService .getScriptProperties() .getProperty('CW_TOKEN'); const ROOM_ID = '123456789'; const url = `https://api.chatwork.com/v2` + `/rooms/${ROOM_ID}/messages`; UrlFetchApp.fetch(url, { method: 'post', headers: { 'X-ChatWorkToken': TOKEN }, payload: { body: message } }); }

セットアップ手順

1

APIトークンを取得

Chatwork管理画面 > API > トークン発行

2

スクリプトプロパティに保存

PropertiesServiceでトークンを安全に保管

3

ルームIDを確認

ChatworkのURL末尾の数字がルームID

4

トリガーを設定

時間主導型トリガーで定期実行(例: 毎朝8時)

SECTION 10 — 外部連携

Slack連携

API

Incoming Webhook でチャンネルに投稿

GAS function sendToSlack(message) { const WEBHOOK_URL = PropertiesService .getScriptProperties() .getProperty('SLACK_WEBHOOK'); const payload = { text: message, username: 'Gmail Bot', icon_emoji: ':email:', channel: '#notifications' }; UrlFetchApp.fetch(WEBHOOK_URL, { method: 'post', contentType: 'application/json', headers: { 'Authorization': `Bearer ${token}` }, payload: JSON.stringify(payload) }); }
💡
Slack APIでリッチなメッセージ(Block Kit)を送ることも可能です。

Webhook設定手順

1

Slack Appを作成

api.slack.com/apps > Create New App

2

Incoming Webhookを有効化

Features > Incoming Webhooks > On

3

チャンネルを指定

投稿先チャンネルを選択してWebhook URLを取得

4

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

Webhook URLをSLACK_WEBHOOKとして保存

SECTION 10 — 外部連携

LINE通知連携

API

LINE Notify API

LINE Notifyを使えば、GASから個人やグループのLINEにプッシュ通知を送信できます。

GAS function sendToLine(message) { const TOKEN = PropertiesService .getScriptProperties() .getProperty('LINE_TOKEN'); UrlFetchApp.fetch( 'https://notify-api.line.me' + '/api/notify', { method: 'post', headers: { 'Authorization': 'Bearer ' + TOKEN }, payload: { message: message } } ); }

活用シーン

緊急メール通知

特定キーワード(「至急」「緊急」)を含むメールを即座にLINEに転送

日次レポート

毎朝の未読メールサマリーをLINEで受け取り

承認リマインダー

承認待ちが48時間以上滞留した場合にリマインド

注意: LINE Notifyは2025年3月末にサービス終了済みです。現在はLINE Messaging APIを使用してください。

ハンズオン

実際にGASでGmail自動化を体験しよう

SECTION 10 — ハンズオン

ハンズオン1: 未読メール一覧を取得

HANDS-ON 01
1

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

script.google.com にアクセスし、新規プロジェクトを作成

2

右のコードをコピー&ペースト

コード.gs に貼り付けて保存

3

関数を実行

listUnreadEmails を選択して実行ボタン(▶)をクリック

4

Gmail権限を承認

初回実行時にGmailアクセス権限の承認ダイアログが表示されます

実行ログ(Ctrl+Enter)で結果を確認しましょう
GAS function listUnreadEmails() { // 未読メールを最大20件取得 const threads = GmailApp.search( 'is:unread', 0, 20 ); Logger.log( `未読メール: ${threads.length}件` ); threads.forEach((thread, i) => { const msg = thread .getMessages()[0]; Logger.log( `[${i + 1}] ` + `${msg.getFrom()}` ); Logger.log( ` 件名: ` + `${msg.getSubject()}` ); Logger.log( ` 日時: ` + `${msg.getDate()}` ); Logger.log('---'); }); }

SECTION 10 — ハンズオン

ハンズオン2: メールをAIで要約

HANDS-ON 02

完成イメージ

未読メールの件名・本文をGemini APIに渡し、要点を3行で要約。結果をスプレッドシートに記録します。

GAS // Gemini API呼び出し共通関数 function callGemini(prompt) { const API_KEY = ScriptApp.getOAuthToken(); const url = 'https://generativelanguage.' + 'googleapis.com/v1beta/models/' + 'gemini-2.5-flash:generateContent' + ``; const res = UrlFetchApp.fetch(url, { method: 'post', contentType: 'application/json', headers: { 'Authorization': `Bearer ${token}` }, payload: JSON.stringify({ contents: [{ parts: [{ text: prompt }]}] }) }); const json = JSON.parse( res.getContentText() ); return json.candidates[0] .content.parts[0].text; }
GAS // メール要約メイン関数 function summarizeEmails() { const threads = GmailApp.search( 'is:unread newer_than:1d', 0, 5 ); const sheet = SpreadsheetApp .getActiveSpreadsheet() .getSheetByName('要約'); // ヘッダー行を設定 sheet.getRange(1, 1, 1, 4).setValues( [['送信者', '件名', '要約', '日時']] ); threads.forEach((thread, i) => { const msg = thread .getMessages()[0]; const body = msg.getPlainBody() .substring(0, 1000); const summary = callGemini( `以下のメールを3行で要約: ${body}` ); sheet.getRange(i + 2, 1, 1, 4) .setValues([[ msg.getFrom(), msg.getSubject(), summary, msg.getDate() ]]); }); }

SECTION 10 — ハンズオン

ハンズオン3: 自動返信ドラフト作成

HANDS-ON 03
1

callGemini関数を用意

前のハンズオンで作成したcallGemini関数を再利用

2

右のコードを追加

autoReplyDraft関数をコード.gsに追加

3

実行して下書きを確認

Gmailの下書きフォルダに返信ドラフトが生成されます

重要: 自動送信はしない

AIが生成した返信は必ず人間が確認してから送信しましょう。不適切な内容や誤った情報が含まれる可能性があります。

GAS function autoReplyDraft() { // 未読の問い合わせメールを取得 const threads = GmailApp.search( 'is:unread subject:お問い合わせ', 0, 3 ); threads.forEach(thread => { const msg = thread .getMessages()[0]; const body = msg.getPlainBody(); // AIで返信文を生成 const replyText = callGemini( `あなたはカスタマーサポートです。 以下のお問い合わせに丁寧に回答 する返信メールを作成してください。 お問い合わせ内容: ${body} 条件: - 敬語を使用 - 具体的な回答を含める - 署名は「カスタマーサポート」` ); // 下書きとして返信を作成 thread.createDraftReply(replyText); Logger.log( '下書き作成完了: ' + msg.getSubject() ); }); }

SECTION 10

Gemini API 共通呼び出し関数

REFERENCE

セットアップ

1

API キーを取得

Google AI Studio(aistudio.google.com)でAPIキーを発行

2

スクリプトプロパティに保存

GCPプロジェクトIDをコード冒頭のPROJECT_ID変数に設定

3

callGemini関数を利用

すべての自動化パターンからこの関数を呼び出す

注意: APIキーをソースコードに直接書かないでください。必ずPropertiesServiceを使用します。

モデル選択ガイド

モデル特徴用途
gemini-2.5-flash高速・低コスト分類・要約
gemini-2.5-pro高精度複雑な分析

無料枠の目安

Gemini 2.5 Flash: 1日あたり約1,500リクエスト(無料)
日常的なメール自動化には十分な量です。

SECTION 10

トリガーで定期自動実行

STEP 05

GASトリガーの種類

トリガー種類説明設定例
時間主導型指定した間隔で実行毎朝8時
カレンダー予定の更新時に実行予定変更時
フォーム送信フォーム回答時に実行回答受信時
スプレッドシート編集時に実行値変更時
GAS // プログラムでトリガーを設定 function createTrigger() { ScriptApp.newTrigger('dailySummary') .timeBased() .atHour(8) .everyDays(1) .create(); }

GUI での設定手順

script.google.com/triggers
トリガー設定画面のキャプチャ
1

左メニューの時計アイコンをクリック

2

「トリガーを追加」ボタンをクリック

3

実行する関数・頻度・時刻を指定して保存

SECTION 10

セキュリティ注意事項

SECURITY

メール本文をAIに送信する際の注意

個人情報の除去

氏名・住所・電話番号・クレジットカード番号などはAIに送信する前にマスキング処理を行う

機密情報の取り扱い

社外秘の契約書・見積書の内容はAIに送らない。送る場合は社内ポリシーを確認

APIキーの管理

APIキーはPropertiesServiceに保存。ソースコードに直書きしない

マスキング処理の例

GAS function maskPersonalInfo(text) { // メールアドレスをマスク text = text.replace( /[\w.-]+@[\w.-]+\.\w+/g, '[EMAIL]' ); // 電話番号をマスク text = text.replace( /\d{2,4}-\d{2,4}-\d{3,4}/g, '[PHONE]' ); // クレジットカード番号をマスク text = text.replace( /\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}/g, '[CARD]' ); return text; } // 使用例 const safeBody = maskPersonalInfo(msg.getPlainBody()); const summary = callGemini(`要約: ${safeBody}`);

SECTION 10

エラーハンドリングとログ

STEP 06

よくあるエラーと対策

エラー原因対策
Exception: Service invoked too many times日次制限超過実行回数を制御
Exception: Limit ExceededAPI レート制限Utilities.sleep()で間隔を空ける
Exception: Authorization is required権限不足OAuth スコープを確認
API 429 Too Many RequestsGemini APIレート制限リトライロジックを追加
GAS // エラーハンドリング付き実行 function safeExecute() { try { dailySummary(); Logger.log('成功'); } catch (e) { Logger.log('エラー: ' + e.message); // エラー通知メール GmailApp.sendEmail( Session.getActiveUser() .getEmail(), '[GAS] 実行エラー', 'エラー内容:\n' + e.message + '\nスタック:\n' + e.stack ); } } // リトライ付きAPI呼び出し function callWithRetry(fn, max) { for (let i = 0; i < max; i++) { try { return fn(); } catch (e) { if (i === max - 1) throw e; Utilities.sleep( 2000 * (i + 1) ); } } }

SECTION 10

コスト管理と日次制限

STEP 07

GmailApp の日次制限

操作無料アカウントWorkspace
メール送信100通/日1,500通/日
メール読み取り制限なし制限なし
GAS実行時間6分/回30分/回
トリガー数20個20個
UrlFetch20,000回/日100,000回/日

Gemini API コスト

無料枠(Gemini 2.5 Flash)

1日あたり約1,500リクエスト無料。日常的なメール処理には十分

従量課金の目安

Flash: 入力$0.15/100万トークン、出力$0.60/100万トークン。メール1通の要約で約$0.0001

💡
コスト削減Tips:
- 本文は先頭500〜1000文字だけ送る
- 分類はFlash、高品質な返信文はProと使い分ける
- キャッシュ(同じ質問への再利用)を検討

SECTION 10

応用: 全自動メールワークフロー

ADVANCED

ここまでのパターンを組み合わせた全自動ワークフローの全体像です。

📧 受信
🤖 AI分類
🏷 ラベル付与
📝 要約
💬 通知
返信ドラフト
GAS function fullWorkflow() { const threads = GmailApp.search('is:unread newer_than:1d', 0, 20); let summaryLines = []; threads.forEach(thread => { const msg = thread.getMessages()[0]; const body = maskPersonalInfo(msg.getPlainBody().substring(0, 500)); // Step 1: AI分類 const category = callGemini(`メールを分類(請求/問合せ/社内/営業/その他): ${body}`); const label = GmailApp.getUserLabelByName(category) || GmailApp.createLabel(category); thread.addLabel(label); // Step 2: 要約 const summary = callGemini(`1行で要約: ${body}`); summaryLines.push(`[${category}] ${msg.getSubject()} - ${summary}`); // Step 3: 問合せなら返信ドラフト作成 if (category.includes('問合せ')) { const reply = callGemini(`丁寧な返信を作成: ${body}`); thread.createDraftReply(reply); } Utilities.sleep(1000); // API制限対策 }); // Step 4: サマリーをChatworkに通知 sendToChatwork('【日次メールサマリー】\n' + summaryLines.join('\n')); }

SECTION 10

まとめ: Gmail自動化チェックリスト

SUMMARY

学んだこと

  • GmailApp の基本メソッド(search, getMessages, sendEmail)
  • 検索演算子を使った条件指定メール取得
  • AI(Gemini API)によるメール分類・要約・返信生成
  • 外部サービス連携(Chatwork / Slack / LINE)
  • トリガーによる定期自動実行
  • セキュリティ(個人情報マスキング、APIキー管理)

導入ステップ

  • まず未読メール一覧取得から始める
  • Gemini APIキーを取得してcallGemini関数を用意
  • 最も効果が高いパターン1つを選んで実装
  • テスト運用で1週間動かす
  • 問題なければトリガーで自動化

「小さく始めて、効果を確認してから拡大する」が自動化成功の鉄則です。

セクション10 完了

お疲れさまでした!次のセクションに進みましょう。

次へ → セクション11: スプレッドシート × AI データ処理
学習項目
7
ハンズオン
3
自動化パターン
5
所要時間
45分
🏠 研修ポータル ▶ この章の動画 📺 動画一覧