Automating Mailcow Mailbox Creation with Selenium and TypeScript
Managing a growing list of email accounts manually in Mailcow can be tedious. Unfortunately, the default UI lacks bulk import tools, and the API requires careful CSRF and session handling.
In this post, I’ll walk you through how I used TypeScript + Node.js + Selenium WebDriver to automate bulk mailbox creation in Mailcow, using real browser automation — including login, CSRF token parsing, and mailbox creation using Mailcow’s internal APIs.
🧩 Problem Statement
You have an Excel sheet (or JSON file) full of email accounts you want to create in Mailcow. Mailcow doesn’t provide a native “Import Mailboxes” feature via the UI.
The REST API exists, but requires:
- CSRF token
- Session cookies
- Non-trivial JSON encoding in form submissions
Rather than mimicking this via curl, we can simulate actual browser behavior — logging in, extracting tokens, and submitting forms like a real admin.
🔧 Tech Stack
- Node.js with TypeScript
- Selenium WebDriver with Chrome
- dotenv for environment config
- JSON file for mailbox user data
- Manual CSRF token extraction from inline JavaScript
⚙️ Setup and Configuration
First, install the dependencies:
1
2
npm install selenium-webdriver chromedriver dotenv
npm install -D typescript ts-node
Then, create a .env file to configure your Mailcow instance:
MAILCOW_URL=https://mail.example.com
MAILCOW_ADMIN=admin
MAILCOW_PASSWORD=123
MAILCOW_DEFAULT_PASSWORD=UserPass123!
📁 Input: users.json
We store user data in a JSON file:
1
2
3
4
[
{ "email": "[email protected]", "name": "John Nguyễn" },
{ "email": "[email protected]", "name": "Jane Phạm" }
]
This gets normalized into local part/domain pairs and ASCII-safe names using a tone-removal function for Vietnamese characters.
🔍 The Magic: Selenium + In-Browser Fetch
Here’s what the script does:
✅ 1. Log in to Mailcow
Selenium opens the login page, fills in the username/password, and clicks the login button. Once it confirms login via URL change, we proceed.
✅ 2. Parse the CSRF token
Mailcow sets a global JS variable:
1
var csrf_token = 'abc123';
We extract this using a regular expression from the page’s HTML source.
✅ 3. Submit mailbox creation via browser fetch()
We inject a fetch call into the browser using driver.executeScript(), passing Mailcow user data and the CSRF token.
This simulates the AJAX behavior the UI uses behind the scenes, making the process very reliable.
🧪 Developer Mode: DevTools On
To help debug or observe behavior:
- We launch Chrome with DevTools open using
--auto-open-devtools-for-tabs - You can visually inspect network requests and page behavior
This is great for verifying POST requests and token handling.
🧠 Why Not Just Use the API Directly?
While Mailcow does have API endpoints (/api/v1/add/mailbox), they:
- Expect CSRF token even with cookies
- Reject malformed encoded JSON in
x-www-form-urlencodedformat - Are best used with full session simulation
By using Selenium and working inside the browser, we bypass all of that complexity.
✅ Output Example
1
2
3
4
✅ Logged in
🔑 CSRF token: 5ae67dfc
📬 Request sent for: [email protected]
📬 Request sent for: [email protected]
🧠 Extending the Script
Here’s what you could add next:
- 📥 Load from Excel with
xlsx - 🧪 Dry-run mode
- 🔁 Retry logic for failed mailbox creation
- 🔄 Create aliases or forwarding rules
- 🐳 Dockerize the script
🧾 Full Source Code
The full script is available on GitHub here: github.com/your-org/mailcow-bulk-mailbox
(Or you can ask me for the full inline code if needed.)
💡 Conclusion
This approach gives you the reliability of a logged-in admin session and the power of API automation, without reverse-engineering Mailcow’s CSRF/session handling.
It’s an elegant, browser-based workaround for an otherwise tedious process.
💬 Have questions? Want to extend this into a more powerful Mailcow CLI tool or integrate it into your provisioning system? Feel free to reach out or drop a comment!