Extracting all Email Addresses from a Gmail Label
As with any other product, when working with Gmail you sometimes get to a point where you want something the product simply does not provide. When that happens, a scripting interface can be a lifesaver. Let’s see how we can put Google Apps Script to use.
List all Email Addresses from a Label’s Messages
Gmail’s most useful feature is the labeling system. The simple fact that you can tag a message with more than one label makes it far superior to message filing systems based on folders.
Let’s say you tag all personal communications with your friends and family with the label friends. If you are throwing a big party you might want to send invitation emails to all of them. If there only was a function to extract a list of all email addresses from all the emails tagged with the label friends.
When I needed this functionality recently I quickly stumbled upon a solution on labnol.org. However, that turned out to be slow and did not even work reliably. So I created my own.
Features
The script extracts email addresses from all messages in all threads tagged with a given label. It processes even large numbers of emails quickly. In addition to the sender’s email address, it lists the sender’s name and the date of the first communication.
Usage
The email extraction script is part of a Google Sheet to provide an easy user interface for data input and output. To use the script copy the sheet to your Google Drive by clicking this link.
Side note: this nifty copy feature is triggered by appending /copy
to the document’s URL.
You will be asked if you want to make the copy:
Next, your copy of the spreadsheet opens in Google Sheets. Fill in the label from which you want to extract email addresses. In this example I am using the label Spam. then click Extract email addresses in the HK Scripts menu:
You will be asked for authorization:
Now the script runs. It should not take long. Its output, the extracted email addresses, are written to a new sheet:
As you can see above, it not only lists the email addresses, but also the person’s name and the time of first communication.
The Script
You do not need this in order to use the email extraction script, but for those interested here is the source code. You can also view it directly in the sheet by navigating to Tools > Script editor.
//
// Searches one label for the first time someone sent you an email
// Returns name, e-mail address (extracted from the "From" field) and message time
//
function GetAddresses ()
{
// Get the active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Label to search
var userInputSheet = ss.getSheets()[0];
var labelName = userInputSheet.getRange("B2").getValue();
// Create / empty the target sheet
var sheetName = "Label: " + labelName;
var sheet = ss.getSheetByName (sheetName) || ss.insertSheet (sheetName, ss.getSheets().length);
sheet.clear();
// Get all messages in a nested array (threads -> messages)
var addressesOnly = [];
var messageData = [];
var startIndex = 0;
var pageSize = 100;
while (1)
{
// Search in pages of 100
var threads = GmailApp.search ("label:" + labelName, startIndex, pageSize);
if (threads.length == 0)
break;
else
startIndex += pageSize;
// Get all messages for the current batch of threads
var messages = GmailApp.getMessagesForThreads (threads);
// Loop over all messages
for (var i = 0; i < messages.length ; i++)
{
// Loop over all messages in this thread
for (var j = 0; j < messages[i].length; j++)
{
var mailFrom = messages[i][j].getFrom ();
var mailDate = messages[i][j].getDate ();
// mailFrom format may be either one of these:
// [email protected]
// any text <[email protected]>
// "any text" <[email protected]>
var name = "";
var email = "";
var matches = mailFrom.match (/\s*"?([^"]*)"?\s+<(.+)>/);
if (matches)
{
name = matches[1];
email = matches[2];
}
else
{
email = mailFrom;
}
// Check if (and where) we have this already
var index = addressesOnly.indexOf (mailFrom);
if (index > -1)
{
// We already have this address -> remove it (so that the result is ordered by data from new to old)
addressesOnly.splice(index, 1);
messageData.splice(index, 1);
}
// Add the data
addressesOnly.push (mailFrom);
messageData.push ([name, email, mailDate]);
}
}
}
// Add data to corresponding sheet
sheet.getRange (1, 1, messageData.length, 3).setValues (messageData);
}
//
// Adds a menu to easily call the script
//
function onOpen ()
{
var sheet = SpreadsheetApp.getActiveSpreadsheet ();
var menu = [
{name: "Extract email addresses",functionName: "GetAddresses"}
];
sheet.addMenu ("HK Scripts", menu);
}
91 Comments
Good script.
But doesn’t work for labels with large number of emails. Execution fails :(
Indeed, the script is good, but I only received 23 emails out of 483. Any solutions to improve scalability?
Thank you for your script!
It works well with from field, but I would need to collect addresses from reply-to field. Can this script be modified to get that done?
use var mailReplyTo = messages[i][j].getReplyTo ();
and then modify the code accordingly.
Hello Rajesh, is there a way you can write where do I need to add the VAR on the code. Im not an expert. Im trying to get this done as Im jus reading and understanding how to implement it.
Rajesh, can you please help to write reply to code , i don’t have any idea how its work this code work perfectly for inbox mail i need reply to address please help me
great little script! thanks.
Very handy. Thanks for the efforts!
This script works perfectly for me, but it only extracts senders. In my case, the email addresses are scattered within the body of all messages in a certain label. Could this script possibly be updated to scan message bodies too? That’d be a great helping hand.
Is it possible to extracts email addresses found in the message body? Thanks
Also would like to extract the body. There’s this other tool, but looks kind of sketch..
http://www.gmailextractor.com/gmail-extractor-buy.html
Tried to use this one but did not work:
http://www.labnol.org/internet/extract-gmail-addresses/28037/#free
Hi Alex and Nick,
Did you manage to find a solution on how you can extract email address from the message body ?
THanks
Hi! Did anyone id the code to extract From, TO and Body fields? Thanks!
Awesome! Worked like a charm, and very simple. Thank you so very much!
Thanks a lot for the script! It was a great help.
I needed it because a spammer had sent 30 emails in my name (see [1] for details) and I wanted to send a warning/apology to all the recipients, so I moved all the spam mails to a new label, changed ‘getFrom’ in the script to ‘getTo’, and seconds later, I had a list of all affected addresses. Thanks!
[1] http://www.digitaltrends.com/social-media/if-you-get-an-email-from-myzamana-trash-it/
Instead of the script from labnol.org this one worked fine and has more features.
Thanks for sharing it!
Amazing easy to use google sheet. Exactly where is was looking for. Thank you so much!
Hi there!
I am trying to use the tool and get
“The coordinates or dimensions of the range are invalid”
msg on the top
it creates a new tab, but nothing inside.
Any ideas what is wrong?
Thaks
Just avoid teh use of spaces ” ” or special characters in the label… it worked for me as a fix for the same error
It is because your label is empty in gmail
OMG! That was incredible – you’re a magician :) Thank you so much!
Great stuff.
Any way to simply collect number of email for each address ?
Very useful
Thanks so much, saved me a bundle of time!
Works superbly
Please can this script be updated to
1) scan through the body of the message for email addresses
2) scan through for contact numbers and possibly addresses?
Thanks
Thanks Helge,
I’ve been reading through this GApps Script and it looks great. I’m going to use it as a starting point for new functionality. I’ve created a new GitHub repo named gmail-linker (https://github.com/joshpadilla/gmail-linker) which will host the code for the new script.
I often perform research throughout the week on my phone, tablet, and various computers (mostly on DevOps, Programming and Cloud Infrastructure topics). So daily, I am emailing myself links with URLs in the body of the messages. I have a specific GMail label “Links” which these messages eventually get moved into. I’ve used services like Evernote, Delicious and others but none really matched up to just keeping all the links (URL lists) nicely categorized in a spreadsheet with a category and notes column (nice and simple).
As you can imagine, as the days and weeks pass on, eventually I fall behind, with a couple hundred emails piling up in the “Links” Gmail label which have never made it into the Google Sheet designed to list all these great links. So finally I am ready to automate the process of extracting the URLs from the messages in the “Links” label and copying them into a Google Sheet. Once they are in a Google Sheet I can add a category and sort as needed.
This should save me a good few hours of work every month and I figured your script was as good a starting point as any, since it does something similar but with email addresses instead of URLs. Thanks again!
Hello Josh, I’d be interested in something that helps me extract URLs from the body of my mails… Did you manage to create the script?
Hi Helge,
Thanks so much for this script. Extracting all Email Addresses from a GMail Label worked for me. It recovered 666 rows of email addresses. Then I was able to use 195 of those email addresses.
I prefer your method because I don’t save Google contacts to avoid my Gmail account from being hacked. This was great! Take care.
This is exactly what I’m looking for…but it failed! It seems that I was looking for too much :( The operation timed out and didn’t list anything. Is there a way to limit the script by time frame?
I fixed a problem I had with this script and then it worked wonderfully for me.
I ran this script initially on one of my larger labels, and the script timed out because it was too massive. (I posted about it here but I guess that post was deleted)
I made the next logical move and simply searched for everything in that label, and added “older:2012/01/01” (you could choose any date) and added a sub label. I then switched “older” to “newer” and gave those a second sub label. I then ran the script twice, one on each sub label, and go two sheets that I then combined.
The one downside is that you end up with a ton of duplicates, but it only took a few minutes to sort the list by address, scan it, and delete the dupes.
I don’t blame the script for timing out. I think my label had at least 14K emails in it. What I do think needs some adjusting is the duplicates it makes. It seems that the script will return the same email address multiple times if the associated name changes, or if the email address has any differentiation in capitalization. I was getting 2, 3, and 4 dupes for some addresses.
Matt I tried to run this script and keep getting an error what line did you add the date and what was causing the error?
thanks.
Thaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanks
Resume: Just write in Label
LabelName older:2016/1/1
Thank you so much for your generosity to share this! Worked well for me.
Thank you very much for your amazing script! It works perfectly.
I was wondering if was possible to also get the email subject…
Can you help me?
Regards,
Cris Bastos
Thanks a lot. This is very useful.!!
I had to use the trick described by Matt Maher as my Label was too big and the script was timing out.
The easiest way to do it is to NOT do anything in Gmail but as coco wrote : directly in the spreadsheet, replace the name of the Label by:
[LabelName] older:2016/01/01
Run the script, a new workesheet will be created
Then modify the Label to:
[LabelName] newer:2016/01/01
Run the script, a new workesheet will be created
Concatenate both lists and remove the duplicates.
Could you help. At what row need to be done changes?
Thanks.
Excellent! changed some lines to achieve my need getting from To, but it was an excellent base…
This just saved me a tonne of work. Thank you!!
this was great. worked perfectly, just what I needed. many thanks.
I get the error message Exceeded maximum execution time
Thank you, it worked ok! Made minor changes, saved me a lot of work.
I am having hard time to extract large number of emails. Any solution? Thanks
Just wanted to know how I can modify script to extract the email from inside the message body.
Hi,
How do I edit the script that I can extract all the emails from my gmail?
meaning every email that has sent me an email or me sending them an email?
Thanks!
Thank you for this. Is there an option to extract only emails from yesterday? (younger than the day before)?
thank you
This is what I get:
The coordinates or dimensions of the range are invalid.DetailsDismiss
Any solution?
I’m getting the same thing. :-( Did you find an answer?
Awesome! First Google hit and a perfect solution! Thanks so much!
Thank you for your contribution!
But the label under label (subfolder) cannot be extracted.
Will you upgrade the script recently?
Thank you!
any help with Exceeded maximum execution time??
Its weird, for me it extracts a lot of emails that are not labeled and other definitely are. Thank you anyways.
Hello Everyone,
This script is not working for me at all with Google business account. Any idea why?
This works like a charm and solved a huge problem for me. THANK YOU!!!!!!
Hello!
I’ve been using this tool all day to save up some time filling excel sheets with our helpdesk emails, but i still need to do some manual work checking each email to extract some info from them, the sheets i need to fill have the following columns:
Sender – Date – Hour – Date Answered – Hour of reply
The first 3 columns are covered by your script which is awesome, but i also need to extract the date and hour of the reply to make this fully automatic, is there a way to do this using your script just modifying it a bit? i’ve been looking through methods but couldn’t find something i could use.
Thanks in advance
Is there a way to pull a list of Recipients of emails in a label vs Responders? I’m trying to pull a list of all contacts that have BOUNCED. As such, their Reply comes from an automated source such as “[email protected]”.
I need to extract the original emails that were supposed to receive the email.
Thanks,
B
I need to extract domain names instead of email addresses. Is it possible? I guess i only need to change the regex
/\s*”?([^”]*)”?\s+/
Can you help?
I have used this several times successfully – but now I have hit a couple of issues which seem to be “outside” of the script. Firstly one of the labels I search has over 6000 emails in it – the script complains that there are too many entries and fails with no output. So I have manually moved emails to another label to reduce it to about 2000 entries. It is now saying that I have exceeded my maximum usage for the day and will not even start the script.
I have waited until the next “day” but it still will not start – seems to count 24hrs rather than looking at the date????
Because of the 6mn time-out.. it can’t extract more than a few hundreds addresses. Have a look here: https://stackoverflow.com/questions/14450819/google-app-script-timeout-5-minutes
Life savier, can we search using “Subject”
I’m after the recipient address so I tried changing the line
var mailFrom = messages[i][j].getFrom ();
to
var mailFrom = messages[i][j].getTo ();
as the rest of the script just parses on the variable, I would have thought this would be a quick hack
However this then returns the error “TypeError: Cannot find function getto in object GmailMessage”
https://developers.google.com/apps-script/reference/gmail/gmail-message shows there is a getto function so not sure why this is not working.
Any ideas?
This is probably too late but this is my code to get ReplyTo emails:
//
// Searches one label for the first time someone sent you an email
// Returns name, e-mail address (extracted from the “ReplyTo” field) and message time
//
function GetAddresses ()
{
// Get the active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Label to search
var userInputSheet = ss.getSheets()[0];
var labelName = userInputSheet.getRange(“B2”).getValue();
// Create / empty the target sheet
var sheetName = “Label: ” + labelName;
var sheet = ss.getSheetByName (sheetName) || ss.insertSheet (sheetName, ss.getSheets().length);
sheet.clear();
// Get all messages in a nested array (threads -> messages)
var addressesOnly = [];
var messageData = [];
var startIndex = 0;
var pageSize = 100;
while (1)
{
// Search in pages of 100
var threads = GmailApp.search (“label:” + labelName, startIndex, pageSize);
if (threads.length == 0)
break;
else
startIndex += pageSize;
// Get all messages for the current batch of threads
var messages = GmailApp.getMessagesForThreads (threads);
// Loop over all messages
for (var i = 0; i < messages.length ; i++)
{
// Loop over all messages in this thread
for (var j = 0; j < messages[i].length; j++)
{
var mailReplyTo = messages[i][j].getReplyTo ();
var mailDate = messages[i][j].getDate ();
// mailReplyTo format may be either one of these:
// [email protected]
// any text
// “any text”
var name = “”;
var email = “”;
var matches = mailReplyTo.match (/\s*”?([^”]*)”?\s+/);
if (matches)
{
name = matches[1];
email = matches[2];
}
else
{
email = mailReplyTo;
}
// Check if (and where) we have this already
var index = addressesOnly.indexOf (mailReplyTo);
if (index > -1)
{
// We already have this address -> remove it (so that the result is ordered by data from new to old)
addressesOnly.splice(index, 1);
messageData.splice(index, 1);
}
// Add the data
addressesOnly.push (mailReplyTo);
messageData.push ([name, email, mailDate]);
}
}
}
// Add data to corresponding sheet
sheet.getRange (1, 1, messageData.length, 3).setValues (messageData);
}
//
// Adds a menu to easily call the script
//
function onOpen ()
{
var sheet = SpreadsheetApp.getActiveSpreadsheet ();
var menu = [
{name: “Extract email addresses”,functionName: “GetAddresses”}
];
sheet.addMenu (“HK reply”, menu);
}
Hey Mitchie, I get an “Illegal Character” when I try to run your version, on this line: var labelName = userInputSheet.getRange(“B2”).getValue();
I think this website converts the quotation marks to ones that the editor does not like. You could try replacing them with new ones in the google scripts editor to see if that helps.
Thanks. Worked like a charm.
not working after granting all the permissions only shows the message running script cancel /Dismiss no results are shown
Is it possible to only show emails that my email address was the only one and nobody else was included in the TO, CC or BCC?
Thanks so much!
God Bless you!
Thanks
Man, you are the best. Like u saved me tons of time and i guess bit of money. Your script works perfect for me, I just exported 243 emails of my clients so easyyyyyyyyyyy.
Wish you all best and thanks for sharing this.
Thanks for Sharing
Thank you so much for this! I needed it for the mails that were sent to not from, so I just changed all the values and it worked like a charm! Probably saver us 10 hours of work! Thanks again!
How did you do this?
Thank you so much for this site.
Thank you so much for this site.
Just also found email-pro-tools.com. Paid for, but after faffing about for ages I gave in and bought it, it worked for me, I was mainly after email addresses in the body and Subject (it does the other too).
I just wanted to say “THANK YOU” for your script.
I enhanced the script expand its capabilities. It now 1) allows me to use standard GMAIL search parameters for more options and 2) extracts all email addresses included in from:, to:, cc:, and bcc:
I modified the script e to search for all emails that match a specific search string entered in cell B2. For example: entering label:mytoplevellabel-mysublevellabel-capstone in B2 will return all the email addresses in all the emails in the mysublevellabel folder.
Entering independence -{“thomas jefferson”} smaller:50K will return all the emails that contain the word independence, are small than 50K, and do not contain the phrase thomas jefferson.
See https://support.google.com/mail/answer/7190 for the complete syntax and examples
I hope people find this helpful.
Michael
Link to the updated script since at 5000 characters it’s too big to post here:
https://script.google.com/d/1nKUsofKtB1_WXhJ8h-RefBfr1y-Rbs_SzOEa-2bD9_TdyOo5hDqvNTlt/edit?usp=sharing
Awesome! I think you need to change the sharing settings of your Google link, though, to allow anonymous access.
Hi Helge,
Thanks for noticing. I copied the script into a text file. It can now be accessed here:
https://drive.google.com/file/d/1IxSdHIpL3cKXxGl7NM4XuXz4a_B7EKY_/view?usp=sharing
Best,
Michael
I need help,,,, I have emails with several email addresses in the body to the email. I would like to pull those email addresses into an excel file. There are several of pieces of text in the body of the email itself. I just need to extract all of the emails that have been assigned a label. (For example on email might contain 30 different email addresses)
I ran the HK Script it only returned the names only from the “From:” id. I need help….
Minor issue in that it didn’t work when the label had a space in it. Worked fine when I replaced the space with a dash.
Thanks heaps.
Still works 2022!
It works for 2022, however I’m just wondering if we could extract the subject as well, because I’m using a filter system and all the Name and Email is the same name. I’m only able to see the difference in the Subject :/
Confirming that after scouring the internet for the best tool to use, this one bags the prize in 2022! Stay awesome and thanks for helping us out here!
How can I tweak this to make it take a list of labels and then output each label in a separate sheet?
For anyone that has trouble with this, or has issues with authorizing 3rd parties access to your personal data
I literally asked Chat GPT to write a script like this, it took 2 seconds and worked just fine. Instructions are as follows. Create a new google sheet where you want your extracted emails to land. Click the tab Extensions > Apps Script. In there you will copypaste the script, and change the “your label name” to your label name. That’s it! Short script below:
I don’t know what I’m doing wrong. I keep getting “Exception: The number of rows in the range must be at least 1.” There are 138 emails in the mailbox with the label I’m using. :\
I get the exact same error…
Here a revised version that works for 100+ mails:
function extractEmailsAndWriteToSheet() {
// Get the active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Label to search
var labelSheet = ss.getSheets()[0];
var labelName = labelSheet.getRange(“B2”).getValue();
// Create or empty the target sheet
var sheetName = “Label: ” + labelName;
var sheet = ss.getSheetByName(sheetName) || ss.insertSheet(sheetName, ss.getSheets().length);
sheet.clear();
// Get all messages in a nested array (threads -> messages)
var addressesOnly = [];
var messageData = [];
var startIndex = 0;
var pageSize = 100;
while (1) {
// Search in pages of 100
var threads = GmailApp.search(“label:” + labelName, startIndex, pageSize);
if (threads.length == 0)
break;
else
startIndex += pageSize;
// Get all messages for the current batch of threads
var messages = GmailApp.getMessagesForThreads(threads);
// Loop over all messages
for (var i = 0; i < messages.length; i++) {
// Loop over all messages in this thread
for (var j = 0; j < messages[i].length; j++) {
var mailFrom = messages[i][j].getFrom();
var mailDate = messages[i][j].getDate();
// mailFrom format may be either one of these:
// [email protected]
// any text
// “any text”
var name = “”;
var email = “”;
var matches = mailFrom.match(/\s*”?([^”]*)”?\s+/);
if (matches) {
name = matches[1];
email = matches[2];
} else {
email = mailFrom;
}
// Check if (and where) we have this already
var index = addressesOnly.indexOf(mailFrom);
if (index > -1) {
// We already have this address -> remove it (so that the result is ordered by data from new to old)
addressesOnly.splice(index, 1);
messageData.splice(index, 1);
}
// Add the data
addressesOnly.push(mailFrom);
messageData.push([name, email, mailDate]);
}
}
}
// Check if there is data to be written
if (messageData.length > 0) {
// Add data to corresponding sheet
sheet.getRange(1, 1, messageData.length, 3).setValues(messageData);
Logger.log(“Emails appended to the sheet.”);
} else {
Logger.log(“No emails found to append to the sheet.”);
}
}