10

Thunderbird 24.2.0 has a -mail command-line parameter, with which a specific mail can be opened from the command line:

$ thunderbird --help
-mail <URL>        Open the message specified by this URL.

I know that one can use this function to open a specific email by an imap:// URI, but I would like to be able to open a specific mail by its unique Message-ID, no matter which folder contains it. Is this possible, and if so, what does the URI look like?

The thunderlink add-on ( https://addons.mozilla.org/en-us/thunderbird/addon/thunderlink/ ) can create message-id based links to emails and then open these with the -thunderlink parameter, but I would still like to know if this can be done with just the -mail parameter.

2 Answers2

8

... for anyone still searching for a solution...
The following command worked for me (thunderbird 102.6.1):

thunderbird mid:<the message ID>

To make this nice and easy:

  1. make sure the "thunderbird" command is in PATH (e.g. you can execute it in a terminal)
  2. install copy message ID AddOn
  3. in the preferences add the following prefix: thunderbird mid:
    (make sure that there are no spaces before and after!)
  4. open an email and click the Copy Message ID button
  5. run the copied command in a terminal to open the mail
raphael
  • 181
  • 1
  • 3
2

Update 2021-03-18: The bug mentioned below has been fixed with Thunderbird version 78.8.1. No adjustments are necessary to open mails from the command line using thunderbird.exe -mail <URL>.


Opening messages with the -mail command line parameter is still possible with a current Thunderbird version (tested on Windows 10 with version 78.6.0, 32-bit).

However, this requires a small change of the module MailNewsCommandLineHandler.jsm, because otherwise a getter-only error occurs when calling the -mail command. The error can be traced via the Thunderbird error console (see below).

Adjusting the module:

  1. Copy the file c:\Program Files (x86)\Mozilla Thunderbird\omni.ja into a temporary directory, rename the file to omni.zip and unpack it.

  2. Open MailNewsCommandLineHandler.jsm, insert

    set _messenger(value) {
        return value;
    }, 
    

    after line 22 and save the file.

  3. Repack all files using the following parameters: zip.exe -0DXqr omni.ja *. Rename the original file to omni.ja.bak and copy the repacked file to c:\Program Files (x86)\Mozilla Thunderbird.

  4. Messages can then be opened using the following command lines:

    thunderbird.exe -mail "mailbox-message://<folderLocation>#<messageKey>" (for local folders)
    thunderbird.exe -mail "imap-message://<folderLocation>#<messageKey>" (for IMAP folders)
    

Finding the right URL:

  • Error console: Open TB, select a message and open the error console (Ctrl + Shift + J). Enter the line

    var hdr = gFolderDisplay.selectedMessage; alert(hdr.folder.getUriForMsg(hdr));
    

    and press enter. This will open a window with the URL for the selected message.

  • SQLite database: If you plan to build your own search tool (e.g. by writing a Python plugin for the Wox desktop launcher), it is perhaps best to create the URLs dynamically.

    The Thunderbird database can be found under %APPDATA%\Thunderbird\Profiles\<profile>\global-messages-db.sqlite. The tables messagesText_content, messages and folderLocations contain all information needed to assemble the URL strings.

    A simple Python script that can be used to generate the URLs might look something like this:

    import sqlite3
    import re
    import sys
    import os
    import json
    

    Replace db_path with your profile location

    (Help > Troubleshooting Information > Open Folder)

    db_path = r"%APPDATA%\Thunderbird\Profiles\xxxxxxxx.default"

    con = sqlite3.connect(os.path.join(db_path, "global-messages-db.sqlite")) cursor = con.cursor()

    query = """ SELECT messagesText_content.*, strftime('%Y-%m-%d, %H:%M', DATETIME(messages.date/1000000, "unixepoch", "localtime")), messages.folderID, messages.messageKey FROM messagesText_content JOIN messages ON messages.id=messagesText_content.docid WHERE messagesText_content.c3author NOT LIKE "%daemon%" OR messagesText_content.c3author NOT LIKE "%DAEMON%" ORDER BY messages.date DESC """

    def get_messages(): messages = [] cursor.execute(query) for i in cursor: messages.append({ "text": i[1] if i[1] else "", "subject": i[2], "attachments": f'attach:{i[3]}' if i[3] else "", "sender": i[4], "receiver": i[5], "date": i[6], "folder_id": i[7], "message_key": i[8] }) return messages

    def get_folders(): cursor.execute("SELECT * FROM folderLocations") return {i[0]: i[1:] for i in cursor.fetchall()}

    def collect_urls(terms): r1 = "(mailbox|imap)(?=://)" r2 = "\1-message" messages = get_messages() folders = get_folders() results = {} for msg in messages: msg_str = str(msg.values()).lower() if all(i.lower() in msg_str for i in terms): folder = folders.get(msg["folder_id"])[0] url = re.sub(r1, r2, folder) url = f'{url}#{msg["message_key"]}' msg["text"] = msg["text"][:50] results.update({url: msg}) return json.dumps( results, indent=4, ensure_ascii=False )

    if name == "main": if len(sys.argv) > 1: print(collect_urls(sys.argv[1:]))

    Just use it like so:

     <C:\>python collect_urls.py search terms test message
    

    { "imap-message://a%40b.cd@imap.provider.com/INBOX#28649": { "text": "Test message contains search terms", "subject": "Test message", "attachments": "", "sender": "John Doe <e@f.gh>", "receiver": "i@j.kl", "date": "2022-10-02, 14:20", "folder_id": 607, "message_key": 28649 } }