Channels
Inbound is unsigned JSON or SES→SNS. Catalog inbound is webhook — cx.handle("email", …), not listen(). Self-host needs no Caspian API key.
Self-host
from_address is the real send identity. bot_token="local" satisfies paperwork; unsigned verify still does not use it.
export EMAIL_FROM='bot@example.com'
export PORT=8080cx.channels.add(
"email",
via="self-host",
from_address=from_address,
bot_token="local",
)
# POST → cx.handle("email", body, headers)await cx.channels.add("email", {
via: "self-host",
from_address,
bot_token: "local",
})
// POST → await cx.handle("email", body, headers)POST simplified inbound JSON the adapter already parses:
curl -sS -X POST http://127.0.0.1:8080/ \
-H 'Content-Type: application/json' \
-d '{"from":"a@b.c","to":"bot@example.com","subject":"x","body":"/help","message_id":"<1>"}'Outbound is SMTP. thread.post answers the inbound mail as a threaded reply (In-Reply-To). thread.send starts a new conversation with no In-Reply-To.
What it can do
Receive, reply, send, media, threading. No buttons.