2015年7月16日木曜日

Google Apps ScriptでGmail取得するとメール内容によって異常に重かった時の対処

以前、Gmailの未読メールの件数を表示する投稿
   
をしましたが
今度はメールの内容を一部表示するよう対応しようとした際に
1メッセージに4秒もかかってしまうものがあり
なぜ????と悩んでしまったので備忘録です。
コード.gsにLogger.logを至る所に差し込んでみたところ
原因は getMessages()
   
でした
Threadに対してgetMessages()でメッセージを取得するのですが
なにかしらの条件に当てはまる内容?であると
異常に重くなるようです。

でなんでやーと色々やってみた結果
getMessagesForThreadsを使えば早くなりました!

以前の遅いコードは以下です
//未読メール取得関数
function getMail(){
  var datReturn =new Object();
 
  //スレッド取得
  var thds = GmailApp.search("is:unread", 0, 500);

  var i = 1;
  var cFrom = '';
  var cSub = '';
  var cMsgid='';
  var cThdurl='';
  for(var n in thds){
    var thd = thds[n];
    //*** こいつが遅い! ***
    var msgs = thd.getMessages(); 
    //******************
    cThdurl = thd.getPermalink();
    for(m in msgs){
      var msg = msgs[m];
      cFrom =msg.getFrom();
      var searchchar = Session.getActiveUser().getEmail();
      var searchidx = cFrom.search(searchchar);
      if (searchidx <= 0 && msg.isUnread() === true){
      cTo = msg.getTo();
      cSub = msg.getSubject();
      cMsgid = msg.getId();
      datReturn['from' + i] =cFrom;
      datReturn['subject' + i] = cSub;
      datReturn['msgid' + i] = cMsgid;
      datReturn['url' + i] = cThdurl;
      i++;
      }
    }
  }
  datReturn['count'] = i;
  return(datReturn)
}
  

以下は速度改善したコードです。
//コード.gsのトップに以下の1行だけ記載しておく
var cachedata = CacheService.getScriptCache();
  
//未読メール取得関数
function getMail(){
  var datReturn =new Object();
  var key = "MailAdress"
  
  //スレッド取得
  var thds = GmailApp.search("is:unread", 0, 500); //
  var k = 1;
  var cFrom = '';

//  メールアドレスはキャッシュしておく
  var searchchar = suna_cache.get(key);
  if (searchchar === null){
    searchchar = Session.getActiveUser().getEmail();
    suna_cache.put(key,searchchar);
  }
  //一括取得しgetMessages()を使わない!
  var msgs = GmailApp.getMessagesForThreads(thds);
  for (var i = 0 ; i < msgs.length; i++) {
   for (var j = 0; j < msgs[i].length; j++) {
     cFrom = msgs[i][j].getFrom();
     var searchidx = cFrom.search(searchchar);
     if (searchidx <= 0 && msgs[i][j].isUnread() === true){
      datReturn['from' + k] =cFrom; 
      datReturn['subject' + k] = msgs[i][j].getSubject();
      datReturn['msgid' + k] = msgs[i][j].getId();
      datReturn['url' + k] = msgs[i][j].getThread().getPermalink();
      k++;
     }
   }
  }
  datReturn['count'] = k;
  return(datReturn)
}
//キャッシュ
var suna_cache = {
  put: function(key,data){
    cachedata.put(key,data,60*60*48); //
  },
  get: function (key){
     return cachedata.get(key);
  }
};
  

いずれも同じ結果を取得します。
遅いコード側は遅くなるメールがあると1件4秒でしたが
速い方は遅くなるメールがいても0.5秒程度で完了してます
重くなる原因のメール内容はGoogleからくるお知らせなんですが
なんなんでしょうねぇ
まぁgetMessagesForThreads
   
で一括取得するのなんて
当たり前なのかもしれませんが;

ついでにメール表示するテストページを作ってみました
もちろんGoogleにログインしてないと見れませんし
ボタンが表示されておりますので押して承認して頂いたあと
リロードする必要があります
悪さなどしておりませんが
承認してもいいよ~って方だけ見てください
テストページへ
   

0 件のコメント: