Google Apps脚本类GmailApp批处理操作? [英] Google Apps Script Class GmailApp Batch Operations?

查看:144
本文介绍了Google Apps脚本类GmailApp批处理操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经花了一个月左右的时间在搞怪GAS,并且我已经非常熟悉使用批处理操作读取电子表格(或从电子表格写入)(例如getValues(),setValues()).但是,我目前正在编写一个脚本,该脚本使用类GmailApp从Gmail中提取大量数据,我的代码运行非常缓慢(甚至超时),而且似乎无法弄清楚如何使用批处理操作对于我正在尝试做的事情.到目前为止,这是我的代码(更改了电子邮件地址和名称):

I've been fooling around with GAS for a month or so now, and I've become fairly familiar with using batch operations to read/write to/from spreadsheets (e.g. getValues(), setValues()). However, I'm currently writing a script that pulls a sizable amount of data out of Gmail using class GmailApp, my code is running very slowly (and even timing out), and I can't seem to figure out how to use batch operations for what I'm trying to do. Here's my code thus far (with the email address and name changed):

 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对象(该对象将电子邮件的正文和日期作为属性)创建对象构造函数.然后,我遍历每个线程,当给定的电子邮件与我要查找的发件人匹配时,我为该电子邮件创建电子邮件对象的实例,并将该电子邮件对象放入数组中.目标是最终获得一个来自所有所需发件人的电子邮件对象数组.但是,您可能已经注意到代码经常调用Google的API,但是我似乎无法弄清楚与Gmail进行接口的批处理操作.有任何想法吗?非常感谢.

As you can see, I'm querying my email for all threads with the given label, making an object constructor for a custom Email object (which will have the body and date of an email as properties). Then I'm looping through each thread and when a given email matches the sender I'm looking for, I create an instance of the Email object for that email and place that Email object into an array. The goal is that in the end I'll have an array of Email objects that are all from my desired sender. However as you've probably noticed the code calls Google's APIs way too often, but I can't seem to figure out batch operations for interfacing with Gmail. Any ideas? Thanks so much.

推荐答案

我认为您正在寻找GmailApp.getMessagesForThreads().

I think you are looking for 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的奇妙之处):

Of course you can also write this a little more concisely (sorry, I can't turn up an opportunity to educate about the wonders of 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次通话,因此速度很快.

This makes a grand total of 2 calls to Gmail, so it's going to be fast.

实际上,如果您按照上面的建议将"from"部分集成到搜索中,则只需要:

In fact, if you integrate the 'from' part into the search as was suggested above, all you need is:

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() };
      });}));
}

最后,由于您实际上并不关心线程的结构,因此您可以在映射之前将数组连接起来,从而导致:

Finally, since you don't actually care about the thread structure, you can just concat the arrays before the map, which leads to this:

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() }; 
      });
}

(我留在较早的示例中,以防您确实关心线程结构,而您只是给出一个最小的示例).

(I left in the earlier samples in case you do care about the thread structure and you were just giving a minimal example).

这篇关于Google Apps脚本类GmailApp批处理操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