WuKongIM Docs

Webhooks

Consume message and online-status events securely and idempotently.

Webhooks send committed messages, offline recipients, and online-status changes to one product HTTP endpoint. They are suitable for asynchronous business work, not client message synchronization.

Enable webhooks

Configure wukongim.toml:

[webhook]
http_addr = "https://events.example.com/wukongim"
focus_events = ["msg.notify", "msg.offline", "user.onlinestatus"]
queue_size = 1024
workers = 16
request_timeout = "5s"
retry_max_attempts = 3

The server puts the event name in the query string:

POST https://events.example.com/wukongim?event=msg.notify
Content-Type: application/json

Only HTTP 200 is success. Connection errors, timeouts, and other status codes receive a finite number of attempts within the current in-memory job.

Supported events

EventRequest bodyTypical use
msg.notifyArray of committed messagesAudit, search indexing, asynchronous notification
msg.offlineOne message and a bounded batch of offline UIDsOffline-push candidate calculation
user.onlinestatusArray of compatibility status stringsUID-owner-local, best-effort session hint

Representative msg.notify request:

[
  {
    "header": {"no_persist": 0, "red_dot": 1, "sync_once": 0},
    "setting": 0,
    "expire": 0,
    "message_id": 123456789,
    "message_idstr": "123456789",
    "client_msg_no": "order-20260730-0001",
    "message_seq": 42,
    "from_uid": "system",
    "channel_id": "u1001",
    "channel_type": 1,
    "timestamp": 1785398400,
    "payload": "eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoib3JkZXJfdXBkYXRlIn0="
  }
]

JSON encodes payload as Base64. For small recipient sets, msg.offline uses to_uids. At the compression threshold it may instead use compress: "gzip" with Base64-encoded compress_to_uids; receivers must support both forms.

Each user.onlinestatus item has this form:

{uid}-{device_flag}-{online:0|1}-{session_id}-{device_online_count}-{total_online_count}

The counts cover active sessions on the UID owner's current node only. They are not cluster-global presence and the event stream is neither complete nor ordered. A UID may contain -; parse the final five numeric fields from the right and treat the remaining prefix as the UID.

Reliability boundary

Webhook delivery is bounded and best effort

Queue saturation, process exit, request cancellation, or retry exhaustion can lose an event. The current runtime has no disk-backed webhook outbox or crash replay. A webhook failure does not change an already-successful SENDACK or durable append.

Recommended receiver flow:

  1. Verify network origin and ingress identity.
  2. Limit body size and allowlist the event value.
  3. Persist the raw event and an idempotency key to your own durable queue.
  4. Return HTTP 200 promptly after persistence.
  5. Run business logic asynchronously with a retryable state machine.

Suggested idempotency keys:

  • msg.notify: event + message_id;
  • msg.offline: event + message_id + uid, deduplicated per recipient;
  • user.onlinestatus: deduplicate the complete string and treat it only as a local-session hint, never global online truth.

Security

The current HTTP sender sets only Content-Type: application/json; it does not add a signature or shared-secret header. Build a trusted boundary around it in production:

  • use HTTPS;
  • prefer a private network, service mesh, or egress proxy;
  • enforce mTLS, fixed egress identity, or controlled credentials at the reverse proxy;
  • restrict source IPs and request rates;
  • never expose the callback as an anonymous public write endpoint;
  • avoid logging complete sensitive payloads.

Capacity and failure handling

  • queue_size is the bounded in-memory capacity for each event queue.
  • workers controls concurrent sends per event queue.
  • msg_notify_batch_max_items and its wait setting control message batches.
  • offline_uid_batch_size controls offline UID chunking and compression.
  • retry_max_attempts is the total number of attempts, not additional retries after the first.

If the receiver fails continuously, repair or isolate it instead of growing WuKongIM's memory queues without bound. Critical product state must remain reconstructable from the product database or message history.

On this page