ウェブフック

概要

Sora Cloud では Sora のウェブフックを利用できます。指定した URL にウェブフックリクエストを送信します。

制限

1 プロジェクト 1 ウェブフック URL

ウェブフックの通知先 URL は 1 プロジェクト当たり、それぞれのウェブフックにつき 1 つずつです。

利用できるウェブフック送信先のポート番号

  • ウェブフック送信先が HTTP の場合に利用できるポート番号は 80 番のみ
  • ウェブフック送信先が HTTPS の場合に利用できるポート番号は 443 番のみ

タイムアウト

ウェブフックのタイムアウトは 10 秒です。これを超えた場合は送信側から切断を行います。 タイムアウトが頻発する場合は一時的にウェブフックでの送信を停止する場合があります。

タイムアウトした場合は認証処理はエラーとして返します。

Sora 認証ウェブフック

認証ウェブフック

  • 戻りのステータスコードは 200 OK を期待します

払い出し可能な項目

  • client_id
  • bundle_id
  • audio
  • audio_codec_type
  • audio_bit_rate
  • audio_opus_params
  • audio_lyra_params
  • video
  • video_codec_type
  • video_bit_rate
  • data_channel_signaling
  • ignore_disconnect_websocket
  • ignore_max_connections
  • data_channels
  • metadata
  • event_metadata
  • recording
  • recording_expire_time
  • recording_split_only
  • recording_split_duration
  • recording_metadata
  • recording_format
  • signaling_notify
  • signaling_notify_metadata
  • signaling_notify_ice_connection_state
  • simulcast
  • simulcast_auto_rids
  • simulcast_rpc_rids
  • simulcast_request_rid
  • simulcast_rid
    • 2027 年 12 月に廃止します
    • 代わりに simulcast_request_rid を利用してください
  • simulcast_encodings
    • AV1 でサイマルキャストを利用した録画をする場合は scalabilityModeL1T1 を設定してください
  • simulcast_multicodec
  • simulcast_codecs
  • spotlight
  • spotlight_number
    • この払い出しは非推奨です
    • Sora セッションウェブフックの "type": "session.created" の戻り値で spotlight_number を払い出してください
  • spotlight_encodings
    • AV1 でスポットライトを利用した録画をする場合は scalabilityModeL1T1 を設定してください
  • rtc_stats
  • video_vp9_params
    • profile_id
  • video_av1_params
    • profile
    • level_idx
    • tier
  • video_h264_params
    • profile_level_id
    • b_frame
  • video_h265_params
    • level_id
    • b_frame
    • profile_id
    • tier_flag
    • tx_mode
  • forwarding_filters
  • recording_block
  • turn_tcp_only
  • turn_tls_only
  • connection_lifetime
  • playout_delay_min_delay
  • playout_delay_max_delay
  • cluster_affinity
  • ice_connection_state_disconnected_timeout_ms
  • ice_connection_state_failed_timeout_ms
  • static_ip_address

Sora セッションウェブフック

セッションウェブフック

戻りのステータスコードは 200 OK を期待します。

払い出し可能な項目

セッションウェブフックの "type": "session.created" の戻り値で以下の項目を払い出すことが可能です。

  • session_metadata
  • session_lifetime
  • forwarding_filters
  • spotlight_number
  • max_connections
  • duplicate_client_id
  • recording
  • recording_metadata
  • recording_expire_time
  • recording_split_duration
  • recording_split_only
  • recording_format

Sora イベントウェブフック

イベントウェブフック

  • 戻りのステータスコードは 200 OK を期待します

Sora 統計ウェブフック

統計ウェブフック

  • 戻りのステータスコードは 200 OK を期待します

Sora Cloud ウェブフック

録画ファイルアップロード時のウェブフック送信

録画ファイルアップロード時のウェブフック送信

  • 戻りのステータスコードは 200 OK を期待します

recording-report.uploaded

Sora Cloud が録画レポートファイルのアップロード完了時に通知します。

archive.uploaded

Sora Cloud が一括録画時の録画ファイルとメタデータファイルのアップロード完了時に通知します。

split-archive.uploaded

Sora Cloud が分割録画時の分割録画ファイルとメタデータファイルのアップロード完了時に通知します。

split-archive-end.uploaded

Sora Cloud が分割録画時の録画終了ファイルのアップロード完了時に通知します。

Hisui Cloud のウェブフック通知

Hisui Cloud のウェブフック送信

  • 戻りのステータスコードは 200 OK を期待します

hisui-cloud-job.started

録画合成開始時に通知します。

hisui-cloud-job.composited

録画合成成功時に通知します。

hisui-cloud-job.uploaded

録画合成ファイルのアップロード成功時に通知します。

hisui-cloud-job.completed

録画合成処理が完了時に通知します。

hisui-cloud-job.canceled

処理キャンセル時に通知します。

hisui-cloud-job.failed

処理失敗時に通知します。

ウェブフックの IP アドレス

Sora Cloud のウェブフックは Cloudflare Workers を利用して実現しています。

そのため Cloudflare の IP アドレス範囲 からウェブフックを通知します。

署名

Sora Cloud が通知する Sora のウェブフックの HTTP ヘッダーにはそのウェブフックの署名が付与されています。

