Referencia de API del SDK de Combos
SDK 1.1.0 · Revisado el 2026-10-13. Esta es la API JavaScript que los juegos utilizan mediante window.combos. Incluye los 10 métodos globales y los 4 del cliente TikTok. Cada método detalla sus entradas, resultado, comportamiento ante fallos y ejemplo. Para crear un juego completo, sigue el tutorial de TikTok; para conectar la interfaz, consulta cuentas y localización.
Las llamadas pasan por el host de Combos. Son métodos JavaScript, no endpoints REST: el juego no necesita una URL base de API, una clave de API, una envoltura de estado HTTP ni construir mensajes postMessage. El valor resuelto es el resultado directamente, sin una propiedad envolvente data.
Entorno de ejecución y configuración de TypeScript
El reproductor compatible de Combos inyecta el SDK. No instales un segundo script de ejecución ni sobrescribas window.combos. Una web independiente o una vista previa local puede carecer de este objeto; compruébalo desde el código del navegador y mantén disponible el juego básico. No accedas a window durante el renderizado en el servidor.
Para disponer de autocompletado, guarda la declaración pública como combos-host-sdk.d.ts junto al código del juego e incluye ese directorio en tu proyecto TypeScript. El archivo solo proporciona tipos. Los ejemplos que importan TTLiveClient usan import type, sin añadir dependencias de ejecución.
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;
}Cada bloque TypeScript es una función auxiliar independiente: invócala desde tu interfaz y captura los rechazos de las promesas. Las funciones terminadas en AfterClick corresponden a una acción iniciada por el jugador. El null de una función auxiliar indica indisponibilidad o cancelación según su código; no es un resultado adicional del SDK. Los bloques JSON muestran solicitudes o resultados sin envolturas, con identidades y fechas ficticias. Adapta los textos de interfaz al idioma de tu juego.
Índice de métodos
| Método | Función | Tiempo de espera de la solicitud al host |
|---|---|---|
init() | Descubrir capacidades | 3 segundos; después, compatibilidad de reserva |
checkSession() | Consultar el estado de sesión | 10 segundos |
login() | Abrir el inicio de sesión del host | 5 minutos |
getUserInfo() | Obtener la identidad del jugador para el juego | 10 segundos |
requestI18n(params) | Traducir texto original visible | 30 segundos |
getSetting() | Consultar decisiones de Cloud Ability | 10 segundos |
authorize(params) | Solicitar un permiso | 5 minutos |
openSetting() | Abrir los ajustes de permisos del host | 5 minutos |
getCloudAbilitySession() | Obtener una sesión temporal | 10 segundos |
getTTLiveClient() | Obtener el cliente de este documento | Síncrono; sin solicitud |
client.connect(options) | Iniciar el flujo de interacciones | Ciclo de vida propio; sin plazo total fijo |
client.getLiveStatus() | Consultar el estado de interacción | Solicitud de sesión y hasta 5 segundos para HTTP |
client.onStatusChange(listener) | Suscribirse al estado | Síncrono |
client.disconnect() | Detener este cliente | Síncrono |
La primera llamada al host puede emplear además hasta 3 segundos en descubrir capacidades. Son límites de espera del SDK, no garantías de servicio. Los métodos públicos no aceptan timeout, AbortSignal, callbacks de éxito ni parámetros adicionales de identidad.
Comprueba la compatibilidad antes de llamar
Consulta init().methods; no basta con que exista la función. El host Web actual admite checkSession y login; getUserInfo depende de un contexto de juego confiable, requestI18n del soporte de traducción del host Play y TikTok de su capacidad y contexto de inicio registrado. Otros hosts Web o App anteriores pueden diferir.
El host Web actual no anuncia getSetting, authorize, openSetting ni getCloudAbilitySession. Su contrato se documenta para hosts que los anuncien expresamente. Publicar un juego no activa automáticamente Cloud Ability ni TikTok. Un método ausente de la lista de capacidades rechaza con unsupported antes de enviar su solicitud al host.
getTTLiveSession es un nombre de capacidad interna. Comprueba su presencia antes de utilizar getTTLiveClient(); no existe un método público combos.getTTLiveSession(). La API global tampoco incluye métodos de logout, request genérico, guardado en la nube, pagos, clasificación o registro de regalos.
Inicialización y cuentas
combos.init()
combos.init(): Promise<ICombosHostInitResult>
Parámetros: ninguno. Requiere sesión: no. Devuelve: una promesa con methods, un array de nombres de capacidades disponibles. No inicia sesión, abre interfaces ni conecta con TikTok.
Las llamadas simultáneas comparten el descubrimiento; el resultado se almacena para el documento actual del juego. Los demás métodos del host lo ejecutan automáticamente. En una lista válida se eliminan nombres desconocidos y duplicados. Si el descubrimiento falla, el resultado no es válido o el host no responde en 3 segundos, resuelve con ['checkSession', 'login']. Una lista vacía válida permanece vacía. Esta reserva permite compatibilidad, pero no demuestra que una página independiente tenga un host operativo. Las llamadas posteriores aún pueden agotar su tiempo de espera. No hay una opción pública para forzar la actualización.
La siguiente respuesta es ilustrativa; no asumas que esos métodos están siempre disponibles.
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>
Parámetros: ninguno. Requiere sesión: no. Devuelve: true si el host confirma una sesión iniciada; en otro caso, false. Consulta el estado sin abrir el inicio de sesión. Solo el booleano exacto true cuenta como sesión iniciada; no se aceptan cadenas u objetos evaluados como verdaderos.
Consúltalo justo antes de cada acción independiente de cuenta. No conserves el resultado como garantía permanente: la sesión puede cambiar después. Un error de transporte o tiempo de espera rechaza la promesa; no equivale a un false normal ni demuestra un cierre de sesión. Si devuelve false, permite que el jugador elija iniciar sesión. Tras un login() satisfactorio para esa misma acción, continúa directamente sin repetir la comprobación.
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>
Parámetros: ninguno; nunca envíes ID de cuenta, contraseña o token. Requiere sesión: no. Efecto: abre el flujo de acceso del host cuando es necesario. Invócalo desde una acción del jugador y desactiva su control mientras espera.
status | Significado y siguiente paso |
|---|---|
success | La acción actual puede continuar, sin recargar, sondear ni volver a comprobar la sesión |
cancelled | El jugador canceló; vuelve al juego sin bucles de error ni nuevas solicitudes automáticas |
La cancelación resuelve normalmente. Una ventana bloqueada, un fallo de transporte o sincronización de sesión, o el tiempo de espera agotado rechazan la promesa. Un resultado mal formado o estado desconocido produce request_failed. En el host Web actual, un jugador que ya inició sesión recibe success sin un nuevo flujo de acceso. El resultado no contiene credenciales ni perfil; solicita este último por separado.
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>
Parámetros: ninguno. Condiciones previas: getUserInfo anunciado, contexto de juego confiable en el host y sesión existente. Sin sesión, rechaza con session_required. Una comprobación previa satisfactoria no elimina la necesidad de capturar una caducidad posterior.
| Campo | Tipo y presencia | Significado |
|---|---|---|
appId | string obligatorio y no vacío | Identidad de la aplicación del juego; no es una URL de Post ni un ID de proyecto suministrado por el juego |
openId | string obligatorio y no vacío | Identidad del jugador dentro de esta aplicación; úsala junto con appId |
nickName | string obligatorio, puede estar vacío | Nombre visible; proporciona una alternativa |
avatarUrl | string obligatorio, puede estar vacío | Avatar visible; usa una alternativa si falta o falla su carga |
locale | string obligatorio y no vacío | Idioma público guardado del jugador, como en o zh-CN; el idioma actual del producto si no hay ninguno guardado |
No contiene correo, teléfono, ID de usuario de plataforma, token de acceso ni sesión de Cloud Ability. No deduzcas identidades entre aplicaciones a partir de openId, ni uses esta respuesta del navegador como prueba de autenticación para tu servidor. Trata los nombres como texto, no HTML. Identidades ausentes, campos visibles que no sean cadenas u otro resultado inválido causan request_failed; el host y el backend pueden devolver códigos adicionales.
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"
}Localización del juego
combos.requestI18n(params)
combos.requestI18n(params: ICombosHostRequestI18nParams): Promise<ICombosHostI18nResult>
Requiere sesión: el puente Web actual de traducción no exige haber iniciado sesión. El host debe anunciar requestI18n. Muestra primero el texto original; la traducción es una mejora asíncrona opcional y no debe bloquear la carga.
| Parámetro | Tipo | Obligatorio | Significado |
|---|---|---|---|
sourceLocale | string | Sí | Idioma del texto suministrado, por ejemplo en o zh-CN; no es el idioma de destino |
sourceTexts | string[] | Sí | Cadenas originales exactas o plantillas estables que el juego ya muestra |
No existe targetLocale. El host selecciona su idioma actual de producto. El host Web actual recorta espacios del locale, omite entradas vacías o no textuales, elimina cadenas duplicadas y solicita traducciones en lotes de 50. Ese tamaño de lote no es un límite público de entrada del SDK. Prefiere grupos pequeños de textos estables para completar la petición dentro de los 30 segundos; no traduzcas en cada fotograma.
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}" }
}| Campo del resultado | Significado |
|---|---|
needed: false | Conserva todos los textos originales. No existen locale ni translations en esta rama |
needed: true | Hay traducciones disponibles, aunque el mapa puede ser parcial |
locale | Idioma de destino elegido por el host; solo aparece si needed es true |
translations | Texto original → traducción; las claves son los textos exactos, no IDs de tu aplicación |
Idiomas equivalentes, falta de texto utilizable, traducción no disponible y fallos actuales del backend Web pueden resolver con { needed: false }. El SDK también convierte resultados de traducción mal formados en esa rama. Los métodos no compatibles y los tiempos de espera de transporte sí pueden rechazar. Conserva el original para cada traducción ausente o vacía. Aplica el resultado con textContent, nunca innerHTML.
Traduce plantillas como Score: {score} antes de insertar valores: el SDK no interpola marcadores. Comprueba que los marcadores necesarios permanezcan en la plantilla traducida. Conserva los textos originales entre llamadas; no vuelvas a traducir textos ya traducidos con un sourceLocale desactualizado.
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.
}
}API opcionales de Cloud Ability
Estos cuatro métodos no se anuncian en el host Web actual. Detecta cada método individualmente. Los ejemplos son integración condicional para un host compatible, no una forma de activar la función. Una autorización concedida tampoco demuestra que el propietario haya habilitado la capacidad subyacente.
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 }| Campo o valor | Contrato |
|---|---|
scope | Solo está definido 'ai_model'; obligatorio para authorize |
decision | El entorno acepta AUTHORIZATION_DECISION_GRANTED o AUTHORIZATION_DECISION_DENIED |
AUTHORIZATION_DECISION_UNSPECIFIED | Figura como valor cero en la unión exportada; el SDK no lo acepta como decisión devuelta válida |
decidedAtMs | Número finito obligatorio; fecha Unix en milisegundos, no segundos ni fecha de caducidad |
Ausencia de ai_model | Nunca se ha consultado al jugador sobre este permiso del juego; no equivale a denegación |
session | Credencial obligatoria no vacía; sensible, temporal y solo en memoria |
expiresAtMs | Número finito obligatorio; caducidad Unix en milisegundos, sin TTL fijo garantizado |
Estas API no reciben IDs de usuario, dispositivo, proyecto, Post o instancia de juego. El host proporciona el contexto confiable y controla las interfaces de acceso y permisos. Cumple sus requisitos de sesión antes de acciones protegidas. No repitas automáticamente las solicitudes cuando se deniegue un permiso.
combos.getSetting()
combos.getSetting(): Promise<ICombosHostAuthSetting>
Parámetros: ninguno. Tiempo de espera: 10 segundos. Lee las decisiones del jugador actual para este juego sin abrir ajustes. Resuelve con ICombosHostAuthSetting; {} es válido si falta la decisión ai_model.
El SDK solo conserva el scope conocido ai_model. Si existe, exige una decisión concedida o denegada y un decidedAtMs finito; un registro inválido rechaza con request_failed. No interpretes la ausencia del scope como denegación ni mantengas una decisión obsoleta después de que el jugador cambie los ajustes.
{
"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>
Parámetros: un objeto obligatorio con scope: 'ai_model'; sin valor por defecto, comodines, array de scopes ni decisión del llamante. Tiempo de espera: 5 minutos. Solicitud interactiva de permiso controlada por el host; debe partir de una acción del jugador.
Devuelve un registro de autorización, no todos los ajustes. AUTHORIZATION_DECISION_DENIED es un resultado resuelto normal. Continúa la acción autorizada solo con GRANTED; una denegación no justifica repetir la solicitud automáticamente. No existe un resultado cancelled. Interpreta el cierre de la interfaz según el registro o rechazo real, no según los estados de login. Los hosts no compatibles, registros inválidos, errores de transporte y tiempos agotados rechazan.
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>
Parámetros: ninguno. Tiempo de espera: 5 minutos. Abre los ajustes de permisos del host mediante una acción del jugador y resuelve con el ICombosHostAuthSetting resultante. No acepta un objeto para conceder permisos silenciosamente.
Actualiza la interfaz con los ajustes devueltos, incluidos scopes ausentes o denegados. No devuelve un booleano, un registro individual ni un estado de acceso. Se aplica la misma validación que en getSetting(). Los métodos no compatibles, resultados inválidos y fallos del host o transporte rechazan. El SDK no define un estado de cancelación separado.
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>
Parámetros: ninguno. Tiempo de espera: 10 segundos. En un host compatible, resuelve con { session, expiresAtMs } para la partida actual. La llamada no muestra permisos ni demuestra acceso a todos los modelos de IA. Gestiona los errores de sesión, permisos y disponibilidad de capacidades del host.
Conserva la credencial en memoria y úsala únicamente con la integración Cloud Ability documentada por ese host. Nunca la incluyas en registros, capturas, URLs, almacenamiento local o código fuente. Comprueba su caducidad, obtén una nueva sesión cuando corresponda y descarta la anterior si cambia el jugador o la partida. No hay refreshToken, parámetro TTL ni garantía de autenticación general para un backend. Un resultado inválido rechaza con 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.
}Referencia del cliente TikTok
Actualmente no hay un proceso disponible para activar la integración real de TikTok. El contrato siguiente no significa que un juego recién publicado pueda recibir regalos reales. Puedes crear el juego, ejecutar el simulador y publicarlo en Combos; la integración real debe esperar a que la plataforma ofrezca un proceso de activación.
El cliente gestiona la sesión de interacción TikTok de este juego, no el estado global de la emisión LIVE. Controla transporte, latidos, renovación de sesión y reconexión. El juego controla las instrucciones, efectos, deduplicación persistente y resultados veraces. El tutorial completo incluye el mapeo de regalos, la publicación, materiales de preparación y un proyecto ejecutable.
combos.getTTLiveClient()
combos.getTTLiveClient(): TTLiveClient
Parámetros: ninguno. Devuelve: un TTLiveClient síncronamente, sin solicitud de red al obtenerlo. Las llamadas repetidas devuelven la misma instancia para este documento del SDK/juego; evita controladores en competencia entre componentes.
Comprueba la capacidad getTTLiveSession como en el ejemplo. Tener el objeto no acredita compatibilidad, sesión iniciada, inicio registrado ni conexión satisfactoria. Completa el flujo de cuenta antes de una conexión real. Las claves del proveedor, credenciales CAS, launchData y URLs de WebSocket se gestionan internamente; aquí no hay parámetros para proporcionarlos.
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>
Parámetros: un objeto options obligatorio con onCommand, función que devuelve boolean o Promise<boolean>. La firma pública no incluye opciones de sala, streamer, token, reconexión ni tiempo de espera.
Devuelve Promise<void> después de la trama de disponibilidad del flujo. No prueba un efecto de regalo ni conectividad permanente; observa el estado por separado. La recuperación puede dejar la promesa pendiente indefinidamente. Ofrece una acción para detener antes de esperarla. Repetir connect cuando la conexión ya está solicitada reutiliza la promesa pendiente o resuelve de inmediato; no sustituye el manejador original. Desconecta antes de cambiarlo.
La falta de onCommand rechaza con un Error normal. Una desconexión explícita o estado terminal antes de estar listo también rechaza la promesa pendiente. Los fallos transitorios de transporte o sesión suelen iniciar recuperación en vez de rechazar inmediatamente. IDs de comandos distintos pueden ejecutar manejadores asíncronos simultáneos; serializa los cambios compartidos o usa transacciones.
interface TTLiveConnectOptions {
onCommand: (command: TTLiveCommand) => boolean | Promise<boolean>;
}
interface TTLiveCommand {
messageId: string;
instruction: string;
count: string;
timestamp: string;
}| Campo del callback | Tipo y validación | Responsabilidad del juego |
|---|---|---|
messageId | string no vacío, máximo 256 caracteres en SDK 1.1.0 | Clave opaca de idempotencia; persiste el resultado junto con el efecto |
instruction | string | Coteja las instrucciones declaradas; el SDK no valida el catálogo de regalos |
count | string de dígitos decimales que conserva enteros grandes | Valida límites antes de convertir; no uses Number a ciegas. El parser permite cero y ceros iniciales |
timestamp | string | Representación temporal de origen; el tipo público no promete unidad ni formato. No prueba identidad u orden |
El ejemplo ilustra un comando, no una API de registro de regalos. El callback no incluye IDs de espectadores, nombres, precios o IDs de regalos reales. count es la cantidad de la instrucción mapeada, no necesariamente el número de regalos ni su valor en monedas.
{
"messageId": "example-command-001",
"instruction": "gift_flash",
"count": "3",
"timestamp": "1791800000"
}| Resultado del manejador | Comportamiento del SDK |
|---|---|
true o promesa resuelta en true | Comunica ejecución satisfactoria; devuelve solo tras confirmar el efecto y su registro |
false o promesa resuelta en false | Comunica rechazo o fallo definitivo, por ejemplo una instrucción no admitida sin efecto |
| Excepción, promesa rechazada o resultado no booleano | Resultado desconocido y sin ACK; el SDK reconecta y el comando puede repetirse |
La deduplicación en memoria es limitada y se borra al desconectar explícitamente o recargar el documento. No proporciona ejecución persistente exactamente una vez. Guarda atómicamente messageId, efecto y resultado; devuelve el resultado guardado para duplicados. No devuelvas false tras un efecto parcial cuyo resultado sea incierto. El ejemplo Gift Arena usa una transacción.
Esta función auxiliar permite cancelar de inmediato y registra el manejo de rechazos. Proporciona el manejador real y callbacks de interfaz que no lancen excepciones; aún puedes esperar connected. Conserva stop para conexiones pendientes y establecidas.
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>
Parámetros: ninguno. Consulta el estado actual, lo publica a los suscriptores y resuelve con TTLiveStatus. No inicia el flujo de comandos. Obtiene internamente la sesión del host (10 segundos de espera más el descubrimiento inicial si corresponde) y después limita a 5 segundos la solicitud HTTP de estado.
Los fallos de red, HTTP, formato de sesión o resultado de estado se representan como estados, normalmente unknown, y no demuestran ended. Un tt_not_launched del host se convierte en ended con relaunch_game. Un estado terminal también detiene un cliente activo. Durante el juego, prefiere suscripciones a sondear repetidamente este método.
interface TTLiveStatus {
state: 'connecting' | 'connected' | 'recovering' | 'ended' | 'unknown';
reason: string;
action: 'none' | 'wait' | 'relaunch_game';
confirmedAtMs: number;
}| Campo o valor | Significado y acción |
|---|---|
state: connecting | Se está estableciendo la conexión inicial |
state: connected | Se confirmó la sesión de interacción del juego |
state: recovering | El SDK recupera el transporte; deja actuar sus reintentos |
state: unknown | No hay confirmación; no declares terminada la emisión |
state: ended | Terminó esta sesión de interacción; revisa action |
reason | Cadena de diagnóstico, puede estar vacía o adquirir nuevos valores; no es un enum cerrado |
action: none | No se solicita recuperación |
action: wait | Espera la recuperación; mantén un control para cancelar |
action: relaunch_game | Pide al streamer que reabra el juego desde LIVE Studio, no que reinicie la emisión |
confirmedAtMs | Milisegundos Unix del último inicio o latido confirmado por TikTok; 0 significa desconocido, no caducidad |
Entre los motivos conocidos están platform_unconfirmed, transport_unavailable, client_disconnected, tt_not_launched y session_required. Decide la recuperación por state y action; la lista no es exhaustiva y los motivos crudos no son textos finales para jugadores.
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
Parámetros: listener síncrono obligatorio que recibe TTLiveStatus. Devuelve: una función para cancelar la suscripción. El listener se ejecuta inmediatamente con el estado actual y después cuando cambia algún campo; una nueva confirmación de latido puede provocar una actualización sin cambiar state.
Cancela la suscripción cuando desaparezca su interfaz. Quitar un listener no desconecta el cliente; desconectar tampoco elimina listeners. No lances excepciones en él: la llamada inmediata puede propagar un error del consumidor. El ejemplo imprime valores del protocolo para depurar; localiza los mensajes de producción.
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
Parámetros: ninguno. Devuelve: undefined (void). Detiene temporizadores, reintentos pendientes y socket; borra la caché en memoria de ejecuciones y resultados; rechaza una conexión aún pendiente. Publica unknown / client_disconnected / wait con confirmedAtMs: 0.
No es una API síncrona para terminar la emisión ni prueba un ACK de cierre del servidor. No elimina tus registros persistidos ni revierte un manejador en ejecución. Cancela las suscripciones por separado, protege el trabajo tardío del juego y conserva los registros. Después puedes volver a conectar el mismo cliente; repetir la desconexión es seguro para la limpieza.
import type { TTLiveClient } from './combos-host-sdk';
function stopTikTok(client: TTLiveClient, unsubscribe: () => void) {
unsubscribe();
client.disconnect();
}Errores y recuperación
Los métodos del host rechazan con un Error que contiene code y message de tipo cadena. Compara code, no el mensaje para humanos. La lista no es exhaustiva: pueden pasar códigos del host o backend. Los fallos del ciclo TikTok pueden ser objetos Error sin code; getLiveStatus representa deliberadamente muchos fallos como estados.
Distingue decisiones normales de fallos: checkSession() === false, cancelled en acceso, DENIED en autorización y needed: false en traducción son resultados resueltos. La función siguiente preserva esa diferencia sin asumir una clase concreta ni registrar credenciales.
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) };
}
}| Código | Significado | Recuperación |
|---|---|---|
unsupported | El host no anunció el método | Oculta o desactiva la capacidad opcional y conserva el juego básico |
timeout | Se agotó la espera del SDK | Finaliza la carga y ofrece reintento manual; no asumas que el host canceló la operación |
transport_failed | Falló el envío al host | Comprueba el reproductor compatible y mantén la interfaz alternativa |
request_failed | Fallo del host o resultado inválido | Captura el error, revisa la acción y reintenta solo si es seguro |
disposed | Se destruyó el documento o cliente del SDK | Detén su trabajo y callbacks; evita bucles de reintento |
session_required | No hay sesión de cuenta disponible | Ofrece acceso y después reintenta la acción original |
model_not_supported | El host o backend rechazó el modelo | Usa un modelo compatible con esa integración Cloud Ability |
100250001 | Falló la validación del permiso | Comprueba scope y contexto confiable del host |
100260001 / 100260002 | Creación o contexto de sesión inválido, o sesión inválida | Restablece la partida o sesión autorizada; no inventes IDs ni credenciales |
100260004 | Falta autorización para el modelo de IA | Respeta la decisión y usa autorización del host si está disponible |
100260005 | La capacidad del juego está desactivada | El propietario debe revisar la disponibilidad; repetir el acceso no la activa |
Los códigos numéricos son códigos conocidos del host o backend; no garantizan que el host Web actual exponga Cloud Ability. Primero aplica las reglas de disponibilidad de cada método. Para códigos desconocidos, muestra un error recuperable y registra solo diagnósticos no sensibles.
reason y action de TikTok son campos de estado, no códigos de error del host. Rechazar el manejador no genera automáticamente un ACK de fallo. No envuelvas efectos que quizá ya ocurrieron con catch(() => false). Un tiempo de espera del host solo detiene la espera del SDK; no existe cancelación pública de acceso, autorización o traducción. Evita reintentos automáticos que reabran interfaces o repitan acciones inciertas.
Ciclo de vida y límites de integración
- Lee las capacidades una vez por documento; comprueba la cuenta actual antes de cada nueva acción de cuenta.
- Vincula acceso y permisos a acciones del jugador. Gestiona cancelaciones y denegaciones sin reabrir la misma solicitud.
- Mantén opcional la traducción y visible el texto original. Descarta resultados de interfaz asíncronos obsoletos al eliminar una escena.
- Asigna un único responsable al cliente TikTok del documento. Suscribe el estado, conecta un manejador persistente y permite cancelar durante la espera.
- Cancela suscripciones y desconecta al salir de la interacción. Conserva los registros de ejecución y descarta sesiones sensibles al terminar la partida o cuenta.
window.combos no ofrece dispose() global, eventos de cambio de cuenta, cancelación de acceso ni ajuste global de tiempo de espera. No rellenes esas carencias llamando clases internas o rutas HTTP no documentadas. El demo descargable y sus límites de almacenamiento son decisiones del juego, no API adicionales del SDK.
Versión, tipos y ejemplos completos
La declaración pública de TypeScript define la forma para el editor. Esta referencia también contrasta la validación de ejecución de SDK 1.1.0, los tiempos de espera, las capacidades Web, la traducción y el ciclo TikTok. La existencia de un tipo no demuestra disponibilidad de ejecución; versiones futuras del SDK o host pueden cambiar el comportamiento.
- Cuentas y localización: botones, continuación del acceso y actualización segura de texto.
- Crear un juego TikTok: declaración de regalos, proyecto completo, pruebas locales, publicación y preparación de la futura integración y validación LIVE.
- Descargar Gift Arena: código completo con ejecución transaccional de comandos.
Los ejemplos se comprueban contra los tipos públicos. Esa comprobación y el simulador local no acreditan acceso con cuentas reales, permisos Cloud Ability ni entrega de regalos de pago; esas pruebas necesitan un host apto, la cuenta adecuada y un juego registrado cuando exista un proceso de activación.