ウェブフック

概要

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

  • data_channels

  • metadata

  • event_metadata

  • signaling_notify

  • signaling_notify_metadata

  • simulcast

  • simulcast_rid

  • simulcast_encodings

    • AV1 でサイマルキャストを利用した録画をする場合は scalabilityModeL1T1 を設定してください

  • simulcast_multicodec

  • simulcast_codecs

  • spotlight

  • spotlight_number

    • この払い出しは非推奨です

    • Sora セッションウェブフックの "type": "session.created" の戻り値で spotlight_number を払い出してください

  • spotlight_encodings

    • AV1 でスポットライトを利用した録画をする場合は scalabilityModeL1T1 を設定してください

  • user_agent_stats

    • この払い出しは 2025 年 6 月末にて利用ができなくなります

  • rtc_stats

  • video_vp9_params

    • profile_id

  • video_av1_params

    • profile

  • video_h264_params

    • profile_level_id

    • b_frame

  • video_h265_params

    • level_id

    • b_frame

  • forwarding_filter

  • recording_block

  • turn_tcp_only

  • turn_tls_only

  • connection_lifetime

  • playout_delay_min_delay

  • playout_delay_max_delay

  • cluster_affinity

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

セッションウェブフック

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

払い出し可能な項目

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

  • session_metadata

  • session_lifetime

  • forwarding_filter

  • spotlight_number

  • recording

  • recording_metadata

  • recording_expire_time

  • recording_split_duration

  • recording_split_only

注意

録画機能の 制限 に該当する指定を行っていた場合、録画は開始されません。

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 Wokers を利用して実現しています。

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

署名

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

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

署名の検証

t:

タイムスタンプ

v1:

署名

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

署名ペイロード

重要

署名には必ずプライマリー API Key が利用されます。

  • タイムスタンプ (文字列)

  • 文字 .

  • JSON ペイロード (リクエストボディ)

署名疑似コード:

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

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

        sequenceDiagram
    participant client as クライアント
    participant sora as WebRTC SFU Sora
    participant cloud as Sora Cloud
    participant app as アプリケーションサーバー
    client->>sora: "type": "connect"
    sora->>+cloud: 認証ウェブフック
    note over cloud: アクセストークンを確認
    cloud->>+app: 認証ウェブフック
    app-->>-cloud: 200 OK<br>"allowed": true
    cloud-->>-sora: 200 OK<br>"allowed": true
    sora->>client: "type": "offer"
    client->>sora: "type": "answer"
    note over client,sora: WebRTC 確立
    sora->>+cloud: セッションウェブフック<br>"type": "session.created"
    cloud->>+app: セッションウェブフック<br>"type": "session.created"
    app-->>-cloud: 200 OK
    cloud-->>-sora: 200 OK
    sora->>+cloud: イベントウェブフック<br>"type": "connection.created"
    cloud->>+app: イベントウェブフック<br>"type": "connection.created"
    app-->>-cloud: 200 OK
    cloud-->>-sora: 200 OK
    note over client,sora: 1 分経過
    sora->>+cloud: イベントウェブフック<br>"type": "connection.updated"
    cloud->>+app: イベントウェブフック<br>"type": "connection.updated"
    app-->>-cloud: 200 OK
    cloud-->>-sora: 200 OK
    client->>sora: "type": "disconnect"
    sora->>+cloud: イベントウェブフック<br>"type": "connection.destroyed"
    cloud->>+app: イベントウェブフック<br>"type": "connection.destroyed"
    app-->>-cloud: 200 OK
    cloud-->>-sora: 200 OK
    sora->>client: シグナリング切断
    

Sora Cloud 関連ウェブフック

  • Sora イベントウェブフック

    • recording.started

    • recording.report

    • archive.started

    • archive.avaiable

  • Sora Cloud ウェブフック

    • archive.uploaded

    • recording-report.uploaded

        sequenceDiagram
    autonumber
    participant client as クライアント
    participant sora as WebRTC SFU Sora
    participant cloud as Sora Cloud
    participant app as アプリケーションサーバー
    participant s3 as オブジェクトストレージ
    note over client,sora: WebRTC 確立
    app->>+cloud: StartRecording API
    cloud->>+sora: StartRecording API
    sora-->>-cloud: 200 OK
    cloud-->>-app: 200 OK
    note over sora: 録画開始
    sora->>+cloud: イベントウェブフック<br>"type": "recording.started"
    cloud->>+app: イベントウェブフック<br>"type": "recording.started"
    app-->>-cloud: 200 OK
    cloud-->>-sora: 200 OK
    app->>+cloud: StopRecording API
    cloud->>+sora: StopRecording API
    sora-->>-cloud: 200 OK
    cloud-->>-app: 200 OK
    note over sora: 録画終了
    par
        sora->>+cloud: イベントウェブフック<br>"type": "archive.avaiable"
        cloud->>+app: イベントウェブフック<br>"type": "archive.avaiable"
        app-->>-cloud: 200 OK
        cloud-->>-sora: 200 OK
        sora->>s3: 録画ファイルアップロード
        cloud->>+app: Sora Cloud ウェブフック<br>"type": "archive.uploaded"
        app-->>-cloud: 200 OK
    and
        sora->>+cloud: イベントウェブフック<br>"type": "recording.report"
        cloud->>+app: イベントウェブフック<br>"type": "recoding.report"
        app-->>-cloud: 200 OK
        cloud-->>-sora: 200 OK
        sora->>s3: 録画レポートアップロード
        cloud->>+app: Sora Cloud ウェブフック<br>"type": "recording-report.uploaded"
        app-->>-cloud: 200 OK
    end
    
© Copyright 2024, Shiguredo Inc. Created using Sphinx 8.1.3