Metadata-Version: 2.4
Name: temail
Version: 0.1.0
Summary: A cross-platform terminal UI for disposable / temporary email providers
Author: 0xbad4
License: MIT License
        
        Copyright (c) 2026 0xbad4
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/0xbad4/temail
Project-URL: Repository, https://github.com/0xbad4/temail
Project-URL: Issues, https://github.com/0xbad4/temail/issues
Project-URL: Changelog, https://github.com/0xbad4/temail/blob/main/CHANGELOG.md
Keywords: temp-mail,disposable-email,tui,mail.tm,1secmail,guerrillamail
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Terminals
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.25
Requires-Dist: windows-curses>=2.3; platform_system == "Windows"
Dynamic: license-file

# temail

A terminal UI for disposable/temporary email providers. Generates a
throwaway address and displays incoming mail without leaving the
terminal.

![SC](.img/screenshot.png)

Top bar: message count, current selection, keybinds. Status line
underneath. Body shows the selected message. Bottom bar shows
`PROVIDER | address`, so the active mailbox is always visible.

## Install

From PyPI:

```bash
pip install temail
```

From source:

```bash
git clone https://github.com/0xbad4/temail
cd temail
pip install -e .
```

Or install just the dependencies and run the module directly:

```bash
pip install -r requirements.txt
python3 -m temail
```

Windows also needs `windows-curses`; it's declared as a
platform-conditional dependency, so both install methods above pull it
in automatically without adding anything to Linux/macOS installs.

## Usage

```bash
temail                          # uses the default provider (mailtm)
temail -p 1secmail              # pick a specific provider
temail --provider guerrillamail
temail -lp                      # list all supported providers
temail --refresh 10             # poll every 10s instead of the default 20s
```

If you installed from source without `pip install -e .`, run
`python3 -m temail` instead of `temail`.

### Keybindings

| Key        | Action                     |
|------------|----------------------------|
| LEFT/RIGHT | switch between messages    |
| UP/DOWN    | scroll a long message body |
| `r`        | force a refresh            |
| `q` / ESC  | quit                       |

The inbox also refreshes automatically in the background on the
interval set by `--refresh` (default 20s), so leaving temail open is
enough to catch new mail as it arrives.

## Supported providers

| Key             | Service                                                                                                            | API key required             |
|-----------------|---------------------------------------------------------------------------------------------------------------------|-------------------------------|
| `mailtm`        | [Mail.tm](https://mail.tm) ([API docs](https://docs.mail.tm))                                                     | No                            |
| `1secmail`      | [1secMail](https://www.1secmail.com) ([API docs](https://www.1secmail.com/api/))                                  | No                            |
| `guerrillamail` | [Guerrilla Mail](https://www.guerrillamail.com) ([API docs](https://www.guerrillamail.com/GuerrillaMailAPI.html)) | No                            |
| `tempmailio`    | [temp-mail.io](https://temp-mail.io) ([API docs](https://docs.temp-mail.io))                                      | Yes - paid account, see below |

All credit for the underlying mail infrastructure goes to these
services; temail is a terminal client built on top of their public
APIs. Please respect each provider's terms of use (rate limits, no
reselling their API, and so on) - see the linked docs.

`tempmailio` is included as a worked example of a key-based provider
(see below), not because it's free - it currently requires an active
paid plan to obtain an API key. Use one of the other three for
something that works out of the box.

### API keys / environment variables

None of the free providers require a key. For providers that do, the
key is always read from an environment variable, never passed as a
CLI argument, and never stored anywhere by this tool.

| Provider     | Env var               | Where to get a key                      |
|--------------|------------------------|-------------------------------------------|
| `tempmailio` | `TEMPMAILIO_API_KEY`  | https://temp-mail.io/profile/api (paid)  |

```bash
export TEMPMAILIO_API_KEY="your-key-here"
temail -p tempmailio
```

`temail -lp` always shows the current list of providers along with
which env var, if any, each one expects.

## Adding your own provider

Providers are plain classes implementing a three-method interface, so
adding a new one requires no changes to the UI.

1. **Create a file** in `src/temail/providers/`, e.g. `myservice.py`:

   ```python
   from __future__ import annotations

   import os
   from typing import List

   import requests

   from .base import Message, TempMailProvider

   API = "https://api.myservice.example"


   class MyServiceProvider(TempMailProvider):
       # shown to the user via --provider/-p and --list-provider
       key = "myservice"
       display_name = "MyService"
       # informational only - listed by --list-provider so users know
       # what to set. Leave empty if no key is needed.
       env_vars: List[str] = ["MYSERVICE_API_KEY"]
       # True if the provider needs a paid/registered key
       requires_key = True

       def __init__(self) -> None:
           super().__init__()
           api_key = os.environ.get("MYSERVICE_API_KEY")
           if self.requires_key and not api_key:
               raise RuntimeError(
                   "MyService requires an API key - set MYSERVICE_API_KEY"
               )
           self.session = requests.Session()
           if api_key:
               self.session.headers.update({"Authorization": f"Bearer {api_key}"})

       def create_inbox(self) -> str:
           """Create or claim a mailbox, set self.address, and return it."""
           r = self.session.post(f"{API}/inboxes", timeout=10)
           r.raise_for_status()
           self.address = r.json()["address"]
           return self.address

       def fetch_messages(self) -> List[Message]:
           """Return the current message list. Leave `body` empty here;
           it is loaded lazily by fetch_body, only for the message that's
           currently on screen."""
           r = self.session.get(f"{API}/inboxes/{self.address}/messages", timeout=10)
           r.raise_for_status()
           return [
               Message(
                   id=str(item["id"]),
                   sender=item["from"],
                   subject=item.get("subject") or "(no subject)",
                   date=item.get("date", ""),
               )
               for item in r.json()
           ]

       def fetch_body(self, message: Message) -> str:
           """Return the full plain-text body for one message."""
           r = self.session.get(f"{API}/messages/{message.id}", timeout=10)
           r.raise_for_status()
           return r.json().get("text", "(empty message)")
   ```

2. **Register it** in `src/temail/providers/__init__.py`:

   ```python
   from .myservice import MyServiceProvider

   PROVIDERS = {
       MailTmProvider.key: MailTmProvider,
       OneSecMailProvider.key: OneSecMailProvider,
       GuerrillaMailProvider.key: GuerrillaMailProvider,
       TempMailIoProvider.key: TempMailIoProvider,
       MyServiceProvider.key: MyServiceProvider,   # include here
   }
   ```

3. **Done.** `temail -p myservice` now works, and `myservice` appears in
   `temail -lp` along with its env var requirement.

Notes:

- The base class lives in `src/temail/providers/base.py`.
  `TempMailProvider` is an ABC with three abstract methods
  (`create_inbox`, `fetch_messages`, `fetch_body`) and a `Message`
  dataclass (`id`, `sender`, `subject`, `date`, `body`, `snippet`).
- Raise on unrecoverable errors (bad or missing key, service down) in
  `__init__` or `create_inbox`; the CLI catches these and prints them
  cleanly before the UI starts.
- Errors raised from `fetch_messages`/`fetch_body` during the run loop
  are also caught and shown in the status line, so a transient network
  blip won't crash the session.
- The layout in `cli.py` (top bar / status / body / bottom bar) is
  provider-agnostic by design, but nothing prevents a provider-specific
  tweak if a given service needs a different shape - `draw` and
  `build_body_lines` are plain functions you're free to extend.

## License

MIT - see [LICENSE](LICENSE).
