Skip to content

Documentation Sync

This page is auto-generated from plugins/adapters/satori/README.md. Please edit the in-package README and then run pnpm sync:adapter-docs.

@zhin.js/adapter-satori

Zhin.js Satori chat protocol adapter (Plugin Runtime). Supports forward WebSocket client (connection: ws) and Webhook inbound (connection: webhook, POST route via httpHostToken).

Do not confuse with @zhin.js/satori: the latter is a Vercel satori SVG image rendering toolkit (packages/toolkit/satori), used to render HTML/React as SVG. It is not a chat protocol. See @zhin.js/satori README.

Features

  • Satori protocol compatible
  • Forward WebSocket (connection: ws, default): the application connects to the SDK at ws(s)://baseUrl, IDENTIFY + heartbeat
  • Bearer Token authentication (API and WS IDENTIFY)
  • Channel / private chat message send/receive, message id format is channelId:messageId
  • Convention-based defineAdapter / definePlugin (no usePlugin needed)
  • Webhook (connection: webhook): the SDK sends POST with Satori-Opcode: 0 events to path

Installation

bash
pnpm add @zhin.js/adapter-satori

Plugin Runtime

  • @zhin.js/adapter — convention-based adapters/satori.ts (defineAdapter)
  • @zhin.js/coremessageGatewayToken inbound/outbound
  • @zhin.js/plugin-runtimeplugin.ts (definePlugin)
  • @zhin.js/host-http — Webhook mode requires httpHostToken to register POST route
  • Configuration goes to plugins.<instanceKey> via the plugin's schema.json (baseUrl / token / ...)

Inbound: gateway.receive({ adapter, target: channelId, content: text, sender, id, metadata }) Outbound: send({ target: channelId, payload }) -> Satori message.create (payload is rendered by gateway/core; no segment-mapper)

Inbound metadata.mentioned: set to true when the id of an <at id="..."/> element in the message content equals the login selfId (from READY/event login.user.id).

Minimal Configuration

yaml
# zhin.config.yml (Plugin Runtime)
plugins:
  satori:
    connection: ws
    heartbeat_interval: 10000
    endpoints:
      - name: satori-bot
        baseUrl: "http://127.0.0.1:5140"
        token: "${SATORI_TOKEN}"

The root plugin zhin.plugins (or project graph) must reference @zhin.js/adapter-satori (instanceKey: satori).

Optional Fields

FieldDescription
heartbeat_intervalWS PING interval (milliseconds), default 10000
tokenBearer; can also be set via the SATORI_TOKEN environment variable

Webhook

yaml
plugins:
  satori:
    connection: webhook
    endpoints:
      - name: satori-bot
        baseUrl: "http://127.0.0.1:5140"
        path: "/satori/webhook"
        token: "${SATORI_TOKEN}"

The SDK sends POST requests to path, with header Satori-Opcode: 0 indicating events; the adapter obtains the platform / userId from the login in the first event for subsequent API calls.

Authentication

  • API: request header Authorization: Bearer {token}
  • WebSocket: token is passed in the IDENTIFY body

Message ID and Recall

  • Message id format is channelId:messageId, making it easy to parse when sending messages or recalling.
  • Recall requires channel_id + message_id; the adapter parses them from the format described above.

AI Tools

See agent/skills/satori.md for skill documentation.

Protocol Documentation