5

I would like to tag all incoming mails which include a calendar invite. Then I would like to move them into a different folder. I tried the method described in this answer, but it doesn't work: I tried a find a header named "Content-Type" with the content "text/calendar" but it didn't work.

I also tried the addon FiltaQuilla, which failed as well. I used following code there:

var sHeaderToLookFor = "content-type";
var sContentInHeader = "text/calendar";
var bFoundIt = false;
function msgHdrGetHeaders(aMsgHdr, k) {
    let uri = aMsgHdr.folder.getUriForMsg(aMsgHdr);
    let messageService = MailServices.messenger.messageServiceFromURI(uri);
    MsgHdrToMimeMessage(aMsgHdr, null, function (aMsgHdr, aMimeMsg) { k(aMimeMsg);  }, true, { partsOnDemand: true, examineEncryptedParts:true });
}

msgHdrGetHeaders(message, function (aHeaders) {
    if (aHeaders.has(sHeaderToLookFor)) {
        var pattern = new RegExp(sContentInHeader);
        Application.console.log("InBetween_1");
        if (!bFoundIt)
            bFoundIt= pattern.test(aHeaders.get(sHeaderToLookFor));
        Application.console.log(bFoundIt);
        Application.console.log("InBetween_2");
    }
});

Application.console.log("AtEnd_1");
Application.console.log(bFoundIt);
Application.console.log("AtEnd_2");
bFoundIt;

I had following output on the console after testing the filter on an email with an .ics invite:

AtEnd_1
false
AtEnd_2
InBetween_1
true
InBetween_2

So basically, this filter with JavaScript would work. But it doesn't work because MsgHdrToMimeMessage() will call the callback after the Filter has returned "false" to FiltaQuilla. I would need to make the code wait (use it synchronously instead of asynchronously), but I have no idea of how to do that.

Anyway, I am not really focused in using FiltaQuilla. I would just like to have a solution for my problem.

I use IMAP and I save my emails on my local HD for offline email reading.

There was an older Thunderbird version where FiltaQuilla worked (something like 24.x), and there where even older versions of Thunderbird (like 3.x) where filters on headers worked. But something changed and now I don't know how to filter anymore.

  • It seems that this is a bug of Thunderbird: bugzilla.mozilla.org/show_bug.cgi?id=622307 . But I can't imagine that this issue exists for several years. – nusi Aug 28 '15 at 12:37
  • As an interim solution I just came up with, you can look for "ics" or "vcs" (those are usual extensions of calendar appointment files). Note that the use of those extensions may depend on client and/or OS, but it may be useful as a rule of thumb or for an emergency case. – ysmartin May 23 '18 at 17:37
0

Finally found a solution for that. Below JavaScript code works fine with FiltaQuilla and Thunderbird 38.2.0.

{
    var sHeaderToLookFor = "content-type";
    var sContentInHeader = "text/calendar";

    var hwindow = Components.classes["@mozilla.org/appshell/appShellService;1"]
            .getService(Components.interfaces.nsIAppShellService)
            .hiddenDOMWindow;
    function waitFor(callback, message, timeout, interval, thisObject) {
        timeout = timeout || 5000;
        interval = interval || 100;
        var self = {counter: 0, result: callback.call(thisObject)};
        function wait() {
            self.counter += interval;
            self.result = callback.call(thisObject);
        }
        var timeoutInterval = hwindow.setInterval(wait, interval);
        var thread = Components.classes["@mozilla.org/thread-manager;1"].getService().currentThread;
        while ((self.result != true) && (self.counter < timeout)) {
            thread.processNextEvent(true);
        }
        hwindow.clearInterval(timeoutInterval);
        if (self.counter >= timeout) {
            message = message || arguments.callee.name + ": Timeout exceeded for '" + callback + "'";
            throw new TimeoutError(message);
        }
      return true;
    }

    var bFoundIt = false;
    var called = false;
    function msgHdrGetHeaders(aMsgHdr, k) {
        let uri = aMsgHdr.folder.getUriForMsg(aMsgHdr);
        let messageService = MailServices.messenger.messageServiceFromURI(uri);
        MsgHdrToMimeMessage(aMsgHdr, null,
            function(aMsgHdr, aMimeMsg) {
                try {
                    k(aMimeMsg);
                }
                catch (ex)
                {
                }
                finally {
                    called = true;
                }
            },
            true, { partsOnDemand: true, examineEncryptedParts:true });
    }

    msgHdrGetHeaders(message, function (aHeaders) {
        if (aHeaders.has(sHeaderToLookFor)) {
            var pattern = new RegExp(sContentInHeader);
            // Application.console.log("InBetween_1");
            if (!bFoundIt)
                bFoundIt = pattern.test(aHeaders.get(sHeaderToLookFor));
            Application.console.log(bFoundIt);
            // Application.console.log("InBetween_2");
        }
    });

    waitFor(function () called, "Timeout waiting for message to be parsed");
    // Application.console.log("AtEnd_1");
    Application.console.log(bFoundIt);
    // Application.console.log("AtEnd_2");
    bFoundIt;
}

I used the waitFor() function from https://searchcode.com/codesearch/view/21382111/. That link seems to be the source from the Thunderbird test library (/thunderbird-14.0/comm-release/mail/test/resources/mozmill/mozmill/extension/resource/modules/utils.js)

Anyway, if someone else has a similar problem, where he wants to parse headers of emails on IMAP folders, he can use above code and just change "sHeaderToLookFor" and "sContentInHeader" to his needs.

| improve this answer | |
  • Nusi, Can you explain how to configure FiltaQuilla to use your script? Thanks! Jay – user496320 Sep 11 '15 at 20:03

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.