Revision control

Copy as Markdown

Other Tools

# net.thunderbird URLs
In some circumstances you may need a way to talk to Thunderbird from a web browser, and the best
way to do that is with a URL. A URL can be linked on web pages for the user to click on, or an HTTP
request can redirect to a URL.
Thunderbird provides the custom URL protocol `net.thunderbird:` for this purpose. Thunderbird will
handle URLs of the form `net.thunderbird://component/arguments` where `component` is the name of a
component registered in the category manager. The URL is passed to the `observe` function on the
component.
## OS Registration
Thunderbird must be pre-registered with the operating system as the handler of `net.thunderbird`
URLs. You can check if it is, and make it so, by running this code:
```js
const shellService = Cc["@mozilla.org/mail/shell-service;1"].getService(Ci.nsIShellService);
// Check if this install of Thunderbird is the handler of net.thunderbird URLs.
const isDefault = shellService.isDefaultClient(false, Ci.nsIShellService.NET_THUNDERBIRD);
if (!isDefault) {
// Set this install of Thunderbird to be the handler of net.thunderbird URLs.
// You shouldn't do this without the user's permission.
shellService.setDefaultClient(false, Ci.nsIShellService.NET_THUNDERBIRD);
}
```
(Even if Thunderbird _is_ the handler, if there are multiple profiles, there's no guarantee which
profile will be used.)
Alternatively, there is UI for this check in the Settings tab, under "System Integration".
## Adding a component
### Pick a name
It should uniquely identify what the URL does and wouldn't ever be used by another part of
Thunderbird. Also it's the host part of a URL, so stick to lower-case letters, numbers, and maybe
`-` or `.` if you really must.
### Design your URL
It will be `net.thunderbird://`, plus the name of your component, plus `/` and any extra
information you want to include. Extra information can be appended directly to the URL path, e.g.
`net.thunderbird://mycomponent/foo/bar` and/or using search parameters, e.g.
`net.thunderbird://mycomponent/?foo=bar`. What you do will depend on your needs. You may need to
consider:
- URL encoding characters
- versioning, if your URL could be used with past or future versions of Thunderbird
- not including sensitive information
```{warning}
Anybody could construct a URL and put it on a web page, so data we get from one should never be
naïvely trusted. Don't add a component that creates or deletes items, or sends any kind of
request, without user confirmation.
```
### Write your code
You'll need an object that implements `nsIObserver`, which will be called when Thunderbird is given
a URL to load:
```js
export class MyComponent {
QueryInterface = ChromeUtils.generateQI(["nsIObserver"]);
observe(subject, topic, data) {
if (topic == "net-thunderbird-url") {
// `data` contains the URL.
}
}
}
```
If necessary this code should deconstruct the URL ([`URL`][mdn_url] and
[`URLSearchParams`][mdn_urlsearchparams] are your friends here).
```{note}
There should only ever be a single instance of your component. It will be instantiated with
`getService` and not `createInstance`.
```
### Register your component
Add it to a components.conf file. For a JS component, this is all you need:
```python
{
"cid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", # Use a real UUID. :-)
"contract_ids": ["@mozilla.org/my-component;1"],
"constructor": "MyComponent",
"categories": {"net-thunderbird-url": "mycomponent"}, # This will be the host part of the URL.
}
```
Change each line to point to your actual component, obviously. [More information about registering
XPCOM components][components].
### Rebuild
This may take a little while because adding a component requires a lot of things to be rebuilt.
### Try it
You should be good to go. If Thunderbird (your local build) is the default application for mail
then clicking on a link in a browser should bring Thunderbird to the front and run your code.
For a simple check, type `data:text/html,<a href="net.thunderbird://mycomponent/foo/bar">click me</a>`
in your browser's address bar.
### Write tests
Please add automated tests for your new component.
To simulate a click on a URL in a browser, call the observe method with the same data it would see
in real-world use:
```js
const service = Cc["@mozilla.org/my-component;1"].getService(Ci.nsIObserver);
service.observe(null, "net-thunderbird-url", "net.thunderbird://mycomponent/test");
```
### Document
Add your component to the list below with a description of what it does and give example URLs to
illustrate how to use it.
## Components
- `replay` is a test component which simply records the URL to be checked later on.