Skip to content

Enffun-EL/Mail-Console

Repository files navigation

Mail Console

中文文档

Mail Console is a local-first mailbox workspace for managing large Outlook / Hotmail account libraries, receiving verification codes or recent messages, refreshing OAuth tokens, and exposing the same operations through an API key protected developer interface.

It is intentionally simple to deploy: a standard-library Python backend, native HTML/CSS/JavaScript, and plain text/JSON data files. No database, Node build step, or frontend framework is required.

If Mail Console saves you time or helps your workflow, please consider giving the project a star. It helps more people discover the project and keeps development moving.

Screenshots

Dashboard Account Library
Mail Console dashboard Chinese Mail Console account library English
Mail Console dashboard English Mail Console account library Chinese

Privacy-safe screenshot mode:

http://127.0.0.1:8899/?privacy=1
http://127.0.0.1:8899/?privacy=1&lang=en

privacy=1 masks mailbox addresses, group names, and account counts in the UI. It is intended for screenshots, demos, and documentation. It does not modify data/accounts.txt, categories, tokens, or any local account assets.

Highlights

  • Dashboard-first UI designed for hundreds or thousands of mailbox accounts.
  • Nested folder-like categories with drag-and-drop account and group movement.
  • Dense but readable account rows, expandable history, and per-account receive state.
  • Receive verification codes or recent messages from a single account or selected accounts.
  • Outlook REST first, IMAP fallback, with Inbox/Junk/Archive/Deleted/Clutter coverage where available.
  • Page-local receive history with duplicate suppression by mailbox arrival time and content.
  • Import .txt files or pasted account text, deduplicated by real email address.
  • Export normalized account lines as email----mailbox_password----client_id----refresh_token.
  • Manual and scheduled Outlook refresh token maintenance with local backups.
  • Config-driven login, password hashing, session cookies, local themes, and resource overview.
  • Developer API with an independent enable switch and API key.

Table Of Contents

Quick Start

Requirements:

  • Python 3.10+
  • Windows PowerShell for the bundled control script, or any shell that can run python app.py

Windows double-click start:

start_mail_console.vbs

Windows double-click stop:

stop_mail_console.vbs

Command line start:

python app.py

Open the console:

http://127.0.0.1:8899

Default local login when no config.json exists:

admin / admin

For any shared machine, server, or public network, create config.json and change the password before exposing the service.

AI Agent Deployment

Paste this into an AI coding agent and let it deploy from the README:

Please read this README and deploy Mail Console safely on this machine:
https://raw.githubusercontent.com/Enffun-EL/Mail-Console/main/README.md

Real mailbox accounts, passwords, OAuth client IDs, refresh tokens, API keys, session secrets, and generated config files are private assets. Keep them in ignored local files, not in issues, pull requests, logs, screenshots, or README examples.

Configuration

config.json is the recommended configuration entry point. Environment variables and command line arguments are best used as deployment overrides.

Create a local config file:

copy config.example.json config.json

On macOS/Linux:

cp config.example.json config.json

Configuration precedence:

command line arguments > environment variables > config.json > built-in defaults

Example:

{
  "server": {
    "host": "127.0.0.1",
    "port": 8899
  },
  "auth": {
    "enabled": true,
    "username": "admin",
    "password": "change-this-password",
    "passwordHash": "",
    "secret": "replace-with-a-long-random-string",
    "cookieSecure": false,
    "sessionSeconds": 86400
  },
  "paths": {
    "accounts": "data/accounts.txt",
    "categories": "data/categories.json",
    "archive": "data/token-refresh-archive",
    "tokenSchedule": "data/token-refresh-schedule.json"
  },
  "fetch": {
    "waitSeconds": 120,
    "intervalSeconds": 5,
    "maxConcurrent": 8
  },
  "api": {
    "enabled": false,
    "key": ""
  }
}

Important options:

Section Option Description
server host, port HTTP bind address and port. Changing these requires restart.
auth enabled Enable or disable browser login. Disable only on trusted local networks.
auth username, password Basic local login credentials.
auth passwordHash Takes priority over password when set. Generate with python scripts/make_password_hash.py.
auth secret Session signing secret. Use a long random value in production.
auth cookieSecure Set to true when the app is served through HTTPS.
fetch waitSeconds, intervalSeconds, maxConcurrent Default receive timeout, polling interval, and concurrency.
api enabled, key Developer API switch and key. Prefer managing these from the UI.

