Inconsistencies between app scripts GmailApp.search and the search in gmail interface - google-apps-script

I'm trying to build a google app script to import mail received from an online form to a spreadsheet.
I am using two labels: One "to_process" is added by a gmail filter, the other one "processed" is added by this script after the email was added to the sheet.
I am searching for all emails that have "to_process" but not "processed" using the search query 'label:to_process !label:processed in:all'
I got it working partially (see the core of the script below)
I'm running the script using the script editor run function.
The problem is that using the same query in gmail interface i get more than 100 emails, but in the log of the script I get 6, and they are all processed.
Am I missing something?
function extractInfo() {
var step = 30;
var max = 500;
var currentStep = 0;
while(max--) {
var threads = GmailApp.search('label:to_process !label:processed in:all', currentStep++ * step, step);
if(threads.length == 0) break;
Logger.log("-------- found threads: " + threads.length);
var threadId = threads.length;
while(threadId--) {
var thread = threads[threadId];
thread.refresh();
if(hasLabel(thread, "processed")) {
Logger.log("was processed: " + thread.getPermalink())
continue;
}
if(!hasLabel(thread, "to_process")) {
Logger.log("isn't mark to process: " + thread.getPermalink())
continue;
}
var messages = thread.getMessages();
var messageId = messages.length;
while(messageId--) {
var message = messages[messageId];
var row = extractMessageData(message);
sheet.appendRow(row);
GmailApp.markMessageRead(message);
}
threads[threadId].addLabel(processedLabel);
}
}
}
function hasLabel(thread, name) {
var labels = thread.getLabels();
var l = labels.length;
while(l--) {
if(labels[l].getName() == name) {
return true;
}
}
return false;
}

After much trail and error I partially figured this out.
What I see in gmail ui is in fact message, and not threads. But handling labels is a per thread thing.
I simply pulled all message of all threads from a given label, and then processed theses.
If a thread has a label "processed" it doesn't mean all it's messages were processed, which is a problem.
There are still inconsistencies regarding the number of messages i see in the UI and what I get using the API though.

Related

How to filter out all emails that came from a mailing list in Gmail

Is there a way to filter out all emails that came from a mailing list within Gmail or Google Apps Script using a search query. I know you can filter out a specific email address using list:info#example.com. But I want a catch-all type of query or even a query to catch-all from a specific domain such as list:#example.com. However, this does not work. Any ideas? Any help is greatly appreciated, thank you!
This function will trash all messages from all inbox thread that are not in the list.
function emailFilter() {
var list=['a#company.com','b#company.com','c#company.com','d#company.com','e#company.com'];
var threads=GmailApp.getInboxThreads();
var token=null;
for(var i=0;i<threads.length;i++) {
if(threads[i].getMessageCount()) {
var messages=threads[i].getMessages();
for(var j=0;j<messages.length;j++) {
if(list.indexOf(messages[j].getFrom()==-1)) {
messages[j].moveToTrash();
}
}
}
}
}
I haven't tested it because I keep my inbox empty all of the time. You might want to replace 'moveToTrash()' to 'star()' for testing
What I could understand from your question and your comments, you need to filter the emails in a user's inbox that he has received, which don't only contain a certain label, but also a certain domain. If I understood well this code can help you:
function checkLabels() {
// Get the threads from the label you want
var label = GmailApp.getUserLabelByName("Label Test List");
var threadArr = label.getThreads();
// Init variable for later use
var emailDomain = '';
// Iterate over all the threads
for (var i = 0; i < threadArr.length; i++) {
// for each message in a thread, do something
threadArr[i].getMessages().forEach(function(message){
// Let's get the domains from the the users the messages were from
// example: list:#example.com -> Result: example.com
emailDomain = message.getFrom().split('<').pop().split('>')[0].split('#')[1];
// if emailDomain is equal to example.com, then do something
if(emailDomain === 'example.com'){
Logger.log(message.getFrom());
}
});
}
}
Using the Class GmailApp I got a certain label with the .getUserLabels() method and iterate through the threads thanks to the .getInboxThreads method. With a second loop and the .getMessages() you can get all the messages in a thread and for knowing the one who sent them, just use the .getFrom() method.
Docs
For more info check:
Gmail Service.
Class GmailMessage.
Class GmailThread.
So I was able to avoid replying to emails that come from a mailing list address by using the getRawContent() method and then searching that string for "Mailing-list:". So far the script is working like a charm.
function autoReply() {
var interval = 5; // if the script runs every 5 minutes; change otherwise
var date = new Date();
var day = date.getDay();
var hour = date.getHours();
var noReply = ["email1#example.com",
"email2#example.com"];
var replyMessage = "Hello!\n\nYou have reached me during non-business hours. I will respond by 9 AM next business day.\n\nIf you have any Compass.com related questions, check out Compass Academy! Learn about Compass' tools and get your questions answered at academy.compass.com.\n\nBest,\n\nShamir Wehbe";
var noReplyId = [];
if ([6,0].indexOf(day) > -1 || (hour < 9) || (hour >= 17)) {
var timeFrom = Math.floor(date.valueOf()/1000) - 60 * interval;
var threads = GmailApp.search('from:#example.com is:inbox after:' + timeFrom);
var label = GmailApp.getUserLabelByName("autoReplied");
var repliedThreads = GmailApp.search('label:autoReplied newer_than:4d');
// loop through emails from the last 4 days that have already been replied to
for (var i = 0; i < repliedThreads.length; i++) {
var repliedThreadsId = repliedThreads[i].getMessages()[0].getId();
noReplyId.push(repliedThreadsId);
}
for (var i = 0; i < threads.length; i++) {
var message = threads[i].getMessages()[0];
var messagesFrom = message.getFrom();
var email = messagesFrom.substring(messagesFrom.lastIndexOf("<") + 1, messagesFrom.lastIndexOf(">"));
var threadsId = message.getId();
var rawMessage = message.getRawContent();
var searchForList = rawMessage.search("Mailing-list:");
var searchForUnsubscribe = rawMessage.search("Unsubscribe now");
// if the message is unread, not on the no reply list, hasn't already been replied to, doesn't come from a mailing list, and not a marketing email then auto reply
if (message.isUnread() && noReply.indexOf(email) == -1 && noReplyId.indexOf(threadsId) == -1 && searchForList === -1 && searchForUnsubscribe === -1){
message.reply(replyMessage);
threads[i].addLabel(label);
}
}
}
}

