ウェブフックの型定義

ここではウェブフックの型について説明します。

型の表記は TypeScript で記述します。

基本的なデータ型

// JSON 値を表します。
// 仕様は RFC 8259 に従います。
type JSONValue =
  | null
  | boolean
  | number
  | string
  | JSONValue[]
  | { [key: string]: JSONValue | undefined };

// UnixTime
// 例: 1704067199
type UnixTime = number;

// RFC3339 UTC (マイクロ秒)
// 例: 2023-12-31T23:59:59.999999Z
type Timestamp = string;

// ストリームの種別
type Role = "sendrecv" | "sendonly" | "recvonly";

// サイマルキャストで視聴する映像の種類
type SimulcastRid = "r0" | "r1" | "r2";

// 音声の設定
type Audio =
  | boolean
  | {
      codec_type?: AudioCodecType;
      bit_rate?: number;
      opus_params?: OpusParams;
    };

type OpusParams = {
  channels?: number;
  maxplaybackrate?: number;
  minptime?: number;
  ptime?: number;
  stereo?: boolean;
  sprop_stereo?: boolean;
  useinbandfec?: boolean;
  usedtx?: boolean;
};

// 映像の設定
type Video =
  | boolean
  | {
      codec_type?: VideoCodecType;
      bit_rate?: number;
      // 利用するには sora.conf で signaling_vp9_params = true を設定する必要があります
      vp9_params?: VP9Params;
      // 利用するには sora.conf で signaling_av1_params = true を設定する必要があります
      av1_params?: AV1Params;
      // 利用するには sora.conf で signaling_h264_params = true を設定する必要があります
      h264_params?: H264Params;
      // 利用するには sora.conf で signaling_h265_params = true を設定する必要があります
      h265_params?: H265Params;
    };

type VP9Params = {
  // 0..3
  profile_id?: number;
};

type AV1Params = {
  // 0..2
  profile?: number;
};

type H264Params = {
  profile_level_id?: string;
  // sora.conf で h264_b_frame = true を設定する必要があります
  b_frame?: boolean;
};

type H265Params = {
  level_id?: number;
  // sora.conf で h265_b_frame = true を設定する必要があります
  b_frame?: boolean;
};

// 音声コーデックの種類
type AudioCodecType = "OPUS";

// 映像コーデックの種類
type VideoCodecType = "VP9" | "VP8" | "AV1" | "H264" | "H265";

// DataChannel の方向
type Direction = "sendrecv" | "sendonly" | "recvonly";

// DataChannels
type DataChannel = {
  label: string;
  direction: Direction;
  ordered?: boolean;
  max_packet_life_time?: number;
  max_retransmits?: number;
  protocol?: string;
  compress?: boolean;
};

type ForwardingFilterRuleField = "connection_id" | "client_id" | "kind";

type ForwardingFilterRuleOperator = "is_in" | "is_not_in";

type ForwardingFilterRuleKindValue = "audio" | "video";

type ForwardingFilterRule = {
  field: ForwardingFilterRuleField;
  operator: ForwardingFilterRuleOperator;
  values: [string];
};

type ForwardingFilterAction = "block" | "allow";

type ForwardingFilter = {
  version?: string;
  metadata?: JSONValue;
  action?: ForwardingFilterAction;
  rules: [[ForwardingFilterRule]];
};

type SoraClientType =
  | "Sora JavaScript SDK"
  | "Sora iOS SDK"
  | "Sora Android SDK"
  | "Sora Unity SDK"
  | "Sora C++ SDK"
  | "Sora Python SDK"
  | "Sora C SDK"
  | "OBS-Studio-WHIP"
  | "OBS-Studio-WHEP";

// SoraClient
type SoraClient = {
  environment?: string;
  raw?: string;
  type?: SoraClientType;
  version?: string;
  commit_short?: string;
  libwebrtc?: string;
};

// RTCRtpCodecParameters
// https://www.w3.org/TR/webrtc/#dom-rtcrtpcodecparameters
type SimulcastCodec = {
  // payloadType や channels は省略
  mimeType: string;
  clockRate: number;
  sdpFmtpLine?: string;
};

