GAS(Google Apps Script)を使うと、Gmailで届いたメールを検索し、必要な情報をスプレッドシートへ自動転記できます。メール本文だけでなく、添付されたWordファイルをGoogleドライブへ保存し、内容を読み取って一覧にすることも可能です。
私は、特定の送信元と件名に合うメールからWord形式の報告書を取り出し、Googleドライブへ保存して、報告内容をスプレッドシートへ追加する仕組みを使っています。スプレッドシートはデータベースのように蓄積し、人ごとの状況を確認できる形にしています。
ただし、GASをいきなり定期実行すると、検索条件の間違いや二重転記に気づかないまま処理が続くおそれがあります。まずダミーのメール1件で、検索、保存、変換、抽出、転記を一工程ずつ確認することが大切です。
この記事では、GASでメールをスプレッドシートへ自動転記するサンプルコードと、設定手順、Word報告書に合わせた直し方、安全に運用するための確認項目を紹介します。自動化する業務をまだ選べていない方は、先にAIを使える業務を15分で棚卸しする方法も参考にしてください。

取得資格
- SEO検定1級
- SEOマーケティングアドバイザー
2020年からブログを始めて、エンタメ系のジャンルは約1年で月間10,000PVほど。2021年にWebライターとして独立しSEOメディア運用ディレクターとして現在も活動中。田舎に戻りHP製作やSNS運用マーケティング支援なども対応。
GASでメールをスプレッドシートへ自動転記する全体像

今回作るのは、Gmail、Googleドライブ、Googleドキュメント、GoogleスプレッドシートをGASでつなぐ仕組みです。処理を大きく分けると、次の5工程になります。
| 工程 | GASが行うこと | 確認する結果 |
|---|---|---|
| 1. 検索 | 送信元と件名で対象メールを絞る | テストメールだけが見つかる |
| 2. 保存 | `.docx` の添付をDriveへ保存する | Word原本が指定フォルダに残る |
| 3. 変換 | WordをGoogleドキュメント形式へ変換する | Docs版を開ける |
| 4. 抽出 | 固定ラベルに続く値を本文から取り出す | 管理番号や状況を取得できる |
| 5. 転記 | 抽出値と原本URLをSheetsへ追加する | 1報告につき1行が増える |
サンプルでは、Word本文に「管理番号:」「対象者:」「報告日:」「状況:」「次回対応:」という固定ラベルがあり、各ラベルと値が同じ行に書かれている前提です。実際の報告書が表形式だったり、書く人によって見出しが変わったりする場合は、抽出部分を調整する必要があります。
また、転記した値だけでなくWord原本のURLも残します。抽出結果に違和感があったとき、元の報告書へ戻って確認できるようにするためです。
Google Apps ScriptのGmailサービスには検索用の `search()`、メッセージには添付を取得する `getAttachments()` があります。今回の流れは、これらの公式機能を組み合わせて作ります。GmailApp|Google for Developers、GmailMessage|Google for Developers
自動転記を始める前に用意する5つのもの

実際の業務メールを使う前に、次の5つをテスト用として用意します。
- 送信元と件名を限定したテストメール
- 固定ラベルを入れたダミーのWordファイル
- 原本と変換版を保存するGoogleドライブのフォルダ
- 転記先のGoogleスプレッドシート
- Apps Scriptのプロジェクトと高度なDriveサービス
テスト用のWordファイルには、次のような架空の内容だけを入れてください。
管理番号:TEST-001 対象者:テスト太郎 報告日:2026-09-01 状況:初回確認済み 次回対応:翌週に再確認
スプレッドシートを開き、「拡張機能」から「Apps Script」を選びます。Apps Scriptの編集画面が開いたら、左側の「サービス」からDrive APIを追加してください。WordをGoogleドキュメント形式へ変換する部分で、高度なDriveサービスを使うためです。高度なDriveサービス|Google for Developers
Wordファイルは、GoogleドキュメントのMIMEタイプを指定してDriveへアップロードすると、Googleドキュメント形式へ変換できます。Googleの公式ガイドでも、Microsoft WordからGoogleドキュメントへのインポートが案内されています。ファイルデータのアップロード|Google Drive API
なお、シート内の計算や文字の組み替えだけなら、GASを使わず関数で済む場合があります。ChatGPTでスプレッドシート関数を作る方法も確認し、GmailやDriveなど複数サービスをまたぐ処理にGASを使うと、仕組みを必要以上に複雑にせずに済みます。
GASでWord添付を自動転記するサンプルコード

