5

私は 1 か月ほど GAS をいじっており、バッチ操作を使用してスプレッドシートを読み書きすることにかなり慣れてきました (getValues()、setValues() など)。ただし、現在、クラス GmailApp を使用して Gmail からかなりの量のデータを引き出すスクリプトを作成しています。コードの実行が非常に遅く (タイムアウトすることさえあります)、バッチ操作の使用方法がわかりません。私がやろうとしていることのために。これまでのコードは次のとおりです(メールアドレスと名前が変更されています):

 function fetchEmails(){
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var threads = GmailApp.search('in: label:searchedLabel');
  var messages = new Array();

  function Email(message){
  this.date = new Date(message.getDate());
  this.body = message.getBody();
  }

  for(var i=0;i<threads.length;i++){
    for(var j=0;j<threads[i].getMessageCount();j++){
      if(threads[i].getMessages()[j].getFrom()=="firstName lastName <email@domain.com>"){
       var message = new Email(threads[i].getMessages()[j]);
       messages.push(message);
      }
    }
  }  
}

ご覧のとおり、指定されたラベルを持つすべてのスレッドについてメールをクエリし、カスタム Email オブジェクト (メールの本文と日付をプロパティとして持つ) のオブジェクト コンストラクターを作成しています。次に、各スレッドをループして、特定のメールが探している送信者と一致する場合、そのメールの Email オブジェクトのインスタンスを作成し、その Email オブジェクトを配列に配置します。目標は、最終的に、目的の送信者からのすべての Email オブジェクトの配列を取得することです。しかし、お気づきかもしれませんが、コードが Google の API をあまりにも頻繁に呼び出していることに気付いたかもしれませんが、Gmail とやり取りするためのバッチ操作を理解できないようです。何か案は?本当にありがとう。

4

1 に答える 1

12

GmailApp.getMessagesForThreads() を探していると思います。

function fetchEmails(){
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var threads = GmailApp.search('label:searchedLabel');
  var messages = new Array();

  function Email(message){
    this.date = new Date(message.getDate());
    this.body = message.getBody();
  }

  var gmailMessages = GmailApp.getMessagesForThreads(threads);

  for(var i=0;i<thread.length;i++){
    var messagesForThread = gmailMessages[i];
    for(var j=0;j<messagesForThread.length;j++){
      if(messagesForThread[j].getFrom()=="firstName lastName <email@domain.com>"){
       var message = new Email(messagesForThread[j]);
       messages.push(message);
      }
    }
  }  
}

もちろん、これをもう少し簡潔に書くこともできます (申し訳ありませんが、JavaScript の素晴らしさについて説明する機会はありません)。

function fetchEmails(){
  var messages = Array.prototype.concat.apply([], GmailApp.getMessagesForThreads(
      GmailApp.search('label:searchedLabel')).map(function(messagesForThread) {
    return messagesForThread.filter(function(message) {
      return message.getFrom() == "firstName lastName <email@domain.com>";
    }).map(function(message) {
      return { date: new Date(message.getDate()), body: message.getBody() };
    });}));
}

これにより、Gmail に対して合計 2 回の呼び出しが行われるため、高速になります。

実際、上記のように「from」部分を検索に統合する場合、必要なのは次のとおりです。

function fetchEmails(){
  var messages = Array.prototype.concat.apply([], GmailApp.getMessagesForThreads(
    GmailApp.search('label:searchedLabel from:email@domain.com')).map(
      function(messagesForThread) {
        return messagesForThread.map(function(message) {
          return { date: new Date(message.getDate()), body: message.getBody() };
      });}));
}

最後に、実際にはスレッド構造を気にしないので、マップの前に配列を連結するだけで、次のようになります。

function fetchEmails(){
  var messages = GmailApp.getMessagesForThreads(
        GmailApp.search('label:searchedLabel from:email@domain.com'))
      .reduce(function(a, b){ return a.concat(b); })
      .map(function(message) {
         return { date: new Date(message.getDate()), body: message.getBody() }; 
      });
}

(スレッド構造に関心があり、最小限の例を示している場合に備えて、以前のサンプルを残しました)。

于 2012-08-19T20:23:30.247 に答える