// RTCRtpEncodingParameters
// https://w3c.github.io/webrtc-pc/#dom-rtcrtpencodingparameters
type SimulcastEncoding = {
  // https://www.w3.org/TR/webrtc/#dom-rtcrtpcodingparameters-rid
  rid: SimulcastRid;
  // https://www.w3.org/TR/webrtc/#dom-rtcrtpencodingparameters-active
  active?: boolean;
  // https://www.w3.org/TR/webrtc/#dom-rtcrtpencodingparameters-scaleresolutiondownby
  scaleResolutionDownBy?: number;
  // https://www.w3.org/TR/webrtc/#dom-rtcrtpencodingparameters-maxbitrate
  maxBitrate?: number;
  // https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-maxframerate
  maxFramerate?: number;
  // https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-adaptiveptime
  adaptivePtime?: boolean;
  // https://www.w3.org/TR/webrtc-svc/#dom-rtcrtpencodingparameters-scalabilitymode
  scalabilityMode?: string;
  // https://w3c.github.io/webrtc-extensions/#rtcrtpencodingparameters
  codec?: SimulcastCodec;
};

完全な型定義

認証ウェブフック

// 認証ウェブフックリクエスト
type AuthWebhookRequest = {
  timestamp: Timestamp;
  id: string;

  version: string;
  label: string;
  node_name: string;

  role: Role;
  channel_id: string;
  client_id?: string;
  bundle_id?: string;
  connection_id: string;

  multistream: boolean;
  simulcast: boolean;
  simulcast_rid?: SimulcastRid;
  simulcast_multicodec?: boolean;
  spotlight: boolean;
  spotlight_number?: number;
  spotlight_focus_rid?: "none" | SimulcastRid;
  spotlight_unfocus_rid?: "none" | SimulcastRid;

  audio: boolean;
  audio_codec_type?: string;
  audio_bit_rate?: number;

  video: Video;
  video_codec_type?: VideoCodecType;
  video_bit_rate?: number;
  video_vp9_params?: VP9Params;
  video_av1_params?: AV1Params;
  video_h264_params?: H264Params;
  video_h265_params?: H265Params;

  data_channel_signaling: boolean;
  ignore_disconnect_websocket: boolean;
  data_channels?: [DataChannel];

  forwarding_filter?: ForwardingFilter;

  auth_metadata?: JSONValue;
  metadata?: JSONValue;

  whip?: boolean;
  whep?: boolean;

  sora_client?: SoraClient;

  channel_connections: number;
  channel_sendrecv_connections: number;
  channel_sendonly_connections: number;
  channel_recvonly_connections: number;

  e2ee: boolean;
};

// type: offer の encodings に含まれる codec 払い出される値とは異なるので注意
type SimulcastCodecs = [
  {
    rid: SimulcastRid;
    codec_type: VideoCodecType;
    codec_params?: VP9Params | AV1Params | H264Params | H265Params;
  },
];

// 認証ウェブフック成功レスポンス
// 200 OK で返してください
type AuthWebhookAcceptResponse = {
  allowed: true;

  audio?: boolean;
  audio_codec_type?: string;
  audio_bit_rate?: number;
  audio_opus_params?: OpusParams;

  video?: boolean;
  video_codec_type?: string;
  video_bit_rate?: number;

  video_vp9_params?: VP9Params;
  video_av1_params?: AV1Params;
  video_h264_params?: H264Params;
  video_h265_params?: H265Params;

  client_id?: string;
  bundle_id?: string;

  simulcast?: boolean;
  simulcast_rid?: SimulcastRid;
  simulcast_encodings?: [SimulcastEncoding];
  simulcast_multicodec?: boolean;
  simulcast_codecs?: SimulcastCodecs;

  spotlight?: boolean;
  // 非推奨です
  // session.created の戻り値をご利用ください
  spotlight_number?: number;
  spotlight_focus_rid?: "none" | SimulcastRid;
  spotlight_unfocus_rid?: "none" | SimulcastRid;
  spotlight_encodings?: [SimulcastEncoding];

  data_channel_signaling?: boolean;
  ignore_disconnect_websocket?: boolean;
  data_channels?: [DataChannel];

  forwarding_filter?: ForwardingFilter;
  
  connection_lifetime?: number;

  cluster_affinity?: string;

  metadata?: JSONValue;
  event_metadata?: JSONValue;

  signaling_notify?: boolean;
  signaling_notify_metadata?: JSONValue;
  signaling_notify_metadata_ext?: JSONValue;

  recording_block?: boolean;

  ipv4_address?: string;
  ipv6_address?: string;

  turn_fqdn?: string;
  turn_tls_fqdn?: string;

  playout_delay_min_delay?: number;
  playout_delay_max_delay?: number;

  // user_agent_stats は 2025 年 6 月リリース予定の Sora にて廃止予定です
  user_agent_stats?: boolean;
  // user_agent_stats の代わりに rtc_stats をご利用ください
  rtc_stats?: boolean;

  stats_exporter?: boolean;

  audio_streaming_language_code?: string;

  turn_tcp_only?: boolean;
  turn_tls_only?: boolean;

  rtp_packet_loss_simulator_incoming?: number;
  rtp_packet_loss_simulator_outgoing?: number;
};

