Gmail Emails Counts by Script - google-apps-script

I am trying to count all my emails, with the label " complete - others", with Google Scripts. The thing is, the query is not counting all the emails. If I look into the label, I have, at least, 21k threads, and the script counts me just 591 emails.
Do you know how can I do to get this corrected?
Thanks !
Code sample:
`function countMessages3() {
var spreadsheet = SpreadsheetApp.getActive()
SpreadsheetApp.setActiveSheet(spreadsheet.getSheetByName('Mails'))
var threads = GmailApp.search('in:sent');
var receivedCount = 0;
for(var i=0; i<threads.length; i++)
{
receivedCount = receivedCount + threads[i].getMessageCount();
}
spreadsheet.getRange('\'Mails\'!B4').setValue(receivedCount);`

I guess, the code that you have provided is searching messages in sent folder. To search messages in a label I think you do something like:
1.Get label using getUserLabelByName() https://developers.google.com/apps-script/reference/gmail/gmail-app.html#getuserlabelbynamename
2.Get all threads for that label using getThreads() https://developers.google.com/apps-script/reference/gmail/gmail-label.html#getthreads
3.Then aggregate messages count in each thread using getMessageCount()
https://developers.google.com/apps-script/reference/gmail/gmail-thread.html#getmessagecount
Something like this :
var labelName = "complete-others";
var messageCount = 0;
var label = GmailApp.getUserLabelByName(labelName);
var threads = label.getThreads();
threads.forEach(function(thread) {
messageCount += thread.getMessageCount();
});
spreadsheet.getRange('\'Mails\'!B4').setValue(messageCount);

Here's a function that will count your emails.
function countEmailsWithLabel(query) {
var n=0;
var ts=GmailApp.search(query);
ts.forEach(function(t,i){
var ms=t.getMessages();
n+=ms.length;
});
Logger.log(n);
return n;
}
The problem of course is figuring what the search query supposed to be. I have several test emails in a label I created as 'Q0/TEST' but where I search in Gmail I see that the search is 'label:q0-test' which doesn't agree with my label. So I tried searching with a search query of 'label:q0-test' and that didn't work. So now I use the query with the label as I created it so that the search query is now 'label:Q0/TEST' and I get the correct result of 3. So I would recommend that you use the labels as you created them rather than what you see in search box of the Gmail search.
Actually I ran into this inconsistency a few weeks ago and I suspect it has probably caused some difficulties for new programmers.

Related

Using Gmail labels in Apps Script for Sheets

