📨

【GAS】Gmail受信トレイの指定日以前のメールを自動で定期削除する

に公開

はじめに

Gmailを長く使っていると、メルマガや通知メールを自動振り分けしていても、受信トレイがあっという間に容量いっぱいになりがちです。
全てのメールを片っ端から削除するのは不安が残ります。必要なメールだけ残しつつ、古いメールを定期的に掃除したい。この記事では、そういったときのために、Google Apps Scriptを使ってGmail自動削除する仕組みを作ります。

対象者

  • 個人のGmailアカウントを使っていて、受信トレイがすぐに埋まってしまう方
  • 会社のGoogle Workspaceではなく、まずは自分の個人アカウントで試してみたい方
  • Google Apps Scriptを学びたい方

この記事でできること

この記事では、個人のGmailアカウントで「受信トレイ in:inbox にある、指定日[X]日以前のメール」を毎日自動で削除する方法を紹介します。

前提

  • 毎日1000通レベルでメールが届くことを想定する
  • スクリプト1回あたりの処理件数を制限して、実行時間上限に引っかかりにくくする
  • まずはゴミ箱に移動するだけに留めて挙動を確認する
  • 問題がないと判断できた後、必要なら完全削除のスクリプトに切り替える

なぜ「受信トレイ in:inbox かつ older_than:30d」に限定するのか

Gmailの検索クエリにはさまざまな条件がありますが、今回の条件を整理すると次のようになります。

  • in:inbox

    • 受信トレイに属しているスレッドだけを対象にする
    • アーカイブ済みのスレッドや、別ラベルに移動したスレッドは対象外になる
  • older_than:30d

    • 現在より30日前より古いスレッドを対象にする

受信トレイに残っているメールは、多くの人にとって「未整理のタスク置き場」のような存在になりがちです。それを時間で区切って、自動的に掃除していくのが今回の狙いです。

また、GmailAppは「スレッド単位」で操作するため、スレッドを1つ削除すれば、そのスレッド内の全メッセージがまとめて処理されます。

設計のポイント

検索条件の設計

今回の検索クエリは次の通りです。

  • in:inbox older_than:30d

Gmailの検索バーにそのまま貼り付ければ、実際にどのスレッドがヒットするかを事前に確認できます。

Apps Scriptの実行時間制限を考慮したバッチ設計

Google Apps Scriptには、1回の実行あたりの実行時間上限があります。
そのため、古いメールが大量に溜まっている状態で一気に処理すると、上限に引っかかって途中でエラー終了してしまう可能性があります。
そこで次のようなパラメータを用意して、1回の実行で処理しすぎないようにします。

  • batchSize

    • 1回のバッチで操作するスレッド数の上限
    • 例 100
  • maxThreadsPerRun

    • 1回の実行全体で処理するスレッド数の上限
    • 例 2000

whileループで、以下の形で、少しずつスレッドを削っていきます。

  • 残り件数が maxThreadsPerRun に達するまで
  • 毎回 batchSize 件ずつ検索して処理

毎日このスクリプトを実行すれば、最初の数日は大量に削除され、その後は「新しく30日を超えたメールだけ」が対象になるため、自然と処理件数が落ち着いていきます。

ログ設計

スクリプトがどのくらい動いたのかを把握するために、Logger.logで次の情報を出力します。

  • バッチごとのスレッド数
  • バッチごとのメッセージ数
  • 実行全体の累計スレッド数
  • 実行全体の累計メッセージ数

これにより、以下のような感覚がつかみやすくなります。

  • どのくらいのペースでメールが削除されているか
  • 古いメールを一掃し終わるまでに何回くらい実行が必要か

Apps Scriptの実行ログは、エディタ画面から以下の手順で確認できます。

  • 左側の「実行」メニュー
  • 対象の実行履歴を選択
  • ログタブを開く

安全運用のステップ

いきなり完全削除してしまうのはリスクが高いため、この記事では次のステップを推奨します。

  1. まずはゴミ箱に移動するだけのスクリプトで運用する
  2. 数日〜数週間ほど様子を見て、問題ないことを確認する
  3. 必要があれば完全削除用のスクリプトに切り替える

Gmailの仕様として、ゴミ箱に移動されたメールは一定期間後に自動削除されます。そのため、そもそも完全削除のスクリプトが不要なケースもあります。