次のコードは、対象メールを検索し、Word原本とGoogleドキュメント版をDriveへ保存して、12列のスプレッドシートへ転記します。最初に `CONFIG` の4項目を自分のテスト環境へ置き換えてください。
| 設定値 | 入れる内容 | 公開時の注意 |
|---|---|---|
| `SENDER` | テストメールの送信元 | 実在アドレスを記事や質問文へ貼らない |
| `SUBJECT_KEYWORD` | テスト用件名の一部 | 普段のメールと重ならない言葉にする |
| `SPREADSHEET_ID` | 転記先SheetsのID | URL全体ではなくID部分を使う |
| `FOLDER_ID` | 保存先DriveフォルダのID | 閲覧権限も確認する |
以下はそのままコピーしてApps Scriptへ貼り付けられる完成コードです。書き換えが必要なのは、この記事内の `CONFIG` の4項目だけです。
const CONFIG = {
SENDER: 'report@example.com',
SUBJECT_KEYWORD: 'テスト報告書',
SPREADSHEET_ID: 'SPREADSHEET_ID',
SHEET_NAME: 'REPORTS',
FOLDER_ID: 'FOLDER_ID',
DAYS_BACK: 30,
MAX_THREADS: 50,
};
const HEADERS = [
'処理キー', '受信日時', '送信元', '件名', '管理番号', '対象者',
'報告日', '状況', '次回対応', 'Word原本URL',
'GoogleドキュメントURL', '処理日時',
];
function transferWordReports() {
const sheet = getReportSheet();
ensureHeaders(sheet);
const processedKeys = getProcessedKeys(sheet);
const threads = GmailApp.search(buildSearchQuery(), 0, CONFIG.MAX_THREADS);
const messages = threads
.flatMap((thread) => thread.getMessages())
.sort((a, b) => a.getDate() - b.getDate());
messages.forEach((message) => {
const attachments = message.getAttachments({
includeInlineImages: false,
includeAttachments: true,
}).filter((file) => file.getName().toLowerCase().endsWith('.docx'));
attachments.forEach((attachment) => {
const processingKey = `${message.getId()}:${attachment.getName()}`;
if (processedKeys.has(processingKey)) return;
const originalFile = saveOriginalWord(attachment, message.getDate());
const convertedFile = convertWordToGoogleDoc(attachment, message.getDate());
const text = DocumentApp.openById(convertedFile.id).getBody().getText();
const fields = extractReportFields(text);
sheet.appendRow([
processingKey,
message.getDate(),
message.getFrom(),
message.getSubject(),
fields.managementId,
fields.person,
fields.reportDate,
fields.status,
fields.nextAction,
originalFile.getUrl(),
convertedFile.webViewLink || `https://docs.google.com/document/d/${convertedFile.id}/edit`,
new Date(),
]);
processedKeys.add(processingKey);
});
});
}
function buildSearchQuery() {
return [
`from:${CONFIG.SENDER}`,
`subject:${CONFIG.SUBJECT_KEYWORD}`,
`newer_than:${CONFIG.DAYS_BACK}d`,
'has:attachment',
'filename:docx',
].join(' ');
}
function getReportSheet() {
const spreadsheet = SpreadsheetApp.openById(CONFIG.SPREADSHEET_ID);
return spreadsheet.getSheetByName(CONFIG.SHEET_NAME)
|| spreadsheet.insertSheet(CONFIG.SHEET_NAME);
}
function ensureHeaders(sheet) {
if (sheet.getLastRow() === 0) {
sheet.appendRow(HEADERS);
}
}
function getProcessedKeys(sheet) {
if (sheet.getLastRow() < 2) return new Set();
const values = sheet.getRange(2, 1, sheet.getLastRow() - 1, 1)
.getDisplayValues()
.flat()
.filter(Boolean);
return new Set(values);
}
function saveOriginalWord(attachment, receivedAt) {
const folder = DriveApp.getFolderById(CONFIG.FOLDER_ID);
const fileName = buildFileName(receivedAt, attachment.getName());
return folder.createFile(attachment.copyBlob()).setName(fileName);
}
function convertWordToGoogleDoc(attachment, receivedAt) {
const sourceName = attachment.getName().replace(/\.docx$/i, '');
const fileName = buildFileName(receivedAt, `${sourceName}-変換版`);
const metadata = {
name: fileName,
mimeType: 'application/vnd.google-apps.document',
parents: [CONFIG.FOLDER_ID],
};
return Drive.Files.create(metadata, attachment.copyBlob(), {
fields: 'id,name,webViewLink',
});
}
function buildFileName(date, originalName) {
const timeZone = Session.getScriptTimeZone();
const dateText = Utilities.formatDate(date, timeZone, 'yyyyMMdd-HHmmss');
return `${dateText}-${originalName.replace(/[\\/:*?"<>|]/g, '-')}`;
}
function extractReportFields(text) {
return {
managementId: extractLabeledValue(text, '管理番号'),
person: extractLabeledValue(text, '対象者'),
reportDate: extractLabeledValue(text, '報告日'),
status: extractLabeledValue(text, '状況'),
nextAction: extractLabeledValue(text, '次回対応'),
};
}
function extractLabeledValue(text, label) {
const escapedLabel = label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const pattern = new RegExp(`^${escapedLabel}\\s*[::\\t]\\s*(.+)$`, 'm');
const match = text.match(pattern);
return match ? match[1].trim() : '';
}このコードは、報告書の形式が固定されている場合の出発点です。見出しと値が別の行にある、Word内の表を使っている、旧形式の `.doc` が届くなど、条件が違えば修正が必要です。
処理済みかどうかは、Gmailのスレッドにラベルを付ける方法ではなく、「メッセージID+添付ファイル名」をスプレッドシートの1列目へ記録して判定します。同じスレッドへ新しい報告書が返信された場合も、別のメッセージとして扱いやすくするためです。
メールをスプレッドシートへ自動転記する5ステップ