Supported environment overrides include PANEL_HOST, PANEL_PORT, PANEL_USER, PANEL_PASSWORD, PANEL_PASSWORD_HASH, PANEL_AUTH_ENABLED, MAIL_CONSOLE_API_ENABLED, and MAIL_CONSOLE_API_KEY. See .env.example for more.

Account File Format

Default account file:

data/accounts.txt

Supported account lines:

email----mailbox_password
email----mailbox_password----outlook_client_id----outlook_refresh_token
openai_email----openai_password----mailbox_password----outlook_client_id----outlook_refresh_token

Category headers are supported:

[Project A]
demo@example.com----password----client_id----refresh_token

Project B----demo2@example.com----password----client_id----refresh_token

Nested categories use /:

Registered/CPA/PLUS

Import And Export

  • Import from the UI with a .txt file or pasted account text.
  • Append import keeps existing accounts and skips duplicate email addresses.
  • Replace import backs up the current account file and writes a deduplicated file.
  • Export always writes email----mailbox_password----client_id----refresh_token.

Receiving Codes And Messages

Mail Console has two receive modes:

  • code: extracts six-digit verification codes from relevant messages.
  • message: returns the latest visible email subject, sender, arrival time, and preview/body.

Receive behavior:

  • Outlook REST is used first when OAuth credentials are present.
  • IMAP is used as fallback when REST times out or is unavailable.
  • The UI keeps receive history only in the current browser page session.
  • Each account keeps up to 30 receive records in memory.
  • Duplicate results are suppressed by mode, mailbox arrival time, and received content.
  • If content is the same but mailbox arrival time differs, it is treated as a new email.

If a sender reports that a message was sent but Mail Console does not show it, verify that the mailbox provider actually exposes it through Outlook REST/IMAP. In practice, mail can be delayed, blocked, greylisted, or routed differently per recipient.

Developer API

Open the user menu in the top-right corner and choose API.

API controls:

  • Use the slider to enable or disable API access.
  • Generate a key to create and save a new API key. The previous key becomes invalid immediately.
  • Use the eye icon to reveal the key temporarily.
  • Use Copy Key to copy it.
  • The API documentation panel uses the current browser origin, so local, cloud, IP, domain, and HTTPS deployments show the correct base URL automatically.

Authentication headers:

Authorization: Bearer YOUR_API_KEY

or:

X-API-Key: YOUR_API_KEY

Fetch one mailbox:

curl -X POST "http://127.0.0.1:8899/api/v1/fetch" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"email\":\"demo@outlook.com\",\"mode\":\"message\",\"wait\":120,\"recentMinutes\":60}"

Fetch verification code instead:

{
  "email": "demo@outlook.com",
  "mode": "code",
  "wait": 120,
  "recentMinutes": 10
}

Batch fetch:

curl -X POST "http://127.0.0.1:8899/api/v1/fetch_batch" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"emails\":[\"a@outlook.com\",\"b@outlook.com\"],\"mode\":\"message\",\"parallel\":4}"

Common API endpoints:

Method Path Purpose
GET /api/accounts List accounts, categories, counts, and max concurrency.
POST /api/v1/fetch Fetch one mailbox using API-key auth.
POST /api/v1/fetch_batch Fetch multiple mailboxes using API-key auth.
POST /api/category Move accounts to a category.
POST /api/create_category Create a category.
POST /api/rename_category Rename or move a category path.
POST /api/delete_category Delete a category and move its accounts back to uncategorized.
GET /api/export Export normalized account lines.
GET / POST /api/token_schedule Read or save token refresh schedule.
POST /api/refresh_tokens Refresh selected or all OAuth tokens.
GET /api/workspace_stats Read process memory, local data size, and disk free space.

Treat the API key like a password. When API is enabled, the key can call protected operations in this app.

Token Refresh

  • Refresh selected OAuth accounts manually.
  • Refresh all OAuth accounts manually.
  • Schedule refreshes by interval: every N minutes, hours, or days.
  • Day-based schedules can use a clock time, such as every 30 days at 03:00.
  • Schedule state is stored in data/token-refresh-schedule.json by default.
  • Backups and reports are written under data/token-refresh-archive.

Deployment

Local-only default:

{
  "server": {
    "host": "127.0.0.1",
    "port": 8899
  }
}

