🛠️

Gmailの不要なメールを一括削除する

2023/01/08に公開

概要

Gmailを長年使用していると、2度と読むことのないであろう不要なメールが蓄積していく
ひとつひとつ心を込めて削除するのも一興だが、筆者はものぐさなのでスクリプトに任せようと思う
このネタは何番煎じかわからないが、ログを残したり、コンディション指定を適宜書き換えやすくするために多少の工夫をしている

環境

個人用アカウントのGoogle Apps Script

注意事項

Google App Scriptには処理のタイムアウトが設定されているのだが、本記事の主旨から外れるため対策をしていない
!!メールを削除するという特性上、十分に注意して実行すること!!

ソースコード全体

function deleteTrashMail() {
  
  // Specify conditions to be deleted
  const searchCondition = [
    'category:promotions'
  ];

  // Specified in 1 month
  const retention = "1m";
  // Delete emails that have exceeded the specified period and are not starred
  const baseCondition = [
    'older_than:' + retention,
    '-is:starred'
  ];
   
  function createDateStr(dt){
    return Utilities.formatDate(dt,Session.getTimeZone(),"yyyy-MM-dd HH:mm:ss");
  }
  
  var deleteLog = new Map();
  const MAX_SIZE = 500;
  searchCondition.forEach(function(elem){
    const mergeCondition = baseCondition.concat(elem).join("\u0020");
    
    var response = GmailApp.search(mergeCondition, 0, MAX_SIZE);
    do{
      response.forEach(function (thread) {
        thread.getMessages().forEach(function (msg){
          const dt = msg.getDate();
          deleteLog.set(dt,[createDateStr(dt), msg.getSubject(), msg.getFrom()].join("\u0020"));
        });
        thread.moveToTrash();
      });
      response = GmailApp.search(mergeCondition, 0, MAX_SIZE);
    }while(response.length!=0);
  });
  
  if(deleteLog.size){
    const sortedLog = new Map([...deleteLog.entries()].sort((a, b) => a[0] - b[0]));
    const address = Session.getEffectiveUser().getEmail();
    MailApp.sendEmail(address, 'MyReport', Array.from(sortedLog.values()).join("\n"));
  };
}

各処理の詳細

削除対象のコンディションを指定する
各々のコンディションについて、削除処理は1回ずつ走る
#コンディションの指定方法はGmailのGUIと同じ
 https://support.google.com/mail/answer/7190?hl=en

const searchCondition = [
    'category:promotions'
  ];

削除対象としない保持期間を指定する
その他に設定したい共通のコンディションがあればここに定義する

  // Specified in 1 month
  const retention = "1m";
  // Delete emails that have exceeded the specified period and are not starred
  const baseCondition = [
    'older_than:' + retention,
    '-is:starred'
  ];

削除処理を実行する
具体的にはbaseConditionと"serchConditionの各要素"をそれぞれマージし、ループ処理としている
また、削除したメールはdeleteLogに記録する

  searchCondition.forEach(function(elem){
    const mergeCondition = baseCondition.concat(elem).join("\u0020");
    
    var response = GmailApp.search(mergeCondition, 0, MAX_SIZE);
    do{
      response.forEach(function (thread) {
        thread.getMessages().forEach(function (msg){
          const dt = msg.getDate();
          deleteLog.set(dt,[createDateStr(dt), msg.getSubject(), msg.getFrom()].join("\u0020"));
        });
        thread.moveToTrash();
      });
      response = GmailApp.search(mergeCondition, 0, MAX_SIZE);
    }while(response.length!=0);
  });

deleteLogが空でなければ、タイムスタンプの昇順にソートしたログを自身のアカウント(スクリプトを実行したアカウント)宛てに送信する

  if(deleteLog.size){
    const sortedLog = new Map([...deleteLog.entries()].sort((a, b) => a[0] - b[0]));
    const address = Session.getEffectiveUser().getEmail();
    MailApp.sendEmail(address, 'MyReport', Array.from(sortedLog.values()).join("\n"));
  };

※ちなみにこんなログが届く

2023-01-02 01:02:03 件名 "送信者名"<foo@bar.com>
2023-01-02 04:05:06 件名 "送信者名"<baz@qux.co.jp>
...

Discussion