// 認証ウェブフック失敗レスポンス
// 200 OK で返してください
type AuthWebhookRejectResponse = {
  allowed: false;
  reason: string;
};

セッションウェブフック

// セッションウェブフック生成リクエスト
type SessionWebhookCreatedRequest = {
  type: "session.created";

  timestamp: Timestamp;
  id: string;

  version: string;
  label: string;
  node_name: string;

  // cluster = true の時のみ含まれる
  external_signaling_url?: string;

  channel_id: string;
  session_id: string;

  multistream: boolean;
  spotlight: boolean;

  created_time: UnixTime;
  created_timestamp: Timestamp;
};

// 200 OK で返してください
type SessionWebhookCreatedResponse = {
  // 最大 2,592,000 秒 (30 日) まで指定できます
  session_lifetime?: number;
  session_metadata?: JSONValue;

  spotlight_number?: number;

  forwarding_filter?: ForwardingFilter;

  audio_streaming?: boolean;
  audio_streaming_auto?: boolean;

  recording?: boolean;
  recording_metadata?: JSONValue;
  recording_expire_time?: number;
  recording_split_only?: boolean;
  recording_split_duration?: number;
};

// セッションウェブフック更新リクエスト
type SessionWebhookUpdatedRequest = {
  type: "session.updated";

  timestamp: Timestamp;
  id: string;

  version: string;
  label: string;
  node_name: string;

  // cluster = true の時のみ含まれる
  external_signaling_url?: string;

  channel_id: string;
  session_id: string;

  multistream: boolean;
  spotlight: boolean;
  spotlight_number: number;

  created_time: number;
  created_timestamp: string;

  max_connections: number;
  total_connections: number;

  session_metadata?: JSONValue;

  // 録画機能 (セッション単位) が有効な時のみ
  recording?: SessionRecording;

  // クラスター有効の場合は含まれない
  connections?: [SessionConnection];
};

type SessionWebhookDestroyedReason =
  | "normal"
  | "validation_error"
  | "webhook_error"
  | "terminated_api"
  | "lifetime_expired"
  | "abort";

// セッションウェブフック破棄リクエスト
type SessionWebhookDestroyedRequest = {
  type: "session.destroyed";

  timestamp: Timestamp;
  id: string;

  version: string;
  label: string;
  node_name: string;

  // cluster = true の時のみ含まれる
  external_signaling_url?: string;

  channel_id: string;
  session_id: string;

  multistream: boolean;
  spotlight: boolean;
  spotlight_number?: number;

  created_time: number;
  created_timestamp: string;

  destroyed_time: number;
  destroyed_timestamp: string;

  reason: SessionWebhookDestroyedReason;

  max_connections: number;
  total_connections: number;

  session_metadata?: JSONValue;

  // クラスター有効の場合は含まれない
  connections?: [SessionConnection];
};

type SessionRecording = {
  recording_id: string;
  // 未指定の場合は含まれない
  recording_metadata?: JSONValue;
  // 未指定の場合は含まれない
  expire_time?: number;
  // expire_time が未指定の場合は含まれない
  expired_at?: number;
  split_only: boolean;
  split_duration?: number;
  start_timestamp: string;
};

type SessionConnection = {
  role: Role;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  simulcast: boolean;

  audio: boolean;
  audio_codec_type?: string;
  audio_bit_rate?: number;

  video: boolean;
  video_codec_type?: string;
  video_bit_rate?: number;
  video_vp9_params?: VP9Params;
  video_av1_params?: AV1Params;
  video_h264_params?: H264Params;
  video_h265_params?: H265Params;

  // 認証は成功したが WebRTC が確立できなかった場合、 null が入ってくる
  connection_created_timestamp: Timestamp | null;
  // 認証は成功したが WebRTC が確立できなかった場合、 null が入ってくる
  connection_destroyed_timestamp: Timestamp | null;

  event_metadata?: JSONValue;
};

