# IMAP-to-IMAP Email Migration

Migrate all emails from one provider to another for a domain. Used for moving boy's emails (greyson@, garrison@) from SiteGround to MXroute.

## Process

1. **DNS check** — Verify MX records point to the destination provider:
   ```bash
   dig +short MX iamgmb.com
   ```

2. **Verify old account access**:
   ```bash
   python3 -c "
   import imaplib, ssl
   ctx = ssl.create_default_context()
   s = imaplib.IMAP4_SSL('old_host', 993, ssl_context=ctx, timeout=10)
   s.login('email@domain.com', 'password')
   r = s.select('INBOX')
   print(f'{r[1][0].decode()} messages in INBOX')
   s.logout()
   "
   ```

3. **List all folders** — SiteGround uses `INBOX.` prefix for subfolders; MXroute uses flat top-level folder names.

4. **Migrate each folder**:
   - Map old folder names to new folder names (e.g. `INBOX.Deleted Messages` → `Trash`)
   - Create destination folders on new server
   - Copy messages preserving dates via IMAP APPEND

5. **Verify** — Count messages on new server match old server per folder.

## Folder Mapping (SiteGround → MXroute)

| SiteGround | MXroute |
|-----------|---------|
| INBOX | INBOX |
| INBOX.Trash | Trash |
| INBOX.Deleted Messages | Trash |
| INBOX.Sent | Sent |
| INBOX.Sent Messages | Sent |
| INBOX.Drafts | Drafts |
| INBOX.spam | INBOX.spam |
| INBOX.Junk | Junk |
| INBOX.Archive | Archive |

## Pitfalls

- **Folder listing format differs** — SiteGround uses `INBOX.` subfolder notation and returns `"."` entries from LIST (ignore those). MXroute returns flat format `(flags) "." folder_name`.
- **IMAP responses are bytes** — Decode with `decode()`, not `.decode('ascii')`. UTF-8 is safe.
- **Rate limits** — If migrating many messages (300+ per folder), batch in groups of 50 and add `time.sleep(0.5)` between batches.
- **Deduplication** — Messages ARE appended. If the script runs twice, duplicates happen. Track by `(folder, UID)` composite key.
- **Password visibility** — SMTP/IMAP passwords are passed on the command line in heredocs. Use `ps aux | grep` awareness. For production, read from a file.
