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

2 Answers 2

7

... 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
1
  • 1
    You can also open the mail source with Ctrl+U then search for Message-ID: <ID> May 4 at 10:03
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%[email protected]/INBOX#28649": {
             "text": "Test message contains search terms",
             "subject": "Test message",
             "attachments": "",
             "sender": "John Doe <[email protected]>",
             "receiver": "[email protected]",
             "date": "2022-10-02, 14:20",
             "folder_id": 607,
             "message_key": 28649
         }
     }
    
4
  • Do you know how stable this number is? Like if I have two thunderbird instances downloading synced with the same email accounts would they share the same id?
    – tobiasBora
    Sep 12, 2022 at 22:12
  • 1
    Yes, as far as I can tell, IMAP accounts seem to share the IDs across different Thunderbird installations and profiles, e.g. imap-message://a%[email protected]/INBOX#28579 would always lead to the same message, regardless of where you retrieve it. Sep 27, 2022 at 19:31
  • Great, thanks! But if I move the message to another folder than INBOX I guess it will get a different number/adress.
    – tobiasBora
    Sep 28, 2022 at 8:25
  • 1
    The IMAP URLs are stabIe even when messages are moved to different folder locations, I think. I've just added a small Python script so that you can check the URLs for your specific use case. Oct 2, 2022 at 14:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .