Skip to content

Instantly share code, notes, and snippets.

@moayadhani
Last active March 7, 2024 21:05
Show Gist options
  • Star 38 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save moayadhani/fcb75d0bf5be50b83e36e05746e2722d to your computer and use it in GitHub Desktop.
Save moayadhani/fcb75d0bf5be50b83e36e05746e2722d to your computer and use it in GitHub Desktop.
Get Gmail Emails By Assigned Label
var ui = SpreadsheetApp.getUi();
function onOpen(e){
ui.createMenu("Gmail Manager").addItem("Get Emails by Label", "getGmailEmails").addToUi();
}
function getGmailEmails(){
var input = ui.prompt('Label Name', 'Enter the label name that is assigned to your emails:', Browser.Buttons.OK_CANCEL);
if (input.getSelectedButton() == ui.Button.CANCEL){
return;
}
var label = GmailApp.getUserLabelByName(input.getResponseText());
var threads = label.getThreads();
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];
if (message.isUnread()){
extractDetails(message);
GmailApp.markMessageRead(message);
}
}
threads[i].removeLabel(label);
}
}
function extractDetails(message){
var dateTime = message.getDate();
var subjectText = message.getSubject();
var senderDetails = message.getFrom();
var bodyContents = message.getPlainBody();
var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
activeSheet.appendRow([dateTime, senderDetails, subjectText, bodyContents]);
}
@moayadhani
Copy link
Author

moayadhani commented Dec 19, 2021

@BenitaGeorge ,

The template that you have looks similar to the email template what I explain in my part-2 video. I explain how to do that in detail.

Since video 2 provides an explanation on how to get the data out of emails arriving with content that look similar to yours in the following format, then I guess it can be applied to you:

Name:
Phone:
Email:
Date:
Number of Attendees:
Pickup or Delivery :
Time :
Delivery Address:

That being said, there is a possibility that it fails because your emails may come with different internal HTML formatting applied to the emails by your email sender. To help you out better with this, I hope that you are able to email me sample messages by downloading them as files and attaching them in your email simply as shown in the following screen recording (my email is moa29000@gmail.com):
https://i.imgur.com/NfwPmi3.gif

Regarding the extraction of 1000 emails, the same script could be automated as well as applied to previous emails by applying the label and making those emails unread.

Thanks

@BenitaGeorge
Copy link

@moayadhani I have sent you an email containing some sample messages as you asked.

@moayadhani
Copy link
Author

Hi @BenitaGeorge,
Thanks for sending. I have checked your email and replied to you. Will keep in touch there

@edoardodg
Copy link

Hi Moayad,

first of all thanks a lot for your youtube tutorial and for sharing this code, super useful.

I was looking for a way to pull into excel the date, subject, sender and id for all my emails in Gmail. Do you think it's possible? Alternatively, do you know how I could do it in a range of messages? I've tried with the code below but it's not retrieving anything.

Thanks in advance for any help!

Edoardo

var ui = SpreadsheetApp.getUi();
function onOpen(e){
ui.createMenu("Gmail Manager 1").addItem("Get Emails", "getGmailEmails").addToUi();
}

function getGmailEmails() {
// const threads = GmailApp.getStarredThreads();
const threads = GmailApp.getInboxThreads(0, 10)[0];

for (var i = 0; i < threads.length; i++) {
message = threads[i].getGmailEmails();
extractDetails(message);
}
}

function extractDetails(message){
var dateTime = message.getDate();
var subjectText = message.getSubject();
var senderDetails = message.getFrom();
var identificativo = message.getId();

var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
activeSheet.appendRow([dateTime, senderDetails, subjectText, identificativo]);
}

@moayadhani
Copy link
Author

Hi @edoardodg,
I am glad that my programs were useful to you. Before getting into your codes, there is no intuitive way of pulling out all Gmail emails. This is because Google has set some quota on the runtime of Google Script. The number of threads that can be read in one call is also limited to 500 threads. As such, email pulling needs to be planned and scheduled quite well using Apps script triggers and by tracking the last thread that was ever executed, not forgetting monitoring the runtime of the script. It is possible this way.

That being said, I am sharing here with you a program that gets you Gmail emails iteratively:

function getGmailEmails() {
  var strtIdx = 0;
  var threadsToRead = 5;
  let threads;
  do {
    threads = GmailApp.getInboxThreads(strtIdx, threadsToRead);
    for (var i = 0; i < threads.length; i++) {
      let messages = threads[i].getMessages();
      for (let j = 0; j < messages.length; j++) {
        var message = messages[j];
        extractDetails(message);
      }
    }
    strtIdx += threadsToRead;
  } while (threads.length == threadsToRead);
}

function extractDetails(message) {
  var dateTime = message.getDate();
  var subjectText = message.getSubject();
  var senderDetails = message.getFrom();
  var identificativo = message.getId();

  var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  activeSheet.appendRow([dateTime, senderDetails, subjectText, identificativo]);
}

Feel free to send me an email if you need help. My email is moa29000@gmail.com