Add label to all emails in inbox to who I replied?

How would I go about Google Apps scripting to apply a label to all emails in my inbox to which I had replied?
I was looking at Gmail's filters but couldn't figure out how to construct this filter.
How about this sample script? Although I looked for the sample script for this situation, unfortunately I couldn't also find. So I created this as my try, because I also wanted to use this script. The concept of this script is as follows.
When there are more than 2 messages in a thread, there might be a possibility to have replied.
For more than 2 messages in a thread
The email address of "from" for the 1st message is the sender's address.
When the email address of "to" of after 2nd messages is the same to that of "from" of 1st one, it is indicates that the thread was replied by owner.
I prepared a sample script from above concept.
Sample script :
In order to use this sample, please input label. When run myFunction(), the label is added to the mails that owner replied in Inbox.
function myFunction() {
var label = "temp"; // Please input a label you want to use.
var threadId = "";
var thread = GmailApp.getInboxThreads();
thread.forEach(function(th) {
th.getMessages().forEach(function(msg) {
var mm = msg.getThread().getMessages();
if (mm.length > 0) {
var temp = [];
mm.forEach(function(m) {
var re = /<(\w.+)>/g;
var from = m.getFrom();
var to = m.getTo();
temp.push({
from: from.match(re) ? re.exec(from)[1] : from,
to: to.match(re) ? re.exec(to)[1] : to
});
});
if (temp.length > 1 && threadId != th.getId()) {
if (temp.filter(function(e){return temp[0].from == e.to}).length > 0) {
var rr = th.addLabel(GmailApp.getUserLabelByName(label));
Logger.log("Label '%s' was added to threadId %s.", label, rr.getId())
}
threadId = th.getId();
}
}
});
});
}
Note :
The mails that it was replied to the mails that owner sent are not retrieved.
If you use this sample script, please test using for example var th = GmailApp.getInboxThreads(0, 50);, and understand the flow. And please run above script.
Reference :
GmailApp
addLabel()
If I misunderstand your question, I'm sorry.
Edit 1 :
In order to use this sample script, please enable Gmail API at Advanced Google Services and API console. The flow of it is as follows.
Enable Gmail API v1 at Advanced Google Services
On script editor
Resources -> Advanced Google Services
Turn on Gmail API v1
Enable Gmail API at API console
On script editor
Resources -> Cloud Platform project
View API console
At Getting started, click Enable APIs and get credentials like keys.
At left side, click Library.
At Search for APIs & services, input "Gmail". And click Gmail API.
Click Enable button.
If API has already been enabled, please don't turn off.
If now you are opening the script editor with the script for using Gmail API, you can enable Gmail API for the project by accessing this URL https://console.cloud.google.com/apis/api/gmail.googleapis.com/overview
Sample script :
This script adds a label to only replied email. addLabel of GmailApp adds a label to only the thread. This cannot add the label to the specific messages in the thread. So I used Gmail API. When you use this script, please modify label, userId and thread for your environment.
function myFunction() {
var label = "#####"; // Please input a label you want to use.
var userId = "me"; // If you use this script by yourself, userId is "me".
var thread = GmailApp.getInboxThreads(); // In this setting, all mails in Inbox are retrieved. If you want to use the specific mails, please modify here.
var threadId = "";
thread.forEach(function(th) {
th.getMessages().forEach(function(msg) {
var mm = msg.getThread().getMessages();
if (mm.length > 0) {
var temp = [];
mm.forEach(function(m) {
var re = /<(\w.+)>/g;
var from = m.getFrom();
var to = m.getTo();
temp.push({
from: from.match(re) ? re.exec(from)[1] : from,
to: to.match(re) ? re.exec(to)[1] : to,
threadId: th.getId(),
messageId: m.getId()
});
});
if (temp.length > 1 && threadId != th.getId()) {
if (temp.filter(function(e){return temp[0].from == e.to}).length > 0) {
var receivedFrom = temp.filter(function(e){return e.threadId == e.messageId})[0].from;
temp.filter(function(e){return e.to == receivedFrom}).forEach(function(e){
Gmail.Users.Messages.modify(
{"addLabelIds": [Gmail.Users.Labels.list(userId).labels.filter(function(e){return e.name == label})[0].id]},
userId,
e.messageId
);
Logger.log("Label '%s' was added to messageId '%s'.", label, e.messageId)
});
}
threadId = th.getId();
}
}
});
});
}
Note :
In this sample script, var thread = GmailApp.getInboxThreads(); to retrieve threads is used. This means that all threads in Inbox are retrieved. So please modify this if you want to retrieve the specific threads.
Edit 2 :
The flow of this modified script is as follows.
Received an email from user A.
You reply to the received email.
The label is added to this message.
Received a reply from user A
If you replied to the 1st message, the label is added to this message.
Script :
function myFunction() {
var label = "#####"; // Please input a label you want to use.
var userId = "me"; // If you use this script by yourself, userId is "me".
var thread = GmailApp.getInboxThreads(); // In this setting, all mails in Inbox are retrieved. If you want to use the specific mails, please modify here.
var threadId = "";
thread.forEach(function(th) {
th.getMessages().forEach(function(msg) {
var mm = msg.getThread().getMessages();
if (mm.length > 0) {
var temp = [];
mm.forEach(function(m) {
var re = /<(\w.+)>/g;
var from = m.getFrom();
var to = m.getTo();
temp.push({
from: from.match(re) ? re.exec(from)[1] : from,
to: to.match(re) ? re.exec(to)[1] : to,
threadId: th.getId(),
messageId: m.getId()
});
});
if (temp.length > 1 && threadId != th.getId()) {
if (temp.filter(function(e){return temp[0].from == e.to}).length > 0) {
var receivedFrom = temp.filter(function(e){return e.threadId == e.messageId})[0].from;
if (temp.filter(function(e){return e.to == receivedFrom}).length > 0) {
temp.forEach(function(e, i){
if (i > 0) {
Gmail.Users.Messages.modify(
{"addLabelIds": [Gmail.Users.Labels.list(userId).labels.filter(function(e){return e.name == label})[0].id]},
userId,
e.messageId
);
Logger.log("Label '%s' was added to messageId '%s'.", label, e.messageId)
}
});
}
}
threadId = th.getId();
}
}
});
});
}
Edit 3:
A sends email to me.
I respond and keep this email in my inbox.
A responds to my response.
A’s response comes as a second email because conversations view is off.
I am not going to respond again to his email from 4.
I am running the script. 1. Should be labelled but 4. Should not be labelled
I could know that you want to add the label to only 2 for above situation. In this case, my 2nd sample works fine. But you said this script is not what you want. I thought that the relation between thread ID and message IDs may be different from my consideration. So I prepared a sample script for retrieving message IDs in a thread ID. Before you use this script, please do above your scenario. After this, please run this script, and retrieve message IDs and the thread ID. Please tell me the result and the message ID you want to add the label.
This script retrieves messages in a thread ID. messageId, from, to and subject are retrieved for the information of each message.
function myFunction() {
var result = [];
var thread = GmailApp.getInboxThreads();
var threadId = "";
thread.forEach(function(th) {
th.getMessages().forEach(function(msg) {
var mm = msg.getThread().getMessages();
if (mm.length > 1) {
var ids = {threadId: msg.getThread().getId()}
var mids = [];
mm.forEach(function(m) {
mids.push({
messageId: m.getId(),
from: m.getFrom(),
to: m.getTo(),
subject: m.getSubject()
});
});
ids.message = mids;
if (threadId != th.getId()) {
result.push(ids);
}
}
threadId = th.getId();
});
});
Logger.log(JSON.stringify(result))
}
Edit 4 :
This script adds a label to a replied message. This script supposes the following situation.
You receive an email from user "A" in Inbox. This is message "1". At this time, a thread is created.
You reply to user "A" for message "1". The replied message is message "2". This message is added to the created thread.
You receive an email from user "A" as the reply. This message is message "3". This message is also added to the created thread.
For above situation, this script adds a label to only message "2".
Script :
function myFunction() {
var label = "temp"; // Please input a label you want to use.
var userId = "me"; // If you use this script by yourself, userId is "me".
var thread = GmailApp.getInboxThreads(); // In this setting, all mails in Inbox are retrieved. If you want to use the special mails, please modify here.
var threadId = "";
thread.forEach(function(th) {
th.getMessages().forEach(function(msg) {
var mm = msg.getThread().getMessages();
if (mm.length > 1) {
var temp = [];
mm.forEach(function(m) {
var re = /<(\w.+)>/g;
var from = m.getFrom();
var to = m.getTo();
temp.push({
from: from.match(re) ? re.exec(from)[1] : from,
to: to.match(re) ? re.exec(to)[1] : to,
threadId: th.getId(),
messageId: m.getId()
});
});
if (temp.length > 1 && threadId != th.getId()) {
var ar = temp.filter(function(e){return temp[0].from == e.to});
if (ar.length > 0) {
if (ar.length > 1) ar.splice(1, ar.length - 1);
ar.forEach(function(e){
Gmail.Users.Messages.modify(
{"addLabelIds": [Gmail.Users.Labels.list(userId).labels.filter(function(e){return e.name == label})[0].id]},
userId,
e.messageId
);
Logger.log("Label '%s' was added to messageId '%s'.", label, e.messageId)
});
}
threadId = th.getId();
}
}
});
});
}
Note :
When you use this script, in this script, var thread = GmailApp.getInboxThreads(); is used for retrieving messages. This means that messages in Inbox are retrieved. If you want to retrieve in other places, please modify this.
Edit 5 :
function myFunction() {
var label = "temp"; // Please input a label you want to use.
var userId = "me"; // If you use this script by yourself, userId is "me".
var thread = GmailApp.getInboxThreads(); // In this setting, all mails in Inbox are retrieved. If you want to use the special mails, please modify here.
var threadId = "";
thread.forEach(function(th) {
th.getMessages().forEach(function(msg) {
var mm = msg.getThread().getMessages();
if (mm.length > 1) {
var temp = [];
mm.forEach(function(m) {
var re = /<(\w.+)>/g;
var from = m.getFrom();
var to = m.getTo();
temp.push({
from: from.match(re) ? re.exec(from)[1] : from,
to: to.match(re) ? re.exec(to)[1] : to,
threadId: th.getId(),
messageId: m.getId()
});
});
Logger.log("temp : %s", temp) // Added
if (temp.length > 1 && threadId != th.getId()) {
var ar = temp.filter(function(e){return temp[0].from == e.to});
Logger.log("ar : %s", ar) // Added
if (ar.length > 0) {
if (ar.length > 1) ar.splice(1, ar.length - 1);
ar.forEach(function(e){
Gmail.Users.Messages.modify(
{"addLabelIds": [Gmail.Users.Labels.list(userId).labels.filter(function(e){return e.name == label})[0].id]},
userId,
e.messageId
);
Logger.log("Label '%s' was added to messageId '%s'.", label, e.messageId)
});
}
threadId = th.getId();
}
}
});
});
}

