取引先から届く納品書や写真などの添付ファイルを、そのつどメールを開いてGoogleドライブへ保存し直している場合、件数が増えるほど保存漏れや同じファイルの重複保存が起きやすくなります。
Gmail単体には添付ファイルだけを外部へ自動保存する機能がなく、対応にはGoogle Apps Script(Googleが提供するスクリプト環境)によるコードの実装が欠かせません。
この記事では、条件に一致したメールの添付ファイルだけをGoogleドライブへ自動保存し、保存済みのメールを再処理しない仕組みまで整理しています。
完成イメージ
完成するのは、指定した条件に一致するメールの添付ファイルを、月別のフォルダへ自動で振り分けて保存する仕組みです。
検索条件は送信元・件名・添付の有無などを組み合わせて指定でき、条件に合わないメールの添付ファイルは保存対象から外れます。
対象を絞り込む条件は業務によって異なるため、まず何を基準に保存対象を決めるかを整理しておく必要があります。
| 絞り込みたい対象 | 検索クエリの例 | 向いている場面 |
|---|---|---|
| 特定の取引先からの添付ファイルだけ |
| 取引先ごとにフォルダを分けて保管したい場合 |
| 件名に決まった語句が入るメールだけ |
| 書類の種類ごとに保存先を分けたい場合 |
| 添付ファイルがあるメール全件 |
| 受信トレイの添付ファイルを一括で退避したい場合 |
条件を絞り込みすぎると保存対象から漏れるメールが出てくるため、最初は広めの条件で動かし、実際に保存されたファイルを見ながら条件を調整していく進め方が安全です。
手順
ラベルの準備からトリガー設定まで、4つのステップで完成します。
Step1. 保存先フォルダを準備する
Googleドライブで添付ファイルの保存先にしたいフォルダを作成し、URLに含まれるフォルダIDを控えておきます。
このフォルダの直下には、コードが月別のサブフォルダを自動で作成していく設計です。
Step2. コードを貼り付ける(コード全文)
script.google.comを開き、「新しいプロジェクト」を選択します。
表示されているコードをすべて消し、次のコードを貼り付ける流れです。
function saveMailAttachmentsToDrive() {
const searchQuery = 'has:attachment -label:添付保存済'; // ★ここを変える: 保存対象にしたいメールの検索条件
const rootFolderId = 'ここに保存先フォルダのIDを入力'; // ★ここを変える: 保存先フォルダのID
const processedLabelName = '添付保存済';
let processedLabel = GmailApp.getUserLabelByName(processedLabelName);
if (!processedLabel) {
processedLabel = GmailApp.createLabel(processedLabelName);
}
const rootFolder = DriveApp.getFolderById(rootFolderId);
const threads = GmailApp.search(searchQuery);
threads.forEach((thread) => {
thread.getMessages().forEach((message) => {
saveAttachmentsFromMessage(message, rootFolder);
});
thread.addLabel(processedLabel);
});
}
function saveAttachmentsFromMessage(message, rootFolder) {
const attachments = message.getAttachments();
if (attachments.length === 0) {
return;
}
const monthFolder = getOrCreateMonthFolder(rootFolder, message.getDate());
attachments.forEach((attachment) => {
monthFolder.createFile(attachment);
});
}
function getOrCreateMonthFolder(rootFolder, date) {
const yyyy = date.getFullYear();
const mm = ('0' + (date.getMonth() + 1)).slice(-2);
const folderName = yyyy + '-' + mm;
const existingFolders = rootFolder.getFoldersByName(folderName);
if (existingFolders.hasNext()) {
return existingFolders.next();
}
return rootFolder.createFolder(folderName);
} searchQueryを書き換えれば、完成イメージの表で挙げた条件にそのまま差し替えられます。
rootFolderIdにはStep1で控えたフォルダIDを入力します。
添付ファイルはメールの受信日をもとに年-月という名前のフォルダを自動作成して保存されるため、あらかじめ月別フォルダを手作業で用意しておく必要はありません。
Step3. 1件だけ実行して確認する
保存対象になりそうなメールが1件だけ届いている状態でsaveMailAttachmentsToDriveを実行し、保存先フォルダに月別フォルダと添付ファイルが作成されているかを確認します。
初回実行時はGoogleアカウントへのアクセス許可を求める画面が出るため、内容を確認したうえで許可します。
Step4. 時間トリガーを設定する
スクリプトエディタの時計マークの「トリガー」を開き、右下の「トリガーを追加」から設定する流れです。
実行する関数はsaveMailAttachmentsToDriveを選び、イベントのソースは時間主導型、種類は分ベースのタイマーを選んで実行間隔を指定します。
保存すれば、指定した間隔で新着メールの確認と添付ファイルの保存が自動で繰り返されます。
添付ファイルを保存するだけでなく、メールの内容そのものを記録に残したい場合は、受信メールをスプレッドシートへ書き出す方法も参考になる進め方です。

二重保存を防ぐ処理済み管理
このコードでは、保存済みのスレッドに添付保存済というラベルを付け、検索条件に-label:添付保存済を含めることで、一度処理したメールを次回の実行対象から除外しています。
ラベルではなく実行日時を記録して比較する方法もありますが、実行間隔がずれたり手動で追加実行したりした際に対象範囲がずれやすく、ラベルによる管理のほうが確認しやすくなります。
1つのスレッドに複数のメールが含まれる場合、このコードはスレッド単位でラベルを付けるため、既に処理したスレッドに後から返信が届くと添付ファイルの再確認が漏れる点には注意が必要です。
取引先とのやり取りが1メール1スレッドで完結しない業務では、スレッド単位ではなくメッセージ単位で処理済みかどうかを判定する設計に変更したほうが安全です。
保存されたファイルが増えてフォルダの見通しが悪くなってきた場合は、ドライブ全体のファイルを種類別・年月別に整理する仕組みも合わせて検討する価値があります。

Google Apps Scriptでの添付ファイル自動保存について相談してみませんか?
「取引先ごとに保存先フォルダを分けたい」「添付ファイルの保存と同時に台帳への記録も自動化したい」「社内にGoogle Apps Scriptを設計できる人材がいない」
少しでもお心当たりがあれば、お気軽にご相談ください。
現在、Google Apps Scriptを使った業務自動化のお悩みをお伺いする 無料の個別相談 を実施しています。
よくある質問
Q. PDFや画像以外のファイル形式でも保存できますか?
保存できます。
message.getAttachments()はメールに添付された形式を問わずすべて取得するため、Excelファイルや圧縮ファイルが添付されていても同じコードで保存対象として扱われる仕組みです。
Q. 保存先のフォルダをGoogleドライブの共有ドライブにできますか?
できます。
rootFolderIdに共有ドライブ内のフォルダIDを指定すれば、そのままの構成で保存できます。
ただし、実行するアカウントにその共有ドライブへの編集権限が必要です。
Q. 添付ファイルのファイル名が重複した場合はどうなりますか?
同じ名前のまま両方とも保存され、上書きはされません。
Googleドライブは同一フォルダ内に同名ファイルが複数存在しても区別して保持できる仕組みのため、ファイルが消えることはありません。
ただし見分けが付きにくくなる場合は、ファイル名にメール受信日時を付け足す処理を追加すると管理しやすくなります。
Q. 一度も処理していない過去のメールもまとめて保存できますか?
できます。
searchQueryにafter:やbefore:を組み合わせた期間指定を加えると、過去に届いた未処理のメールも検索対象に含められる仕組みです。
初回実行時は対象件数が多くなりがちなので、期間を区切って数回に分けて実行すると安全です。