A minimal Thunderbird add-on that adds a "Run Script" action to mail filters. When an email matches your filter criteria, it executes an external script with email metadata as arguments.
- Execute any script (Python, Bash, etc.) when emails arrive
- Pass email metadata as command-line arguments
- Works with Thunderbird 115 - 146+
- Lightweight (~330 lines of core code)
- Download
run-script-filter.xpifrom this repository - Open Thunderbird
- Go to Menu (☰) → Add-ons and Themes (or press
Ctrl+Shift+A) - Click the gear icon (⚙️) → Install Add-on From File...
- Select the downloaded
run-script-filter.xpi - Click Add when prompted
- Restart Thunderbird (required!)
git clone https://github.com/user/thunderbird-run-script-addon.git
cd thunderbird-run-script-addon
zip -r run-script-filter.xpi manifest.json background.js api/ content/Then install the generated .xpi file as described above.
- Open Thunderbird's Error Console: Menu → Developer Tools → Error Console (or
Ctrl+Shift+J) - Look for:
Run Script Filter: Filter action registered successfully! - Go to Tools → Message Filters → Select account → New...
- In "Perform these actions", you should see "Run Script" in the dropdown
- Go to Tools → Message Filters
- Select an email account
- Click New...
- Set filter name (e.g., "Process Incoming Emails")
- Set conditions:
- For testing: Select "Match all messages"
- For production: Set specific criteria
- Under Perform these actions, select "Run Script"
- Enter the action value (see format below)
- Click OK to save
/absolute/path/to/script,arg1,arg2,arg3,...
Examples:
# Simple - just run a script
/home/user/scripts/notify.sh
# With email variables
/home/user/scripts/process.py,@SUBJECT@,@AUTHOR@,@MESSAGEID@
# Trigger incremental email processing
/home/user/projects/rag-system/scripts/process_emails.py,--incremental| Variable | Description | Example Value |
|---|---|---|
@SUBJECT@ |
Email subject line | "Meeting tomorrow" |
@AUTHOR@ |
From address (full) | "John Doe john@example.com" |
@MESSAGEID@ |
Message-ID header | "abc123@mail.example.com" |
@RECIPIENTS@ |
To addresses | "user@example.com" |
@CCLIST@ |
CC addresses | "cc@example.com" |
@DATE@ |
Human-readable date | "Mon Jan 15 2024 10:30:00 GMT+0000" |
@DATEINSECONDS@ |
Unix timestamp | "1705315800" |
@MESSAGEURI@ |
Thunderbird internal URI | "mailbox://..." |
@FOLDERNAME@ |
Folder name | "INBOX" |
@ACCOUNT@ |
Account name | "imap.gmail.com" |
- Create a test script:
#!/bin/bash
# Save as: ~/test-email-filter.sh
echo "$(date): Email received" >> ~/email-filter-log.txt
echo " Subject: $1" >> ~/email-filter-log.txt
echo " From: $2" >> ~/email-filter-log.txt- Make it executable:
chmod +x ~/test-email-filter.sh- Create a filter with action value:
/home/YOUR_USERNAME/test-email-filter.sh,@SUBJECT@,@AUTHOR@
-
Test the filter:
- Select an email in Thunderbird
- Go to Tools → Run Filters on Selected Messages
-
Check the log:
cat ~/email-filter-log.txt#!/usr/bin/env python3
# Save as: ~/test-email-filter.py
import sys
from datetime import datetime
with open("/tmp/email-filter-log.txt", "a") as f:
f.write(f"\n{'='*50}\n")
f.write(f"Time: {datetime.now()}\n")
for i, arg in enumerate(sys.argv):
f.write(f" Arg {i}: {arg}\n")- Restart Thunderbird after installing the add-on
- Check Error Console (
Ctrl+Shift+J) for errors - Verify the add-on is enabled in Add-ons Manager
| Issue | Solution |
|---|---|
| Script not found | Use full absolute path (not ~ or relative) |
| Permission denied | Make executable: chmod +x /path/to/script |
| No output | Add shebang: #!/usr/bin/env python3 or #!/bin/bash |
| Still not working | Check Error Console for Run Script Filter: messages |
Add this to your script to verify it's being called:
#!/usr/bin/env python3
import sys
with open("/tmp/debug.txt", "a") as f:
f.write(f"Called with: {sys.argv}\n")┌─────────────────────────────────────────────────────────────┐
│ THUNDERBIRD │
├─────────────────────────────────────────────────────────────┤
│ 1. Add-on loads background.js │
│ 2. WindowListener injects code into messenger window │
│ 3. DomContentScript patches filter editor UI │
│ 4. Custom filter action "Run Script" is registered │
│ 5. When filter matches → nsIProcess executes your script │
└─────────────────────────────────────────────────────────────┘
thunderbird-run-script-addon/
├── manifest.json # Add-on metadata & permissions
├── background.js # Registers WindowListener & DomContentScript
├── api/
│ ├── WindowListener/ # Injects scripts into TB windows
│ │ ├── implementation.js
│ │ └── schema.json
│ └── DomContentScript/ # Patches filter editor UI
│ ├── implementation.js
│ └── schema.json
├── content/
│ ├── inject.js # Loaded into messenger window
│ ├── runscript-filter.js # Main filter action logic
│ └── filter-editor.js # Adds text input to filter UI
├── run-script-filter.xpi # Packaged add-on (ready to install)
├── test-script.py # Example Python test script
└── test-script.sh # Example Bash test script
| Thunderbird Version | Status |
|---|---|
| 115.x (ESR) | ✅ Tested |
| 128.x | ✅ Tested |
| 140.x+ | ✅ Should work |
This add-on uses the WindowListener and DomContentScript experimental APIs from FiltaQuilla by R Kent James and Axel Grude.
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
This add-on incorporates code from FiltaQuilla (GPL-3.0), specifically the WindowListener and DomContentScript experimental APIs.
Contributions are welcome! Please feel free to submit issues and pull requests.