getMessageById() slows down

I am working on a script that works with e-mails and it needs to fetch the timestamp, sender, receiver and subject for an e-mail. The Google script project has several functions in separate script files so I won't be listing everything here, but essentially the main function performs a query and passes it on to a function that fetches data:
queriedMessages = Gmail.Users.Messages.list(authUsr.mail, {'q':query, 'pageToken':pageToken});
dataOutput_double(sSheet, queriedMessages.messages, queriedMessages.messages.length);
So this will send an object to the function dataOutput_double and the size of the array (if I try to get the size of the array inside the function that outputs data I get an error so that is why this is passed here). The function that outputs the data looks like this:
function dataOutput_double(sSheet, messageInfo, aLenght) {
var sheet = sSheet.getSheets()[0],
message,
dataArray = new Array(),
row = 2;
var i, dateCheck = new Date;
dateCheck.setDate(dateCheck.getDate()-1);
for (i=aLenght-1; i>=0; i--) {
message = GmailApp.getMessageById(messageInfo[i].id);
if (message.getDate().getDate() == dateCheck.getDate()) {
sheet.insertRowBefore(2);
sheet.getRange(row, 1).setValue(message.getDate());
sheet.getRange(row, 2).setValue(message.getFrom());
sheet.getRange(row, 3).setValue(message.getTo());
sheet.getRange(row, 4).setValue(message.getSubject());
}
}
return;
};
Some of this code will get removed as there are leftovers from other types of handling this.
The problem as I noticed is that some messages take a long time to get with the getMessageById() method (~ 4 seconds to be exact) and when the script is intended to work with ~1500 mails every day this makes it drag on for quite a while forcing google to stop the script as it takes too long.
Any ideas of how to go around this issue or is this just something that I have to live with?
Here is something I whipped up:
function processEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var messages = Gmail.Users.Messages.list('me', {maxResults:200, q:"newer_than:1d AND label:INBOX NOT label:PROCESSED"}).messages,
headers,
headersFields = ["Date","From","To","Subject"],
outputValue=[],thisRowValue = [],
message
if(messages.length > 0){
for(var i in messages){
message = Gmail.Users.Messages.get('me', messages[i].id);
Gmail.Users.Messages.modify( {addLabelIds:["Label_4"]},'me',messages[i].id);
headers = message.payload.headers
for(var ii in headers){
if(headersFields.indexOf(headers[ii].name) != -1){
thisRowValue.push(headers[ii].value);
}
}
outputValue.push(thisRowValue)
thisRowValue = [];
}
var range = ss.getRange(ss.getLastRow()+1, ss.getLastColumn()+1, outputValue.length, outputValue[0].length);
range.setValues(outputValue);
}
}
NOTE: This is intended to run as a trigger. This will batch the trigger call in 200 messages. You will need to add the label PROCESSED to gmail. Also on the line:
Gmail.Users.Messages.modify( {addLabelIds:["Label_4"]},'me',messages[i].id);
it shows Label_4. In my gmail account "PROCESSED" is my 4th custom label.