手順とコード

ここからは、実際のApps Scriptのコードと手順を紹介します。

スクリプトファイルの作成手順

  1. ブラウザで https://script.google.com にアクセスして新しいプロジェクトを作成する
  2. コードエディタに表示されている Code.gs の中身を全て削除する
  3. これから紹介するコードを貼り付ける
  4. プロジェクト名を分かりやすい名前に変更する

ここまでできたら、実際のコードを見ていきます。

受信トレイの30日より前メールをゴミ箱に移動するスクリプト

まずは一番安全な「ゴミ箱に移動するだけ」のスクリプトです。

/**
 * 受信トレイの「30日より前のメール」を削除用にゴミ箱へ移動する
 * 対象  in:inbox older_than:30d
 * ログ  処理したスレッド数とメッセージ数を実行ログに出力する
 */
function deleteOldInboxMails() {
  // 検索条件 受信トレイかつ30日より前
  var query = 'in:inbox older_than:30d';

  // 一度に処理するスレッド数 1バッチあたり
  var batchSize = 100;

  // 1回の実行で処理する最大スレッド数
  // 毎日1000通レベルを想定しつつ余裕を持った値にしておく
  var maxThreadsPerRun = 2000;

  var totalThreadsMoved = 0;
  var totalMessagesMoved = 0;

  while (totalThreadsMoved < maxThreadsPerRun) {
    var remaining = maxThreadsPerRun - totalThreadsMoved;
    var fetchSize = Math.min(batchSize, remaining);

    // 毎回検索結果の先頭から取得する
    var threads = GmailApp.search(query, 0, fetchSize);

    if (threads.length === 0) {
      Logger.log('処理対象スレッドが無くなったため終了します。');
      break;
    }

    // このバッチでのメッセージ総数をカウントする
    var messageCountInBatch = 0;
    for (var i = 0; i < threads.length; i++) {
      messageCountInBatch += threads[i].getMessageCount();
    }

    // 安全策として当初はゴミ箱への移動に留めておく
    GmailApp.moveThreadsToTrash(threads);

    totalThreadsMoved += threads.length;
    totalMessagesMoved += messageCountInBatch;

    Logger.log(
      'バッチ処理  %s スレッド  %s メッセージをゴミ箱へ移動 累計  %s スレッド  %s メッセージ',
      threads.length,
      messageCountInBatch,
      totalThreadsMoved,
      totalMessagesMoved
    );

    // 連続実行による負荷を抑えるために少し待機する 単位はミリ秒
    Utilities.sleep(500);
  }

  Logger.log(
    'deleteOldInboxMails 完了  合計 %s スレッド  %s メッセージをゴミ箱へ移動しました',
    totalThreadsMoved,
    totalMessagesMoved
  );
}

完全削除したい場合のスクリプト例

次に、ゴミ箱を経由せずに完全削除するスクリプトです。
この関数はテストや挙動確認を十分に行ったあと、本当に必要だと判断できた場合のみ利用してください。

/**
 * 受信トレイの「30日より前のメール」を完全削除する
 * ゴミ箱の有無に関わらずスレッドを削除するため取り返しがつかない
 */
function deleteOldInboxMailsPermanently() {
  var query = 'in:inbox older_than:30d';
  var batchSize = 100;
  var maxThreadsPerRun = 2000;

  var totalThreadsDeleted = 0;
  var totalMessagesDeleted = 0;

  while (totalThreadsDeleted < maxThreadsPerRun) {
    var remaining = maxThreadsPerRun - totalThreadsDeleted;
    var fetchSize = Math.min(batchSize, remaining);

    var threads = GmailApp.search(query, 0, fetchSize);
    if (threads.length === 0) {
      Logger.log('処理対象スレッドが無くなったため終了します。');
      break;
    }

    var messageCountInBatch = 0;
    for (var i = 0; i < threads.length; i++) {
      messageCountInBatch += threads[i].getMessageCount();
    }

    // 完全削除 ゴミ箱も含めて削除される
    GmailApp.deleteThreads(threads);

    totalThreadsDeleted += threads.length;
    totalMessagesDeleted += messageCountInBatch;

    Logger.log(
      '[完全削除] バッチ処理  %s スレッド  %s メッセージを削除  累計  %s スレッド  %s メッセージ',
      threads.length,
      messageCountInBatch,
      totalThreadsDeleted,
      totalMessagesDeleted
    );

    Utilities.sleep(500);
  }

  Logger.log(
    '[完全削除] deleteOldInboxMailsPermanently 完了  合計 %s スレッド  %s メッセージを削除しました',
    totalThreadsDeleted,
    totalMessagesDeleted
  );
}

