我在使用gmail时遇到了各种各样的速率限制,我不确定我能做些什么来绕过它们。我想要完成的是搜索gmail中任何带有“过期”标签的邮件(以分钟为单位的不同时间)。我的目的是让邮件规则在一段时间后变得不相关的邮件上应用这些标签。我希望这些邮件保留在我的收件箱中,直到过期,然后自动存档。我基于我在http://googleappsdeveloper.blogspot.com/2011/07/gmail-snooze-with-apps-script.html上看到的一篇文章提出了这个通用的技术
我有一个触发器,它每五分钟运行一次"expire“函数。
因此,每隔五分钟,它会调用10次GmailApp.getUserLabelByName,并调用一次getThreads()。然后根据它找到的匹配线程的数量,对每个线程:
1 x getFirstMessageSubject 1 x getLastMessageDate 1 x addLabel 1 x moveToArchive 1 x removeLabel
即每个线程5次调用。
因此,我会认为,我正在进行10个电话/5分钟,或2880个电话,仅仅是为了寻找消息。然后,假设我在一天中发现了1000条消息,即额外的5000个电话。加在一起会有7880个电话,这在我认为的配额限制之下,但我有点不清楚。根据配额限制下的https://docs.google.com/a/macros/latinschool.org/dashboard,对于像我这样的Google Apps for Edu帐户,我每天应该能够进行10,000次GMail读取和10,000次GMail写入操作。我想我所有的电话都属于这两个中的一个。
我可以减少我正在使用的标签/次数,而不是获得主题(我正在使用它进行调试),但除此之外,我不确定如何才能使这个脚本更有效。我完全不清楚我是如何达到目标的(参见上面的数学)。
下面是我的代码:
/**
* 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);
}
}
发布于 2012-12-21 12:53:02
我花了很长时间看你在做什么,它看起来你的数学是正确的。但是,我知道使用批处理操作是处理电子表格时的最佳实践。所以,我查阅了一些参考资料,发现了一些关键函数:
GmailApp.moveThreadsToArchive(GmailThreads[]);
label.removeFromThreads(GmailThreads[]);
label.addToThreads(GmailThreads[]);
我假设,这些函数将减少使用API进行的读/写调用的数量。(如果我说错了,请纠正我。)
尽管如此,当我使用你的代码时,我发现这些函数一次只能处理100个线程,所以如果有更多的线程,那么必须对操作进行批处理。我还检查了对GmailApp服务的调用的速度和可伸缩性,发现大多数调用的延迟与所涉及的项数是松散无关的。批量归档6个线程所需的时间(在一两秒内)与100个线程的时间相同,至少在我的测试中是这样。在发布Gmail之前,我还努力在脚本中做了尽可能多的工作。最后,我修改了您与超时交互的方式。我一直想不通你是如何得到数组中的值的,所以我修改了数组和标签。他们现在将读取"expires/in 15 etc“等。该脚本大约需要30秒来处理300条左右的消息,这些消息实际上有标签。
另一种方法可能是运行一次搜索,一次查找所有标签,然后检查标签。然而,当你检查每个线程的属性时,这可能仍然会调用太多的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);
}
https://stackoverflow.com/questions/13935468
复制相似问题