@edoardodg
Copy link

Thanks a lot Moayad!

it worked and then got suspended as it ran for too long, I'll iterate and get it done :) Finally I'll be able to clean up my mailbox!

thanks again!!

Edoardo

@moayadhani
Copy link
Author

@edoardodg,

Great! Thanks for confirming it worked well for you...
Happy "mailboxing"

@Pradeep-manoharan
Copy link

@moayadhani @moayadhani @jigarsolanki0212 can you please help me...? even I log off all my Google accounts. but it does not work
Screenshot (174)

@moayadhani
Copy link
Author

@Pradeep-manoharan ,
Your code is wrong. Please change line 15 to:
var messages = threads[i].getMessages();

You forgot the brackets.

Feel free to reach me over email at moa29000@gmail.com

@moayadhani
Copy link
Author

Hi @ShilpaST,
I am afraid I did not understand well what you want to achieve. Would you please explain more with screenshots or a screen recording?
You may also share a sample spreadsheet with me over email at moa29000@gmail.com or moayad@codewondo.com

@AryanKhan91
Copy link

@moayadhani - Firstly, this is awesome and works absolutely fine.
Secondly, I want a help regarding the step where the labels are removed once marked as read. This is done to avoid duplicate fetches but I intend to retain the labels in the Gmail.

However, I still want to avoid the duplicate fetched but do not want the emails to be removed with the label.

Is that possible? Can you reply with a fix here or a video where that is demonstrated?

I will really appreciate that help.

@moayadhani
Copy link
Author

moayadhani commented May 21, 2022

@AryanKhan91

I am glad it helped.

Well, there should not be any problem with label removal. You seem to want the label for your reference. To solve this, you can create 2 filters, each assigns a different label. One is to be used by this script and another is for your reference. The one that is used by the script will actually be removed by the program and the other label will NOT be touched.

Feel free to drop me an email in case you would need help. My email is moa29000@gmail.com | moayad@codewondo.com

@AryanKhan91
Copy link

Thanks a ton @moayadhani, fortunately I added 2 labels with the same mindset that if one is removed by script, the other one is still there.

Happy to know that was the solution to it!

Also @moayadhani, how can we ensure that whenever there is another email added in that label then it is automatically fetched by a script?

Will I have to set a trigger on a daily basis to guess if there is any, it will be added else no change will appear in the sheet?

@ShilpaST
Copy link

ShilpaST commented May 23, 2022

@moayadhani
How can we got to know who is the last user & last activity in shared gmail using appscript.

@onlyforgithub
Copy link

Hi @adamincolorado You can run scripts automatically by creating time-driven triggers as an example. I have made an animated image as a simple demonstration for you guys on how to do that, and here is the link: https://i.imgur.com/UvHgsak.gif

The script that I am sharing in this Git takes care of what you want by not considering the previously processed emails and that is done by making processed emails as READ. You can view my YouTube video to see a demonstration about this script.

Please get back to me to me at moa29000@gmail.com in case you need further help.

Hi @moayadhani,

This has been very helpful and the manually triggered script works beautifully, although I changed it to look for a predetermined label like you did in the YouTube video. I would like it to run at least several times a day, and appreciated the video demonstration you provided on how to create a trigger for it to run automatically. Unfortunately I get the same error message every time:

Exception: Cannot call SpreadsheetApp.getUi() from this context.
at unknown function

Do you have a suggestion for what I could adjust to make it work?

Thank you.


@sonali1234-stack
Copy link

sonali1234-stack commented Aug 24, 2022

@moayadhani Hey, I'm getting error with this script. And received this kind of body. Can you please look into this?
image

this is inbox message.
image

@conanthecoder12
Copy link

@moayadhani Hey, I'm getting error with this script. And received this kind of body. Can you please look into this? image

this is inbox message. image

Looks like you have getID instead of getPlainBody in your variables?

@moayadhani
Copy link
Author

Hi @ShilpaST,

@moayadhani How can we got to know who is the last user & last activity in shared gmail using appscript.

I am not sure what you exactly mean but I guess that such tracking is hard to do. Are you tracking the sent emails or what?

@moayadhani
Copy link
Author

Hi @adamincolorado You can run scripts automatically by creating time-driven triggers as an example. I have made an animated image as a simple demonstration for you guys on how to do that, and here is the link: https://i.imgur.com/UvHgsak.gif
The script that I am sharing in this Git takes care of what you want by not considering the previously processed emails and that is done by making processed emails as READ. You can view my YouTube video to see a demonstration about this script.
Please get back to me to me at moa29000@gmail.com in case you need further help.

Hi @moayadhani,

This has been very helpful and the manually triggered script works beautifully, although I changed it to look for a predetermined label like you did in the YouTube video. I would like it to run at least several times a day, and appreciated the video demonstration you provided on how to create a trigger for it to run automatically. Unfortunately I get the same error message every time:

Exception: Cannot call SpreadsheetApp.getUi() from this context. at unknown function

