lala ✉︎
A Cloudflare Worker template that catches inbound mail and gives your agent a clean queue to drain.
What it is
Point any email address — kirby@postflight.co, support@example.com, whatever — at a lala Worker.
Inbound mail gets parsed, stored as a row in D1, and archived (raw .eml + attachments) to R2.
Your code drains the queue, marks each row processed, and moves on.
sender ─→ Cloudflare Email Routing ─→ lala Worker
│
├─ INSERT row in D1 subject, from, body, attachments
├─ PUT raw.eml in R2 inbox/<id>/raw.eml
└─ PUT attachments in R2 inbox/<id>/<n>-<filename>
Quick install
For consumers (e.g. an agent that needs to read an existing inbox):
curl -fsSL https://lala.postflight.co/install | bash
Installs the lala Python client + CLI, and drops a Claude-Code-style
skill into ~/.claude/skills/lala/.
Or just pip directly:
pip install "git+https://github.com/postflightco/lala.git#subdirectory=py"
Provision a new inbox
One-time setup of an inbox (provisioner side). Run on a host that has wrangler:
npx wrangler login # one-time npx github:postflightco/lala init my-inbox # walks you through
Interactive prompts cover Cloudflare account, zone, and which addresses to route.
Drops a gitignored lala.env in the project source dir with everything
consumers need (account id, D1 id, Worker URL, shared secret).
Read messages
lala count- show queue sizes (processed=0 vs 1)
lala list- print queued messages
lala show 42- full dump of one message
lala download 42- pull raw .eml + attachments to disk
lala mark 42- flip processed=1 with optional
--notes lala tail- poll for new unprocessed messages
Python:
from lala import Inbox
with Inbox.from_env() as inbox:
for msg in inbox.unprocessed(limit=20):
result = handle(msg)
for att in msg.attachments:
bytes_ = inbox.download_attachment(att)
inbox.mark_processed(msg.inbox_id, notes=str(result))
Cron / scheduled drain
*/5 * * * * cd /path/to/openclaw \ && set -a && . /path/to/lala.env && set +a \ && python -m openclaw.drain
State lives in D1, so re-runs are safe — a partially-processed message just stays queued for the next sweep.
What it does NOT do
- Outbound mail. lala is inbound-only. Use your project's existing transactional provider (Resend, Postmark, Cloudflare Email Sending) to reply.
- Webhook delivery. Planned. For now agents poll D1 directly; webhook bridge is a v0.2 add.
Skills for agents
The install script drops a Claude-Code-compatible skill at
~/.claude/skills/lala/SKILL.md. Agents discover it the same way
any other skill is loaded. You can also fetch it directly:
curl -fsSL https://lala.postflight.co/skills/lala/SKILL.md
Reference
- Source: github.com/postflightco/lala
- Python: /py
- Skill: /skills/lala/SKILL.md
- Install: /install