// セッションウェブフック全破棄リクエスト
type SessionWebhookVanishedRequest = {
  type: "session.vanished";

  timestamp: Timestamp;
  id: string;

  version: string;
  label: string;
  node_name: string;

  // cluster = true の時のみ含まれる
  external_signaling_url?: string;
};

セッションウェブフック (録画)

type SessionWebhookRecordingStartedRequest = {
  type: "recording.started";

  timestamp: Timestamp;
  id: string;

  version: string;
  label: string;
  node_name: string;

  channel_id: string;
  session_id: string;
  session_metadata?: JSONValue;

  data: SessionWebhookRecordingStartedData;
};

type SessionWebhookRecordingStartedData = {
  channel_id: string;
  session_id: string;
  recording_id: string;
  recording_metadata?: JSONValue;
  split_only: boolean;
  split_duration?: number;
  created_at: number;
  expire_time?: number;
  expired_at?: number;
  start_timestamp: Timestamp;
};

type SessionWebhookRecordingReportRequest = {
  type: "recording.report";

  timestamp: Timestamp;
  id: string;

  version: string;
  label: string;
  node_name: string;

  channel_id: string;
  session_id: string;
  session_metadata?: JSONValue;

  data: SessionWebhookRecordingReportData;
};

type SessionWebhookRecordingReportData = {
  channel_id: string;
  session_id: string;
  recording_id: string;
  recording_metadata?: JSONValue;
  split_only: boolean;
  split_duration?: number;
  created_at: number;
  expire_time?: number;
  expired_at?: number;
  file_path: string;
  filename: string;
  file_written: boolean;
  start_timestamp: Timestamp;
  stop_timestamp: Timestamp;
  archives: [SessionWebhookRecordingReportArchive];
  failed_archives: [SessionWebhookRecordingReportFailedArchive];
};

type SessionWebhookRecordingReportArchive = {
  label: string;
  node_name: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;
  file_path?: string;
  filename?: string;
  metadata_file_path?: string;
  metadata_filename?: string;
  start_time_offset: number;
  start_timestamp: Timestamp;
  stop_time_offset: number;
  stop_timestamp: Timestamp;
  size?: number;
  split_last_index?: string;
};

type SessionWebhookRecordingReportFailedArchive = {
  label: string;
  node_name: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;
};

セッションウェブフック (音声ストリーミング)

// セッションウェブフック音声ストリーミング開始リクエスト
type SessionWebhookAudioStreamingStartedRequest = {
  type: "audio-streaming.started";

  timestamp: Timestamp;
  id: string;

  version: string;
  label: string;
  node_name: string;

  // cluster = true の時のみ含まれる
  external_signaling_url?: string;

  channel_id: string;
  session_id: string;

  multistream: boolean;
  spotlight: boolean;

  created_time: UnixTime;
  created_timestamp: Timestamp;

  session_metadata?: JSONValue;

  data: AudioStreamingStartedData;
};

type AudioStreamingStartedData = {
  audio_streaming_auto: boolean;
  audio_streaming_started_timestamp: string;
};

// セッションウェブフック音声ストリーミング停止リクエスト
type SessionWebhookAudioStreamingStoppedRequest = {
  type: "audio-streaming.stopped";

  timestamp: string;
  id: string;

  version: string;
  label: string;
  node_name: string;

  // cluster = true の時のみ含まれる
  external_signaling_url?: string;

  channel_id: string;
  session_id: string;

  multistream: boolean;
  spotlight: boolean;

  created_time: UnixTime;
  created_timestamp: Timestamp;

  session_metadata?: JSONValue;

  data: AudioStreamingStoppedData;
};

type AudioStreamingStoppedData = {
  audio_streaming_auto: boolean;
  audio_streaming_started_timestamp: Timestamp;
  audio_streaming_stopped_timestamp: Timestamp;
};

イベントウェブフック