コードを貼り付けてから定期実行するまでを、次の5ステップで進めます。
- ダミーファイルと出力先を作る
- 設定値と高度なDriveサービスを用意する
- 手動実行して権限を承認する
- 検索から転記までを結果で確認する
- 時間主導型トリガーを設定する
1. ダミーファイルと出力先を作る
固定ラベルを入れたWordファイルを作り、テスト用件名で自分宛てに送ります。Driveにはテスト専用フォルダ、Sheetsには空のスプレッドシートを用意してください。
本番のメールアドレスや報告書を使うと、検索条件が間違っていたときの影響が大きくなります。最初は普段使わない件名に限定し、対象メールが1件だけになる状態を作ります。
2. 設定値と高度なDriveサービスを用意する
`SENDER`、`SUBJECT_KEYWORD`、`SPREADSHEET_ID`、`FOLDER_ID` をテスト環境に合わせます。スプレッドシートIDはURLの `/d/` と `/edit` の間、フォルダIDはDriveフォルダURLの末尾にある文字列です。
そのうえで、Apps Scriptの「サービス」からDrive APIを追加します。サンプル内の `Drive.Files.create()` は、通常の `DriveApp` ではなく高度なDriveサービスの機能です。
3. 手動実行して権限を承認する
Apps Script上部の関数選択で `transferWordReports` を選び、「実行」を押します。初回はGmail、Drive、Docs、Sheetsなどへのアクセス許可を求められます。どのアカウントで実行しているか、表示された権限がコードの処理内容と合っているかを確認してから承認してください。Apps Scriptの認可|Google for Developers
権限画面が出たこと自体は、処理が成功した証拠ではありません。承認後にもう一度実行し、DriveとSheetsの結果を確認します。
4. 検索から転記までを結果で確認する
テスト用フォルダには、Word原本とGoogleドキュメント版の2ファイルが作られます。Sheetsには見出し行とデータ1行が入り、管理番号から次回対応までがWordの内容と一致しているかを見比べます。
同じコードをもう一度手動実行し、行が増えないことも確認してください。増えた場合は、処理キーが1列目へ保存されているか、添付ファイル名が実行のたびに変わっていないかを調べます。
5. 時間主導型トリガーを設定する
手動実行で正しい結果を確認できたら、Apps Scriptの「トリガー」から `transferWordReports` の時間主導型トリガーを作ります。毎日や毎時間など、報告書の頻度に合う間隔を選びます。
インストール型トリガーは、作成したアカウントの権限で実行されます。担当者が変わる業務では、個人アカウントへ依存させるか、管理用アカウントを使うかも先に決めてください。インストール型トリガー|Google for Developers
スプレッドシートへ保存する12列と確認方法