I am trying to evaluate emails with an existing label called "TestLabel" (applied via a simple Gmail filter on receipt), then once processed via a script called "extractDetails", remove the label. My problem is that old emails, that previously had the label but have already been processed, continue to meet the condition in subsequent executions. I have verified (at least visually) that the label is no longer attached. I have also turned off "conversation" view in Gmail, hoping/believing that the nested thread was the issue. Strangely, not all previous emails get reprocessed - but, for example, the most recent 35 or so from a list of hundreds. The only thing I've found that solves this is permanently deleting the prior emails, but I'd like to avoid doing so, and I am also curious to simply solve the problem.
My code is as follows:
function getGmailEmails(){
var label = GmailApp.getUserLabelByName('TestLabel');
var threads = label.getThreads();
var i = 0;
for(var i = threads.length - 1; i >=0; i--){
var messages = threads[i].getMessages();
for (var j = 0; j <messages.length; j++){
var message = messages[j];
extractDetails(message);`
}
threads[i].removeLabel(label);
threads[i].markRead()
threads[i].moveToArchive(); ;
}
}
Thank you to this community for your assistance. Hopefully I posed this question properly.
Edit: This short script returns a value of 57, when the verfied # of labelled messages in Gmail is 2. The other 55 emails were, at one point, also labelled the same but have been processed and the label has been removed.
function getLabel () {
var label = GmailApp.search('label:TestLabel');
Logger.log(label[0].getMessageCount());
}
Further edit:
I changed the applied label to a new one in the Gmail Filter and the script. Oddly, the legacy emails still are captured - not only without the original label, but most certainly without the new one. I'm baffled.

Google Apps Script for loop not processessing all items from getThreads()

I am attempting to create a function that reads the body of emails and extracts parts to place in a sheet.
I am currently using the below code to pull the emails.
var label = GmailApp.getUserLabelByName("VOIDS");
var threads = label.getThreads();
for (var i = 0; i <= threads.length; i++)
{
var message = threads[i].getMessages();
var body = message[0].getPlainBody();
//email processing//
threads[i].removeLable(label)
}
I've got the loop to do what I need it to do as far as processing the email and placing it where I need it, however it seems to be skipping emails. I've left out the code for the process as it's just a bunch of split() functions on the body variable to extract the appropriate information and paste it into a sheet.
The total number of emails skipped varies based on how many it has to process, but re-running the script results in the same emails being skipped each time.
All emails are having their label removed and all emails are identical save for a few value changes.
This is my first time working with GmailApp outside of sending emails. I'm sure that this is something super simple that I'm just missing, but despite all my Google searching I can't seem to find a solution.
Thank you!
Please bear in mind that getThreads might not return all the threads in your mailbox.
From the official reference docs
getThreads()
Gets the threads that are marked with this label.
This calls fail when the size of all threads is too large for the system to handle. Where the thread size is unknown, and potentially very large, please use getThreads(start, max) and specify ranges of the threads to retrieve in each call.
Resources
https://developers.google.com/apps-script/reference/gmail/gmail-label#getthreads
Related
Trying to understand getThreads in GAS
Make getThreads() app script call count over 500
A thread can contain more than one email
The line var body = message[0].getPlainBody(); implies that you are only proceeding the body of the first message of each thread.
To apply your request t all emails, you need to create a second loop, iterating through each email of each thread.
Sample:
var label = GmailApp.getUserLabelByName("VOIDS");
var threads = label.getThreads();
for (var i = 0; i <= threads.length; i++){
var messages = threads[i].getMessages();
for (var j = 0; j <= messages.length; j++){
var message = messages[j];
var body = message.getPlainBody();
//email processing//
}
threads[i].removeLable(label);
}

Google Apps Script search not returning all threads

I'm trying to search threads under one label. This is the code I have for the search:
//set "label" to label to be searched
var label = "sampleLabel"
//get all threads with the label
var emails = GmailApp.search('label: ' + label);
I tested it on a label with 11 threads (each with one message in it) and it only returned 3.
I saw this was asked before, but that seemed to be a different issue.
I appreciate any help you can give me.
There is a actually an easy way to get all the threads with a specific label! See the method documentation here.
var LABEL = "mylabel";
// Get out labels by name
var label = GmailApp.getUserLabelByName(LABEL);
// The threads currently assigned to the label
var threads = label.getThreads();

How to read all emails in gmail using google apps script

I'm trying to read ALL email in my gmail account - inbox, sent, draft, trash, emails with labels, archive, etc. I could live without the junk but I want everything else.
(all examples below use try {} catch {} to avoid errors with empty labels etc.)
I've tried
for (var i=StartLabel; i<=EndLabel; i++)
{
var label = labels[i].getName();
// get all messages, then join them into a single dimension array
var messages = GmailApp.getMessagesForThreads(GmailApp.search("label:" + label))
.reduce(function(a, b) {return a.concat(b);});
CountByLabels += messages.length;
}
That gives me everything in the labels (I think) but not the other stuff.
I tried other things, to get the inbox (to combine with the above) or all of the emails
var messages = GmailApp.getMessagesForThreads(GmailApp.getInboxThreads()).reduce(function(a, b) {return a.concat(b);});
CountInbox += messages.length;
but I only get about 549 results (GMail shows 5,478). If I add in the results from getPriorityInboxThreads I get 1,829 results.
I tried
// get all messages, then join them into a single dimension array
var messages = GmailApp.getMessagesForThreads(GmailApp.search("(is:unread OR is:read) in:anywhere")).reduce(function(a, b) {return a.concat(b);});
CountByLabels += messages.length;
I get 598 results.
I tried different search terms in the code directly above, eg:
is:unread = 528 results
is:read = 1,037 results
is:read OR is:unread = 599 results
None of them gave the right number, or even close, and incidentally if I try those search terms directly in gmail I get a totally different, and much higher, result for each - several thousand, or 'many'.
I don't think this is related to How to use Google App Scripts to retrieve Gmail emails in a customised way? as the numbers returned are not round numbers (eg 500).
I'm assuming that I can use getSpamThreads, getStarredThreads, getTrashThreads, getDraftMessages to get the relevant folders but until I understand why I'm only getting some emails from the inbox I don't trust those to give me everything.
Can anyone help?
Try this:
function allEmailsInLabels() {
var allLabels,i,j,L,L2,msgCount,theCount,threads,thisLabel;
msgCount = 0;
theCount = 0;
allLabels = GmailApp.getUserLabels();
L = allLabels.length;
for (i = 0; i < L; i++) {
Logger.log("label: " + allLabels[i].getName());
thisLabel = allLabels[i];
threads = thisLabel.getThreads();
//Logger.log('threads: ' + threads);
L2 = threads.length;
for (j = 0; j < L2; j++) {
msgCount = threads[j].getMessageCount();
//Logger.log('thread message count: ' + threads[j].getMessageCount());
// You could do something with threads[j] here like
// threads[j].moveToTrash();
theCount = theCount + msgCount;
};
};
//Logger.log('theCount: ' + theCount);
};
It first gets all the labels, then the threads, then the message count in each thread, and keeps a running count. You'll also need to get the messages in the inbox, that code doesn't include them. This is the sample code from the documentation that shows the basic concept:
// Log the subject lines of your Inbox
var threads = GmailApp.getInboxThreads();
for (var i = 0; i < threads.length; i++) {
Logger.log(threads[i].getFirstMessageSubject());
}
I had the same question. Reading a little bit more in the reference in the Google Developers Website, I discovered, reading about the function moveToInbox, a Google sample that used the Search to get all e-mails that weren't in the Inbox (https://developers.google.com/apps-script/reference/gmail/gmail-thread#movetoinbox). I decided to combine this with the getInboxThreads and with these two, my code was shorter and found every e-mail that I had received (less spam and junk).
function getEmails() {
var generalThreads, inboxThreads;
inboxThreads = GmailApp.getInboxThreads();
generalThreads = GmailApp.search('-in:inbox');
}
Every single email that was in the folder "All mail" in the Gmail was in these two variables after this.
I don't know if this can help anyone, but surely helped me.
I know this is coming a bit delayed, but having had the same problem and looking at some of the solutions offered here, I wanted to offer up my own solution, which also uses the search function:
function getEmails() {
var allEmailThreads = GmailApp.search('label:all')
}
This actually filters for every email, regardless of the mailbox, and seems to me to be the simplest solution to the question.
This is not an answer to your problem (but is probably one of the reasons your total results returned don't agree with what you are seeing in gmail inbox) but highlights one of the problems I encountered when calling getPriorityInboxThreads() is that it ignores any thread that is not flagged as "important" in the primary inbox.
//returns 10 threads and 1st message for each thread
function getThreads(){
var ret = '';
var threads = GmailApp.getPriorityInboxThreads(0, 10);
for (var i = 0 ; i < threads.length; i++) {
var id = threads[i].getId();
var message = GmailApp.getMessageById(id);
ret += "subject: " + message.getSubject() +'\n';
Logger.log("subject: " + message.getSubject());
/*Edited this out as it doesn't return anything
//check for labels on this thread
var labels = threads[i].getLabels();
for (var j = 0; j < labels.length; j++) {
Logger.log(labels[j].getName());
} */
}
return ret;
}
"Important" is classed as a system flag and getPriorityInboxThreads() ignores any thread that is not flagged important....
I would like to select all threads in "Primary" inbox irrespective of being labelled as "important".
To test, simply change any thread in inbox to important or not etc.
After I published a video on how to get Gmail messages into a Google spreadsheet, I received a feedback from some viewers that they could only get a number of messages but others fail to be processed. Therefore, I did some research and found that the process of getting emails may fail and make the system unable to handle the huge amount of emails. This is mentioned in the Gmail API here:
https://developers.google.com/apps-script/reference/gmail/gmail-label#getthreads
The documentation suggests to use getThreads(start, max) where start and max are the limiting parameters.
You may view the video and download the full code from YouTube and GitHub:
https://youtu.be/gdgCVqtcIw4

Google Script check a column if contains a certain word

I am new to Google Scripting.
I created a script where Google Spreadsheet should connect to GMail. Everything is working well.
My problem is, I need to check if an email content has the word "ORDER". If yes, it should get the word "ORDER" and the numbers after it.
For example, an email contains "ORDER 90104" in the message body, then the Google script should insert ORDER 90104 to a column in the sheet. An example email could be:
Hi, the customer is requesting for ORDER 90104. Thanks.
Is this even possible? As of now, I used getPlainBody() and I can get all the contents of the email and put it in a column. My plan was to check that column and look for the word ORDER. Though I can't find/end with a solution for it.
Here's my working code getting the email content of the 1st three emails:
function getGMail() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var threads = GmailApp.getInboxThreads(0,3);
cell = sheet.getRange("A1");
for (var i = 0; i < threads.length; i++) {
threadMessage = threads[i].getMessages();
var emailContent = threadMessage[0].getPlainBody();
cell.offset(i,0).setValue(emailContent);
}
}
Any advice or comments will be greatly appreciated.
Thanks!
Hello theladydevbugger,
As you didn't gave a lot of code my answer will be quite short: yes you can do that!
How: use a regexp: /ORDER [0-9]+/g.
How to use the regexp: bellow a sample code
var emailBody = yourMail.getPlainBody(); // supposing "yourMail" is the mail you retrieved
var isThereAnyOrder = false;
if(mailBody.search(/ORDER [0-9]+/g)>-1){
isThereAnyOrder=true;
var order=mailBody.match(/ORDER [0-9]+/g)>-1)[0];
Logger.log(order);
// do something with the order
}
else{
// there is no order do nothing
}