私の今の個人ドメイン(shin.do)のメールアドレスでGmailを始めたのは2011年1月からです。14年ほど使ってきて、メールボックスには20万通のメールが溜まり、与えられた20GBのストレージ容量のうち70%以上を消費していました(Google Photoは使っていないので、ほぼメールのみで70%使用している状況)。14年でこんな感じですので、このペースならまだしばらく使えそうでしたが「思い立ったが吉日!」ということで、Gmailのメールボックスを整理することにしました。
小さなメールをちまちま消しても埒が空かないので、まずはサイズの大きいメールを探しました。Gmailでは、検索ウィンドウで “larger:10mb” などとすれば10MB以上のメールを見つけることができます。ただ、今回は個人メールアドレスなので、サイズの大きなメールはそう多くはありませんでした。
次の整理のターゲットは広告・通知系メールです。長年使っているとこれらのメールが大量に溜まっているはずです。しかし、Gmailには送信メール件数の多いメールアドレスを教えてくれるような機能はありません。というわけで、Google Apps Scriptを使ってGoogle Sheetに送信者アドレス毎のメール数を集計することにしました。
コーディングはChatGTP先生にお手伝いいただきました(笑) 最初のコードはメールの最初100件しかみてくれなかったり、全メールを対象にするとtimeoutしてしまったり(Google Apps Scriptは実行に30分以上かかるものはtimeoutになる)、累計処理がうまくいかなかったり、で、何回かChatGTP先生とやりとりしながら、やっと期待通りに動くようになったのが以下のコードです。
function countEmailsBySenderWithResume() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const PROGRESS_CELL = "A2"; // 処理済みスレッド数を保存
const STATUS_CELL = "A1"; // ステータスメッセージ
const SENDER_CELL = "A4"; // 送信者
const COUNT_CELL = "B4"; // メール数累計
const START_ROW = 5; // データ書き出し開始行
const BATCH_SIZE = 100; // 1回で処理するスレッド数
// 初期化(初回だけ)
if (sheet.getRange(STATUS_CELL).getValue() === "") {
sheet.clear();
sheet.getRange(STATUS_CELL).setValue("実行中");
sheet.getRange(PROGRESS_CELL).setValue(0);
sheet.getRange(SENDER_CELL).setValue("送信者");
sheet.getRange(COUNT_CELL).setValue("件数");
}
let start = Number(sheet.getRange(PROGRESS_CELL).getValue());
const threads = GmailApp.getInboxThreads(start, BATCH_SIZE);
if (threads.length === 0) {
sheet.getRange(STATUS_CELL).setValue("完了!");
return;
}
// 今回分のメールを集計
const senderCounts = {};
for (let i = 0; i < threads.length; i++) {
const messages = threads[i].getMessages();
for (let j = 0; j < messages.length; j++) {
const sender = messages[j].getFrom();
senderCounts[sender] = (senderCounts[sender] || 0) + 1;
}
}
// 既存の集計を取得してマージ
const totalCounts = {};
const lastRow = sheet.getLastRow();
if (lastRow >= START_ROW) {
const dataRange = sheet.getRange(START_ROW, 1, lastRow - START_ROW + 1, 2);
const data = dataRange.getValues();
for (let i = 0; i < data.length; i++) {
const sender = data[i][0];
const count = Number(data[i][1]);
if (sender) totalCounts[sender] = count;
}
}
// 今回の集計を加算
for (let sender in senderCounts) {
totalCounts[sender] = (totalCounts[sender] || 0) + senderCounts[sender];
}
// ソートして書き出し
const sorted = Object.entries(totalCounts).sort((a, b) => b[1] - a[1]);
sheet.getRange(START_ROW, 1, sorted.length, 2).setValues(sorted);
// 進捗更新
sheet.getRange(PROGRESS_CELL).setValue(start + BATCH_SIZE);
sheet.getRange(STATUS_CELL).setValue(`処理中:${start + BATCH_SIZE} スレッド`);
}
これを実行するとBATCH_SIZEで指定されたメール数を処理して終了します。もう一度実行すると次のバッチを処理してくれるので、これを繰り返し実行することで、timeoutを避けつつ全メールを対象にすることができます。このスクリプトを手で何回も実行するのは現実的ではないので、時間主導型のトリガを使って定期的に起動するようにします。
ここでは10分おきに実行するように指定しています。1分間隔にすればもっと早く動作させることができますが、Google Apps Scriptは1日に起動できるサービスの回数に上限がありますので、あまり間隔を短くし過ぎるとエラーになってしまいます。というわけで、私はのんびりと10分間隔で動かしました。
トリガされるとApps Scriptを動かしているシートが以下のように徐々に結果が更新されていくはずです。
私の場合は全メールが処理されるのに何日かかかりました。このスクリプトは完全にクラウド側で動きますので、一旦トリガの設定をすれば、あとはクライアントPC側はネットワークから切り離されても問題なく動き続けてくれます。なので、何日かかってもさして大きな問題はないと思います。また、トリガが自動的に解除されるようなロジックは入っていないので、自分のメールボックスにあるメール数が処理されたらトリガを削除しましょう。
ここまでくれば、あとはメール送信件数が多い送信者からのメールを選択して消していくだけです。Gmailでは検索ウィンドウで、”from:foo@bar.com” などとすれば、foo@bar.comから送られたメールを抽出できます。このように抽出されたメールを全選択して、一括削除をすればOKです。この作業もApps Scriptで自動化することができると思いますが、メールの削除を伴うので、スクリプトの開発・デバッグ中に消してはないけないメールを謝って消してしまう事故が心配です。というわけで、今回は削除作業は目で確認しながら手動でやることにしました。削除まではせずとも、こうして得られたメール送信元リストは、不要な広告メールを送ってくるところを効率的にunsubscribeするのにもきっと役立つはずです。
今回の一連の作業で私のGmailのメール件数は約20万通から7万通ほどに削減され、使用率も70%から40%にまで低下しました。この作業を5年に一度くらいやっていけば、おそらく一生Gmailを使い続けていくことができるのではないかと思います(Gooleがサービスを辞めたりしなければ、ですが^^;)。皆さんも、たまにGmailのお掃除をしてみてはいかがでしょう? スッキリしますよ!
Photo by Stephen Phillips - Hostreviews.co.uk on Unsplash