サンプルコードは、次の12列を左から順に作ります。
| 列 | 保存する内容 | 用途 |
|---|---|---|
| 処理キー | メッセージID+添付名 | 同じ添付の二重転記を防ぐ |
| 受信日時 | Gmailの受信日時 | 報告の並び順を確認する |
| 送信元 | メールの送信元 | 想定した相手かを確認する |
| 件名 | メール件名 | 検索条件と照合する |
| 管理番号 | Wordから抽出したID | 人や案件を一意に識別する |
| 対象者 | Wordから抽出した対象者 | 人ごとの確認に使う |
| 報告日 | Wordに記載された日付 | 受信日と報告日を分ける |
| 状況 | Wordから抽出した状況 | 現在の状態を一覧で見る |
| 次回対応 | Wordから抽出した予定 | 次の行動を確認する |
| Word原本URL | 保存した `.docx` のURL | 元の報告書へ戻る |
| GoogleドキュメントURL | 変換版のURL | 抽出元のテキストを確認する |
| 処理日時 | GASが転記した日時 | 実行状況を確認する |
私の運用では、スプレッドシートを人ごとの状況を見られるデータベースとして使っています。対象者名だけでは同姓同名や表記揺れが起きるため、可能であれば管理番号など重複しない値も持たせてください。
空欄があった場合に、空欄のまま転記するか、処理を止めるかも業務に合わせて決めます。重要な項目なら、「管理番号が空なら行を追加せずエラーを記録する」などの条件を加えた方が安全です。
また、Sheetsの `appendRow()` はシート末尾へ行を追加します。既存行を更新して最新状態だけを残したい場合は、管理番号を検索して該当行を更新する別設計が必要です。Sheet class|Google for Developers
自分の報告書に合わせてGASを直すプロンプト2選

サンプルコードをChatGPTなどのAIに修正してもらう場合は、実際の個人情報やファイルIDを消し、ダミーの入力例と期待する出力を渡します。ここでは、目的別に2つのプロンプトを用意しました。
- Word報告書から取り出す項目を変える
- GASのエラーや空欄を一工程ずつ調べる
1. 抽出項目を変えるプロンプト
次のGoogle Apps Scriptは、GmailのWord添付をGoogleドキュメントへ変換し、本文の固定ラベルから値を取り出すコードです。
【現在の抽出項目】
管理番号、対象者、報告日、状況、次回対応
【変更後の抽出項目】
ここに必要な項目を書く
【ダミーのWord本文】
ここに個人情報を含まない例を書く
【期待するスプレッドシートの1行】
ここに列名とダミー値を書く
変更する関数とHEADERSだけを示してください。
固定ラベルが見つからない場合は空文字にし、推測で値を補わないでください。
変更理由と、ダミーデータで確認する手順も説明してください。列を変えるときは、`HEADERS`、`extractReportFields()`、`appendRow()` の並びをそろえる必要があります。AIが一部だけ変えていないか、列名と値を左から見比べてください。
2. エラーを切り分けるプロンプト
Google Apps Scriptでメール添付の自動転記をテストしています。
コード全体を書き直さず、失敗している工程だけを切り分けてください。
【実行した関数】
【表示されたエラー全文】
【検索・保存・変換・抽出・転記のうち成功した工程】
【期待した結果】
【実際の結果】
【ダミーの入力例】
【高度なDriveサービスの追加状況】
次の順番で回答してください。
1. 最も可能性が高い原因
2. 確認する場所
3. 最小限の修正コード
4. 修正後のテスト手順
メールアドレス、氏名、ファイルID、認証情報はダミー値のまま扱ってください。エラー文だけでなく、「Driveには保存できたがSheetsに行が増えない」のように、成功した工程も伝えます。原因の範囲が狭まり、関係のない部分まで書き換えられるのを防げます。
GASで自動転記できないときの6つの確認

動かない場合は、コード全体を交換する前に、次の6項目を順番に確認します。
- Gmailの検索条件でテストメールが1件見つかるか
- 添付ファイルが `.docx` になっているか
- 高度なDriveサービスを追加したか
- Word本文のラベルとコードの文字が一致しているか
- 1列目の処理キーで処理済みになっていないか
- トリガーを作ったアカウントに必要な権限があるか
Gmail検索で対象が見つからない
まずGmailの検索窓へ、`buildSearchQuery()` が作る条件をそのまま入れてください。Gmail画面で見つからなければ、GASでも取得できません。送信元、件名、検索日数を一つずつ外し、どの条件で0件になるかを確認します。
Wordを変換できない
`Drive is not defined` などDriveに関するエラーが出る場合は、Apps Scriptの「サービス」にDrive APIが追加されているかを確認します。`.doc`、パスワード付きファイル、破損したファイルなどは、同じコードで処理できない場合があります。最初は自分で作った単純な `.docx` を使ってください。
抽出した値が空欄になる
Googleドキュメントへ変換したファイルを実際に開き、本文が読めるかを確認します。そのうえで「管理番号:TEST-001」のように、ラベルと値が同じ行にあるかを見ます。全角・半角の違い、ラベル末尾の空白、表のセル区切りによって、正規表現と一致しないことがあります。
2回目のテストで行が増えない
これは重複防止が働いた正常な結果かもしれません。同じメールをもう一度転記したい場合は、テスト用メールを新しく送るか、テストシートの該当行とDrive上のテストファイルを確認してから、処理キーを扱ってください。本番データの処理キーを安易に消すと二重転記につながります。
トリガーだけ失敗する
手動実行したアカウントと、トリガーを作ったアカウントの違いを確認します。保存先フォルダや転記先シートへの権限がない場合、手動では動いても別アカウントのトリガーでは失敗します。Apps Scriptの実行履歴も開き、エラーが起きた関数と時刻を確認してください。
仕事のメールを自動転記するときの5つの安全ルール

