WebSocket API

Events

概述

所有 WebSocket 可能收到的回應事件格式參考。關於連線與認證方式,請參考 連線與認證;關於請求操作,請參考 Voice Translation Actions


目錄

  1. session_started - Session 啟動成功
  2. result - 辨識/翻譯結果
  3. status - 通用狀態回應
  4. task_complete - 任務處理完成
  5. config_updated - 設定更新完成
  6. tts_ready - TTS 語音就緒
  7. tts_error - TTS 合成失敗
  8. viewer_count - 觀眾人數更新
  9. broadcast_phase_changed - 廣播階段變更
  10. speaker_renamed - 說話者重命名
  11. speaker_reassigned - 語者身份修改
  12. speakers_merged - 語者合併
  13. language_switch_start - 語言切換開始
  14. batch_retranslation - 批次重翻結果
  15. language_switch_done - 語言切換完成
  16. tts_mode_changed - TTS 模式變更
  17. language_switched - 互譯語言切換完成
  18. tts_updated - 互譯 TTS 設定更新
  19. conversation_mode_changed - 對話模式變更
  20. speaker_language_changed - 用戶語言變更
  21. error - 錯誤事件
  22. segment_uploaded - 音訊分段上傳完成
  23. stt_event - STT 連線狀態事件
  24. viewer_joined - 觀眾加入事件
  25. viewer_left - 觀眾離開事件
  26. upload_error - 上傳錯誤
  27. summary_done - 摘要生成完成
  28. summary_error - 摘要生成失敗

session_started

說明

start action 成功後,伺服器回傳包含完整 Session 初始資訊的事件。前端可透過 recording_type 區分錄音類型。

一般錄音(transcribe / conversation / record)

{
  "type": "voice-translation",
  "data": {
    "action": "session_started",
    "session_id": "550e8400-e29b-41d4-a716-446655440000",
    "task_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "recording_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "recording_type": "transcribe",
    "recognition_mode": "single",
    "message": "語音辨識已開始"
  }
}

廣播模式(broadcast)

{
  "type": "voice-translation",
  "data": {
    "action": "session_started",
    "session_id": "550e8400-e29b-41d4-a716-446655440000",
    "task_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "recording_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "recording_type": "broadcast",
    "recognition_mode": "multi_speaker",
    "phase": "standby",
    "viewer_count": 0,
    "queue_count": 0,
    "peak_viewers": 0,
    "total_viewers": 0,
    "message": "語音辨識已開始"
  }
}

欄位說明

欄位類型說明
session_idstring會話 ID(WS 連線層級,連線結束即失效)
task_idstring任務 ID(與 REST /api/v1/tasks/{taskId} 及 Webhook data.task_id 為同一識別碼)
recording_idstringDeprecated(V1.4.1 起):與 task_id 同值,將於 V2.0.0 移除,請改用 task_id
recording_typestring錄音類型:transcribeconversationrecordbroadcast
recognition_modestring辨識模式:singlemulti_speaker
messagestring狀態描述訊息
phasestring廣播階段:standbylive(僅廣播模式)
viewer_countint目前在線觀眾數(僅廣播模式)
queue_countint排隊等待中的觀眾數(僅廣播模式)
peak_viewersint本次廣播峰值觀眾數(僅廣播模式)
total_viewersint累計曾連線的觀眾總數(僅廣播模式)

ID 對齊提示:WebSocket、REST、Webhook 三個介面以 task_id(UUID)作為任務的統一識別碼。session_id 是 WS 連線層級的識別碼,與 task 不同概念;recording_id 為 V1.4.1 之前的舊名,值與 task_id 完全相同,僅作為向後相容保留。


result

說明

語音辨識與翻譯結果。一個 result 事件可能包含 origin(辨識結果)和/或 translations(翻譯結果)。

origin(語音辨識結果)

{
  "type": "voice-translation",
  "data": {
    "action": "result",
    "origin": {
      "sid": 1,
      "language": "zh-TW",
      "text": "你好,很高興認識你",
      "is_final": true,
      "speaker_id": "0",
      "detected_language": "zh-TW",
      "start_time": "00:05"
    }
  }
}

origin 欄位說明

欄位類型說明
sidint句子編號,從 1 開始
languagestring來源語言代碼。互譯模式下為自動偵測的語言
textstring辨識出的文字
is_finalboolean是否為最終結果
speaker_idstring說話者原始 ID
speaker_labelstring(多人模式)顯示標籤(套 alias 後;無 alias 時等於 speaker_id
detected_languagestring偵測到的語言。互譯模式下由系統自動判定
start_timestring句子開始時間(mm:ss);廣播 standby 階段不送此欄位,進 live 後從 00:00 起算

translations(翻譯結果)

{
  "type": "voice-translation",
  "data": {
    "action": "result",
    "translations": {
      "en-US": {
        "sid": 1,
        "text": "Hello, nice to meet you",
        "is_final": true
      }
    }
  }
}

translations 欄位說明

翻譯結果以語言代碼為 key,每個語言的翻譯物件包含:

欄位類型說明
sidint句子編號
textstring翻譯後的文字
is_finalboolean是否為最終結果
is_retranslationboolean是否為重新翻譯結果(僅 retranslate 時)
speaker_idstring(多人模式)原始語者 ID(自 v1.5.3 與 origin 對齊)
speaker_labelstring(多人模式)顯示標籤(套 alias 後;無 alias 時等於 speaker_id

重要retranslate action 的成功回應走獨立的 action: "translation" 事件( result),payload 結構與本表相同。詳見 voice-translation.md retranslate 成功回應


status

說明

通用狀態回應,用於 pause、resume、stop、set_name 等操作的確認。

{
  "type": "voice-translation",
  "data": {
    "action": "status",
    "message": "語音辨識已暫停"
  }
}

欄位說明

欄位類型說明
messagestring狀態描述

task_complete

說明

stop 後音檔和逐字稿上傳完成時觸發。task_id 可用於後續 REST API 查詢任務詳情。

{
  "type": "voice-translation",
  "data": {
    "action": "task_complete",
    "task_id": "550e8400-e29b-41d4-a716-446655440000",
    "message": "任務處理完成"
  }
}

欄位說明

欄位類型說明
task_idstringRecording UUID,可用於後續 API 查詢
messagestring狀態描述

config_updated

說明

設定更新完成事件,在 config action 成功後觸發。

{
  "type": "voice-translation",
  "data": {
    "action": "config_updated",
    "updated": ["terminology", "fuzzy_correction", "translation_dict"],
    "message": "設定已更新"
  }
}

欄位說明

欄位類型說明
updatedstring已更新的設定類型(terminologyfuzzy_correctiontranslation_dict
terminology_effectivestring(可選)若錄製中更新術語庫,值為 "next_turn" 表示新術語從下一句生效;初始 config 不會出現此欄位
messagestring狀態訊息

tts_ready

說明

TTS 語音合成完成事件。包含音訊資料和 Word Boundary 資訊(可用於卡拉 OK 效果)。

{
  "type": "voice-translation",
  "data": {
    "action": "tts_ready",
    "sid": 1,
    "language": "en-US",
    "transcript": "你好,很高興認識你",
    "text": "Hello, nice to meet you",
    "audio": "Base64EncodedMP3...",
    "format": "mp3",
    "duration_ms": 2500,
    "boundaries": [
      {"offset_ms": 0, "duration_ms": 350, "text_offset": 0, "word_length": 5, "text": "Hello", "boundary_type": "WordBoundary"},
      {"offset_ms": 350, "duration_ms": 100, "text_offset": 5, "word_length": 1, "text": ",", "boundary_type": "PunctuationBoundary"},
      {"offset_ms": 500, "duration_ms": 250, "text_offset": 7, "word_length": 4, "text": "nice", "boundary_type": "WordBoundary"},
      {"offset_ms": 750, "duration_ms": 200, "text_offset": 12, "word_length": 2, "text": "to", "boundary_type": "WordBoundary"},
      {"offset_ms": 950, "duration_ms": 350, "text_offset": 15, "word_length": 4, "text": "meet", "boundary_type": "WordBoundary"},
      {"offset_ms": 1300, "duration_ms": 300, "text_offset": 20, "word_length": 3, "text": "you", "boundary_type": "WordBoundary"}
    ]
  }
}

欄位說明

欄位類型說明
sidint句子編號
languagestringTTS 語言
transcriptstring原始逐字稿(STT 識別結果)
textstring翻譯文字(TTS 合成來源)
audiostringBase64 編碼的 MP3 音訊
formatstring音訊格式(固定為 mp3
duration_msint音訊總時長(毫秒)
boundariesarrayWord Boundary 陣列

Word Boundary 欄位說明

欄位類型說明
offset_msint該字詞在音訊中的起始時間(毫秒)
duration_msint該字詞持續時間(毫秒)
text_offsetint在原文字串中的位置(字元索引)
word_lengthint字詞長度(字元數)
textstring字詞內容
boundary_typestring邊界類型,常見值:WordBoundaryPunctuationBoundarySentenceBoundary

tts_error

說明

TTS 合成失敗事件。

{
  "type": "voice-translation",
  "data": {
    "action": "tts_error",
    "sid": 1,
    "language": "en-US",
    "error": "translation_not_found",
    "message": "No translation available for language: en-US"
  }
}

欄位說明

欄位類型說明
sidint句子編號
languagestringTTS 語言
errorstring錯誤碼
messagestring錯誤訊息
transcriptstring(可選)對應原始逐字稿,便於前端定位失敗位置

TTS 錯誤碼

錯誤碼說明
translation_not_found找不到該語言的翻譯
tts_synthesis_failedTTS 合成失敗
tts_quota_exceededTTS 使用量已達上限

viewer_count

廣播模式專用

說明

廣播進行中,系統每 3 秒檢查一次觀眾人數,若有變動則推送此事件給主講者。

{
  "type": "voice-translation",
  "data": {
    "action": "viewer_count",
    "viewer_count": 45,
    "queue_count": 8,
    "peak_viewers": 50,
    "total_viewers": 123
  }
}

欄位說明

欄位類型說明
viewer_countint目前在線觀眾數
queue_countint排隊等待中的觀眾數
peak_viewersint本次廣播峰值觀眾數
total_viewersint累計曾連線的觀眾總數

注意:此事件僅在觀眾人數或排隊人數有變動時才會推送,避免不必要的訊息傳輸。


broadcast_phase_changed

說明

當廣播階段從預備(standby)切換到正式(live)時觸發。

{
  "type": "voice-translation",
  "data": {
    "action": "broadcast_phase_changed",
    "phase": "live",
    "message": "廣播已開始"
  }
}

欄位說明

欄位類型說明
phasestring新的階段:standbylive
messagestring狀態描述訊息

speaker_renamed

說明

全域重命名說話者完成事件。

{
  "type": "voice-translation",
  "data": {
    "action": "speaker_renamed",
    "speaker_id": "Guest-1",
    "new_label": "王經理",
    "affected_sids": [1, 3, 5, 8]
  }
}

欄位說明

欄位類型說明
speaker_idstring解析後的原始語者 ID(即使輸入是顯示標籤,事件回傳仍是原始 ID)
new_labelstring新顯示標籤
affected_sidsint受影響的句子編號列表

speaker_reassigned

說明

修改單句語者身份完成事件。

{
  "type": "voice-translation",
  "data": {
    "action": "speaker_reassigned",
    "sid": 5,
    "old_speaker_id": "Guest-1",
    "new_speaker_id": "Guest-2",
    "new_speaker_label": "李小華"
  }
}

欄位說明

欄位類型說明
sidint修改的句子編號
old_speaker_idstring原始語者 ID
new_speaker_idstring新的原始語者 ID
new_speaker_labelstring新語者顯示標籤(套用 speaker_aliases 後;無 alias 時等於 new_speaker_id

speakers_merged

說明

語者合併完成事件。合併後,該 source 語者未來產生的辨識結果也會自動轉換為 target 語者。

{
  "type": "voice-translation",
  "data": {
    "action": "speakers_merged",
    "source_speaker_id": "Guest-2",
    "target_speaker_id": "Guest-1",
    "affected_sids": [3, 5, 7]
  }
}

欄位說明

欄位類型說明
source_speaker_idstring被合併的原始語者 ID
target_speaker_idstring合併目標的原始語者 ID
affected_sidsnumber受影響的句子 ID 列表

若需取得 target 語者顯示標籤,請查詢 speaker_aliases 或下次 init_metadata 事件。


language_switch_start

說明

語言切換開始事件,在 switch_language action 觸發後送出。

{
  "type": "voice-translation",
  "data": {
    "action": "language_switch_start",
    "translation_language": "ja-JP",
    "total_segments": 15,
    "message": "開始切換語言並重新翻譯"
  }
}

欄位說明

欄位類型說明
translation_languagestring新的翻譯目標語言
total_segmentsint需要重新翻譯的句子數
messagestring狀態描述

batch_retranslation

說明

批次重翻結果事件,在語言切換過程中逐句送出。

{
  "type": "voice-translation",
  "data": {
    "action": "batch_retranslation",
    "sid": 3,
    "translations": {
      "ja-JP": {
        "sid": 3,
        "text": "今日はプロジェクトの進捗について話し合いましょう",
        "is_final": true,
        "is_retranslation": true
      }
    }
  }
}

欄位說明

欄位類型說明
sidint句子編號
translationsobject翻譯結果(格式同 result 的 translations)

language_switch_done

說明

語言切換完成事件。

{
  "type": "voice-translation",
  "data": {
    "action": "language_switch_done",
    "translation_language": "ja-JP",
    "success_count": 15,
    "failed_count": 2,
    "failed_sids": [3, 7],
    "message": "語言切換完成"
  }
}

欄位說明

欄位類型說明
translation_languagestring翻譯目標語言
success_countint成功翻譯的句子數
failed_countint翻譯失敗的句子數
failed_sidsint翻譯失敗的句子編號列表(failed_count > 0 時才包含)
messagestring狀態描述

tts_mode_changed

說明

TTS 播放模式變更事件。

{
  "type": "voice-translation",
  "data": {
    "action": "tts_mode_changed",
    "tts_mode": "async"
  }
}

欄位說明

欄位類型說明
tts_modestring新的模式:syncasync

language_switched

說明

互譯模式(conversation)語言切換完成事件。當 switch_language 在互譯模式下成功切換 STT 來源語言後觸發。

{
  "type": "voice-translation",
  "data": {
    "action": "language_switched",
    "language": "en-US",
    "translation_language": "zh-TW",
    "message": "語言已切換"
  }
}

欄位說明

欄位類型說明
languagestring新的 active 語言(STT 來源)
translation_languagestring新的翻譯目標語言
messagestring狀態訊息

tts_updated

說明

互譯模式(conversation)TTS 設定更新事件。當 set_tts 成功更新 TTS 開關或語音設定後觸發。

{
  "type": "voice-translation",
  "data": {
    "action": "tts_updated",
    "tts_enabled": true,
    "tts_config": {
      "zh-TW": { "voice": "zh-TW-HsiaoChenNeural", "speaking_rate": 1.0 },
      "en-US": { "voice": "en-US-GuyNeural", "speaking_rate": 1.2 }
    }
  }
}

欄位說明

欄位類型說明
tts_enabledbooleanTTS 是否啟用
tts_configobject各語言的 TTS 設定(voice、speaking_rate)

conversation_mode_changed

說明

互譯模式(conversation)對話模式變更事件。當 switch_conversation_mode 成功切換自動/手動模式後觸發。

{
  "type": "voice-translation",
  "data": {
    "action": "conversation_mode_changed",
    "conversation_mode": "manual"
  }
}

欄位說明

欄位類型說明
conversation_modestring新的對話模式:automanual

speaker_language_changed

說明

互譯模式(conversation)用戶語言變更事件。當 set_speaker_language 成功變更用戶語言後觸發,包含變更後的完整語言映射。

{
  "type": "voice-translation",
  "data": {
    "action": "speaker_language_changed",
    "speaker_language_map": {
      "1": "ja-JP",
      "2": "en-US"
    }
  }
}

欄位說明

欄位類型說明
speaker_language_mapobject變更後的用戶語言映射(key 為用戶編號字串)

segment_uploaded

說明

音訊分段上傳完成事件。每當一個音訊片段成功上傳至雲端儲存時觸發,可用於前端顯示上傳進度。

{
  "type": "voice-translation",
  "data": {
    "action": "segment_uploaded",
    "segment_index": 0,
    "duration_sec": 30.5
  }
}

欄位說明

欄位類型說明
segment_indexnumber分段索引(從 0 開始)
duration_secnumber該分段的時長(秒)

stt_event

說明

STT 連線狀態事件。當語音辨識服務的連線狀態發生變化時觸發,可用於前端顯示 STT 服務狀態。

{
  "type": "voice-translation",
  "data": {
    "action": "stt_event",
    "event": "connected",
    "message": "STT 服務已連線"
  }
}

欄位說明

欄位類型說明
eventstring事件類型:connected / disconnected / error
messagestring事件描述訊息

viewer_joined

說明

觀眾加入事件(僅廣播模式)。當觀眾加入廣播時,主講者會收到此事件。

{
  "type": "voice-translation",
  "data": {
    "action": "viewer_joined",
    "viewer": {
      "id": "viewer_abc123",
      "ip": "192.168.1.100",
      "language": "zh-TW"
    },
    "viewer_count": 5,
    "queue_count": 2
  }
}

欄位說明

欄位類型說明
viewerobject加入的觀眾資訊
viewer.idstring觀眾 ID
viewer.ipstring觀眾 IP 地址
viewer.languagestring觀眾選擇的語言
viewer_countnumber目前觀眾人數
queue_countnumber排隊中的人數

viewer_left

說明

觀眾離開事件(僅廣播模式)。當觀眾離開廣播時,主講者會收到此事件。

{
  "type": "voice-translation",
  "data": {
    "action": "viewer_left",
    "viewer_id": "viewer_abc123",
    "viewer_count": 4,
    "queue_count": 1
  }
}

欄位說明

欄位類型說明
viewer_idstring離開的觀眾 ID
viewer_countnumber目前觀眾人數
queue_countnumber排隊中的人數

error

說明

錯誤事件。當操作失敗或系統異常時觸發。

{
  "type": "error",
  "data": {
    "error_code": "session_not_started",
    "severity": "error",
    "message": "語音辨識尚未開始",
    "context": "voice-translation",
    "request_id": "req_abc123xyz789",
    "timestamp": "2026-01-15T10:30:45.123Z"
  }
}

句子級錯誤(如某句的某個語言翻譯失敗)會額外帶上 siddetails

{
  "type": "error",
  "data": {
    "error_code": "llm_content_filtered",
    "severity": "warning",
    "message": "LLM 內容被過濾",
    "context": "translation",
    "sid": 5,
    "request_id": "req_abc123xyz789",
    "timestamp": "2026-04-26T10:30:45.123Z",
    "details": {
      "provider": "azure_openai",
      "source_lang": "zh-TW",
      "translation_language": "ja"
    }
  }
}

欄位說明

欄位類型說明
error_codestring錯誤碼(程式化處理用)
severitystring嚴重程度:fatal / error / warning
messagestring人類可讀的錯誤訊息
contextstring錯誤來源分類
sidint可選。句子級錯誤的句子編號(如該句翻譯失敗);非句子級錯誤不帶
request_idstring請求追蹤 ID
timestampstring錯誤發生時間(ISO 8601)
detailsobject可選。錯誤上下文,常見 key:providertranslation_languagesource_langinternal_error(單一訊息 panic recovered)會額外帶 message_type(必有)與 action(best-effort,解析失敗時不出現),詳見 websocket-api.md 單一訊息錯誤

嚴重程度說明

severity說明處理建議
fatal致命錯誤停止服務,要求重新連線
error操作失敗顯示錯誤提示,允許重試
warning警告顯示警告,不阻斷操作

完整錯誤碼列表請參考 錯誤碼參考


upload_error

v1.5.6 文件修正:早期文件描述 type: "voice-translation" + action: "upload_error" 的獨立事件格式,但實際 wire 上從未送出此格式。儲存上傳失敗一律走統一 error envelope,錯誤碼為下表三者之一。

若你的 client 監聽 action === "upload_error",應改為監聽 type === "error" 並比對 error_code

儲存層錯誤碼(透過 error 事件送出)

錯誤碼說明
storage_connection_failed儲存服務連線失敗
storage_upload_failed檔案上傳失敗
storage_queue_full上傳佇列已滿

summary_done

說明

錄音停止後、Server 端非串流摘要生成完成時推送的事件。客戶端收到此事件後可呼叫 GET /api/v1/sse/history/transcribe/{taskId} 取得摘要內容(payload 不含 final_content,避免 WebSocket 訊息肥大)。

v1.5.5 新增 summary_fallback_level / summary_dropped_segments 兩個 fallback 審計欄位:當 custom prompt 或逐字稿內容觸發 LLM 服務內容過濾時,後端會自動降級(L1→L2→L3)並透過這兩欄通知客戶端實際走的路徑。

範例

L1 直接成功(無 fallback、未觸發過濾):

{
  "type": "voice-translation",
  "data": {
    "action": "summary_done",
    "task_id": "550e8400-e29b-41d4-a716-446655440000",
    "summary_id": "sum_a1b2c3d4e5f6g7h8",
    "summary_mode": "custom",
    "summary_template": "skin-clinic-acme-v2",
    "summary_plain_text": true,
    "tokens_used": { "input": 1234, "output": 567 }
  }
}

L3 觸發(逐字稿分段丟段後產出摘要):

{
  "type": "voice-translation",
  "data": {
    "action": "summary_done",
    "task_id": "550e8400-e29b-41d4-a716-446655440000",
    "summary_id": "sum_a1b2c3d4e5f6g7h8",
    "summary_mode": "custom",
    "summary_template": "skin-clinic-acme-v2",
    "summary_plain_text": true,
    "tokens_used": { "input": 3456, "output": 789 },
    "summary_fallback_level": 3,
    "summary_dropped_segments": [3, 7]
  }
}

欄位說明

欄位類型說明
actionstring固定為 summary_done
task_idstringRecording UUID
summary_idstring此次摘要的內部 ID
summary_modestring"builtin""custom"
summary_templatestringeffective slug — builtin → 內建模板 slug(如 meeting);custom → 客戶 slug
summary_plain_textboolean是否為純文字輸出
tokens_used.input / .outputintToken 用量(L2/L3 fallback 觸發時為全部呼叫的累計值)
summary_fallback_levelint (omit)僅 fallback 觸發時出現23),L1 直接成功則 omit。2=L2 中性 prompt;3=L3 分段丟段
summary_dropped_segmentsint (omit)僅 fallback_level=3 時出現,被剝除的逐字稿段 indices(原序)

Fallback level 解讀(供前端 UI 對應提示)

summary_fallback_level意義建議 UI 提示
(欄位 omit)L1 直接成功,無 fallback不顯示提示
2Customer prompt 觸發過濾,改用中性 fallback prompt「您的自訂指令含 Azure 內容過濾無法處理的詞彙,已使用中性模式產生摘要」
3逐字稿內容觸發過濾,binary search 剝除觸發段後產出「逐字稿含 N 段無法處理,已省略相關內容後產生摘要」(N = summary_dropped_segments.length

L3 失敗時不會發送 summary_done,而是 summary_error with error_code=llm_content_filtered(見下方 §summary_error)。

注意:payload 刻意不含 final_content。客戶端需自行呼叫 GET /api/v1/sse/history/transcribe/{taskId} 取得摘要全文。summary_fallback_levelsummary_dropped_segments 也會在歷史回放時透過 init_summary event 的 top-level 欄位提供。


summary_error

說明

摘要生成失敗時推送的事件,客戶端不需要再輪詢判斷。

範例

{
  "type": "voice-translation",
  "data": {
    "action": "summary_error",
    "task_id": "550e8400-e29b-41d4-a716-446655440000",
    "error_code": "summary_failed",
    "message": "摘要生成失敗"
  }
}

欄位說明

欄位類型說明
actionstring固定為 summary_error
task_idstringRecording UUID
error_codestring摘要錯誤碼(如 summary_failed / summary_timeout / summary_mode_field_mismatch 等)
messagestring人類可讀錯誤訊息(已 sanitize,不含 LLM raw error)

版本:V1.5.7 最後更新:2026-05-20

Copyright © 2026