Combos SDK API 參考
SDK 1.1.0 · 核對日期:2026-10-13。本文涵蓋遊戲透過 window.combos 使用的所有 JavaScript API:10 個全域方法與 TikTok 用戶端的 4 個方法。各方法均說明輸入、傳回值、失敗行為及範例。從零製作遊戲請看 TikTok 實作教學;按鈕整合範例請看帳號與多語言。
呼叫由 Combos 宿主處理。這些是 JavaScript 方法,不是 REST 端點;遊戲不必設定 API 位址、API Key、HTTP 回應封裝,也不必手動傳送 postMessage。Promise 成功時直接傳回結果,沒有外層 data。
執行環境與 TypeScript 設定
支援此能力的 Combos 播放器會注入 SDK。不要另載第二份執行階段指令碼或覆寫 window.combos。獨立網站與本機預覽可能沒有此物件,應在瀏覽器程式中先檢查並保留基本玩法。伺服器端繪製時不要存取 window。
需要編輯器提示時,將公開型別宣告 儲存為遊戲原始碼旁的 combos-host-sdk.d.ts,並讓 TypeScript 專案包含該目錄。宣告檔只提供型別,不會安裝 SDK。下方 TTLiveClient 等型別使用 import type,不會增加執行階段相依套件。
curl --fail --location https://combos.converge.ai/host-sdk.d.ts --output ./combos-host-sdk.d.tsasync function readCapabilities() {
const sdk = window.combos;
if (!sdk) return [];
const { methods } = await sdk.init();
return methods;
}每個 TypeScript 區塊都是獨立輔助函式,由你的介面呼叫並處理 Promise 拒絕。名稱含 AfterClick 的函式應綁定玩家操作。範例中的 null 依程式表示不支援或登入取消,不是 SDK 額外的傳回值。JSON 展示原始請求或結果格式,身分與時間均為示意值;介面文字請配合遊戲語言調整。
方法索引
| 方法 | 用途 | 宿主請求逾時 |
|---|---|---|
init() | 查詢能力 | 3 秒後採相容備援 |
checkSession() | 讀取登入狀態 | 10 秒 |
login() | 開啟宿主登入 | 5 分鐘 |
getUserInfo() | 讀取遊戲內玩家身分 | 10 秒 |
requestI18n(params) | 翻譯已顯示的原文 | 30 秒 |
getSetting() | 讀取 Cloud Ability 授權 | 10 秒 |
authorize(params) | 申請一項權限 | 5 分鐘 |
openSetting() | 開啟權限設定 | 5 分鐘 |
getCloudAbilitySession() | 取得短期工作階段憑證 | 10 秒 |
getTTLiveClient() | 取得目前頁面的用戶端 | 同步,不發送請求 |
client.connect(options) | 建立互動串流 | 獨立生命週期,無固定總時限 |
client.getLiveStatus() | 查詢互動狀態 | 先取得工作階段,HTTP 最多 5 秒 |
client.onStatusChange(listener) | 訂閱狀態 | 同步 |
client.disconnect() | 停止用戶端 | 同步 |
首次呼叫可能另花最多 3 秒查詢能力。這些是 SDK 的等待時限,不是服務等級保證。公開方法不接受 timeout、AbortSignal、成功回呼參數或額外身分資訊。
先檢查宿主支援情況
以 init().methods 為準,不能只看函式是否存在。目前 Web 宿主支援 checkSession 與 login;getUserInfo 需要可信的遊戲上下文,requestI18n 需要 Play 宿主提供翻譯能力,TikTok 需要相應能力與已登記的啟動上下文。舊版 Web 或 App 宿主可能不同。
目前 Web 宿主不宣告 getSetting、authorize、openSetting、getCloudAbilitySession。這些契約適用於明確宣告支援的宿主。發布遊戲不會自動啟用 Cloud Ability 或 TikTok。方法不在能力清單時,SDK 會在送出該方法請求前以 unsupported 拒絕。
getTTLiveSession 是內部能力名稱。使用 getTTLiveClient() 前要檢查它,但沒有公開的 combos.getTTLiveSession()。全域 API 也沒有 logout、通用 request、雲端存檔、付款、排行榜或禮物註冊方法。
初始化與帳號
combos.init()
combos.init(): Promise<ICombosHostInitResult>
參數:無。需要登入:否。傳回:含 methods 能力名稱陣列的 Promise。不會登入、開啟介面或建立 TikTok 連線。
同時呼叫會共用查詢,結果在目前遊戲頁面內快取;其他宿主方法也會自動初始化。有效陣列中的未知名稱與重複項會被過濾。查詢失敗、格式無效或 3 秒內未回覆時,傳回 ['checkSession', 'login'];有效的空陣列仍維持空白。相容備援不代表獨立頁面有可用宿主,後續仍可能逾時。沒有公開的強制重新查詢選項。
下方只是回應範例,不要假定所有宿主都支援這份清單。
interface ICombosHostInitResult {
methods: Array<
| 'checkSession' | 'login' | 'getUserInfo' | 'requestI18n'
| 'getSetting' | 'authorize' | 'openSetting'
| 'getCloudAbilitySession' | 'getTTLiveSession'
>;
}{
"methods": ["checkSession", "login", "getUserInfo", "requestI18n", "getTTLiveSession"]
}combos.checkSession()
combos.checkSession(): Promise<boolean>
參數:無。需要登入:否。傳回:宿主回報已登入時為 true,否則為 false;不會開啟登入介面。只有嚴格等於布林值 true 才視為登入,字串或物件等真值不算。
每次獨立帳號操作前即時查詢,不要永久快取;檢查後狀態仍可能改變。傳輸錯誤或逾時會拒絕 Promise,不能當成正常 false 或登出證據。正常傳回 false 時讓玩家選擇登入。同一操作的 login() 成功後直接繼續,不必再次檢查。
async function readSession() {
const sdk = window.combos;
if (!sdk) return null;
const { methods } = await sdk.init();
if (!methods.includes('checkSession')) return null;
return sdk.checkSession();
}combos.login()
combos.login(): Promise<ICombosHostLoginResult>
參數:無,不傳帳號 ID、密碼或 token。需要登入:否。副作用:必要時開啟宿主登入流程。應由玩家操作觸發,等待時停用發起按鈕。
status | 意義與後續動作 |
|---|---|
success | 繼續目前操作,不必重載、輪詢或再次查詢登入 |
cancelled | 玩家取消,返回遊戲,不自動重新開啟提示 |
取消屬正常傳回。彈出視窗被擋、傳輸或登入同步失敗、逾時會拒絕 Promise。無效結果或未知狀態會報 request_failed。目前 Web 宿主對已登入玩家直接傳回 success。結果不含憑證與玩家資料,資料須另行取得。
interface ICombosHostLoginResult {
status: 'success' | 'cancelled';
}async function loginAfterClick() {
const sdk = window.combos;
if (!sdk) return null;
const { methods } = await sdk.init();
if (!methods.includes('checkSession') || !methods.includes('login')) return null;
if (await sdk.checkSession()) return { status: 'success' as const };
return sdk.login();
}{ "status": "success" }combos.getUserInfo()
combos.getUserInfo(): Promise<ICombosHostUserInfo>
參數:無。前提:宣告支援 getUserInfo、有可信遊戲上下文且已登入。未登入會報 session_required;即使先前檢查成功,也要處理請求時工作階段失效。
| 欄位 | 型別與必要性 | 意義 |
|---|---|---|
appId | 必填非空 string | 目前遊戲的應用程式身分,不是 Post 網址或自行指定的專案 ID |
openId | 必填非空 string | 玩家在此應用程式內的身分,與 appId 一起使用 |
nickName | 必填 string,可空白 | 顯示暱稱,需準備預設名稱 |
avatarUrl | 必填 string,可空白 | 顯示頭像,缺失或載入失敗需有備援 |
locale | 必填非空 string | 玩家已儲存的公開產品語言,如 en、zh-CN;未儲存時為目前產品語言 |
沒有電子郵件、電話、平台使用者 ID、登入 token 或 Cloud Ability 憑證。不能用 openId 推斷跨應用程式身分,或把瀏覽器結果當成自己伺服器的驗證證明。顯示欄位按文字處理,不當作 HTML。缺少身分、顯示欄位不是字串等無效結果會報 request_failed;宿主或後端也可能傳回其他錯誤碼。
interface ICombosHostUserInfo {
appId: string;
openId: string;
nickName: string;
avatarUrl: string;
locale: string;
}async function readPlayerAfterClick() {
const sdk = window.combos;
if (!sdk) return null;
const { methods } = await sdk.init();
if (!methods.includes('checkSession') || !methods.includes('login') || !methods.includes('getUserInfo')) return null;
if (!(await sdk.checkSession())) {
const login = await sdk.login();
if (login.status === 'cancelled') return null;
}
return sdk.getUserInfo();
}{
"appId": "app_example",
"openId": "player_example",
"nickName": "Alex",
"avatarUrl": "",
"locale": "en"
}遊戲多語言
combos.requestI18n(params)
combos.requestI18n(params: ICombosHostRequestI18nParams): Promise<ICombosHostI18nResult>
登入要求:目前 Web 翻譯橋接不要求先登入,但必須宣告 requestI18n。先顯示原文,翻譯作為非同步增強,不阻擋遊戲載入。
| 參數 | 型別 | 必填 | 意義 |
|---|---|---|---|
sourceLocale | string | 是 | 原文語言,如 en、zh-CN,不是目標語言 |
sourceTexts | string[] | 是 | 遊戲已顯示的精確原文字串或固定模板 |
沒有 targetLocale,由宿主選擇目前產品語言。Web 實作會修剪語言標籤兩端空白、略過空字串與非字串項目、移除重複原文,並每批 50 條請求翻譯;50 不是公開 SDK 輸入上限。建議以少量穩定介面文字分組,讓請求能在 30 秒內完成,不要每個動畫影格都呼叫。
interface ICombosHostRequestI18nParams {
sourceLocale: string;
sourceTexts: string[];
}
type ICombosHostI18nResult =
| { needed: false }
| { needed: true; locale: string; translations: Record<string, string> };{
"sourceLocale": "en",
"sourceTexts": ["Play", "Score: {score}"]
}{
"needed": true,
"locale": "zh-CN",
"translations": { "Play": "开始", "Score: {score}": "得分:{score}" }
}| 傳回欄位 | 意義 |
|---|---|
needed: false | 保留全部原文,此分支沒有 locale、translations |
needed: true | 有翻譯結果,但對照表可能不完整 |
locale | 宿主選定的目標語言,僅在 needed 為 true 時存在 |
translations | 精確原文字串對應翻譯,不使用遊戲自訂 ID 作為鍵 |
語言等價、沒有有效文字、翻譯不可用或 Web 後端翻譯失敗,均可能正常傳回 { needed: false }。SDK 也會把格式無效的結果轉為此分支;不支援與傳輸逾時仍可能拒絕。缺失或空白的翻譯逐項保留原文,使用 textContent,不要使用 innerHTML。
先翻譯 Score: {score} 模板再代入數值,SDK 不負責插值。使用前檢查必要佔位符是否保留。重複呼叫時保留最初原文,不要把已翻譯文字搭配舊 sourceLocale 再送出。
async function translateVisibleLabels(nodes: HTMLElement[]) {
const sourceTexts = nodes.map(node => node.textContent ?? '');
const sdk = window.combos;
if (!sdk) return;
try {
const { methods } = await sdk.init();
if (!methods.includes('requestI18n')) return;
const result = await sdk.requestI18n({ sourceLocale: 'en', sourceTexts });
if (!result.needed) return;
nodes.forEach((node, index) => {
node.textContent = result.translations[sourceTexts[index]] || sourceTexts[index];
});
} catch {
// Source text stays visible.
}
}選用的 Cloud Ability API
目前 Web 宿主不宣告以下四個方法,每個都要獨立檢查。範例適用於支援的宿主,無法透過呼叫自動開通。玩家同意授權,也不代表遊戲擁有者已啟用底層能力。
type CombosHostPermissionScope = 'ai_model';
type CombosHostAuthorizationDecision =
| 'AUTHORIZATION_DECISION_UNSPECIFIED'
| 'AUTHORIZATION_DECISION_GRANTED'
| 'AUTHORIZATION_DECISION_DENIED';
interface ICombosHostPlayableAuthorization {
decision: CombosHostAuthorizationDecision;
decidedAtMs: number;
}
type ICombosHostAuthSetting = Readonly<
Partial<Record<CombosHostPermissionScope, ICombosHostPlayableAuthorization>>
>;
interface ICombosHostAuthorizeParams { scope: CombosHostPermissionScope }
interface ICombosHostCloudAbilitySession { session: string; expiresAtMs: number }| 欄位或值 | 契約 |
|---|---|
scope | 目前只有 'ai_model',authorize 必填 |
decision | 執行階段接受 AUTHORIZATION_DECISION_GRANTED 或 AUTHORIZATION_DECISION_DENIED |
AUTHORIZATION_DECISION_UNSPECIFIED | 公開型別中的零值,不是 SDK 接受的有效回傳決定 |
decidedAtMs | 必填有限數值,Unix 毫秒時間,不是秒或到期時間 |
缺少 ai_model | 尚未詢問玩家此遊戲的權限,與拒絕不同 |
session | 必填非空敏感憑證,短期有效,只能存於記憶體 |
expiresAtMs | 必填有限數值,Unix 毫秒到期時間,不保證固定有效期間 |
不接收使用者、裝置、專案、Post 或遊玩實例 ID。可信上下文、登入與權限介面由宿主提供。受保護操作須符合該宿主的登入要求;拒絕後不要反覆提示。
combos.getSetting()
combos.getSetting(): Promise<ICombosHostAuthSetting>
參數:無。逾時:10 秒。讀取目前玩家對目前遊戲的決定,不開啟權限設定。傳回 ICombosHostAuthSetting;尚無 ai_model 時 {} 是有效結果。
SDK 只保留已知的 ai_model。該鍵存在時,必須有同意或拒絕決定及有限數值 decidedAtMs,否則報 request_failed。缺失不等於拒絕,玩家修改設定後也不能沿用過期決定。
{
"ai_model": {
"decision": "AUTHORIZATION_DECISION_GRANTED",
"decidedAtMs": 1791800000000
}
}async function readPermissionSettings() {
const sdk = window.combos;
if (!sdk) return null;
const { methods } = await sdk.init();
if (!methods.includes('getSetting')) return null;
return sdk.getSetting();
}combos.authorize(params)
combos.authorize(params: ICombosHostAuthorizeParams): Promise<ICombosHostPlayableAuthorization>
參數:必填物件,包含 scope: 'ai_model';無預設值,不接受萬用字元、權限陣列或自行指定決定。逾時:5 分鐘。從玩家操作發起,互動權限介面由宿主管理。
傳回單筆記錄,不是完整設定。AUTHORIZATION_DECISION_DENIED 為正常結果;只有 GRANTED 才能繼續授權操作,拒絕後不自動再問。此方法沒有 cancelled 契約,關閉介面須依實際記錄或拒絕處理,不套用登入狀態。不支援、無效記錄、傳輸錯誤與逾時均會拒絕 Promise。
async function requestAiPermissionAfterClick() {
const sdk = window.combos;
if (!sdk) return null;
const { methods } = await sdk.init();
if (!methods.includes('authorize')) return null;
return sdk.authorize({ scope: 'ai_model' });
}{ "decision": "AUTHORIZATION_DECISION_DENIED", "decidedAtMs": 1791800000000 }combos.openSetting()
combos.openSetting(): Promise<ICombosHostAuthSetting>
參數:無。逾時:5 分鐘。由玩家操作開啟權限設定,完成後傳回 ICombosHostAuthSetting;不能傳入物件來靜默授予權限。
依結果更新介面,包含缺失或拒絕的範圍。傳回值不是布林值、單筆記錄或登入狀態;驗證規則與 getSetting() 相同。不支援、無效結果或宿主、傳輸失敗會拒絕;SDK 未定義獨立取消狀態。
async function openPermissionsAfterClick() {
const sdk = window.combos;
if (!sdk) return null;
const { methods } = await sdk.init();
if (!methods.includes('openSetting')) return null;
return sdk.openSetting();
}combos.getCloudAbilitySession()
combos.getCloudAbilitySession(): Promise<ICombosHostCloudAbilitySession>
參數:無。逾時:10 秒。支援的宿主會提供目前遊玩的 { session, expiresAtMs }。此呼叫不會顯示授權提示,也不代表可使用所有 AI 模型;需處理登入、權限與能力可用性錯誤。
憑證只留在記憶體,僅用於該宿主說明的 Cloud Ability 整合。不能放入日誌、截圖、網址、本機儲存或原始碼。使用前檢查期限,需要時重新取得,玩家或遊玩實例改變時丟棄舊值。沒有 refreshToken、TTL 參數或通用後端身分驗證保證。格式無效會報 request_failed。
async function obtainCloudSession() {
const sdk = window.combos;
if (!sdk) return null;
const { methods } = await sdk.init();
if (!methods.includes('getCloudAbilitySession')) return null;
const value = await sdk.getCloudAbilitySession();
if (value.expiresAtMs <= Date.now()) throw new Error('Session already expired');
return value; // Keep in memory only; never log or persist this value.
}TikTok 用戶端參考
目前真實 TikTok 接入尚無可用的開通流程。以下契約不代表新發布遊戲可以收到真實禮物。現在可以製作遊戲、執行模擬器並發布至 Combos;真實接入須等待平台提供開通程序。
用戶端管理此遊戲的 TikTok 互動工作階段,不是主播整體直播狀態。它負責傳輸、心跳、續期及重連,遊戲負責指令、效果、持久化去重與真實結果。禮物對應、發布、準備材料與專案見完整教學。
combos.getTTLiveClient()
combos.getTTLiveClient(): TTLiveClient
參數:無。傳回:同步取得 TTLiveClient,此時不發送網路請求。同一 SDK/遊戲頁面重複呼叫會取得同一實例,不要讓不同元件競爭控制連線。
先檢查能力清單中的 getTTLiveSession。取得物件不證明已支援、已登入、完成啟動登記或已連線。真實連線前完成帳號流程;平台金鑰、CAS 憑證、launchData 與 WebSocket 位址由內部管理,沒有自行傳入的參數。
async function getTikTokClient() {
const sdk = window.combos;
if (!sdk || typeof sdk.getTTLiveClient !== 'function') return null;
const { methods } = await sdk.init();
if (!methods.includes('getTTLiveSession')) return null;
return sdk.getTTLiveClient();
}client.connect(options)
client.connect(options: TTLiveConnectOptions): Promise<void>
參數:必填 options,其中必填 onCommand 函式須傳回 boolean 或 Promise<boolean>。沒有房間 ID、主播 ID、token、重連或逾時設定。
收到 ready 訊框後完成 Promise<void>,不代表禮物已生效或永遠在線,需另外觀察狀態。恢復期間可能一直等待,應先提供停止操作。已有連線意圖時重複呼叫會共用等待中的 Promise 或立即完成,不更換原回呼;更換前先斷線。
缺少 onCommand 會以普通 Error 拒絕。就緒前斷線或進入終止狀態也會拒絕;暫時網路或工作階段故障通常進入恢復。不同訊息 ID 的非同步處理可能並行,請將共享狀態更新序列化或使用交易。
interface TTLiveConnectOptions {
onCommand: (command: TTLiveCommand) => boolean | Promise<boolean>;
}
interface TTLiveCommand {
messageId: string;
instruction: string;
count: string;
timestamp: string;
}| 回呼欄位 | 型別與驗證 | 遊戲責任 |
|---|---|---|
messageId | 非空 string,SDK 1.1.0 上限 256 字元 | 不透明冪等鍵,與效果、結果一同儲存 |
instruction | string | 比對自行宣告的指令,SDK 不驗證遊戲禮物清單 |
count | 十進位數字字串,保留大整數精度 | 先檢查業務範圍,再轉型;不能直接 Number。SDK 解析不會拒絕零或前導零 |
timestamp | string | 來源時間表示,公開型別未保證單位與格式;不能當成身分或順序證明 |
以下是指令範例,不是禮物註冊 API。沒有觀眾 ID、暱稱、禮物價格或真實禮物 ID。count 為對應後的指令數量,不一定等於禮物件數或金幣價值。
{
"messageId": "example-command-001",
"instruction": "gift_flash",
"count": "3",
"timestamp": "1791800000"
}| 處理結果 | SDK 行為 |
|---|---|
true 或 Promise 完成為 true | 回報成功;須等效果與回執提交後才傳回 |
false 或 Promise 完成為 false | 回報確定拒絕/失敗,例如不支援指令且無效果 |
| 拋錯、Promise 拒絕、非布林值 | 結果未知且未確認,SDK 重連,指令可能重送 |
SDK 記憶體去重有限,主動斷線或頁面重載會清除,並非持久的恰好一次保證。將 messageId、效果與結果原子儲存,重送時傳回舊結果。部分效果不確定時不能傳回 false;Gift Arena示範交易處理。
下方輔助函式立即提供取消,並處理連線拒絕。傳入真實指令處理函式及不拋錯的介面回呼;仍可等待 connected,並保留 stop 以取消等待或已建立的連線。
import type { TTLiveClient, TTLiveConnectOptions, TTLiveStatus } from './combos-host-sdk';
function attachTikTok(
client: TTLiveClient,
onCommand: TTLiveConnectOptions['onCommand'],
onStatus: (status: TTLiveStatus) => void,
onConnectionError: (error: unknown) => void,
) {
const unsubscribe = client.onStatusChange(onStatus);
const connected = client.connect({ onCommand });
void connected.catch(onConnectionError);
return {
connected,
stop() {
unsubscribe();
client.disconnect();
},
};
}client.getLiveStatus()
client.getLiveStatus(): Promise<TTLiveStatus>
參數:無。即時查詢並發布給監聽者,傳回 TTLiveStatus,不啟動指令流。內部先取得宿主工作階段,請求逾時 10 秒,首次另可能查詢能力,再對狀態 HTTP 請求設定 5 秒時限。
網路、HTTP、工作階段解析或狀態格式錯誤會轉成狀態,通常是 unknown,不是 ended 的證據。宿主 tt_not_launched 會轉為 ended / relaunch_game。終止狀態也會停止活動用戶端。遊玩時優先訂閱,不要密集輪詢。
interface TTLiveStatus {
state: 'connecting' | 'connected' | 'recovering' | 'ended' | 'unknown';
reason: string;
action: 'none' | 'wait' | 'relaunch_game';
confirmedAtMs: number;
}| 欄位或值 | 意義/處理 |
|---|---|
state: connecting | 建立初始連線中 |
state: connected | 此遊戲互動工作階段已確認 |
state: recovering | SDK 正恢復傳輸,等待重試 |
state: unknown | 無法確認,不能宣告主播已下播 |
state: ended | 此互動結束,檢查 action |
reason | 診斷字串,可為空或新增值,不是封閉列舉 |
action: none | 無需恢復動作 |
action: wait | 等待恢復,保留取消入口 |
action: relaunch_game | 請主播從 LIVE Studio 重新開啟遊戲,不是重新開播 |
confirmedAtMs | 最近啟動/心跳確認的 Unix 毫秒,0 表示未知,不是期限 |
已知原因包含 platform_unconfirmed、transport_unavailable、client_disconnected、tt_not_launched、session_required。用 state 與 action 決定恢復流程;不要假定原因清單完整或直接作為玩家文案。
import type { TTLiveClient } from './combos-host-sdk';
async function checkTikTokStatus(client: TTLiveClient) {
const status = await client.getLiveStatus();
return status;
}{ "state": "unknown", "reason": "transport_unavailable", "action": "wait", "confirmedAtMs": 0 }client.onStatusChange(listener)
client.onStatusChange(listener: (status: TTLiveStatus) => void): () => void
參數:必填同步監聽函式,接收 TTLiveStatus。傳回:取消訂閱函式。註冊時立即通知目前狀態,之後在欄位變化時通知;即使 state 相同,心跳時間變動也可能觸發。
介面移除時取消訂閱。移除監聽不會斷線,斷線也不會移除監聽。回呼不要拋錯,首次直接呼叫可能將例外傳出。範例用協定值除錯,正式狀態文字須本地化。
import type { TTLiveClient } from './combos-host-sdk';
function showTikTokStatus(client: TTLiveClient, output: HTMLElement) {
const unsubscribe = client.onStatusChange(status => {
output.textContent = `${status.state} · ${status.action}`;
});
return unsubscribe; // Call when the UI is removed.
}client.disconnect()
client.disconnect(): void
參數:無。傳回:undefined(void)。停止計時器、重試與連線,清空用戶端記憶體執行/結果快取,拒絕等待中的連線 Promise。發布 unknown / client_disconnected / wait,confirmedAtMs 為 0。
這不是同步結束 TikTok 直播或確認伺服器結束 ACK 的 API。不刪遊戲自存的回執,也不能回復已執行中的處理函式。另行取消介面訂閱、防止遲到工作更新舊場景、保留持久回執。同一用戶端之後可重新連線,清理時可重複斷線。
import type { TTLiveClient } from './combos-host-sdk';
function stopTikTok(client: TTLiveClient, unsubscribe: () => void) {
unsubscribe();
client.disconnect();
}錯誤與恢復
宿主方法失敗會拒絕 Promise,Error 帶字串 code、message。依代碼而非自然語言訊息判斷;清單不完整,宿主與後端可傳遞其他代碼。TikTok 生命週期也可能使用沒有 code 的普通 Error;getLiveStatus 則把多種失敗表示為狀態。
checkSession() === false、登入 cancelled、授權 DENIED、翻譯 needed: false 均為正常結果。下方範例保留這種區別,不依賴指定錯誤類別,也不記錄憑證。
function readErrorCode(error: unknown): string | null {
if (error && typeof error === 'object' && 'code' in error && typeof error.code === 'string') {
return error.code;
}
return null;
}
async function checkAccountSafely() {
const sdk = window.combos;
if (!sdk) return { kind: 'unavailable' as const };
try {
return { kind: 'success' as const, signedIn: await sdk.checkSession() };
} catch (error) {
return { kind: 'error' as const, code: readErrorCode(error) };
}
}| 代碼 | 意義 | 處理 |
|---|---|---|
unsupported | 宿主未宣告 | 停用選用功能,保留基本遊戲 |
timeout | SDK 等待逾時 | 結束載入,提供玩家重試;不代表宿主已取消 |
transport_failed | 無法送出請求 | 檢查播放器環境,保留備援介面 |
request_failed | 宿主失敗或格式無效 | 查明動作,安全時才重試 |
disposed | SDK 頁面/用戶端已銷毀 | 停止工作,不循環重試 |
session_required | 帳號工作階段不可用 | 提供登入,成功後重試原操作 |
model_not_supported | 模型遭拒 | 使用該 Cloud Ability 支援的模型 |
100250001 | 權限請求無效 | 檢查 scope 與宿主可信上下文 |
100260001 / 100260002 | 工作階段建立、上下文或憑證無效 | 重新建立合法遊玩工作階段,不偽造 ID |
100260004 | AI 模型未授權 | 尊重決定,支援時透過宿主授權 |
100260005 | 遊戲能力已關閉 | 由擁有者確認能力,重新登入不能啟用 |
數字碼是已知宿主/後端錯誤,不代表 Web 已開放 Cloud Ability。先檢查能力;未知代碼顯示可恢復提示,只保留非敏感診斷。
TikTok reason、action 是狀態欄位。處理函式拒絕不會自動送出失敗 ACK;可能已生效的操作不能包成 catch(() => false)。宿主逾時只結束 SDK 等待,登入、授權、翻譯沒有公開取消方法。避免自動重試導致重複提示或再次執行結果未知的操作。
生命週期與整合邊界
- 每個頁面查詢一次能力,每次新的帳號操作前檢查當前登入。
- 登入與授權綁定玩家操作,取消或拒絕後不自動再開。
- 保留原文,翻譯為選用能力;場景移除後丟棄過期的非同步更新。
- 由單一模組管理 TikTok 用戶端:訂閱、持久化處理、連線與取消等待。
- 離開時取消訂閱並斷線,保留執行回執;帳號/遊玩結束時丟棄敏感工作階段。
window.combos 沒有全域 dispose()、帳號變更事件、登入取消控制代碼或統一逾時設定。不要用內部類別或未公開宿主 HTTP 路徑補足。示範程式的函式與儲存上限是遊戲選擇,不是額外 SDK API。
版本、型別與完整範例
公開 TypeScript 宣告 是編輯器使用的權威型別。本文亦核對 SDK 1.1.0 的執行階段驗證、逾時、Web 能力選擇、翻譯及 TikTok 生命週期。型別存在不等於能力可用,後續版本可能調整。
- 帳號與多語言:按鈕綁定、登入後續操作與安全文字更新。
- 製作 TikTok 遊戲:禮物、完整專案、本機測試、發布、準備事項與未來 LIVE 驗收。
- 下載 Gift Arena:含交易式指令處理的完整原始碼。
範例會對照公開型別檢查,但型別檢查與模擬器不代表真實登入、Cloud Ability 存取或付費禮物驗收。須在合適宿主、具資格帳號與完成登記的遊戲中另外驗證。