// イベントコネクション生成ウェブフックリクエスト
type EventWebhookConnectionCreatedRequest = {
  type: "connection.created";

  timestamp: Timestamp;
  id: string;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  role: Role;
  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  multistream: boolean;
  simulcast: boolean;
  simulcast_multicodec?: boolean;
  spotlight: boolean;

  event_metadata?: JSONValue;

  data: EventWebhookConnectionCreatedData;
};

// イベントコネクション生成ウェブフックデータ
type EventWebhookConnectionCreatedData = {
  minutes: number;

  audio: boolean;
  audio_codec_type?: AudioCodecType;
  audio_bit_rate?: number;

  video: boolean;
  video_codec_type?: VideoCodecType;
  video_bit_rate?: number;
  video_vp9_params?: VP9Params;
  video_av1_params?: AV1Params;
  video_h264_params?: H264Params;
  video_h265_params?: H265Params;

  recording_block: boolean;

  channel_connections: number;
  channel_sendrecv_connections: number;
  channel_sendonly_connections: number;
  channel_recvonly_connections: number;

  turn_transport_type: "udp" | "tcp";

  created_time: UnixTime;
  created_timestamp: Timestamp;

  ice_connection_state: IceConnectionState;

  total_received_bytes: number;
  total_sent_bytes: number;
};

// イベントコネクション更新ウェブフックリクエスト
type EventWebhookConnectionUpdatedRequest = {
  type: "connection.updated";

  timestamp: Timestamp;
  id: string;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  role: Role;
  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  multistream: boolean;
  simulcast: boolean;
  simulcast_multicodec?: boolean;
  spotlight: boolean;

  event_metadata?: JSONValue;

  data: EventWebhookConnectionUpdatedData;
};

// イベントコネクション更新ウェブフックデータ
type EventWebhookConnectionUpdatedData = {
  minutes: number;

  audio: boolean;
  audio_codec_type?: AudioCodecType;
  audio_bit_rate?: number;

  video: boolean;
  video_codec_type?: VideoCodecType;
  video_bit_rate?: number;
  video_vp9_params?: VP9Params;
  video_av1_params?: AV1Params;
  video_h264_params?: H264Params;
  video_h265_params?: H265Params;

  recording_block: boolean;

  channel_connections: number;
  channel_sendrecv_connections: number;
  channel_sendonly_connections: number;
  channel_recvonly_connections: number;

  turn_transport_type: "udp" | "tcp";

  created_time: UnixTime;
  created_timestamp: Timestamp;

  ice_connection_state: IceConnectionState;

  total_received_bytes: number;
  total_sent_bytes: number;
};

// イベントコネクション破棄ウェブフックリクエスト
type EventWebhookConnectionDestroyedRequest = {
  type: "connection.destroyed";

  timestamp: Timestamp;
  id: string;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  role: Role;
  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  multistream: boolean;
  simulcast: boolean;
  simulcast_multicodec?: boolean;
  spotlight: boolean;

  event_metadata?: JSONValue;

  data: EventWebhookConnectionDestroyedData;
};

type ConnectionDestroyedReason =
  // legacy_event_webhook_connection_destroyed_reason = true の場合のみ null が入ってくる場合があります
  | null
  | "normal"
  | "disconnected_api"
  | "session_destroyed"
  | "lifetime_expired";

// イベントコネクション破棄ウェブフックデータ
type EventWebhookConnectionDestroyedData = {
  minutes: number;

  audio: boolean;
  audio_codec_type?: AudioCodecType;
  audio_bit_rate?: number;

  video: boolean;
  video_codec_type?: VideoCodecType;
  video_bit_rate?: number;
  video_vp9_params?: VP9Params;
  video_av1_params?: AV1Params;
  video_h264_params?: H264Params;
  video_h265_params?: H265Params;

  recording_block: boolean;

  channel_connections: number;
  channel_sendrecv_connections: number;
  channel_sendonly_connections: number;
  channel_recvonly_connections: number;

  turn_transport_type: "udp" | "tcp";

  created_time: UnixTime;
  created_timestamp: Timestamp;

  destroyed_time: UnixTime;
  destroyed_timestamp: Timestamp;

  ice_connection_state: IceConnectionState;

  total_received_bytes: number;
  total_sent_bytes: number;

  reason?: ConnectionDestroyedReason;
  disconnect_api_reason?: string;
  type_disconnect_reason?: string;
};