GASはGoogleアカウントの権限でGmailやDriveを操作します。仕事で使う前に、次の5つをルールにしてください。
- 最初は個人情報を含まないダミーデータで試す
- コードやAIへの質問文に認証情報を入れない
- Gmail、Drive、Docs、Sheetsの権限を必要な範囲にする
- Word原本と処理履歴を残す
- 定期実行後もエラーと転記結果を人が確認する
実際のメールアドレス、氏名、顧客情報、スプレッドシートID、フォルダIDは、公開記事やAIへの質問文にそのまま貼らないでください。`report@example.com` や `FOLDER_ID` のようなダミーへ置き換えても、コードの相談はできます。
トリガーを作成したアカウントが異動や退職で使えなくなると、自動処理が止まる可能性があります。誰が所有し、誰がエラーを確認するかを決めておくことも運用の一部です。
また、自動転記は確認をなくす仕組みではありません。確認する場所を、受信箱、Drive、Sheetsの3か所から、主にSheetsの処理状況へ集約する仕組みです。原本を残し、必要なときに人が照合できる状態を維持してください。
生成AIへ業務データを入力するときの判断は、生成AIに個人情報を入力しても大丈夫?でも詳しく解説しています。
GASのメール自動転記に関するよくある質問

- プログラミング初心者でもGASでメールを自動転記できますか?
-
できます。ただし、コードを貼るだけで終わらせず、検索、保存、変換、抽出、転記のどこまで成功したかを自分で確認できるようにしてください。最初はダミーメール1件の手動実行がおすすめです。
- Word以外の添付ファイルも転記できますか?
-
可能ですが、ファイル形式ごとに読み取り方が変わります。Googleドキュメントへ変換できるファイル、PDF、画像では必要な処理が異なるため、本記事の `.docx` 用コードをそのまま使えるとは限りません。
- 1通にWordファイルが複数ある場合はどうなりますか?
-
サンプルコードは、`.docx` の添付ごとに1行を追加します。処理キーにはメッセージIDと添付ファイル名を使います。同じメール内に同名の添付がある特殊なケースでは識別方法の追加が必要です。
- GASは無料で使えますか?
-
GoogleアカウントでApps Scriptを利用できますが、サービスごとに実行時間や呼び出し回数などの割り当てがあります。利用量やGoogle Workspaceの契約によって条件が変わるため、現在の公式情報を確認してください。
- 確認せずに完全自動化しても大丈夫ですか?
-
最初から完全自動化するのはおすすめしません。検索条件、Wordの書式、権限、空欄、重複をダミーで確認し、手動実行が安定してからトリガーを設定します。運用後も実行履歴と転記結果を定期的に確認してください。
まとめ|まず1件のダミーメールで自動転記を試す

GASを使えば、特定のGmailを検索し、Word添付の原本保存、Googleドキュメントへの変換、必要項目の抽出、スプレッドシートへの転記までをつなげられます。
今回のポイントは、次の5つです。
- 送信元と件名を限定して対象メールを絞る
- Word原本とGoogleドキュメント版をDriveへ残す
- 固定ラベルから必要項目だけを抽出する
- メッセージIDと添付名で二重転記を防ぐ
- 手動実行を確認してから時間主導型トリガーを作る
報告書の形式が違えば、抽出部分の修正は必要です。それでも、検索から転記までを一つの大きな処理として考えず、5工程へ分ければ、どこを直せばよいか判断しやすくなります。
まずは固定ラベルだけを入れたダミーのWordファイルを作り、普段使わないテスト用件名で自分宛てに送ってください。対象が1件だけの状態で `transferWordReports` を手動実行し、Driveの2ファイルとSheetsの1行を確認するところから始めましょう。
