ChatEventRequest chat.event-request@1

Generated at from openvibe-contracts v0.97.0 and openvibe-sdk v0.26.0.

Version
1.0.0
Owner
chat
Visibility
first-party
Status
active
Compatibility
backward
Schema
https://openvibe.network/contracts/chat/event-request.v1.json

chat.event-request@1: what a first-party service hands OpenVibe.Chat's POST /internal/chat/events (chat.event.publish) to push a transient frame to chat sockets: cards, alerts, sounds, media queue state, call invites. Nothing is stored; Chat broadcasts the frame to the target. Applied once per (caller, key): a retry with the same key and body answers the first result, the same key with another body gets 409. Chat also refuses a frame whose JSON is longer than 16384 characters or that has a __proto__, constructor or prototype key; a news card's timestamp must parse as a date.

Fields

FieldTypeRequiredDescriptionConstraints
keystringyesIdempotency key, scoped to the caller and to this route.
  • pattern ^[A-Za-z0-9:._-]+$
  • minLength 1
  • maxLength 160
targetobjectyes
  • no other fields
target.kindenumyesstream: one stream's room; channel: a channel owner's room; owner-streams: every stream of that owner; global: the homepage global chat; all: every socket; user: one person's sockets (call frames only).
  • one of "stream", "channel", "owner-streams", "global", "all", "user"
target.idinteger | nullThe stream, channel owner or user id; required for stream, channel, owner-streams and user, absent or null for global and all.
  • minimum 1
frameobjectyes
frame.typeenumyesThe client frame type. chat is only the transient news card (never saved); a stored line goes through chat.message.send.
  • one of "chat", "system", "donation", "goal-update", "goal-reached", "update", "voice-channels", "alert", "channel-sound", "server_restart", "media_queue_update", "media_now_playing", "redemption", "vibe-coding", "vc-call-invite", "vc-call-response"

Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

Valid: call-invite
{
  "key": "live:call:inv:9f2c",
  "target": {
    "kind": "user",
    "id": 15
  },
  "frame": {
    "type": "vc-call-invite",
    "channelId": "vc-abc",
    "channelName": "Lounge",
    "fromUserId": 3,
    "fromUsername": "host",
    "fromDisplayName": null,
    "fromAvatarUrl": null,
    "createdAt": 1759600000000
  }
}
Valid: donation-card
{
  "key": "live:donation:4812",
  "target": {
    "kind": "stream",
    "id": 42
  },
  "frame": {
    "type": "donation",
    "username": "viewer1",
    "amount": 5,
    "message": "gg"
  }
}
Valid: goal-alert
{
  "key": "live:alert:goal:77:3",
  "target": {
    "kind": "channel",
    "id": 77
  },
  "frame": {
    "type": "alert",
    "streamerId": 77,
    "streamId": null,
    "kind": "goal"
  }
}
Valid: restart-notice
{
  "key": "live:restart:1759600000",
  "target": {
    "kind": "all",
    "id": null
  },
  "frame": {
    "type": "server_restart",
    "message": "Live restarts in a moment."
  }
}
Rejected: alert-not-to-channel
{
  "key": "k2",
  "target": {
    "kind": "stream",
    "id": 42
  },
  "frame": {
    "type": "alert",
    "streamerId": 77,
    "kind": "donation"
  }
}
Rejected: bad-key-characters
{
  "key": "has spaces",
  "target": {
    "kind": "global"
  },
  "frame": {
    "type": "system",
    "message": "hi"
  }
}
Rejected: card-to-a-user
{
  "key": "k4",
  "target": {
    "kind": "user",
    "id": 5
  },
  "frame": {
    "type": "system",
    "message": "hi"
  }
}
Rejected: global-with-id
{
  "key": "k3",
  "target": {
    "kind": "global",
    "id": 5
  },
  "frame": {
    "type": "system",
    "message": "hi"
  }
}
Rejected: missing-key
{
  "target": {
    "kind": "global"
  },
  "frame": {
    "type": "system",
    "message": "hi"
  }
}
Rejected: unknown-frame
{
  "key": "k1",
  "target": {
    "kind": "global"
  },
  "frame": {
    "type": "eval",
    "code": "x"
  }
}

Validate

const contracts = require('openvibe-contracts');
contracts.validate('chat.event-request@1', value);   // { valid, errors: [{ path, message }] }