1

gmail でさまざまなレート制限を実行していますが、それらを回避するために何ができるかわかりません。私が達成しようとしているのは、特定の「期限切れ」ラベルが付いたメッセージをgmailで検索することです(数分でさまざまな時間があります)。私の意図は、一定の時間が経過すると無関係になるメッセージにこれらのラベルを適用するメール ルールを作成することです。これらのメッセージを期限が切れるまで受信トレイに残しておき、その後自動的にアーカイブしたい. 一般的な手法は、http: //googleappsdeveloper.blogspot.com/2011/07/gmail-snooze-with-apps-script.htmlで見た投稿に基づいています。

これは、5 分ごとに「期限切れ」機能を実行するトリガーにあります。

つまり、5 分ごとに GmailApp.getUserLabelByName を 10 回呼び出し、getThreads() を 1 回呼び出します。次に、見つかった一致するスレッドの数に応じて、それぞれについて:

1 x getFirstMessageSubject 1 x getLastMessageDate 1 x addLabel 1 x moveToArchive 1 x removeLabel

これは、スレッドごとに 5 回の呼び出しです。

つまり、メッセージを探しているだけで、5 分間に 10 回、つまり 1 日に 2880 回電話をかけていると思います。次に、1 日の間に 1,000 件のメッセージを見つけたと仮定すると、さらに 5,000 件の通話が発生します。これを合わせると 7,880 回の呼び出しになり、これは私が考えていたクォータ制限を下回っていますが、そこが少し不明確です。https://docs.google.com/a/macros/latinschool.org/dashboardの Quota Limits によると、私のような Google Apps for Edu アカウントの場合、10,000 回の GMail の読み取りと1 日あたり 10,000 回の GMail 書き込みアクション。私の電話はすべて、この 2 つのいずれかに該当すると思います。

使用しているラベル/時間の数を減らすことができ、サブジェクト (デバッグに使用している) を取得できませんが、それ以上に、このスクリプトをより効率的にする方法がわかりません。そして、どのように割り当てに達しているかについてはまったくわかりません (上記の計算を参照してください)。

これが私のコードです:

/**
 * Expire mail after set time by archiving based on labels
 * based on http://googleappsdeveloper.blogspot.com/2011/07/gmail-snooze-with-apps-script.html
 * For more information on interacting with GMail labels, see
 * https://developers.google.com/apps-script/class_gmaillabel
 */

var expiretimes = [5,15,30,60,120,180,240,480,720];  // times in minutes to expire messages


function getLabelName(i) {
  return "expire/expire " + i;
}

function setup() {
  // Create the labels we’ll need for expiring
  GmailApp.createLabel("expire");
  for (var expt = 0; expt < expiretimes.length; expt++) {
    GmailApp.createLabel(getLabelName(expt));
  }
    GmailApp.createLabel("expired");
}


function expiremsgs(expiremin) {
  // get current date
  var nowdate = new Date();
  Logger.log(nowdate);

  // get the label for given name
  var label = GmailApp.getUserLabelByName(getLabelName(expiremin));
  var expiredlabel = GmailApp.getUserLabelByName("expired");
  var threads = label.getThreads();
  Utilities.sleep(1000);
  for (var i = 0; i < threads.length; i++) {
    Logger.log("i: " + i);
    Logger.log(threads[i].getFirstMessageSubject());
    var lastmsgdate = threads[i].getLastMessageDate();
    Logger.log(lastmsgdate);
    var minold = (nowdate-lastmsgdate)/60000; // convert from ms to minutes
    Logger.log(minold);
    if (minold > expiremin) {
      threads[i].addLabel(expiredlabel);
      threads[i].moveToArchive();
      threads[i].removeLabel(label);
      Logger.log("Archived");
    }
  Utilities.sleep(1500);
  }
};

function expire() {
  for (var expt = 0; expt < expiretimes.length; expt++) {
    expiremsgs(expt);
  }
}
4

1 に答える 1

1

私はあなたが何をしていたかをよく調べましたが、あなたの計算は正しいようです. ただし、スプレッドシートを操作する場合は、バッチ アクションを使用するのがベスト プラクティスであることはわかっています。そこで、参考資料を調べてみたところ、いくつかの重要な機能が見つかりました。

GmailApp.moveThreadsToArchive(GmailThreads[]);
label.removeFromThreads(GmailThreads[]);
label.addToThreads(GmailThreads[]);

これらの関数は、API で行っている読み取り/書き込み呼び出しの数を減らすと思います。(Google OP が間違っている場合は修正してください。)

それにもかかわらず、あなたのコードをいじっているときに、これらの関数は一度に 100 スレッドしか処理できないことがわかりました。また、GmailApp サービスへの呼び出しの速度とスケーラビリティをチェックしたところ、ほとんどの呼び出しの遅延は関連するアイテムの数とはほぼ無関係であることがわかりました。少なくとも私のテストでは、6 スレッドのバッチ アーカイブにかかる時間は 100 とほぼ同じ (1 ~ 2 秒以内) です。また、Gmail を使用する前にスクリプトでできる限りのことを行うように努めました。最後に、タイムアウトを操作する方法を変更しました。配列の値をどのように取得しているのか、一生わからなかったので、それとラベルを変更しました。「期限切れ/15分以内」などと表示されるようになりました。

もう 1 つの方法として、1 回の検索ですべてのラベルを検索し、後でラベルを確認する方法があります。ただし、各スレッドのプロパティを確認すると、Gmail への呼び出しが多すぎる可能性があります。

以上がすべて終わったので、これが私のコードの繰り返しです。

var expiretimes = [5,15,30,60,120,180,240,480,720];

function getLabelName(i) {
  return "expire/in " + expiretimes[i]  + " min";
}

function setup() {
  GmailApp.createLabel("expired");
  GmailApp.createLabel("expire");
  for (var expt = 0; expt < expiretimes.length; expt++) {
    GmailApp.createLabel(getLabelName(expt));
  }
}

function expire() {
  var allExpThreads = [];
  for (var expt = 0; expt < expiretimes.length; expt++) allExpThreads = allExpThreads.concat(expiremsgs(expt));
  if(allExpThreads.length > 100) batchExpire(allExpThreads);
  else GmailApp.moveThreadsToArchive(allExpThreads).getUserLabelByName("expired").addToThreads(allExpThreads);
}

function expiremsgs(expiremin) {
  var label = GmailApp.getUserLabelByName(getLabelName(expiremin));   
  var threads = label.getThreads();
  if(threads.length > 0){   
    var threadsToExpire = threads.filter(msgExpired, {date: new Date(), min: expiretimes[expiremin]});
    if(threadsToExpire.length > 100) batchRemoveLabel(threadsToExpire,label);
    else if(threadsToExpire.length > 0) label.removeFromThreads(threadsToExpire);
    return threadsToExpire;
  }
  return [];
}

function msgExpired(thread) {
  return this.date - thread.getLastMessageDate() / 6000 > this.min;
}

function batchRemoveLabel(threads,label) {
  var start = 0, end = 100;
  do {
    label.removeFromThreads(threads.slice(start,end));
    start = end;
    end = end > threads.length - 100 ? threads.length : end + 100;
  } while (start < threads.length);
}

function batchExpire(threads) {
  var start = 0, end = 100;
  var expLabel = GmailApp.getUserLabelByName("expired");
  do {
    GmailApp.moveThreadsToArchive(threads.slice(start,end));
    expLabel.addToThreads(threads.slice(start,end));
    start = end;
    end = end > threads.length - 100 ? threads.length : end + 100;
  } while (start < threads.length);
}
于 2012-12-21T04:53:02.497 に答える