ウェブフックの型定義

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

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

基本的なデータ型

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

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

// サイマルキャストで配信する映像の種類
type SimulcastRid = 'r0' | 'r1' | 'r2'

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

type LyraParams = {
  version?: string
  bitrate?: number
}

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
    }

    // 音声コーデックの種類
type AudioCodecType = 'OPUS' | 'LYRA'

// 映像コーデックの種類
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
}

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

ウェブフック共通のデータ型

// ウェブフックで通知される音声の設定
type WebhookAudio =
  | boolean
  | {
      codec_type?: AudioCodecType
      bit_rate?: number
    }

完全な型定義

認証ウェブフック

// 認証ウェブフックリクエスト
type AuthWebhookRequest = {
  timestamp: 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
  // Sora 2023.1 で simulcast が false の場合は入ってこなくなります
  simulcast_rid: SimulcastRid
  spotlight: boolean

  audio: WebhookAudio
  audio_codec_type?: string
  audio_bit_rate?: number

  video: Video
  video_codec_type?: string
  video_bit_rate?: number

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

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

  e2ee: boolean
  sora_client?: SoraClient

  auth_metadata?: JSONValue
  metadata?: JSONValue
}

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

  audio?: Audio
  audio_codec_type?: string
  audio_bit_rate?: number
  audio_lyra_params?: LyraParams
  audio_opus_params?: OpusParams

  video?: Video
  video_codec_type?: string
  video_bit_rate?: number

  bundle_id?: string
  client_id?: string

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

  simulcast?: boolean
  simulcast_rid?: SimulcastRid
  simulcast_encodings?: [SimulcastEncoding]

  spotlight?: boolean
  spotlight_number?: number
  spotlight_focus_rid?: 'none' | SimulcastRid
  spotlight_unfocus_rid?: 'none' | SimulcastRid
  spotlight_encodings?: [SimulcastEncoding]

  turn_fqdn?: string
  turn_tls_fqdn?: string

  signaling_notify?: boolean
  signaling_notify_metadata?: JSONValue

  h264_profile_level_id?: string

  user_agent_stats?: boolean

  metadata?: JSONValue
  event_metadata?: JSONValue

  ipv4_address?: string
  ipv6_address?: string

  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
}

type SimulcastEncoding = {
  rid: SimulcastRid
  active?: boolean
  scaleResolutionDownBy?: number
  maxBitrate?: number
  maxFramerate?: number
  adaptivePtime?: boolean
}

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

セッションウェブフック

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

  timestamp: string
  id: string

  version: string
  label: string
  node_name: string

  channel_id: string
  session_id: string

  multistream: boolean
  spotlight: boolean

  created_time: number
  created_timestamp: string
}

// 200 OK で返していください
type SessionWebhookCreatedResponse = {
  session_metadata?: JSONValue
  audio_streaming?: boolean
}

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

  timestamp: string
  id: string

  version: string
  label: string
  node_name: string

  channel_id: string
  session_id: string

  multistream: boolean
  spotlight: boolean

  created_time: number
  created_timestamp: string

  destroyed_time: number
  destroyed_timestamp: string

  max_connections: number
  total_connections: number

  session_metadata?: JSONValue

  connections?: [SessionConnection]
}

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

  simulcast: boolean

  audio: WebhookAudio
  audio_codec_type?: string
  audio_bit_rate?: number

  video: Video
  video_codec_type?: string
  video_bit_rate?: number

  connection_created_timestamp: string
  connection_destroyed_timestamp: string

  event_metadata?: JSONValue
}

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

  timestamp: string
  id: string

  version: string
  label: string
  node_name: string
}