HTTP ヘッダー名 sora-cloud-signature にそのウェブフックの生成時間と JSON ペイロードに対する署名が入っています。

署名の検証

t:

タイムスタンプ

v1:

署名

sora-cloud-signature:
t=1692774577,
v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

署名ペイロード

  • タイムスタンプ (文字列)
  • 文字 .
  • JSON ペイロード (リクエストボディ)

署名疑似コード:

signature = hmac(sha256, primary_api_key, "<Timestamp>.<JSON>").hexdigest()

signature と v1 の値を比較することで署名の検証が可能になります。

タイムスタンプは Unix time を利用しています。

署名検証サンプルコード

Python

import hashlib
import hmac
import http.server
import json
import socketserver

# プロジェクトのプライマリー API キーを指定してください
API_KEY = 'api-key'
PORT = 8000

class AuthWebhookResponder(http.server.BaseHTTPRequestHandler):
    def do_POST(self):
        content_length = int(self.headers['content-length'])
        sora_cloud_sig = self.headers['sora-cloud-signature']
        json_string = self.rfile.read(content_length).decode('utf-8')
        body = json.loads(json_string)

        print(sora_cloud_sig)
        print(json_string)
        print(json.dumps(body, indent=2))

        verify_signature(API_KEY, sora_cloud_sig, json_string)

        # 認証を許可する JSON を返す
        allowed = {"allowed": True}
        s = json.dumps(allowed)

        self.send_response(200)
        self.send_header('Content-Length', len(s))
        self.end_headers()
        self.wfile.write(s.encode())

def verify_signature(api_key, sora_cloud_signature_header_value, request_json_string):
    # sora-cloud-signature ヘッダーの値からタイムスタンプと署名を取り出す
    splited = sora_cloud_signature_header_value.split(',')
    signagure_timestamp = splited[0].split('=')[1]
    header_signature_value = splited[1].split('=')[1]

    # 署名する文字列を生成する
    # <タイムスタンプ>.<リクエストJSON>
    msg = f'{signagure_timestamp}.{request_json_string}'

    # 署名する
    signature = hmac \
        .new(
            key=bytes(api_key,'utf-8'),
            msg=bytes(msg, 'utf-8'),
            digestmod=hashlib.sha256) \
        .hexdigest()

    # ヘッダーの値と署名した値が一致することを確認する
    assert(header_signature_value == signature)

with socketserver.TCPServer(("", PORT), AuthWebhookResponder) as httpd:
    print("serving at port", PORT)
    httpd.serve_forever()

ローカル開発環境へウェブフックを送信する

ローカルの開発環境に Sora Cloud からウェブフックを直接送信することは、ネットワーク上の制約によりできません。 そのため ngrok の利用をおすすめします。 ngrok は無料で使い始められます。

ngrok を利用する

URL:

https://ngrok.com/

ngrok アカウントが必要です。 また、固定したエンドポイント URL を利用するには、 Pro プラン ($20/月) 以上のプランに入る必要があります。

https://ngrok.com/docs/getting-started

シーケンス図

Sora 関連ウェブフック

  • Sora 認証ウェブフック
  • Sora セッションウェブフック
    • session.created
    • session.destroyed
  • Sora イベントウェブフック
    • connection.created
    • connection.updated
    • connection.destroyed
クライアントWebRTC SFU SoraSora CloudアプリケーションサーバークライアントWebRTC SFU SoraSora Cloudアプリケーションサーバー"type": "connect"認証ウェブフックアクセストークンを確認認証ウェブフック200 OK"allowed": true200 OK"allowed": true"type": "offer""type": "answer"WebRTC 確立セッションウェブフック"type": "session.created"セッションウェブフック"type": "session.created"200 OK200 OKイベントウェブフック"type": "connection.created"イベントウェブフック"type": "connection.created"200 OK200 OK1 分経過イベントウェブフック"type": "connection.updated"イベントウェブフック"type": "connection.updated"200 OK200 OK"type": "disconnect"イベントウェブフック"type": "connection.destroyed"イベントウェブフック"type": "connection.destroyed"200 OK200 OKシグナリング切断

Sora Cloud 関連ウェブフック

  • Sora イベントウェブフック
    • recording.started
    • recording.report
    • archive.started
    • archive.available
  • Sora Cloud ウェブフック
    • archive.uploaded
    • recording-report.uploaded
クライアントWebRTC SFU SoraSora CloudアプリケーションサーバーオブジェクトストレージクライアントWebRTC SFU SoraSora CloudアプリケーションサーバーオブジェクトストレージWebRTC 確立StartRecording API1StartRecording API2200 OK3200 OK4録画開始イベントウェブフック"type": "recording.started"5イベントウェブフック"type": "recording.started"6200 OK7200 OK8StopRecording API9StopRecording API10200 OK11200 OK12録画終了parandイベントウェブフック"type": "archive.available"13イベントウェブフック"type": "archive.available"14200 OK15200 OK16録画ファイルアップロード17Sora Cloud ウェブフック"type": "archive.uploaded"18200 OK19イベントウェブフック"type": "recording.report"20イベントウェブフック"type": "recording.report"21200 OK22200 OK23録画レポートアップロード24Sora Cloud ウェブフック"type": "recording-report.uploaded"25200 OK26