Developing Thunderbird Addons

What can a web developer do with Thunderbird?


All HTML and Javascript?

Can I try them out?

Outline of this talk

Part one

(quick intro to Thunderbird)

Thunderbird: an old beast

The situation is much better now

Big potential for addons!
Everyone likes to have email their own way. Everyone has a strong sense of what email should be. Everyone wants an option to enable their favorite feature.

Demo addon @

Part two

(getting started with addons)

Getting started

What is an addon?


Montrer le début du demo addon et dire que c'est que du HTML

The best way to get started

Apply every single piece of advice from “Setting up an extension development environment” on MDN.

Then steal the demo addon!

The basics of addons

Not going to cover that: there's excellent online documentation. See Mozilla Developer Network for more.

Lesson 1: how to open a tab in Thunderbird

1 window.openTab("chromeTab", {
2   chromePage: "chrome://demo/content/index.html",
3 });
tab type = (chrome, content, folder, message, your own...) tab options = (specific to each tab type)

Lesson 1: now do something with the tab

A security remainder

Part three

(more lessons)

One golden rule

Steal as much code as you can.
Parler des trucs un peu tricky sur les nsIMsgDBHdr

Lesson 2: listing the accounts

Sounds simple, right?




Here's a working snippet!

1 for each (let account in
2   fixIterator(MailServices.accounts.accounts,
3     Ci.nsIMsgAccount)) {
4   // do stuff with account
5 }

Some tricks here


See the list of accounts in your Thunderbird profile.

Lesson 3: listing the folders

We would like to inspect the folders of a given account.


Pro tip: use

After reading MXR...


This demo recursively iterates over the folders in an account and finds the Inbox


let isInbox =

More things you can do

Iterate on...

Lesson 4: inspect a message

A nsIMsgDBHdr contains everything to display an entry in the message list: date, author, subject, but no attachments, etc.


It is also the entry point to modify messages: mark them read, change tags, etc. (use thunderbird-stdlib!).

Examining a single message

However, nsIMsgDBHdrs are just entry points.


Solution: get the entire message contents and analyze it. This is called streaming the message.

Streaming a message

MsgHdrToMimeMessage(msgHdr, this,
  function (aMsgHdr, aMimeMsg) {
    if (aMimeMsg.has("reply-to"))
      // do stuff
    let atts = aMimeMsg.allUserAttachments;
    // name, size, content type, url
  }, true, {
    aPartsOnDemand: true,

Streaming a message

Allows one to:

More stuff you can do

Ask me!


Inspecting a message, displaying a message.

And now for something completely different

What if you want to search messages? Accross all folders? According to some criterion?

Gloda is your friend

Gloda is your friend

Lesson 5: search messages by subject

let query = Gloda.newQuery(
let myListener = {
  // ...
let collection =


The query is asynchronous.

More Gloda

Lesson 6: Get the thread a message belongs to

onQueryCompleted: function (aCollection) {
      // ...
      onQueryCompleted: function (aColl) {

Lesson 7: all emails involving a particular person

 1 let query = Gloda.newQuery(Gloda.NOUN_MESSAGE);
 2 let q1 = Gloda.newQuery(Gloda.NOUN_IDENTITY);
 3 q1.kind("email");
 4 q1.value("");
 5 q1.getCollection({ // ...
 6   // ...
 7   let q2 = Gloda.newQuery(Gloda.NOUN_MESSAGE);
 8   q2.involves.apply(q2, aCollection.items);
 9   q2.getCollection({ // ...
10     // ...

(read the full code)

Lesson 8: search attachments with a given content-type

1 let query = Gloda.newQuery(Gloda.NOUN_MESSAGE);
2 query.attachmentTypes("application/pdf");


Watch the demo!

Part four

(just kidding, it's a recap)

Thunderbird add-ons



Send me an email or post to with any questions.


Q&A session