Excluding a label from a Google Apps Script

This is my first post :)
I am using a Google Apps Script that tracks e-mail from the last 7 days that have not had a response (basically tracks emails where my message is the last one).
This is the code here:
// This script searches Gmail for conversations where I never received a response
// and puts them in a NoResponse label
var DAYS_TO_SEARCH = 7; // look only in sent messages from last 7 days, otherwise script takes a while
var SINGLE_MESSAGE_ONLY = false; // exclude multi-message conversations where I sent the last message?
function label_messages_without_response() {
var emailAddress = Session.getEffectiveUser().getEmail();
Logger.log(emailAddress);
var EMAIL_REGEX = /[a-zA-Z0-9\._\-]+#[a-zA-Z0-9\.\-]+\.[a-z\.A-Z]+/g;
var label = GmailApp.createLabel("AwaitingResponse");
var d = new Date();
d.setDate(d.getDate() - DAYS_TO_SEARCH);
var dateString = d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate();
threads = GmailApp.search("in:Sent after:" + dateString);
for (var i = 0; i < threads.length; i++)
{
var thread = threads[i];
if (!SINGLE_MESSAGE_ONLY || thread.getMessageCount() == 1)
{
var lastMessage = thread.getMessages()[thread.getMessageCount()-1];
lastMessageSender = lastMessage.getFrom().match(EMAIL_REGEX)[0];
if (lastMessageSender == emailAddress)
{
thread.addLabel(label);
Logger.log(lastMessageSender);
}
}
}
}
The problem is at the moment, when the script runs the un-replied messages go into the "NoResponse" label which is great. However, when I delete the label from the emails that I don't need to follow up on, they come back up again when the script runs again.
My question is:
Would there would be a way to apply a label to messages that don't need to be followed up on, and then work that into the script, so that the script knows to exclude that label?
Any help would be fantastic :)
Thanks
Aidan
May be the script can apply two labels - NoResponse and Processed. You can remove the NoResponse label manually and yet the Processed label would stay.
The filter can be modified like:
threads = GmailApp.search("in:Sent -in:Processed after:" + dateString);

Google Apps Script Class GmailApp Batch Operations?

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);
}
}
}
}
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.
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);
}
}
}
}
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() };
});}));
}
This makes a grand total of 2 calls to Gmail, so it's going to be fast.
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).