LoginSignup
4
2

More than 3 years have passed since last update.

Gmail の掃除のために送信者を件数でランキングする

Last updated at Posted at 2020-10-11

概要

Google Apps Script を使って、受信メールの件数を差出人ごとにランキングした結果をスプレッドシートに出力します。

背景

Google さんが今後ゴミ箱の中身を 30 日で自動消去する(むしろ今まで無限だったの…?)というニュース1でふと思い立って今の使用容量を見てみたら、 全体で14GB、Gmail だけで 3GB も使っていました。

大事なときに全体が15GBに達していたら良くないと思い、要らなそうなメルマガなどを差出人ごとにばっさり消したかったのですが、件数の多い差出人を見る方法がありませんでした。

余談:ゴミ箱の中身も容量の15GBに含まれます。

コード

コード.gs
/**
  便利関数の追加
*/
function extension() {
  // flatMap の追加
  // https://gist.github.com/samgiles/762ee337dff48623e729
  Array.prototype.flatMap = function (lambda) {
    return Array.prototype.concat.apply([], this.map(lambda));
  };

  // groupBy の追加
  // https://stackoverflow.com/questions/14446511/most-efficient-method-to-groupby-on-an-array-of-objects
  Array.prototype.groupBy = function (getKey) {
    const map = new Map();
    this.forEach(item => {
      const key = getKey(item);
      const collection = map.get(key);
      if (!collection) {
        map.set(key, [item]);
      } else {
        collection.push(item);
      }
    });
    return map;
  };
}

/**
  Gmail差出人ごと件数ランキング作成
*/
function fromRanking() {
  // 便利関数の追加
  extension();
  const book = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = book.getActiveSheet();

  // シートのクリア
  sheet.clear();
  sheet.appendRow(['From', 'Count', 'Search', '', 'Running.']);

  // スレッドをメッセージ単位にflatten、差出人でgroupBy、記入
  let row = 2;
  // 検索リンク用数式。" label:inbox" をつけてアーカイブしてないものに絞っても良いかも知れない
  const formula = '=HYPERLINK("https://mail.google.com/mail/u/0/#search/from%3A"&ENCODEURL(RC[-2]),"SEARCH")';
  GmailApp.getInboxThreads()
    .flatMap(th => th.getMessages())
    .map(m => m.getFrom())
    .groupBy(f => f)
    .forEach((v, k) => {
      // 差出人と件数
      sheet.getRange(row, 1, 1, 2).setValues([[k, v.length]]);
      // Gmail 差出人の名前で検索
      sheet.getRange(row, 3).setFormulaR1C1(formula);
      row++;
    });

  // 結果のソート
  // https://excel-ubara.com/apps_script1/GAS030.html
  const lastRow = sheet.getLastRow();
  const lastCol = sheet.getLastColumn();
  sheet.getRange(2, 1, lastRow, lastCol).sort({ column: 2, ascending: false });

  const date = new Date();
  const finishDate = Utilities.formatDate(date, 'Asia/Tokyo', 'yyyy/MM/dd hh:mm:ss');
  sheet.getRange(1, 5).setValue('Finished. ' + finishDate);
}

実行

( ! ) 実行するとアクティブなシートの内容が全て消えますのでご注意ください。

分かる方向け

関数 fromRanking を実行してください。

わからない方向け

  1. スプレッドシートを開き、結果出力したいシートを表示する
  2. スプレッドシート - ツール > スクリプト エディタ
  3. スクリプト エディタ - 実行 > 関数を実行 > fromRanking
  4. E1 セルが Finished. になるまで待つ
4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2