イベント
イベント登録タイミング
コールバックは init() の前後いつでも登録できます。ただし、onStatus は init() 中の状態変更(CONNECTING、SOCKET_CONNECTED など)を受信するために、init() 呼び出し前に登録してください。
destroy()後もコールバックは保持されるため、再初期化時に再登録する必要はありません。
WARNING
各タイプにつきコールバックは1つのみ登録可能で、最後の登録が以前のものを上書きします。
複数の画面やコンポーネントでイベントが必要な場合は、SDKのコールバックをアプリ内の1か所に登録し、受け取ったイベントを必要なコンポーネントに配信してください。
onSignal(callback)
サーバーから受信したシグナルを受け取ります。
js
SDK.onSignal((data) => {
console.log(data.signal, data.payload);
});jsx
useEffect(() => {
window.KlleonSDK.onSignal((data) => {
console.log(data.signal, data.payload);
});
}, []);コールバックパラメータ
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
signal | IncomingSignal | O | シグナル種類(enum、ランタイムでは文字列) |
payload | object | X | シグナル別追加データ |
id | string | O | シグナルUUID |
type | string | O | "SESSION" | "INPUT" | "OUTPUT" |
主要シグナル
会話フロー
| シグナル | 説明 | payload |
|---|---|---|
RESPONSE_TEXT | アバター応答テキスト | { text: string, language: string } |
STT_RESULT | 音声認識結果 | { text: string } |
RESPONSE_PREPARING | 応答準備中(LLMリクエスト直前) | - |
RESPONSE_STARTED | 応答開始 | - |
RESPONSE_ENDED | 応答完了 | - |
USER_SPEECH_STARTED | STTセッション内の発話区間開始(マイクはすでにオン) | - |
USER_SPEECH_STOPPED | STTセッション内の発話区間終了(マイクはまだオン) | - |
ERROR | 応答処理中のエラー(セッション維持) | { type: "STT_ERROR" | "LLM_ERROR" | ... } |
REJECTED | 入力拒否(セッション維持) | { type: "STT_EMPTY" | "MODERATION" | ... } |
セッション管理
| シグナル | 説明 | payload |
|---|---|---|
MATCH_WAITING | マッチング待機中(ローディングUI表示用) | - |
WAIT | サーバー準備中(待機を継続) | - |
SESSION_ENDED | セッション正常終了 | - |
IDLE_TIMED_OUT | アイドル時間超過によりサーバーがセッションを終了 | - |
SESSION_TIMED_OUT | セッションタイムアウト | - |
TIME_EXHAUSTED | 使用時間をすべて使い切った | - |
QUOTA_EXCEEDED | 同接quota超過 | - |
SUSPEND_WARNED | 長時間待機警告 | - |
onStatus(callback)
SDK接続状態の変更を受け取ります。
js
SDK.onStatus((status) => {
console.log('状態:', status);
if (status === 'CONNECTED_FINISH') {
console.log('アバター準備完了');
}
});jsx
const [status, setStatus] = useState('IDLE');
useEffect(() => {
window.KlleonSDK.onStatus((s) => setStatus(s));
}, []);onError(callback)
SDK内部エラー + サーバーエラーを受け取ります。
js
SDK.onError((error) => {
console.error(error.code, error.message);
});jsx
useEffect(() => {
window.KlleonSDK.onError((error) => {
console.error(error.code, error.message);
});
}, []);コールバックパラメータ
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
code | string | O | エラーコード |
message | string | X | 詳細メッセージ |
エラーコード詳細
初期化エラー(init失敗時)
初期化の失敗はエラーコードなしで init() の例外(reject)として伝えられます。メッセージ: "Failed to connect: ..."(SDKキー検証失敗またはWebSocket接続失敗)/ "Failed to connect streaming: ..."(ストリーミング接続失敗)/ "Init failed: ..."(その他の初期化失敗)
ただし接続中のストリーミング側の問題で
onErrorが併発する場合があるため、onErrorの登録はinit()呼び出し前に行うのが安全です。
ランタイムエラー(接続中に発生)
| コード | 発生タイミング | message例 |
|---|---|---|
SOCKET_DISCONNECTED_UNEXPECTEDLY | WebSocketエラー発生 | "WebSocket disconnected unexpectedly: {code}" または "Handover failed after max retries and active socket is dead" |
STREAMING_FAILED | リモートトラック購読失敗 — 接続は維持され、onError のみ伝達 | "Failed to subscribe to remote track" |
STREAMING_DISCONNECTED_UNEXPECTEDLY | ストリーミング異常終了 | "Streaming disconnected: {reason}" または "Remote user left streaming" |
サーバーエラー
| コード | 発生タイミング | message例 |
|---|---|---|
SERVER_ERROR | サーバーから SERVER_ERROR シグナル受信 | サーバーからのメッセージまたは "SERVER_ERROR" |
WORKER_DISCONNECTED | サーバー接続終了シグナル受信 | "WORKER_DISCONNECTED" |
イベント登録例
js
const SDK = window.KlleonSDK;
SDK.onStatus((status) => console.log('状態:', status));
SDK.onSignal((data) => {
if (data.signal === 'RESPONSE_TEXT') {
console.log('アバター:', data.payload.text);
}
});
SDK.onError((error) => {
console.error(`[${error.code}] ${error.message}`);
});
SDK.init({
sdk_key: 'YOUR_SDK_KEY',
avatar_id: 'YOUR_AVATAR_ID',
}).catch((e) => console.error(e.message));jsx
import { useEffect } from 'react';
function App() {
useEffect(() => {
const SDK = window.KlleonSDK;
SDK.onStatus((status) => console.log('状態:', status));
SDK.onSignal((data) => {
if (data.signal === 'RESPONSE_TEXT') {
console.log('アバター:', data.payload.text);
}
});
SDK.onError((error) => {
console.error(`[${error.code}] ${error.message}`);
});
SDK.init({
sdk_key: 'YOUR_SDK_KEY',
avatar_id: 'YOUR_AVATAR_ID',
})
.catch((e) => console.error(e.message));
return () => {
// destroy() は未初期化状態でも安全で、進行中の init の後に自動的に直列化されます
SDK.destroy();
};
}, []);
return <avatar-container style={{ width: 400, height: 600 }} />;
}