type EventWebhookConnectionFailedRequest = {
  type: "connection.failed";

  timestamp: Timestamp;
  id: string;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  role?: Role;
  channel_id?: string;
  client_id?: string;
  bundle_id?: string;
  connection_id: string;

  multistream: boolean;
  simulcast: boolean;
  spotlight: boolean;

  data: EventWebhookConnectionFailedData;
};

type EventWebhookConnectionFailedData = {
  message: string;

  channel_connections: number;
  channel_sendrecv_connections: number;
  channel_sendonly_connections: number;
  channel_recvonly_connections: number;

  total_received_bytes: number;
  total_sent_bytes: number;
};

type IceConnectionState = {
  total_checking_duration_ms: number;
  total_disconnected_duration_ms: number;
};

イベントウェブフック (録画)

type EventWebhookRecordingStartedRequest = {
  type: "recording.started";

  timestamp: Timestamp;
  id: string;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  channel_id: string;

  data: EventWebhookRecordingStartedData;
};

type EventWebhookRecordingStartedData = {
  channel_id: string;
  recording_id: string;
  metadata?: JSONValue;
  split_only: boolean;
  split_duration?: number;
  created_at: number;
  expire_time: number;
  expired_at: number;
  start_timestamp: Timestamp;
};

type EventWebhookRecordingReportRequest = {
  type: "recording.report";

  timestamp: Timestamp;
  id: string;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  channel_id: string;

  data: EventWebhookRecordingReportData;
};

type EventWebhookRecordingReportData = {
  channel_id: string;
  recording_id: string;
  metadata?: JSONValue;
  split_only: boolean;
  split_duration?: number;
  created_at: number;
  expire_time: number;
  expired_at: number;
  file_path: string;
  filename: string;
  file_written: boolean;
  start_timestamp: Timestamp;
  stop_timestamp: Timestamp;
  archives: [EventWebhookRecordingReportArchive];
  failed_archives: [EventWebhookRecordingReportFailedArchive];
};

type EventWebhookRecordingReportArchive = {
  label: string;
  node_name: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;
  file_path?: string;
  filename?: string;
  metadata_file_path?: string;
  metadata_filename?: string;
  start_time_offset: number;
  start_timestamp: Timestamp;
  stop_time_offset: number;
  stop_timestamp: Timestamp;
  size?: number;
  split_last_index?: string;
};

type EventWebhookRecordingReportFailedArchive = {
  label: string;
  node_name: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;
};

type EventWebhookArchiveStartedRequest = {
  type: "archive.started";

  timestamp: Timestamp;
  id: string;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  event_metadata?: JSONValue;

  data: EventWebhookArchiveStartedData;
};

type EventWebhookArchiveStartedData = {
  recording_id: string;

  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  created_at: number;

  audio: boolean;
  audio_codec_type?: string;
  audio_bit_rate?: number;

  video: boolean;
  video_codec_type?: string;
  video_bit_rate?: number;
  video_vp9_params?: VP9Params;
  video_av1_params?: AV1Params;
  video_h264_params?: H264Params;

  start_time: UnixTime;
  start_time_offset: number;
  start_timestamp: Timestamp;
};

type EventWebhookArchiveAvailableRequest = {
  type: "archive.available";

  timestamp: Timestamp;
  id: string;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  event_metadata?: JSONValue;

  data: EventWebhookArchiveAvailableData;
};

type EventWebhookArchiveAvailableData = {
  recording_id: string;

  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  file_path: string;
  filename: string;

  metadata_file_path: string;
  metadata_filename: string;

  size: number;

  created_at: number;

  audio: boolean;
  audio_codec_type?: string;
  audio_bit_rate?: number;

  video: boolean;
  video_codec_type?: string;
  video_bit_rate?: number;
  video_height?: number;
  video_width?: number;
  video_vp9_params?: VP9Params;
  video_av1_params?: AV1Params;
  video_h264_params?: H264Params;

  start_time: UnixTime;
  start_time_offset: number;
  start_timestamp: Timestamp;

  stop_time: UnixTime;
  stop_time_offset: number;
  stop_timestamp: Timestamp;

  stats: JSONValue;
};

type EventWebhookSplitArchiveAvailableRequest = {
  type: "split-archive.available";

  id: string;
  timestamp: Timestamp;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  event_metadata?: JSONValue;

  data: EventWebhookSplitArchiveAvailableData;
};