スクリプトのテスト実行手順

本番運用に入る前に、まずは手動で実行して挙動を確認します。

  1. Apps Scriptエディタの上部で関数を選択できるプルダウンから deleteOldInboxMails を選ぶ
  2. 再生マークのボタンを押して実行する
  3. 初回実行時は権限確認ダイアログが表示されるので、画面の案内に従ってGmailへのアクセスを許可する
  4. 実行が成功したら、左側の「実行」メニューから対象の実行履歴を開き「ログ」タブで処理件数を確認する

特に最初のうちは、maxThreadsPerRunを200や300程度に小さく設定しておき、どのくらいのスレッドが対象になるかを慎重に確認するのがおすすめです。

さらに安全に進めるなら、次の流れで確認します。

  • まずはGmail本体の検索バーに in:inbox older_than:30d を貼り付けて、目視で対象を確認する
  • スクリプトを実行する前に、念のため重要なメールにはスターを付けておく、もしくは別ラベルに移動しておく

毎日自動実行のトリガー設定

手動実行で問題がなさそうなら、時間主導型トリガーを設定して毎日自動実行に切り替えます。

  1. 左側メニューから時計アイコンの「トリガー」を開く
  2. 右下の「トリガーを追加」ボタンをクリックする
  3. フォームで次のように設定する
  • 実行する関数 deleteOldInboxMails
  • 実行するデプロイ Head
  • イベントのソース 時間主導型
  • 時間ベースのトリガーのタイプ 日付ベースのタイマー
  • 時刻 深夜から早朝の時間帯 例: 3時〜4時
  1. 保存ボタンを押してトリガーを有効化する

これで、毎日指定時間帯にスクリプトが起動し、受信トレイの30日より前のメールをゴミ箱へ移動してくれるようになります。

応用例とカスタマイズ案

今回のスクリプトはあくまで基本形なので、運用に合わせて次のような拡張も考えられます。
まずはシンプルな形で安定運用し、慣れてきたら条件や通知方法を少しずつチューニングしていきましょう。

  • スター付きメールや特定ラベル付きメールを除外したい

    • in:inbox older_than:30d -is:starred -label:重要
  • プロモーション系だけを対象にしたい

    • in:inbox category:promotions older_than:30d
  • 自動削除のサマリを毎回自分宛てにメール送信したい

    • 実行結果の件数を本文にまとめて MailApp.sendEmail で送信する

注意点とリスク

メールの自動削除は便利な反面、設定ミスがあると重要なメールを失ってしまうリスクがあります。
特に気を付けたいポイントを整理します。

  • クエリの書き間違い

    • older_than の日数や in:inbox の有無を誤ると、想定外のメールが対象になる
  • 完全削除スクリプトの誤実行

    • deleteOldInboxMailsPermanently をテストなしでいきなりトリガーに設定するのは避ける

不安がある場合は、以下のステップを踏むことをおすすめします。

  • まずはクエリをGmail本体で実行して目視確認する
  • ゴミ箱への移動だけで数週間運用し、問題がないと確信してから完全削除を検討する

おわりに

日々のメール整理は、気付くと後回しになってしまうタスクの代表格です。気力と時間が十分にある日にまとめてやろうとしても、結局は先延ばしになりがちです。
自分の時間を、過去のメールの整理ではなく、別なことに使えるようになる一歩として、この自動削除スクリプトが役に立てばうれしく思います。


株式会社ONE WEDGE

【Serverlessで世の中をもっと楽しく】
ONE WEDGEはServerlessシステム開発を中核技術としてWeb系システム開発、AWS/GCPを利用した業務システム・サービス開発、PWAを用いたモバイル開発、Alexaスキル開発など、元気と技術力を武器にお客様に真摯に向き合う価値創造企業です。
https://onewedge.co.jp/

GitHubで編集を提案

Discussion