Do you have a suggestion for what I could adjust to make it work?

Thank you.

@onlyforgithub,
The error could be because you are logged into multiple Google accounts or that you are opening the Script editor not from the spreadsheet itself (some people open it from the script.google.com directly.

Feel free to email me at moa29000@gmail.com for further help.

@moayadhani
Copy link
Author

conanthecoder12

Sometimes this happens for some encoded emails. I am not really sure why it happens but what I do is try to get the html body using getBody()...

@sonali1234-stack
Copy link

you

Yes, Not getting replies.

@kousiknaga
Copy link

kousiknaga commented Oct 15, 2022

@moayadhani Please assist with your script, how labeled emails will come in spreadsheet automatically instead of manually clicking on Gmail Manager then Get Emails.2ndly can I receive unique emails with unique subject line which arrived first time in this lebeled.

Thanks in advance.

@moayadhani
Copy link
Author

@kousiknaga

Hi,
Regarding the automatic extraction of Gmail emails, I have published a blog with simple steps that show how to do that. Here is the link:
https://codewondo.com/create_apps_script_triggers/

To extract the first email that arrives in the thread, you can replace line 21 to 27 with the following code:

var message = messages[0];
if (message.isUnread()){
  extractDetails(message);
  GmailApp.markMessageRead(message);
}

If you face a problem, please send me an email. My email is moa29000@gmail.com

@KietLeo67
Copy link

hi @moayadhani.
i want to get email header in a label. I used the above code but don't know how to replace the code to get the subject in the label. Can you help me. Thank you
function getGmailEmails() {
var strtIdx = 0;
var threadsToRead = 5;
let threads;
do {
threads = GmailApp.getInboxThreads(strtIdx, threadsToRead);
for (var i = 0; i < threads.length; i++) {
let messages = threads[i].getMessages();
for (let j = 0; j < messages.length; j++) {
var message = messages[j];
extractDetails(message);
}
}
strtIdx += threadsToRead;
} while (threads.length == threadsToRead);
}

function extractDetails(message) {
var dateTime = message.getDate();
var subjectText = message.getSubject();
var senderDetails = message.getFrom();
var identificativo = message.getId();

var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
activeSheet.appendRow([dateTime, senderDetails, subjectText, identificativo]);
}

@bkeneu
Copy link

bkeneu commented Oct 27, 2022

Hi, I have a strange issue, the script runs once and imports the mails to Google sheets but if I delete the data in the sheet and run the script again it does not import any emails. I have tried to generate new emails and run it again but still no luck.

Any ideas I could do to fix this?

@moayadhani
Copy link
Author

Hi @bkeneu,
Well, this seems to be an issue related to your maximum usage of Gmail emails read/write operations. Google has set daily quotas per users. You can check this from the link below:
https://developers.google.com/apps-script/guides/services/quotas

If you think this is not the problem, please send me an email over moa29000@gmail.com OR moayad@codewondo.com and I will help you out.

Best regards

@bkeneu
Copy link

bkeneu commented Oct 27, 2022

I found it , there is a if statement to only extract messages if they are unread - sorry

@moayadhani
Copy link
Author

Yes, I thought that by "generate new emails", you meant new encoming emails that are unread yet.
Anyways, I'm glad that you found a fix

@mtram8
Copy link

mtram8 commented Dec 10, 2023

Hi @moayadhani! Love your tutorial and appreciate your help in advance!

When I tried running the above (pasted below too) source code, I saw a box appear in the UI requesting for Label Name. When I provided the Label Name again, I see error messages that say Error resuming script execution and Script getGmailEmails experienced an error.

Can you please lmk what the source code should be so I can retrieve only email messages labeled General User Support?

Source Code

var ui = SpreadsheetApp.getUi();
function onOpen(e){

ui.createMenu("Gmail Manager").addItem("Get Emails by Label", "getGmailEmails").addToUi();

}

function getGmailEmails(){
var input = ui.prompt('Label Name', 'General User Support', Browser.Buttons.OK_CANCEL);

if (input.getSelectedButton() == ui.Button.CANCEL){
return;
}

var label = GmailApp.getUserLabelByName(input.getResponseText());
var threads = label.getThreads();

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];
  if (message.isUnread()){
    extractDetails(message);
    GmailApp.markMessageRead(message);
  }
}
threads[i].removeLabel(label);

}

}

function extractDetails(message){
var dateTime = message.getDate();
var subjectText = message.getSubject();
var senderDetails = message.getFrom();
var bodyContents = message.getPlainBody();

var activeSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
activeSheet.appendRow([dateTime, senderDetails, subjectText, bodyContents]);
}

@moayadhani
Copy link
Author

@mtram8
Hi! I am pleased you found this code helpful to you.

Regarding the issue you are facing, I guess the previous execution was not successful, and you ran the secod label extraction before the previous is done. That being said, it could be caused by other factors. Can you share with me a short screen recording of the problem and send over email at moa29000@gmail.com and cc moayad@codewondo.com

I will help you out with your issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment