ウェブフック¶
概要¶
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 でサイマルキャストを利用した録画をする場合は
scalabilityMode
にL1T1
を設定してください
simulcast_multicodec
simulcast_codecs
spotlight
spotlight_number
この払い出しは非推奨です
Sora セッションウェブフックの
"type": "session.created"
の戻り値でspotlight_number
を払い出してください
spotlight_encodings
AV1 でスポットライトを利用した録画をする場合は
scalabilityMode
にL1T1
を設定してください
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 のウェブフック通知¶
戻りのステータスコードは
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:
ngrok アカウントが必要です。 また、固定したエンドポイント URL を利用するには、 Pro プラン ($20/月) 以上のプランに入る必要があります。
シーケンス図¶
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