33
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Google Apps ScriptAdvent Calendar 2014

Day 6

うちのGMailはこうなっている(2014年完全版)

Posted at

GMailの裏側で動かしてるGoogle App scriptをまとめてみました。
失敗作ものせてます。

前に書いた記事
http://qiita.com/tienlen/items/6b90932cc2cc72c7f143

これの完全バージョン。

Setting.gs

いわゆる設定ファイルです。
同じスクリプトないであれば、内部でgsファイルを分けていても参照できるようなのでまとめました。

  • SINGLE_MESSAGE_ONLY

    スレッドの状態判定です。
    単一のメールか複数スレッドになっているか判定します。

  • EMAIL_REGEX
    メールアドレスとして正しいかどうかの正規表現です。

  • DAYS_TO_SEARCH
    何日前のメールまでを参照するか?
    たしか、返信待ちのメールの判定に使ってたはず。

  • YOUR_EMAIL_ADDRESS
    GMailアドレスを入れてください。
    Session.getEffectiveUser().getEmail() とするとメアドが取れるけど、
    これだと初回認証がいるのでやめました。

setting
// exclude multi-message conversations where I sent the last message?
var SINGLE_MESSAGE_ONLY = false;
// string for regular expression check
var EMAIL_REGEX = /[a-zA-Z0-9\._\-]+@[a-zA-Z0-9\.\-]+\.[a-z\.A-Z]+/g;
// look only in sent messages from last 7 days, otherwise script takes a while
var DAYS_TO_SEARCH = 7;
// set your email address.
var YOUR_EMAIL_ADDRESS = "your gmail address";

function getEmailAddress() {
  // return Session.getEffectiveUser().getEmail();
  return YOUR_EMAIL_ADDRESS;
}

Received.gs

cleanUp

名前の通り、自動削除関数。
3dayというラベルを持ったメールを受信してから3日後に自動削除してくれます。
いらないメルマガとかその日見たら要らなくなるレポートとかに便利。

cleanUp
function cleanUp() {
  var delayDays = 3 // Enter # of days before messages are moved to trash
  var maxDate = new Date();
  maxDate.setDate(maxDate.getDate()-delayDays);
  var label = GmailApp.getUserLabelByName("3day");
  var threads = label.getThreads();
  for (var i = 0; i < threads.length; i++) {
    if (threads[i].getLastMessageDate()<maxDate)
      {
        threads[i].moveToTrash();
      }
  }
}

setParentLabel

設定してるラベルが階層形式になっていた場合。
設定しているラベルの親ラベルも自動で付与させる関数。
"Social/facebook" とかしてると、 "Social/facebook"には入るけど、"Social"では見れないのが嫌で作った。
フィルターで設定するとルールが2個になってしまうので作った。
結構お気に入り。

setParentLabel
function setParentLabel() {
  var labels = GmailApp.getUserLabels();
  for (var i = 0; i < labels.length; i++) {
    var label = labels[i];
    var labelName = labels[i].getName();
    if (labelName.indexOf('/') != -1) {
      var splitedLabelName = labelName.split('/');
      var parentLabelName = splitedLabelName[0];
      var searchQuery = 'label:' + labelName + ' -label:' + parentLabelName;
      Logger.log(labelName);
      Logger.log(parentLabelName);
      var parentLabel = GmailApp.getUserLabelByName(parentLabelName);
      var threads = GmailApp.search(searchQuery, 0, 500);
      Logger.log(threads.length);
      for (var t = 0; t < threads.length; t++) {
        threads[t].addLabel(parentLabel);
      }
    }
  }
}

sent.gs

label_messages_without_response

返信のない送信メールに対して受信待ちラベル(AwaitingResponse)をつける関数。
Googleの中の人が作ってたのを元に作成
http://googleappsdeveloper.blogspot.jp/2014/05/find-unanswered-emails-with-apps-script.html

