Combos SDK API 레퍼런스
SDK 1.1.0 · 확인일: 2026-10-13. 게임에서 window.combos로 사용하는 JavaScript API 전체를 설명합니다. 전역 메서드 10개와 TikTok 클라이언트 메서드 4개 각각의 입력, 결과, 실패 동작과 예제를 확인할 수 있습니다. 완성된 게임을 만들려면 TikTok 튜토리얼, 버튼 연결은 계정과 다국어를 참고하세요.
호출은 Combos 호스트가 처리합니다. REST 엔드포인트가 아니므로 게임에 API 주소, API 키, HTTP 응답 래퍼 또는 직접 작성한 postMessage가 필요하지 않습니다. Promise는 결과 자체를 반환하며 바깥쪽 data 필드는 없습니다.
실행 환경과 TypeScript 설정
지원되는 Combos 플레이어가 SDK를 주입합니다. 런타임 스크립트를 다시 불러오거나 window.combos를 덮어쓰지 마세요. 독립 페이지나 로컬 미리보기에는 객체가 없을 수 있으므로 브라우저 코드에서 확인하고 기본 게임은 계속 사용할 수 있게 합니다. 서버 렌더링 중에는 window를 읽지 않습니다.
공개 타입 선언 을 게임 소스 옆에 combos-host-sdk.d.ts로 저장하고 TypeScript 프로젝트에 해당 폴더를 포함하면 편집기 자동 완성을 사용할 수 있습니다. 선언 파일은 SDK를 설치하지 않습니다. 예제의 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 블록은 독립적인 도우미 함수입니다. UI에서 호출하고 Promise 거부를 처리하세요. AfterClick 함수는 플레이어의 명시적 동작에 연결합니다. 예제의 null은 코드에 따라 미지원 또는 취소를 나타내며 SDK의 추가 반환값이 아닙니다. JSON은 원시 요청·결과의 예시이고 ID와 시간은 가상 값입니다. UI 문구는 게임 언어에 맞게 바꾸세요.
메서드 목록
| 메서드 | 용도 | 호스트 요청 제한 시간 |
|---|---|---|
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이 자동 활성화되지 않습니다. 목록에 없는 메서드는 해당 요청을 보내기 전에 unsupported로 거부됩니다.
getTTLiveSession은 내부 기능 이름입니다. getTTLiveClient() 전에 확인하지만 공개 combos.getTTLiveSession()은 없습니다. 전역 API에는 logout, 범용 request, 클라우드 저장, 결제, 순위표, 선물 등록 메서드도 없습니다.
초기화와 계정
combos.init()
combos.init(): Promise<ICombosHostInitResult>
매개변수: 없음. 로그인: 불필요. 반환: 지원 기능 이름 배열 methods가 담긴 Promise입니다. 로그인, UI 표시, 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입니다. 로그인 UI는 열지 않습니다. SDK는 정확한 불리언 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을 보내지 않습니다. 로그인: 불필요. 부수 효과: 필요할 때 호스트 로그인 UI를 엽니다. 플레이어 동작으로 시작하고 대기 중 버튼을 비활성화합니다.
status | 의미와 다음 동작 |
|---|---|
success | 현재 동작을 계속합니다. 새로고침·폴링·두 번째 세션 확인은 필요 없습니다 |
cancelled | 취소로 처리하고 게임으로 돌아갑니다. 자동으로 다시 열지 않습니다 |
취소는 정상 결과입니다. 팝업 차단, 전송·로그인 동기화 실패, 시간 초과는 거부됩니다. 잘못된 결과나 알 수 없는 상태는 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 URL이나 게임이 지정한 프로젝트 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 | 정확한 원문 → 번역 매핑. 자체 UI ID가 키가 아닙니다 |
동등한 언어, 유효한 텍스트 없음, 번역 불가, 현재 Web 번역 백엔드 실패는 { needed: false }로 끝날 수 있습니다. 잘못된 번역 응답도 SDK가 이 분기로 바꿉니다. 미지원·전송 시간 초과는 여전히 거부될 수 있습니다. 없거나 빈 번역은 각각 원문으로 대체하고 innerHTML 대신 textContent를 사용하세요.
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 | 공개 타입의 기본값이지만 유효한 반환 결정으로 인정하지 않습니다 |
decidedAtMs | 필수 유한 숫자, Unix 밀리초. 초나 만료 시간이 아닙니다 |
ai_model 키 없음 | 이 게임의 권한을 아직 물어보지 않았습니다. 거부와 다릅니다 |
session | 비어 있지 않은 필수 단기 인증 정보. 메모리에만 보관합니다 |
expiresAtMs | 필수 유한 숫자, Unix 밀리초 만료 시각. 고정 TTL 보장 없음 |
사용자, 기기, 프로젝트, Post, 플레이 인스턴스 ID를 보내지 않습니다. 신뢰된 컨텍스트와 로그인·권한 UI는 호스트가 관리합니다. 보호 동작은 해당 호스트의 로그인 조건을 충족하고 거부 후 계속 다시 묻지 마세요.
combos.getSetting()
combos.getSetting(): Promise<ICombosHostAuthSetting>
매개변수: 없음. 제한 시간: 10초. 현재 게임에 대한 플레이어의 결정을 읽고 설정 UI는 열지 않습니다. 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'인 필수 객체입니다. 기본값, 와일드카드, scope 배열, 호출자가 지정하는 결정은 없습니다. 제한 시간: 5분. 플레이어 동작에서 호스트의 권한 UI를 요청합니다.
전체 설정이 아닌 단일 권한 레코드를 반환합니다. AUTHORIZATION_DECISION_DENIED는 정상 결과이며 GRANTED에서만 계속합니다. 거부 후 자동 재요청하지 않습니다. cancelled 계약은 없으므로 UI 닫힘은 실제 레코드나 거부에 따라 처리하고 로그인 상태를 적용하지 마세요. 미지원, 잘못된 결과, 전송 실패와 시간 초과는 거부됩니다.
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을 반환합니다. 조용히 권한을 부여할 설정 객체는 받지 않습니다.
누락·거부까지 포함해 반환값으로 UI를 갱신합니다. 불리언, 단일 권한, 로그인 상태가 아니며 getSetting()과 동일하게 검증합니다. 미지원, 잘못된 결과, 호스트·통신 실패는 거부됩니다. 별도 취소 상태는 없습니다.
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 }를 받습니다. 권한 UI를 열거나 모든 AI 모델 접근을 보장하지 않으므로 로그인·권한·기능 가용성 오류를 처리해야 합니다.
인증 정보는 메모리에만 보관하고 해당 호스트가 문서화한 Cloud Ability 통합에만 사용하세요. 로그, 스크린샷, URL, 로컬 저장소, 소스에 넣지 않습니다. 사용 전 만료를 확인하고 필요하면 다시 받으며 계정·플레이 변경 시 버립니다. 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>가 완료되지만 효과 실행이나 지속 연결 증거는 아닙니다. 상태를 별도 구독하세요. 복구 동안 무기한 대기할 수 있어 await 전에 중지 조작을 제공해야 합니다. 이미 연결 의도가 있으면 기존 대기를 공유하거나 즉시 완료하며 원래 핸들러는 바꾸지 않습니다. 변경 전 연결을 끊으세요.
onCommand가 없으면 일반 Error로 거부합니다. 준비 전 중지·종료 상태도 대기 중 Promise를 거부합니다. 일시적 통신·세션 오류는 대체로 즉시 거부하지 않고 복구합니다. 서로 다른 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 자체는 0이나 앞자리 0을 거부하지 않음 |
timestamp | string | 원본 시간 표현. 타입은 단위·형식을 보장하지 않으며 신원·순서 증거가 아님 |
아래는 명령 예제이지 선물 등록 API가 아닙니다. 시청자 ID, 이름, 선물 가격·실제 선물 ID는 없습니다. count는 매핑된 명령 수량이며 실제 선물 개수나 코인 값과 다를 수 있습니다.
{
"messageId": "example-command-001",
"instruction": "gift_flash",
"count": "3",
"timestamp": "1791800000"
}| 핸들러 결과 | SDK 동작 |
|---|---|
true 또는 true로 완료 | 성공 보고. 효과·영수증 커밋 이후에만 반환 |
false 또는 false로 완료 | 효과 없는 미지원 명령 등 확정된 실패·거부 보고 |
| throw·Promise 거부·비불리언 | 결과 미확정으로 ACK하지 않음. 재연결 후 재전송 가능 |
SDK 메모리 중복 방지는 제한적이며 명시적 연결 해제나 새로고침으로 사라집니다. 영구적인 정확히 한 번 실행 보장이 아닙니다. messageId, 효과, 결과를 원자적으로 저장하고 중복이면 저장 결과를 반환하세요. 일부 효과가 생겼는지 불명확하면 false로 바꾸면 안 됩니다. Gift Arena에 트랜잭션 예제가 있습니다.
아래 도우미는 즉시 취소를 제공하고 거부 처리를 등록합니다. 실제 명령 핸들러와 예외를 던지지 않는 UI 콜백을 전달합니다. 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 | 비어 있거나 새 값이 생길 수 있는 진단 문자열. 닫힌 enum 아님 |
action: none | 복구 조작 요구 없음 |
action: wait | 복구 대기, 취소는 계속 제공 |
action: relaunch_game | LIVE Studio에서 게임을 다시 열도록 안내. 방송 재시작 아님 |
confirmedAtMs | 최근 TikTok 시작·하트비트 확인의 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가 같아도 하트비트 확인 시각이 바뀌면 호출될 수 있습니다.
UI 제거 시 구독을 해제합니다. 해제는 연결을 끊지 않고 연결 해제도 리스너를 없애지 않습니다. 리스너에서 예외를 던지지 마세요. 최초 즉시 호출의 오류는 바깥으로 전파될 수 있습니다. 예제는 디버깅용 프로토콜 값이며 실제 문구는 다국어 처리하세요.
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). 타이머·재시도·소켓을 멈추고 메모리 실행·결과 캐시를 비우며 대기 중 연결을 거부합니다. unknown / client_disconnected / wait, confirmedAtMs: 0을 발행합니다.
TikTok 방송을 동기 종료하거나 서버 종료 ACK를 증명하는 API가 아닙니다. 게임이 저장한 영수증을 지우거나 실행 중 핸들러를 롤백하지 않습니다. UI 구독을 별도 해제하고 늦게 끝나는 작업을 제어하며 영구 영수증을 보존하세요. 같은 클라이언트로 재연결할 수 있고 정리할 때 반복 해제해도 안전합니다.
import type { TTLiveClient } from './combos-host-sdk';
function stopTikTok(client: TTLiveClient, unsubscribe: () => void) {
unsubscribe();
client.disconnect();
}오류와 복구
호스트 메서드는 문자열 code, message가 있는 Error로 거부됩니다. 메시지가 아닌 코드로 분기하세요. 목록은 완전하지 않으며 호스트·백엔드 코드가 추가될 수 있습니다. TikTok 수명 주기 오류는 코드 없는 일반 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 | 요청 전송 실패 | 지원 플레이어 환경 확인, 대체 UI 유지 |
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 대기만 멈추며 로그인·권한·번역의 공개 취소 API는 없습니다. UI를 다시 열거나 불확실한 작업을 중복하는 자동 재시도는 피합니다.
수명 주기와 통합 경계
- 문서의 기능을 읽고 독립 계정 동작마다 직전에 로그인 상태를 확인합니다.
- 로그인·권한은 플레이어 동작에 연결하고 취소·거부 후 자동 재표시하지 않습니다.
- 원문을 유지하고 번역은 선택적으로 적용하며 제거된 장면의 늦은 UI 결과를 버립니다.
- 한 모듈이 TikTok 클라이언트를 소유하고 구독·영구 명령 처리·연결·대기 취소를 관리합니다.
- 나갈 때 구독 해제·연결 종료를 수행하고 영수증은 보존하며 계정·플레이 종료 시 민감 세션은 버립니다.
window.combos에는 전체 dispose(), 계정 변경 이벤트, 로그인 취소 핸들, 공통 요청 제한 시간 설정이 없습니다. 내부 클래스나 비공개 HTTP로 대신 구현하지 마세요. 예제 함수와 저장 한도는 게임 설계이지 SDK 추가 API가 아닙니다.
버전, 타입과 완성 예제
공개 TypeScript 선언 이 편집기용 타입의 기준입니다. 이 문서는 SDK 1.1.0의 런타임 검증·시간 초과·Web 기능 선택·번역·TikTok 수명 주기도 확인했습니다. 타입 존재는 실제 지원을 의미하지 않으며 이후 버전에서 달라질 수 있습니다.
- 계정과 다국어: 버튼, 로그인 이후 계속하기, 안전한 텍스트 갱신.
- TikTok 게임 제작: 선물, 전체 프로젝트, 로컬 테스트, 게시, 준비와 개통 후 LIVE 검증.
- Gift Arena 다운로드: 트랜잭션 명령 처리까지 포함한 전체 소스.
예제를 공개 타입으로 검사해도 실제 계정 로그인, Cloud Ability 접근, 유료 선물 전달이 검증되는 것은 아닙니다. 해당 흐름은 지원 호스트와 자격 있는 계정·등록 게임에서 별도로 검증해야 합니다.