type EventWebhookSplitArchiveAvailableData = {
  recording_id: string;

  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  split_index: string;

  file_path: string;
  filename: string;

  metadata_file_path: string;
  metadata_filename: string;

  size: number;

  created_at: number;

  audio: boolean;
  audio_codec_type?: string;
  audio_bit_rate?: number;

  video: boolean;
  video_codec_type?: string;
  video_bit_rate?: number;
  video_height?: number;
  video_width?: number;
  video_vp9_params?: VP9Params;
  video_av1_params?: AV1Params;
  video_h264_params?: H264Params;

  start_time: number;
  start_time_offset: number;
  start_timestamp: Timestamp;

  stop_time: UnixTime;
  stop_time_offset: number;
  stop_timestamp: Timestamp;

  stats: JSONValue;
};

type EventWebhookSplitArchiveEndRequest = {
  type: "split-archive.end";

  id: string;
  timestamp: Timestamp;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  event_metadata?: JSONValue;

  data: EventWebhookSplitArchiveEndData;
};

type EventWebhookSplitArchiveEndData = {
  split_last_index: string;

  recording_id: string;

  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  file_path: string;
  filename: string;

  audio: boolean;
  audio_codec_type?: string;
  audio_bit_rate?: number;

  video: Video;
  video_codec_type?: string;
  video_bit_rate?: number;
  video_vp9_params?: VP9Params;
  video_av1_params?: AV1Params;
  video_h264_params?: H264Params;

  start_time: UnixTime;
  start_time_offset: number;
  start_timestamp: Timestamp;

  stop_time: UnixTime;
  stop_time_offset: number;
  stop_timestamp: Timestamp;

  stats: JSONValue;
};

type EventWebhookArchiveFailedRequest = {
  type: "archive.failed";

  timestamp: Timestamp;
  id: string;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  event_metadata?: JSONValue;

  data: EventWebhookSplitArchiveFailedData;
};

type EventWebhookSplitArchiveFailedData = {
  recording_id: string;

  session_id: string;

  split: boolean;
  split_only: boolean;

  file_path?: string;
  filename?: string;

  split_index?: string;
  split_file_path?: string;
  split_filename?: string;

  audio: boolean;
  audio_codec_type?: string;
  audio_bit_rate?: number;

  video: boolean;
  video_codec_type?: string;
  video_bit_rate?: number;
  video_height?: number;
  video_width?: number;
  video_vp9_params?: VP9Params;
  video_av1_params?: AV1Params;
  video_h264_params?: H264Params;

  start_time: UnixTime;
  start_timestamp: Timestamp;

  stop_time: UnixTime;
  stop_timestamp: Timestamp;

  stats: JSONValue;
};

イベントウェブフック (スポットライト)

type EventWebhookSpotlightFocusedRequest = {
  type: "spotlight.focused";

  timestamp: Timestamp;
  id: string;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  channel_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  spotlight_number: number;

  fixed: boolean;

  audio: boolean;
  video: boolean;
};

type EventWebhookSpotlightUnfocusedRequest = {
  type: "spotlight.unfocused";

  timestamp: Timestamp;
  id: string;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  channel_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  spotlight_number: number;

  audio: boolean;
  video: boolean;
};

イベントウェブフック (音声ストリーミング失敗)

type EventWebhookAudioStreamingFailedRequest = {
  type: "audio-streaming.failed";

  timestamp: Timestamp;
  id: string;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  role: Role;

  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  multistream: boolean;
  simulcast: boolean;
  spotlight: boolean;

  data: {
    failed_reason: string;
  };
};

統計ウェブフック

// コネクション RTC 統計情報ウェブフックリクエスト
type StatsWebhookConnectionRtcRequest = {
  type: "connection.rtc";

  timestamp: string;
  id: string;

  log_written: boolean;

  version: string;
  label: string;
  node_name: string;

  role: Role;
  channel_id: string;
  session_id: string;
  client_id: string;
  bundle_id: string;
  connection_id: string;

  multistream: boolean;
  simulcast: boolean;
  spotlight: boolean;

  // https://www.w3.org/TR/webrtc-stats/
  stats?: [object];
};
© Copyright 2024, Shiguredo Inc Created using Sphinx 8.1.3