How to combine filter rules in message filters in Thunderbird to create more advanced filter criteria?

In Thunderbird one can choose either Match all of the following or Match any of the following for a given set of filter rules. There's no way to mix OR and AND logical operators freely to create more complex criteria like ((A AND B) OR (C AND D)) AND E.
Is there any plug-in allowing to achieve the above?


Solution 1:

I needed to filter a bunch of different subjects coming from one person, so my solution was this:

  1. Added a filter to match any of the following, and added any of the subjects I wanted.
  2. The action I set it to perform is to set the priority to lowest.
  3. Then I added a new filter to match all of the following: priority is lowest, and from contains (the email address I wanted to filter from).
  4. The action I set was to move to a certain folder.

One thing you need to make sure of is that the first filer is higher up on the list so it gets performed first. I know it's not the most elegant solution but it can be expanded upon to fit your needs.

Solution 2:

I can't seem to find a good extension to do this, but the quick search toolbar would function just as well if you're just searching over a single folder.

For instance - if I wanted to create criteria for all messages from Tommy and Billy but not those with Fwd in the subject, as well as messages from Sandra including forwards I would set up a search (using the quick search toolbar with it set to search by expression):

((from:Tommy OR from:Billy) AND -subject:Fwd) OR (from:Sandra)

However, with multiple folders, this is not possible.

J

Solution 3:

With FiltaQuilla, and some javascript actions/rules, it is doable. However, here it is an example with some modifications to the FiltaQuilla source so as to simplify the process.

The example here will do three stages of filtering: marking - that only classifies the emails. Then, modifying - that does some logical computation and modifies the email subject or headers. And, action - doing the actual action. Each of the stages will involve editing filters in Thunderbird filter dialog normally, but with added options by FiltaQuilla. The stage 1 and 2 save their results in a newly added email header field, and stage 2 and 3 use the results in the field to do some logic before normal actions.

Steps:

Install FiltaQuilla

It looks many functions are only working with Thunderbird 3.1. Thus upgrade to TB 3.1 first. Then install FiltaQuilla.

In FiltaQuilla preference tab, enable "Suffix to Subject", and "Javascript Action".

Modify FiltaQuilla Source

Edit "[email protected]/content/filtaquilla.js" in the extension directory so that it looks like this:

// Suffix to subject
self.subjectSuffix =
{
  ...
  apply: function(aMsgHdrs, aActionValue, aListener, aType, aMsgWindow)
  {
    for (var i = 0; i < aMsgHdrs.length; i++)
    {
      var msgHdr = aMsgHdrs.queryElementAt(i, Ci.nsIMsgDBHdr);
      ////var appSubject = _mimeAppend(aActionValue, msgHdr.subject, false);
      ////msgHdr.subject = appSubject;
      var headerName = "mykeywords";
      var headerValue = msgHdr.getStringProperty(headerName);
      msgHdr.setStringProperty(headerName, headerValue + " " + aActionValue);
      headerValue = msgHdr.getStringProperty(headerName);
        // Cu.reportError("chg : " + headerName + " : " + headerValue);
    }
  },

The code changes the original action of "Suffix to Subject" into that it will add the suffixed strings into a new header named "mykeywords". This new header field will be used to keep the result from the first two stages of filtering in the forms of string words.

This source code change is to reuse the "Suffix" action since usually suffixing to a subject is not very useful. Thus reusing its internal guts would not affect the usability of FiltaQuilla a lot. If not doing this, an official feature request should be post to FiltaQuilla creator to add the feature you want, or you'll need to write a bit more Javascript code in the filter condition as Javasctipt condition.

Create Filter Rules for Marking

An example is to create a series of rules each will only have one action: "Suffix to Subject", but the suffixed words will each identify what the result it has got. For example, classify the emails according to where they are from by suffixing words "company-A", "company-B", ..., etc. Remember that these words "company-A", "company-B", etc., will be concatenated into the "mykeywords" header field.

Place these rules to the beginning of filter rules list.

Create Filter Rules for Logical Modification

In filter rules header-field drop box, use "Customize" to add "mykeywords" to the list. Then choose "mykeywords contains company-" for condition in filter dialog.

Choose "Javascript Action" in action section. Add some code like this:

for (let index = 0; index < msgHdrs.length; index++)
{
  let hdr = msgHdrs.queryElementAt(index, Ci.nsIMsgDBHdr);
  let s = hdr.getStringProperty("mykeywords");
  let v = s.split("company-"); /* result words are in v[] now */
  let r = ""; /* logic conversion result */
  let cnt = 0;
  if ( v != undefined && v.length != undefined && v.length > 0) {
    let lastVN = 0;
    for(var i=v.length -1; i>=0; i--) {
      let ss = v[i];
      if ( ss.length > 1 ) {
          ss = ss.substring(0);
          /* convert company A into VIP, B into NORMAL, C into IGNORE. 
           * Assume the marking section starts with A,B, then C thus 
           * C gets parsed first, then A and B. 
           */
          if (ss.search(/A/) == 0)  { ss = "V"; lastVN = 1; } /*VIP*/
          else if (ss.search(/B/) == 0 ) { ss = "N"; lastVN = 1; } /*NORMAL*/
          else if (ss.search(/C/) == 0   ) { ss = "IGNORE"; }
          /* prepend subject line */
          if ( cnt == 0 ) { r = ss + "] ";
          } else { if (lastVN == 0) r = ss + " " + r; else  r = ss + r;  }
          cnt ++;
      }
    } /* for(var i=v.length -1; */
    if ( cnt > 0 ) { r = "[" + r; }
  } /* if ( v != undefined && */
  hdr.subject = r + hdr.subject;
} /* for (let index = 0; */

At this point, all the marking results can be accessed by the script from "mykeywords" header field. Just parse the string, then any logic can be applied after the parsing to achieve the logic result you like. For example, you can apply if "A" and "B", add "result-AB" to "mykeywords", etc. Then in the next stage to check "mykeywords contains result-AB" for actually meaning for "A and B".

The above example also shows that the "[VN IGNORE]" can be prepended to the subject line to indicate which of the three companies have been involved in the subject email.

Create Filter Rules for Action

Now create the action rule based on the values contained in "mykeywords". This will be just normal settings.

Notes:

The FiltaQuilla supports javascripts in the condition section. Thus if you don't want to change the extension source code, you'll need to write a bit more code in the condition section of filter dialog. With that code any logic computation can be done too.

Check out FiltaQuilla site for lot more information.

Solution 4:

Maybe you could use tags for each sub-clause of the expression. if ((from:Tommy OR from:Billy) then tag with "TomAndBilly" tag. Then filter looking for not subject:Fwd AND tag TomAndBilly. I haven't tried this, I guess it won't work if TB won't filter more than once. Maybe you can also force it to go more than once by bouncing the mail to different folders, or even accounts (but then it's starting to get really ugly).

I heard better tagging was due in TB3, but it doesn't seem evident in the UI.