Thunderbird Filters Using Arbitrary Logic Matching Rules

FiltaQuilla is a great enhancement to the Thunderbird built-in filter by adding scripting ability. With FiltaQuilla, by writing javascript actions or rules, it is possible to implement any arbitrary complex logic rules for message filtering. There is more, by modifying FiltaQuilla source code a little bit, the implementation can be simplified a lot.  Here is an example how that can be done.

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.


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 “” 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 ( == 0) { ss = "V"; lastVN = 1; } /*VIP*/
          else if ( == 0 ) { ss = "N"; lastVN = 1; } /*NORMAL*/
          else if ( == 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.


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.

The original writing was posted to stackexchange superuser as an answer to a question. Stackexchange is a great adventure by Mr Joel Spolsky and Mr Jeff Atwood.


About minghuasweblog

a long time coder
This entry was posted in All, Mozilla Firefox and Thunderbird and tagged , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s