label_messages_without_response
function label_messages_without_response() {
  var emailAddress = getEmailAddress();
  Logger.log(emailAddress);
  var label = GmailApp.createLabel("AwaitingResponse");
  var d = new Date();
  d.setDate(d.getDate() - DAYS_TO_SEARCH);
  var dateString = d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate();
  threads = GmailApp.search("in:Sent after:" + dateString);
  for (var i = 0; i < threads.length; i++)
  {
    var thread = threads[i];
    if (!SINGLE_MESSAGE_ONLY || thread.getMessageCount() == 1)
    {
      var lastMessage = thread.getMessages()[thread.getMessageCount()-1];
      lastMessageSender = lastMessage.getFrom().match(EMAIL_REGEX)[0];
      if (lastMessageSender == emailAddress)
      {
        thread.addLabel(label);
      }
    }
  }
}

delete_awaiting_response

返信があったメールの受信待ちラベル(AwaitingResponse)を外す関数。

delete_awaiting_response
function delete_awaiting_response() {
  var emailAddress = getEmailAddress();
  var labelAwaiting = GmailApp.getUserLabelByName("AwaitingResponse");
  if (labelAwaiting == null) {
    return;
  }
  
  var labelFinished = GmailApp.createLabel("FinishedExchange");
  
  // 返信が遅すぎるものに関してはlabelを外させる
  var d = new Date();
  d.setDate(d.getDate() - (DAYS_TO_SEARCH * 2));
  
  threads = GmailApp.search("in:sent label:" + labelAwaiting.getName());
  // Logger.log(threads);
  for (var i = 0; i < threads.length; i++) {
    var thread = threads[i];
    var threadMessageCount = thread.getMessageCount();
    var lastMessage = thread.getMessages()[threadMessageCount-1];
    var lastDate = thread.getLastMessageDate();
    lastMessageSender = lastMessage.getFrom().match(EMAIL_REGEX)[0];
    if (lastMessageSender != emailAddress || lastDate < d)
    {
        thread.removeLabel(labelAwaiting);
      if(lastDate < d) {
        thread.moveToArchive();
        thread.addLabel(labelFinished);
      }
    }
  }
}

失敗作たち

getNoLabelSenders

送信されたメールのうちラベル付けしてないメールアドレスとそのメール件数を洗い出してくれる関数。
発想としては良かったんだけど、処理が毎回のようにタイムアウトして変な動きしてしまうのでやめました。
ただ、queryをいじって件数が少なくて軽いものだったら動くので残しています。

getNoLabelSenders
function getNoLabelSenders() {
  var query = 'has:nouserlabels';
  var threadAll = 0;
  var offset = 0;
  var limit = 100;
  var mailAddress = getEmailAddress();
  var AddressList = {};
  var hasMore = true;
  while (hasMore) {
    var threads = GmailApp.search(query, offset, limit);
    if (threads.length < limit) {
      hasMore = false;
    }
    offset = offset + limit;
    for (var i = 0; i < threads.length; i++) {
      var thread = threads[i];
      var firstMessage = thread.getMessages()[0];
      var sender = firstMessage.getFrom().match(EMAIL_REGEX)[0];
      if (sender && sender != mailAddress) {
        if (AddressList[sender] != undefined) {
          AddressList[sender] += 1;
        } else {
          AddressList[sender] = 1;
        }
      }
      // Logger.log(sender);
    }
    hasMore = false;
  }
  // Logger.log(AddressList);
  if (AddressList) {
    var message = "These messages don't have label \n\n";
    for (key in AddressList) {
      message = message + key + ': ' + AddressList[key] + " messages\n";
    }
    GmailApp.sendEmail(mailAddress, 'No label massages', message);
  }
}

archivedReadMail

既読でラベルありのメールをアーカイブする関数。
軽い感じがしたんだけど1件処理するだけでも複数回クエリが動くせいか激重だったのでやめた。

archivedReadMail
function archivedReadMail() {
  var query = 'in:inbox is:read has:userlabels';
  var threadAll = 0;
  var offset = 0;
  var limit = 500;
  var mailAddress = getEmailAddress();
  var AddressList = {};
  var hasMore = true;
  while (hasMore) {
    var threads = GmailApp.search(query, offset, limit);
    Logger.log(threads.length);
    if (threads.length < limit) {
      hasMore = false;
    }
    for (var i = 0; i < threads.length; i++) {
      var thread = threads[i];
      thread.moveToArchive();
    }
    hasMore = false;
  }
}
33
33
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
33
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?