Metadata-Version: 2.4
Name: otp-gateway
Version: 2.0.0
Summary: Zero-dependency OTP receiver via IMAP. Watch your inbox for verification codes from 30+ platforms.
License: MIT
Project-URL: Homepage, https://github.com/fajardev-tech/otp-gateway
Project-URL: Repository, https://github.com/fajardev-tech/otp-gateway
Project-URL: Issues, https://github.com/fajardev-tech/otp-gateway/issues
Keywords: otp,imap,verification,automation,email
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# otp-gateway

Zero-dependency Python library for receiving OTP codes via IMAP.

Watch your inbox for verification emails from **30+ platforms** — GitHub, Google, Discord, OpenAI, and more. No third-party APIs, no SMS gateways. Just IMAP.

## Features

- 🔑 **13 OTP extraction patterns** — digits, alphanumeric, multi-language
- 📬 **IMAP auto-polling** with configurable timeout & interval
- 🔗 **Verification link extraction** from email bodies
- 📛 **Alias generation** for catch-all domains
- 🔄 **Smart dedup** — never returns the same OTP twice
- 🐍 **Zero dependencies** — only Python stdlib
- 🖥️ **CLI + Python API** — use from terminal or import in code

## Install

```bash
pip install otp-gateway
```

Or just copy `otp_gateway/` into your project — zero external deps.

## Quick Start

### Python API

```python
from otp_gateway import OTPGateway, OTPConfig

# Configure
config = OTPConfig(
    imap_email="you@gmail.com",
    imap_password="your-app-password",  # Gmail: use App Password
    domain="yourdomain.com",            # optional: for alias generation
)
gw = OTPGateway(config)

# Option 1: Watch a specific email address
result = gw.wait_for_otp("github-abc123@yourdomain.com")
print(result["value"])  # "847291"

# Option 2: Generate alias + wait
alias = gw.generate_alias("github")
print(alias)  # "github-a7k2m3@yourdomain.com"
# ... use this email to sign up ...
result = gw.wait_for_otp(alias, timeout=90)
print(result["value"])  # the OTP code

# Option 3: One-shot check (no waiting)
result = gw.search_otp("some@email.com")
if result:
    print(result["type"])   # "code", "link", or "raw"
    print(result["value"])  # the OTP code or link
```

### CLI

```bash
# Interactive setup
otp-gateway init

# Or pass credentials directly
otp-gateway --email you@gmail.com --password "xxxx" --domain yourdomain.com generate github
otp-gateway --email you@gmail.com --password "xxxx" wait github-a7k2m3@yourdomain.com

# Or use a config file
otp-gateway --config ~/.otp_gateway/config.json generate openai
otp-gateway --config ~/.otp_gateway/config.json check some@email.com
otp-gateway --config ~/.otp_gateway/config.json list
```

## Config

### JSON config file (`~/.otp_gateway/config.json`)

```json
{
  "imap_server": "imap.gmail.com",
  "imap_port": 993,
  "imap_email": "you@gmail.com",
  "imap_password": "your-app-password",
  "domain": "yourdomain.com"
}
```

### Environment variables

```bash
export OTP_IMAP_SERVER=imap.gmail.com
export OTP_IMAP_EMAIL=you@gmail.com
export OTP_IMAP_PASSWORD=your-app-password
export OTP_DOMAIN=yourdomain.com
```

### Programmatic

```python
config = OTPConfig(
    imap_server="imap.gmail.com",
    imap_port=993,
    imap_email="you@gmail.com",
    imap_password="your-app-password",
    domain="yourdomain.com",
)
```

## How It Works

1. **Catch-all routing**: Set up your domain to forward all `*@yourdomain.com` to one Gmail inbox
2. **Alias generation**: `otp-gateway` creates unique aliases like `github-a7k2m3@yourdomain.com`
3. **IMAP polling**: When you request an OTP, it polls your inbox for emails sent to that alias
4. **Pattern matching**: 13 regex patterns extract the OTP code or verification link
5. **Dedup**: Tracks seen message IDs so the same OTP is never returned twice

### Catch-all domain setup

| Provider | Setup |
|---|---|
| **Cloudflare** | Email Routing → Catch-all → forward to Gmail |
| **Namecheap** | Forwarding → Catch-all |
| **Google Domains** | Email → Forwarding → Add catch-all |
| **Any SMTP** | Configure your mail server's catch-all |

### Gmail App Password

1. Go to [Google Account → Security → App Passwords](https://myaccount.google.com/apppasswords)
2. Generate a new app password for "Mail"
3. Use that 16-char password as `imap_password`

## Supported Platforms

The library works with **any platform that sends OTP via email**. Built-in alias prefixes for:

| Platform | Prefix | | Platform | Prefix |
|---|---|---|---|---|
| GitHub | `gh` | | Discord | `dsc` |
| Google | `go` | | Twitter/X | `tw` |
| OpenAI | `oai` | | Anthropic | `ant` |
| HuggingFace | `hf` | | DeepSeek | `ds` |
| Groq | `grq` | | Replicate | `rep` |
| Modal | `mod` | | Railway | `rlw` |
| AWS | `aws` | | Azure | `azr` |
| Cloudflare | `cf` | | Binance | `bnb` |
| Supabase | `spb` | | Vercel | `vrc` |
| Cohere | `coh` | | Mistral | `mst` |

Add custom prefixes:

```python
gw.add_prefix("myplatform", "mp")
alias = gw.generate_alias("myplatform")  # mp-a7k2m3@yourdomain.com
```

## Response Format

```python
{
    "type": "code",           # "code", "link", or "raw"
    "value": "847291",        # the OTP code or link
    "from": "noreply@github.com",
    "subject": "Your GitHub verification code",
    "date": "Mon, 25 Jun 2026 12:00:00 +0000",
    "msg_id": "42"
}
```

## Error Handling

```python
from otp_gateway import OTPGateway, OTPConfig, OTPTimeoutError, IMAPConnectionError

try:
    code = gw.get_otp("test@example.com", timeout=60)
except OTPTimeoutError:
    print("OTP not received in time")
except IMAPConnectionError:
    print("Can't connect to IMAP server")
```

## Tests

```bash
pip install pytest
pytest tests/ -v
```

All tests use mocks — no real IMAP connection needed.

## Requirements

- Python 3.10+
- No external dependencies (stdlib only)

## License

MIT
