Unfortunately, I tend to get a lot of duplicate e-mails: same sender, same subject, same content. Gmail recognizes the duplication, and minimizes these e-mails when I view them, so I’d like to tap into that recognition.

Specifically, I would like a filter that archives an e-mail, if it is a duplicate of an e-mail already archived, and to mark the e-mail as read, if it is a duplicate of an e-mail already read.

Is there any way to do this?

  • I'm afraid that Gmail filters aren't up to the task. There's nothing that lets you target duplicate messages, or even messages that are part of a conversation. There might be a way to do it with Google Scripts, but not with Gmail by itself. – ale Jul 26 '15 at 19:09
  • @AlE. That would be a fine answer if anyone knows how to do it. Or would that be off-topic here? Not familiar with Google Scripts, and new here anyway. Coding is not a problem for me though. – KRyan Jul 26 '15 at 21:27

Here is a script that may help with the issue. It takes the sender and subject of the 1st message in every inbox thread, and runs a search for them. There isn't a search parameter for the body of the message, so instead every candidate message is compared to the inbox message. If a match is found, its state is determined and the inbox message is treated accordingly.

The script editor has an option (under Resources) to install a time-based trigger that executes the script periodically: every day, every hour, every minute, or at some other intervals. (There is no "new email" event-based trigger.)

Note: I haven't tested the script, since I don't have such duplicates.

Reference: GmailApp documentation and pages linked from there.

function checkDupes() {
  var threads = GmailApp.getInboxThreads();
  for (var i = 0; i < threads.length; i++) {
    var message = threads[i].getMessages()[0];
    var sender = message.getFrom();
    var subject = message.getSubject();
    var body = message.getPlainBody();
    var candidates = GmailApp.search('from:'+sender+' subject:'+subject);
    var found = false; 
    for (var j = 0; j < candidates.length; j++) {
      var messages = candidates[i].getMessages();
      for (var k = 0; k < messages.length; k++) {
        if (messages[k].getPlainBody() === body) {
          found = true;
          if (!messages[k].isUnread()) {
          if (!messages[k].isInInbox()) {
      if (found) {
  • Thanks! Unfortunately, 1/hour isn't good enough for me, but I'll give it a shot so we can confirm it works anyway. – KRyan Jul 27 '15 at 11:55
  • It looks like now you can run a script as often as every minute. – user79865 Aug 12 '15 at 23:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.