Skill: techwithanirudh/temp-mail (version 1.0.1)

--- name: temp-mail description: Temporary email helper backed by Vortex (vortex.email). Use when needing disposable addresses for signup flows: create a mailbox (random localpart), poll for messages, fetch and clear mailboxes. homepage: https://vortex.skyfall.dev metadata: {"clawdis":{"emoji":"✉️","requires":{"bins":["curl"]}}} --- # temp-mail skill This skill provides a Python CLI script to interact with the hosted Vortex API (GET /emails/{email}, DELETE /emails/{email}/clear). Usage examples (scripts are in scripts/): - create: generates a random localpart and prints an address for the provided domain - fetch: queries the Vortex HTTP API to list messages for an address - poll: wait until messages arrive or timeout - clear: delete all messages for an address Run with uv: `uv run {baseDir}/scripts/temp_mail.py` (script includes shebang and metadata header similar to the hn skill) Examples: ```bash # generate a random address uv run {baseDir}/scripts/temp_mail.py create # fetch messages for an address uv run {baseDir}/scripts/temp_mail.py fetch [REDACTED_SECRET] # poll until messages arrive (timeout 60s) uv run {baseDir}/scripts/temp_mail.py poll [REDACTED_SECRET] --timeout 60 # clear mailbox uv run {baseDir}/scripts/temp_mail.py clear [REDACTED_SECRET] ``` Defaults: - VORTEX_URL: https://vtx-api.skyfall.dev - default domain: skyfall.dev (override with VORTEX_DOMAIN env var) Install ```bash # create a venv and install deps (unix) python -m venv .venv source .venv/bin/activate python -m pip install --upgrade pip python -m pip install -r scripts/requirements.txt # or using uv which creates an ephemeral venv for you, e.g. uv run {baseDir}/scripts/temp_mail.py create ``` Notes: - script uses httpx for requests; rich is optional and omitted from requirements - random username generation mirrors the frontend behavior (lowercase alphanumeric), attempted to replicate falso randUserName behavior - hosted instance includes multiple domains, e.g., dash.dino.icu, skyfall.dev, etc. When creating addresses, choose a domain from that list or let the script use the default

path: scripts/requirements.txt
content: httpx>=0.24.0
# rich is optional, not required for core functionality


path: scripts/temp_mail.py
content: #!/usr/bin/env python3
# /// script
# requires-python = ">=3.11"
# dependencies = ["httpx", "rich"]
# ///
"""temp_mail: simple helper for Vortex hosted API"""

from __future__ import annotations
import argparse
import os
import secrets
import string
import sys
import time
import urllib.parse
import asyncio

from rich import print

VORTEX_URL = os.environ.get("VORTEX_URL", "https://vtx-api.skyfall.dev")
DEFAULT_DOMAIN = os.environ.get("VORTEX_DOMAIN", "skyfall.dev")


def rand_username(length: int = 8) -> str:
    alphabet = string.ascii_lowercase + string.digits
    return ''.join(secrets.choice(alphabet) for _ in range(length))


def make_address(domain: str | None = None, length: int = 8) -> str:
    domain = domain or DEFAULT_DOMAIN
    return f"{rand_username(length)}@{domain}"


async def fetch_messages_async(client, addr: str):
    url = f"{VORTEX_URL}/emails/{urllib.parse.quote(addr, safe='')}"
    headers = {
        "User-Agent": "Mozilla/5.0 (compatible; temp-mail/1.0)",
        "Accept": "application/json, text/plain, */*",
        "Origin": "https://vortex.skyfall.dev",
        "Referer": "https://vortex.skyfall.dev/",
    }
    r = await client.get(url, headers=headers, timeout=10)
    r.raise_for_status()
    return r.json()


async def clear_messages_async(client, addr: str):
    url = f"{VORTEX_URL}/emails/{urllib.parse.quote(addr, safe='')}/clear"
    headers = {"User-Agent": "temp-mail/1.0", "Origin": "https://vortex.skyfall.dev"}
    r = await client.delete(url, headers=headers, timeout=10)
    r.raise_for_status()
    return r.status_code


async def poll_for_messages_async(client, addr: str, timeout: int = 60, interval: int = 3):
    deadline = time.time() + timeout
    while time.time() < deadline:
        try:
            msgs = await fetch_messages_async(client, addr)
            if msgs:
                return msgs
        except Exception:
            # ignore transient errors, continue polling
            pass
        await asyncio.sleep(interval)
    return []


async def main_async(args):
    import httpx
    async with httpx.AsyncClient() as client:
        if args.cmd == "create":
            length = args.length or 8
            addr = make_address(args.domain, length)
            print(addr)
            return

        if args.cmd == "fetch":
            addr = args.address
            msgs = await fetch_messages_async(client, addr)
            print(msgs)
            return

        if args.cmd == "clear":
            addr = args.address
            code = await clear_messages_async(client, addr)
            print(code)
            return

        if args.cmd == "poll":
            addr = args.address
            msgs = await poll_for_messages_async(client, addr, timeout=args.timeout, interval=args.interval)
            print(msgs)
            return


def main():
    p = argparse.ArgumentParser(prog="temp_mail")
    sub = p.add_subparsers(dest="cmd")

    create = sub.add_parser("create")
    create.add_argument("--domain", "-d", default=None)
    create.add_argument("--length", "-l", type=int, default=8)

    fetch = sub.add_parser("fetch")
    fetch.add_argument("address")

    clear = sub.add_parser("clear")
    clear.add_argument("address")

    poll = sub.add_parser("poll")
    poll.add_argument("address")
    poll.add_argument("--timeout", "-t", type=int, default=60)
    poll.add_argument("--interval", "-i", type=int, default=3)

    args = p.parse_args()
    if not args.cmd:
        p.print_help()
        sys.exit(1)

    try:
        asyncio.run(main_async(args))
    except Exception as e:
        print("[red]error:[/red]", e)
        sys.exit(1)


if __name__ == '__main__':
    main()


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)