LAN or server deployment:

{
  "server": {
    "host": "0.0.0.0",
    "port": 8899
  },
  "auth": {
    "enabled": true,
    "username": "admin",
    "password": "replace-this"
  }
}

Recommendations for servers:

  • Change the default password before binding to a public interface.
  • Prefer auth.passwordHash instead of a plain password in shared environments.
  • Put the app behind HTTPS before setting auth.cookieSecure=true.
  • Use a firewall or reverse proxy access rules for public deployments.
  • Store config.json and data/ outside public web roots.

PowerShell controller:

powershell -ExecutionPolicy Bypass -File "console_control.ps1" -Action start
powershell -ExecutionPolicy Bypass -File "console_control.ps1" -Action status
powershell -ExecutionPolicy Bypass -File "console_control.ps1" -Action stop

The controller reads config.json and PANEL_PORT to open the correct URL.

Command line overrides:

python app.py --host 127.0.0.1 --port 8899 --config config.json
python app.py --accounts data/accounts.txt --categories data/categories.json
python app.py --api-enabled true --api-key YOUR_API_KEY

Security Notes

  • Do not commit config.json, data/accounts.txt, or real token archives.
  • Do not use admin / admin outside local testing.
  • Refresh tokens are not rendered in normal account rows.
  • Receive history is page-local and disappears after refresh/clear.
  • The UI Clear records action clears page logs, received messages, and codes. It does not delete mailbox server messages.
  • API keys are powerful. Disable API when it is not needed.

Troubleshooting

Message was sent but not received:

  • Check the account in the UI and increase recentMinutes or wait.
  • The sender may show multiple recipients, but Outlook may expose the message for only some mailboxes.
  • Check Inbox, Junk, Archive, Deleted, and Clutter in the mailbox provider.
  • OAuth/REST can see different data from webmail during delivery delays.
  • Use the API/UI failure message. It includes the latest visible Outlook message when no recent message is found.

Login does not work:

  • Verify auth.username, auth.password, or auth.passwordHash.
  • Restart after changing host/port and refresh after changing frontend files.
  • If using HTTPS, only set auth.cookieSecure=true behind HTTPS.

Token refresh failed:

  • Confirm the account line has client_id and refresh_token.
  • Check data/token-refresh-archive for backup and report files.
  • Some Microsoft refresh tokens expire or are revoked and must be replaced.

Project Layout

app.py                               Thin launcher, keeps `python app.py` working
src/mail_console/__init__.py         Package metadata and version marker
src/mail_console/__main__.py         Package entrypoint when `src` is on `PYTHONPATH`
src/mail_console/server.py           HTTP routes, request handling, fetch jobs, schedules
src/mail_console/accounts.py         Account loading, import/export, groups, token writeback
src/mail_console/outlook.py          Outlook OAuth and HTTP JSON helpers
src/mail_console/mail_parser.py      MIME parsing, text cleanup, verification-code extraction
src/mail_console/mail_messages.py    REST message normalization and duplicate-detection keys
src/mail_console/security.py         Password hashes, session signing, secrets
src/mail_console/workspace.py        Local resource stats and cleanup helpers
src/mail_console/models.py           Dataclasses and shared model types
src/mail_console/constants.py        App constants, limits, regexes, Outlook endpoints
src/mail_console/paths.py            Project, data, static, config, archive paths
src/mail_console/utils.py            Small shared parsing and formatting helpers
static/index.html                    Main console UI
static/login.html                    Login page
assets/                              README screenshots
config.example.json                  Configuration template
.env.example                         Optional environment overrides
scripts/make_password_hash.py        Password hash helper
console_control.ps1                  Start / stop / status controller
start_mail_console.vbs               Windows double-click start
stop_mail_console.vbs                Windows double-click stop
accounts.example.txt                 Example account file
data/accounts.txt                    Local real account file, ignored by Git
data/categories.json                 Local category state, ignored by Git
data/token-refresh-schedule.json     Scheduled token refresh state, ignored by Git
data/token-refresh-archive           Refresh-token backups and reports, ignored by Git

About

本地优先的 Outlook/Hotmail 邮箱工作台,支持账号管理、收码收消息、令牌刷新和 API 调用。/Local-first mailbox workspace for managing Outlook/Hotmail accounts, receiving codes/messages, refreshing tokens, and exposing API access.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors