Channels

iMessage

The adapter speaks an HTTP-JSON bridge (BlueBubbles / Sendblue-style), not Apple. Inbound is signed with X-Relay-Signature (HMAC-SHA256 hex of the body, no prefix). HMAC fail-closes without webhook_secret.

export IMESSAGE_API_KEY='…'           # Bearer on outbound relay calls
export IMESSAGE_WEBHOOK_SECRET='…'    # inbound HMAC
export IMESSAGE_RELAY_URL='https://relay.example'
export PORT=8080

api_key here is the relay Bearer token, not a Caspian API key. Self-host needs no CASPIAN_API_KEY.

cx = Caspian()
cx.channels.add(
    "imessage",
    via="self-host",
    api_key=relay_api_key,
    webhook_secret=webhook_secret,
    relay_url=relay_url,
    bot_token="local",
)
const cx = new Caspian()
await cx.channels.add("imessage", {
  via: "self-host",
  api_key: relayApiKey,
  webhook_secret,
  relay_url,
  bot_token: "local",
})

What it can do

Plans Post, Reply, and SendMedia. No buttons, pin, typing, edit, or delete.