イベントウェブフック

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

  timestamp: string
  id: string

  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

  event_metadata?: JSONValue

  data: EventWebhookConnectionCreatedData
}

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

  audio: WebhookAudio
  audio_codec_type?: AudioCodecType
  audio_bit_rate?: number

  video: Video
  video_codec_type?: VideoCodecType
  video_bit_rate?: number

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

  turn_transport_type: 'udp' | 'tcp'

  created_time: number
  created_timestamp: string

  total_received_bytes: number
  total_sent_bytes: number
}

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

  timestamp: string
  id: string

  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

  event_metadata?: JSONValue

  data: EventWebhookConnectionUpdatedData
}

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

  audio: WebhookAudio
  audio_codec_type?: AudioCodecType
  audio_bit_rate?: number

  video: Video
  video_codec_type?: VideoCodecType
  video_bit_rate?: number

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

  turn_transport_type: 'udp' | 'tcp'

  created_time: number
  created_timestamp: string

  total_received_bytes: number
  total_sent_bytes: number
}

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

  timestamp: string
  id: string

  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

  event_metadata?: JSONValue

  data: EventWebhookConnectionDestroyedData
}

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

  audio: WebhookAudio
  audio_codec_type?: AudioCodecType
  audio_bit_rate?: number

  video: Video
  video_codec_type?: VideoCodecType
  video_bit_rate?: number

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

  turn_transport_type: 'udp' | 'tcp'

  created_time: number
  created_timestamp: string

  destroyed_time: number
  destroyed_timestamp: string

  total_received_bytes: number
  total_sent_bytes: number

  reason?: string
  disconnect_api_reason?: string
  type_disconnect_reason?: string
}

type EventWebhookConnectionFailedRequest = {
  type: 'connection.failed'

  timestamp: string
  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
  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 EventWebhookRecordingStartedRequest = {
  type: 'recording.started'

  timestamp: string
  id: string

  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
  created_at: number
  expire_time: number
  expired_at: number
}

type EventWebhookRecordingReportRequest = {
  type: 'recording.report'

  timestamp: string
  id: string

  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
  start_timestamp: string
  stop_timestamp: string
  archives: [EventWebhookRecordingReportArchive]
}

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: string
  stop_time_offset: number
  stop_timestamp: string
  size?: number
  split_last_index?: string
}

type EventWebhookArchiveStartedRequest = {
  type: 'archive.started'

  timestamp: string
  id: string

  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 ArchiveVideo =
  | boolean
  | {
      codec_type?: VideoCodecType
      bit_rate?: number
      height?: number
      width?: number
    }

type EventWebhookArchiveStartedData = {
  recording_id: string

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

  created_at: number

  audio: WebhookAudio
  audio_codec_type?: string
  audio_bit_rate?: number

  video: Video
  video_codec_type?: string
  video_bit_rate?: number

  start_time: number
  start_time_offset: number
  start_timestamp: string
}

type EventWebhookArchiveAvailableRequest = {
  type: 'archive.available'

  timestamp: string
  id: string

  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: WebhookAudio
  audio_codec_type?: string
  audio_bit_rate?: number

  video: ArchiveVideo
  video_codec_type?: string
  video_bit_rate?: number
  video_height?: number
  video_width?: number

  start_time: number
  start_time_offset: number
  start_timestamp: string

  stop_time: number
  stop_time_offset: number
  stop_timestamp: string

  stats: JSONValue
}

type EventWebhookSplitArchiveAvailableRequest = {
  type: 'split-archive.available'

  id: string
  timestamp: string

  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: WebhookAudio
  audio_codec_type?: string
  audio_bit_rate?: number

  video: ArchiveVideo
  video_codec_type?: string
  video_bit_rate?: number
  video_height?: number
  video_width?: number

  start_time: number
  start_time_offset: number
  start_timestamp: string

  stop_time: number
  stop_time_offset: number
  stop_timestamp: string

  stats: JSONValue
}

type EventWebhookSplitArchiveEndRequest = {
  type: 'split-archive.end'

  id: string
  timestamp: string

  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: WebhookAudio
  audio_codec_type?: string
  audio_bit_rate?: number

  video: Video
  video_codec_type?: string
  video_bit_rate?: number

  start_time: number
  start_time_offset: number
  start_timestamp: string

  stop_time: number
  stop_time_offset: number
  stop_timestamp: string

  stats: JSONValue
}

type EventWebhookArchiveFailedRequest = {
  type: 'archive.failed'

  timestamp: string
  id: string

  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

  file_path: string
  filename: string

  audio: WebhookAudio
  audio_codec_type?: string
  audio_bit_rate?: number

  video: ArchiveVideo
  video_codec_type?: string
  video_bit_rate?: number
  video_height?: number
  video_width?: number

  start_time: number
  start_timestamp: string

  stop_time: number
  stop_timestamp: string

  stats: JSONValue
}

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

type EventWebhookSpotlightFocusedRequest = {
  type: 'spotlight.focused'

  timestamp: string
  id: string

  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: string
  id: string

  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
}
© Copyright 2022, Shiguredo Inc Created using Sphinx 5.3.0