Skip to content

Find emails with no reply automatically in Gmail

Find emails with no reply - 1

I recently found a script that looks through your Gmail and adds a label to all of the emails that haven’t had a reply within a certain time period.  As a busy person who sends upwards of 100 emails a day keeping track of everything that needs a response is difficult and this Google script was a treat to find.

What does this script do?

I’m paraphrasing here as it does a lot more than this paragraph gives credit for but in a nut shell it runs through the emails in your inbox and checks your outgoing messages for a question mark (presuming that is attached to a question). Once it finds these emails it checks to see if they are in a date range (which you set at the start of the script) and then sees if you have had a response. If you have not had a reply to your email containing a “?” then it adds the label “No Response”. You can then quickly see all of the threads for which you are awaiting a reply.

If you decide that you don’t need a response, maybe the person has called you, you may add the label “Ignore No Response”, remove the “No Response” Label and it will no longer be picked up as requiring a reply when the script runs.

can anybody use it?

If you have a Gmail or Google Apps account then you can use this script.

how to install theGmaill script

Step 1

Visit the Google Scripts site and create a script. They are added to your Google Drive, so you can edit them there later on if you like.

Step 2

Add the script below into your new script document or get the latest version from Latest version No Response to Question Gmail Script. Right at the top you will see some variables that you can change if you choose including the labels name and time frames of emails to check. Make sure you save your script by click the disk image.

* This script goes through your Gmail Inbox and finds recent emails where you
* were the last respondent. It applies a nice label to them, so you can
* see them in Priority Inbox or do something else.
* To remove and ignore an email thread,
 just remove the unrespondedLabel and
* apply the ignoreLabel.
* This is most effective when paired with a time-based script trigger.
* For installation instructions, read this blog post:
* Credit to for the original script.
* The variation can be found at
// Edit these to your liking.
var unrespondedLabel = ‘No Response’,
   ignoreLabel = ‘Ignore No Response’,
   minDays = 3,
   maxDays = 14;
function main() {
function processUnresponded() {
 var threads =‘is:sent from:me -in:chats older_than:’ + minDays + ‘d newer_than:’ + maxDays + ‘d’),
     numUpdated = 0,
     minDaysAgo = new Date();
 minDaysAgo.setDate(minDaysAgo.getDate() – minDays);
 // Filter threads where I was the last respondent.
 for (var i = 0; i < threads.length; i++) {
   var thread = threads[i],
       messages = thread.getMessages(),
       lastMessage = messages[messages.length – 1],
       lastFrom = lastMessage.getFrom(),
       lastTo = lastMessage.getTo(),  // I don’t want to hear about it when I am sender and receiver
       lastMessageIsOld = lastMessage.getDate().getTime() < minDaysAgo.getTime(),
       lastMessageStripped = lastMessage.getBody().replace(/(<div class=”gmail_extra”>)([\s\S]*)(<\/div>)/, “$1$3″).replace(/(<div class=”gmail_quote”>)([\s\S]*)(<\/div>)/, “$1$3″).replace(/(<blockquote type=”cite”>)([\s\S]*)(<\/blockquote>)/,”$1$3″).replace(/(<a)([\s\S]*)(<\/a>)/, “$1$3”).replace(/(<img)([\s\S]*)(>)/, “$1$3″).replace(/(http)([\s\S]*)(\s|<)/,”$3”),
       containsQuestionMark =‘\\?’);
   if (isMe(lastFrom) && !isMe(lastTo) && lastMessageIsOld && !threadHasLabel(thread, ignoreLabel) && containsQuestionMark > -1) {
     Logger.log(“Subject: ” + lastMessage.getSubject());
     Logger.log(“Message: ” + lastMessageStripped);
     Logger.log(“Contains Question Mark: ” + containsQuestionMark)
 Logger.log(‘Updated ‘ + numUpdated + ‘ messages.’);
function isMe(fromAddress) {
 var addresses = getEmailAddresses();
 for (i = 0; i < addresses.length; i++) {
   var address = addresses[i],
       r = RegExp(address, ‘i’);
   if (r.test(fromAddress)) {
     return true;
 return false;
function getEmailAddresses() {
 // Cache email addresses to cut down on API calls.
 if (!this.emails) {
   Logger.log(‘No cached email addresses. Fetching.’);
   var me = Session.getActiveUser().getEmail(
       emails = GmailApp.getAliases();
   this.emails = emails;
 Logger.log(‘Found ‘ + this.emails.length + ‘ email addresses that belong to you.’);
 return this.emails;
function threadHasLabel(thread, labelName) {
 var labels = thread.getLabels();
 for (i = 0; i < labels.length; i++) {
   var label = labels[i];
   if (label.getName() == labelName) {
     return true;
 return false;
function markUnresponded(thread) {
 var label = getLabel(unrespondedLabel);
function getLabel(labelName) {
 // Cache the labels.
 this.labels = this.labels || {};
 label = this.labels[labelName];
 if (!label) {
   Logger.log(‘Could not find cached label “‘ + labelName + ‘”. Fetching.’, this.labels);
   var label = GmailApp.getUserLabelByName(labelName);
   if (label) {
     Logger.log(‘Label exists.’);
   } else {
     Logger.log(‘Label does not exist. Creating it.’);
     label = GmailApp.createLabel(labelName);
   this.labels[labelName] = label;
 return label;
function cleanUp() {
 var label = getLabel(unrespondedLabel),
     iLabel = getLabel(ignoreLabel),
     threads = label.getThreads(),
     numExpired = 0,
     twoWeeksAgo = new Date();
 twoWeeksAgo.setDate(twoWeeksAgo.getDate() – maxDays);
 if (!threads.length) {
   Logger.log(‘No threads with that label’);
 } else {
   Logger.log(‘Processing ‘ + threads.length + ‘ threads.’);
 for (i = 0; i < threads.length; i++) {
   var thread = threads[i],
       lastMessageDate = thread.getLastMessageDate();
   // Remove all labels from expired threads.
   if (lastMessageDate.getTime() < twoWeeksAgo.getTime()) {
     Logger.log(‘Thread expired’);
   } else {
     Logger.log(‘Thread not expired’);
 Logger.log(numExpired + ‘ unresponded messages expired.’);

Step 3

Setup a trigger to run the script at your preferred time.  Head over to Resources / Current Projects Triggers. There is a limit to how often you can use the API so I chose to run mine just once each morning. If you can’t wait to see if it works just hit Run and the script will kick off straight away.

Step 4

Now you have run your No Response to Questions Gmail script you will have some labels in your account, and some of your emails will most likely be tagged up with the new label.

I find changing the inbox view to “Priority Inbox” in Gmail settings to add a section of “No Response”. To do this you can go to Settings / Inbox / Inbox Sections  and add the “No Response” label to the Inbox Sections

That’s it, you’re good to go and you will be super efficient and follow up everything without fail. Well, maybe not but it’s a start.

Special thanks to Jonathan Kim for getting us started and to Peter our lead developer for making this script just the way I wanted it. If you have suggestions for how we can improve it please let us know and please do visit Jonathan’s website and check out some of his other work.

Co-Founder & Managing Director
Speak with us and you will understand why our clients trust us beyond being just an agency
We grow businesses pragmatically and with the utmost respect for budgets. We treat our clients businesses and budgets as if they were our own. Find out for yourself...