networkException / thundersort

Sort incoming mails based on recipient slug
https://addons.thunderbird.net/en-US/thunderbird/addon/thundersort/
BSD 2-Clause "Simplified" License
5 stars 2 forks source link

Allow sorting into subdirectories #2

Open networkException opened 2 years ago

networkException commented 2 years ago

Suggested by @LeMoonStar

troogyt commented 1 year ago

I'll update this instead of creating a new issue.

I found that if I add forward slashes to the replacement regex, e.g. $3/$2/@$1, instead of periods to separate the captured groups, it dutifully creates a folder structure like this: image

However, it seems to be roughly following this sequence:

  1. match first rule against all messages
  2. create folder structure for first rule
  3. move all messages that match the first new folder - ends up moving all messages even though they only match the top level domain (tld)
  4. after moving all messages that match the tld folder, it then stops because there are no more messages to match against as all messages that were in the INBOX matched, and were moved to, the new tld (first level) folder.

So I think the sequence needs to be something like:

  1. get first message in INBOX
  2. extract matching SMTP field (sender, reply-to, or recipient) - according to the first rule matched
  3. create new replacement folder or slug path/tree - the full path, multi-level
  4. get the full path of the last or lowest level new folder (the most nested folder) - e.g. INBOX/com/domain/sub/@user
  5. move the message from INBOX to INBOX/com/domain/sub/@user
  6. get next message in INBOX

How doable is this do you think?

troogyt commented 1 year ago

I think this API function may be useful: #getparentfolders-folder-includesubfolders

Looking through your source, I am guessing that this might be where it can/would need to be done - in background.ts: image

I hope I am on the right track and this is of use to you.

troogyt commented 1 year ago

Any thoughts on this @networkException or @LeMoonStar ?

networkException commented 1 year ago

I'm sadly quite busy currently, will look at this as soon as I have some spare time

troogyt commented 1 year ago

I'm sadly quite busy currently, will look at this as soon as I have some spare time

In case this helps, here is a Google Apps Script I wrote in an attempt to sort messages into subfolders. Unfortunately I could not achieve the end goal because of a Gmail API limitation on labeling.

I hope it is of some use to you in deriving the logic:

function applyDomainLabelAndRemoveInboxLabel() {
  var threads = GmailApp.getInboxThreads();

  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 msgId = message.getId();
      // Logger.log(msgId);
      var domlab = getDomainFromMessage(message);

      // updateLabels(msgId, domlab[0]);
      updateLabels(msgId, domlab);
    }
  }
}

function getDomainFromMessage(message) {
  var rawMessage = message.getRawContent();
  var domain = null;

  var matchFrom = rawMessage.match(/From:.*<([^>]+)>/i);
  var matchReplyTo = rawMessage.match(/Reply-To:.*<([^>]+)>/i);
  var matchReturnPath = rawMessage.match(/Return-Path: <([^>]+)>/i);
  var matchSender = rawMessage.match(/Sender:.*<([^>]+)>/i);

  if (matchFrom) {
    domain = extractDomain(matchFrom[1]);
  } else if (matchReplyTo) {
    domain = extractDomain(matchReplyTo[1]);
  } else if (matchReturnPath) {
    domain = extractDomain(matchReturnPath[1]);
  } else if (matchSender) {
    domain = extractDomain(matchSender[1]);
  }

  return domain ? [domain] : [];
}

function extractDomain(email) {
  var parts = email.split('@');
  var revdom = null;
  if (parts.length === 2) {
    revdom = reverseDomain(parts[1]);
    return revdom;
  }
  return null;
}

function reverseDomain(domain) {
  var domparts = domain.split('.');
  domparts.reverse();
  var newLabel = null;

  for (var k = 0; k < domparts.length; k++) {
    if (k === 0) {
      newLabel = domparts[k]
    } else {
      newLabel = newLabel.concat("/", domparts[k]);
    }

    var labelObject = GmailApp.getUserLabelByName(newLabel);
    // Logger.log(labelObject.getName());
    if (!labelObject) {
      labelObject = GmailApp.createLabel(newLabel)
    }
  }

  // not sure which of these to return
  return labelObject; // can't find a way to get label IDs using GApps Script
  // return newLabel; 
}

function updateLabels(msgId, addLabel) {
  var jsonLabel = JSON.stringify(addLabel)
  // BREAKS HERE - CANNOT APPLY LABEL TO MESSAGE
  var msgLabel = Gmail.Users.Messages.modify({
    'addLabelIds': [jsonLabel], // can't get this line right
    'removeLabelIds': ['INBOX']
  }, 'me', msgId);
}
troogyt commented 7 months ago

Any progress on this?

networkException commented 7 months ago

I haven't had time to work on the plugin, I will probably do some changes when 115.10.0 releases (not sure if this then already, though)