Référence API du SDK Combos
SDK 1.1.0 · Vérifié le 2026-10-13. Cette API JavaScript est exposée aux jeux par window.combos. Elle comprend les 10 méthodes globales et les 4 méthodes du client TikTok. Chaque méthode présente ses entrées exactes, son résultat, ses échecs et un exemple. Pour créer un jeu complet, suis le tutoriel TikTok ; pour relier l’interface, consulte comptes et localisation.
Les appels passent par l’hôte Combos. Il s’agit de méthodes JavaScript, pas de points d’accès REST : aucune URL de base, clé API, enveloppe de statut HTTP ni construction manuelle de postMessage n’est nécessaire dans le jeu. La valeur résolue est directement le résultat, sans enveloppe data.
Environnement d’exécution et configuration TypeScript
Le lecteur Combos compatible injecte le SDK. N’installe pas un second script d’exécution et ne remplace pas window.combos. Un site autonome ou un aperçu local peut ne pas avoir cet objet ; vérifie sa présence dans le navigateur et conserve le jeu de base. N’accède pas à window pendant le rendu serveur.
Pour l’autocomplétion, enregistre la déclaration publique sous combos-host-sdk.d.ts à côté des sources du jeu et inclus ce dossier dans le projet TypeScript. Ce fichier fournit uniquement des types. Les exemples qui importent TTLiveClient utilisent import type, sans dépendance à l’exécution.
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;
}Chaque bloc TypeScript est une fonction auxiliaire indépendante : appelle-la depuis ton interface et intercepte les promesses rejetées. Les fonctions terminant par AfterClick correspondent à une action du joueur. Leur éventuel null indique une indisponibilité ou une annulation selon le code ; ce n’est pas un résultat supplémentaire du SDK. Les blocs JSON illustrent les requêtes ou résultats bruts avec des identités et dates fictives. Adapte les textes d’interface à la langue du jeu.
Index des méthodes
| Méthode | Fonction | Délai d’attente de la requête à l’hôte |
|---|---|---|
init() | Découvrir les capacités | 3 secondes, puis repli de compatibilité |
checkSession() | Lire l’état de connexion du compte | 10 secondes |
login() | Ouvrir l’authentification de l’hôte | 5 minutes |
getUserInfo() | Lire l’identité du joueur pour ce jeu | 10 secondes |
requestI18n(params) | Traduire les textes source visibles | 30 secondes |
getSetting() | Lire les décisions Cloud Ability | 10 secondes |
authorize(params) | Demander une permission | 5 minutes |
openSetting() | Ouvrir les permissions de l’hôte | 5 minutes |
getCloudAbilitySession() | Obtenir une session temporaire | 10 secondes |
getTTLiveClient() | Obtenir le client de ce document | Synchrone, sans requête |
client.connect(options) | Démarrer le flux d’interaction | Cycle propre, sans délai global fixe |
client.getLiveStatus() | Interroger l’état d’interaction | Requête de session, puis jusqu’à 5 secondes pour HTTP |
client.onStatusChange(listener) | S’abonner à l’état | Synchrone |
client.disconnect() | Arrêter ce client | Synchrone |
Le premier appel à l’hôte peut aussi prendre jusqu’à 3 secondes pour découvrir les capacités. Ce sont des limites d’attente du SDK, pas des garanties de service. Les méthodes publiques n’acceptent ni timeout, ni AbortSignal, ni callback de succès, ni paramètre d’identité supplémentaire.
Vérifier la disponibilité avant l’appel
Utilise init().methods, pas seulement l’existence d’une fonction. L’hôte Web actuel propose checkSession et login ; getUserInfo dépend d’un contexte de jeu fiable, requestI18n du support de traduction de l’hôte Play, et TikTok de la capacité de l’hôte et d’un contexte de lancement enregistré. Les anciens hôtes Web ou App peuvent différer.
L’hôte Web actuel n’annonce ni getSetting, ni authorize, ni openSetting, ni getCloudAbilitySession. Leur contrat concerne les hôtes qui les annoncent explicitement. Publier un jeu n’active pas automatiquement Cloud Ability ou TikTok. Une méthode absente des capacités rejette avec unsupported avant d’envoyer sa requête à l’hôte.
getTTLiveSession est un nom de capacité interne. Vérifie-le avant d’utiliser getTTLiveClient() ; il n’existe aucune méthode publique combos.getTTLiveSession(). L’API globale ne propose pas non plus logout, de request générique, de sauvegarde cloud, de paiement, de classement ou d’enregistrement de cadeaux.
Initialisation et comptes
combos.init()
combos.init(): Promise<ICombosHostInitResult>
Paramètres : aucun. Authentification requise : non. Résultat : une promesse contenant methods, tableau des capacités disponibles. Cet appel ne connecte pas le joueur, n’ouvre aucune interface et ne démarre pas TikTok.
Les appels simultanés partagent la découverte ; son résultat est mis en cache pour le document courant du jeu. Les autres méthodes de l’hôte effectuent automatiquement cette découverte. Les noms inconnus et doublons d’une liste valide sont filtrés. Si la découverte échoue, si le contenu est invalide ou si l’hôte ne répond pas pendant 3 secondes, le résultat est ['checkSession', 'login']. Une liste vide valide reste vide. Ce repli de compatibilité ne prouve pas qu’une page autonome dispose d’un hôte fonctionnel. Les appels suivants peuvent encore expirer. Aucune option publique ne force le rafraîchissement.
La réponse suivante est illustrative ; ne suppose pas que ces méthodes sont toujours 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>
Paramètres : aucun. Authentification requise : non. Résultat : true si l’hôte confirme une session connectée, sinon false. La lecture n’ouvre pas l’authentification. Seul le booléen exact true est accepté, pas une chaîne ou un objet évalué comme vrai.
Lis l’état juste avant chaque action de compte indépendante. Ne conserve pas ce résultat comme garantie permanente : la session peut ensuite changer. Une erreur de transport ou un délai dépassé rejette la promesse ; ce n’est ni un false normal ni une preuve de déconnexion. Si le résultat vaut false, laisse le joueur choisir de se connecter. Après un login() réussi pour la même action, continue directement sans seconde vérification.
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>
Paramètres : aucun ; n’envoie jamais d’identifiant de compte, mot de passe ou token. Authentification requise : non. Effet : ouvre le parcours de connexion de l’hôte si nécessaire. Déclenche-le par une action du joueur et désactive le contrôle pendant l’attente.
status | Signification et suite |
|---|---|
success | L’action peut continuer sans rechargement, interrogation répétée ou seconde vérification |
cancelled | Le joueur a annulé ; retourne au jeu sans boucle d’erreur ni nouvelle demande automatique |
L’annulation résout normalement la promesse. Une fenêtre bloquée, une erreur de transport ou de synchronisation de connexion, ou un délai dépassé entraînent un rejet. Un résultat mal formé ou un statut inconnu donne request_failed. Sur l’hôte Web actuel, un joueur déjà connecté reçoit success sans nouvelle authentification. Le résultat ne contient ni secret de connexion ni profil ; demande ce dernier séparément.
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>
Paramètres : aucun. Prérequis : getUserInfo annoncé, contexte de jeu fiable dans l’hôte et session existante. Sans session, l’appel rejette avec session_required. Une vérification préalable réussie ne dispense pas de traiter une expiration ultérieure.
| Champ | Type et présence | Signification |
|---|---|---|
appId | string obligatoire, non vide | Identité applicative du jeu ; pas une URL de Post ni un ID de projet fourni par le jeu |
openId | string obligatoire, non vide | Identité du joueur dans cette application ; à associer à appId |
nickName | string obligatoire, éventuellement vide | Nom affiché ; prévois un remplacement |
avatarUrl | string obligatoire, éventuellement vide | Avatar affiché ; prévois un remplacement s’il manque ou ne charge pas |
locale | string obligatoire, non vide | Langue publique enregistrée du joueur, par exemple en ou zh-CN ; langue actuelle du produit si aucune n’est enregistrée |
La réponse ne contient ni email, téléphone, ID de plateforme, token de connexion, ni session Cloud Ability. Ne déduis pas une identité entre applications depuis openId et n’utilise pas cette réponse du navigateur comme preuve d’authentification serveur. Affiche les chaînes comme du texte, pas du HTML. Une identité absente, un champ d’affichage non textuel ou un autre résultat invalide entraîne request_failed ; l’hôte/backend peut transmettre d’autres codes.
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"
}Localisation du jeu
combos.requestI18n(params)
combos.requestI18n(params: ICombosHostRequestI18nParams): Promise<ICombosHostI18nResult>
Authentification requise : le pont Web actuel de traduction n’exige pas de connexion. L’hôte doit annoncer requestI18n. Affiche d’abord les textes source ; la traduction est une amélioration asynchrone facultative, pas une condition de chargement.
| Paramètre | Type | Obligatoire | Signification |
|---|---|---|---|
sourceLocale | string | Oui | Langue des textes fournis, par exemple en ou zh-CN ; pas la langue cible |
sourceTexts | string[] | Oui | Chaînes source exactes ou modèles stables déjà affichés dans le jeu |
Il n’y a pas de paramètre targetLocale. L’hôte choisit sa langue produit actuelle. Le traitement Web supprime les espaces aux extrémités du locale, ignore les textes vides ou non textuels, élimine les doublons et traduit par lots de 50. Cette taille de lot n’est pas une limite publique d’entrée du SDK. Privilégie de petits groupes de textes stables pour tenir dans les 30 secondes ; ne traduis pas à chaque image d’animation.
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}" }
}| Champ du résultat | Signification |
|---|---|
needed: false | Conserve tous les textes source ; locale et translations sont absents |
needed: true | Des traductions existent, mais la correspondance peut être partielle |
locale | Langue cible choisie par l’hôte ; présente uniquement avec needed: true |
translations | Texte source → traduction ; les clés sont les textes exacts, pas les IDs de l’application |
Des langues équivalentes, aucun texte utilisable, une traduction indisponible ou une erreur actuelle du backend Web peuvent tous produire { needed: false }. Le SDK convertit aussi les résultats de traduction mal formés vers ce cas. Les méthodes non disponibles et les délais de transport peuvent toutefois rejeter. Pour toute traduction absente ou vide, conserve l’original. Applique avec textContent, jamais innerHTML.
Traduis les modèles tels que Score: {score} avant d’insérer les valeurs : le SDK ne remplace pas les marqueurs. Vérifie la présence des marqueurs nécessaires avant d’utiliser une traduction. Conserve les sources entre appels au lieu de retraduire des textes déjà traduits avec un sourceLocale périmé.
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 Cloud Ability facultatives
Ces quatre méthodes ne sont pas annoncées par l’hôte Web actuel. Détecte chacune séparément. Les exemples servent à une intégration conditionnelle sur un hôte compatible, pas à activer la fonction. Une autorisation accordée ne prouve pas non plus que le propriétaire du jeu a activé la capacité sous-jacente.
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 }| Champ ou valeur | Contrat |
|---|---|
scope | Seul 'ai_model' est défini ; obligatoire pour authorize |
decision | L’exécution accepte AUTHORIZATION_DECISION_GRANTED ou AUTHORIZATION_DECISION_DENIED |
AUTHORIZATION_DECISION_UNSPECIFIED | Valeur zéro présente dans l’union exportée, mais non acceptée comme décision retournée valide |
decidedAtMs | Nombre fini obligatoire, date Unix en millisecondes ; pas des secondes ni une expiration |
Clé ai_model absente | Le joueur n’a jamais été interrogé sur ce scope du jeu ; distinct d’un refus |
session | Secret non vide obligatoire, temporaire, à conserver uniquement en mémoire |
expiresAtMs | Nombre fini obligatoire, expiration Unix en millisecondes ; aucun TTL fixe garanti |
Ces API ne prennent aucun ID d’utilisateur, appareil, projet, Post ou instance de jeu. L’hôte fournit le contexte fiable et contrôle les interfaces de connexion et de permission. Respecte ses prérequis de session avant les actions protégées. Ne relance pas les demandes en boucle après un refus.
combos.getSetting()
combos.getSetting(): Promise<ICombosHostAuthSetting>
Paramètres : aucun. Délai : 10 secondes. Lit les décisions du joueur pour le jeu courant sans ouvrir les paramètres. Résout avec ICombosHostAuthSetting ; {} est valide si la décision ai_model est absente.
Le SDK conserve uniquement le scope connu ai_model. S’il existe, il exige une décision accordée/refusée et un decidedAtMs fini ; un enregistrement invalide rejette avec request_failed. N’assimile pas un scope absent à un refus et ne garde pas une décision périmée après modification des paramètres.
{
"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>
Paramètres : objet obligatoire contenant scope: 'ai_model' ; aucune valeur par défaut, joker, liste de scopes ou décision fournie par l’appelant. Délai : 5 minutes. Cette demande interactive appartient à l’hôte ; déclenche-la par une action du joueur.
Renvoie un enregistrement d’autorisation, pas tous les paramètres. AUTHORIZATION_DECISION_DENIED est un résultat normal. Continue l’action autorisée seulement après GRANTED ; un refus ne justifie pas une nouvelle demande automatique. Il n’existe pas de résultat cancelled. Interprète la fermeture de l’interface via l’enregistrement ou le rejet reçu, pas via les statuts de login. Hôte incompatible, résultat invalide, erreur de transport ou délai dépassé entraînent un rejet.
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>
Paramètres : aucun. Délai : 5 minutes. Ouvre les permissions de l’hôte depuis une action du joueur et résout avec le ICombosHostAuthSetting résultant. Aucun objet ne permet d’accorder discrètement des permissions.
Actualise l’interface à partir des paramètres reçus, y compris les scopes absents ou refusés. Le résultat n’est ni un booléen, ni un enregistrement unique, ni un statut de connexion. La validation est celle de getSetting(). Méthode non disponible, résultat invalide et erreur de l’hôte/transport rejettent. Le SDK ne définit pas de statut d’annulation distinct.
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>
Paramètres : aucun. Délai : 10 secondes. Sur un hôte compatible, résout avec { session, expiresAtMs } pour la partie courante. L’appel n’affiche pas de permission et ne prouve pas un accès à tous les modèles d’IA. Gère les erreurs de session, permission et disponibilité de l’hôte.
Garde le secret en mémoire et utilise-le uniquement avec l’intégration Cloud Ability documentée par cet hôte. Ne l’inclus jamais dans des logs, captures, URL, stockage local ou code source. Vérifie l’expiration, obtiens une nouvelle session si nécessaire et supprime l’ancienne lors d’un changement de joueur ou de partie. Aucun refreshToken, paramètre TTL ou garantie d’authentification générique de backend n’est prévu. Un résultat mal formé rejette avec 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.
}Référence du client TikTok
Aucun parcours d’activation de l’intégration TikTok réelle n’est actuellement disponible. Le contrat ci-dessous ne signifie pas qu’un jeu nouvellement publié peut recevoir de vrais cadeaux. Tu peux créer le jeu, lancer le simulateur et publier sur Combos ; l’intégration réelle doit attendre un processus d’activation fourni par la plateforme.
Le client gère la session d’interaction TikTok de ce jeu, pas l’état global du LIVE du streamer. Il contrôle le transport, les heartbeats, le renouvellement de session et les reconnexions. Le jeu contrôle les instructions, effets, déduplication persistante et résultats fidèles. Le tutoriel complet fournit le mappage des cadeaux, la publication, les éléments de préparation et le projet exécutable.
combos.getTTLiveClient()
combos.getTTLiveClient(): TTLiveClient
Paramètres : aucun. Résultat : un TTLiveClient synchrone, sans requête réseau lors de sa récupération. Les appels répétés renvoient la même instance pour ce document SDK/jeu ; évite des contrôleurs concurrents dans différents composants.
Vérifie la capacité getTTLiveSession comme ci-dessous. Un objet client ne prouve ni compatibilité, ni connexion du compte, ni lancement enregistré, ni connexion du flux. Effectue le parcours de compte avant une connexion réelle. Clés fournisseur, secrets CAS, launchData et URL WebSocket sont gérés en interne ; aucun paramètre ne les accepte ici.
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>
Paramètres : objet options obligatoire. Son onCommand obligatoire doit retourner boolean ou Promise<boolean>. La signature publique n’offre aucune option de salle, streamer, token, reconnexion ou délai.
Renvoie Promise<void> après la trame de disponibilité du flux. Cela ne prouve ni un effet de cadeau ni une connexion permanente ; observe l’état séparément. La récupération peut laisser la promesse en attente indéfiniment. Prévois une action d’arrêt avant de l’attendre. Un nouvel appel à connect alors que la connexion est déjà demandée réutilise la promesse en attente ou résout immédiatement ; il ne remplace pas le gestionnaire initial. Déconnecte avant d’en changer.
L’absence de onCommand rejette avec un Error ordinaire. Une déconnexion explicite ou un état terminal avant disponibilité rejette aussi la promesse en attente. Les erreurs transitoires de transport/session passent généralement en récupération plutôt qu’en rejet immédiat. Des IDs de commande différents peuvent appeler des gestionnaires asynchrones simultanément ; sérialise les modifications partagées ou utilise des transactions.
interface TTLiveConnectOptions {
onCommand: (command: TTLiveCommand) => boolean | Promise<boolean>;
}
interface TTLiveCommand {
messageId: string;
instruction: string;
count: string;
timestamp: string;
}| Champ du callback | Type et validation | Responsabilité du jeu |
|---|---|---|
messageId | string non vide, au plus 256 caractères dans SDK 1.1.0 | Clé opaque d’idempotence ; persiste le résultat avec l’effet |
instruction | string | Compare aux instructions déclarées ; le SDK ne valide pas ton catalogue de cadeaux |
count | string de chiffres décimaux conservant la précision des grands entiers | Vérifie les limites avant conversion ; n’utilise pas Number aveuglément. Le parseur accepte zéro et les zéros initiaux |
timestamp | string | Représentation temporelle source ; le type public ne garantit ni unité ni format. Ce n’est pas une preuve d’identité ou d’ordre |
Cet exemple illustre une commande, pas une API d’enregistrement de cadeaux. Le callback ne contient aucun ID de spectateur, nom, prix ou ID de cadeau réel. count est la quantité de l’instruction mappée, pas nécessairement le nombre de cadeaux ou leur valeur en pièces.
{
"messageId": "example-command-001",
"instruction": "gift_flash",
"count": "3",
"timestamp": "1791800000"
}| Résultat du gestionnaire | Comportement du SDK |
|---|---|
true ou promesse résolue à true | Signale une exécution réussie ; retourne seulement après validation de l’effet et de sa trace persistée |
false ou promesse résolue à false | Signale un refus/échec certain, par exemple une instruction non prise en charge sans effet |
| Exception, promesse rejetée ou résultat non booléen | Résultat inconnu, sans ACK ; le SDK reconnecte et la commande peut revenir |
La déduplication en mémoire est limitée et effacée par une déconnexion explicite ou le rechargement. Elle ne garantit pas une exécution persistante exactement une fois. Enregistre atomiquement messageId, effet et résultat ; rejoue le résultat conservé pour les doublons. Ne retourne pas false après un effet partiel dont l’issue est incertaine. L’exemple Gift Arena utilise une transaction.
Cette fonction auxiliaire rend l’annulation immédiatement disponible et traite les rejets. Fournis ton vrai gestionnaire et des callbacks d’interface qui ne lèvent pas d’erreur ; connected reste disponible pour une attente. Conserve stop pour les connexions en attente comme établies.
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>
Paramètres : aucun. Interroge l’état courant, le publie aux abonnés et résout avec TTLiveStatus. Ne démarre pas le flux de commandes. Obtient d’abord la session de l’hôte (requête de 10 secondes, plus découverte initiale si nécessaire), puis limite la requête HTTP d’état à 5 secondes.
Les erreurs réseau, HTTP, de session ou de contenu d’état sont représentées par des résultats, généralement unknown, et ne prouvent pas ended. Un tt_not_launched de l’hôte devient ended avec relaunch_game. Un état terminal arrête aussi un client actif. Pendant le jeu, privilégie les abonnements aux interrogations répétées.
interface TTLiveStatus {
state: 'connecting' | 'connected' | 'recovering' | 'ended' | 'unknown';
reason: string;
action: 'none' | 'wait' | 'relaunch_game';
confirmedAtMs: number;
}| Champ ou valeur | Signification et action |
|---|---|
state: connecting | Connexion initiale en cours |
state: connected | Session d’interaction du jeu confirmée |
state: recovering | Récupération du transport ; laisse le SDK gérer ses tentatives |
state: unknown | Confirmation indisponible ; ne déclare pas le LIVE terminé |
state: ended | Cette session d’interaction est terminée ; examine action |
reason | Chaîne de diagnostic, éventuellement vide ou enrichie de nouvelles valeurs ; pas un enum fermé |
action: none | Aucune récupération demandée |
action: wait | Attendre la récupération ; conserver un contrôle d’annulation |
action: relaunch_game | Demander au streamer de rouvrir le jeu depuis LIVE Studio, pas de redémarrer le LIVE |
confirmedAtMs | Millisecondes Unix du dernier démarrage/heartbeat TikTok confirmé ; 0 signifie inconnu, pas une expiration |
Les motifs connus incluent platform_unconfirmed, transport_unavailable, client_disconnected, tt_not_launched et session_required. Pilote la récupération avec state et action ; la liste n’est pas exhaustive et les motifs bruts ne sont pas des textes finaux pour les joueurs.
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
Paramètres : listener synchrone obligatoire recevant TTLiveStatus. Résultat : fonction de désabonnement. Le listener reçoit immédiatement l’état courant, puis chaque changement de champs ; un nouveau temps de confirmation de heartbeat peut déclencher une mise à jour sans changement de state.
Désabonne lors du retrait de l’interface concernée. Retirer un listener ne déconnecte pas le client ; déconnecter ne retire pas les listeners. Ne lève pas d’erreur dans le listener : l’appel immédiat peut propager une erreur du consommateur. L’exemple affiche les valeurs du protocole pour déboguer ; localise les messages de production.
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
Paramètres : aucun. Résultat : undefined (void). Arrête les temporisateurs, tentatives et socket ; vide le cache d’exécution/résultats en mémoire ; rejette une connexion encore en attente. Publie unknown / client_disconnected / wait avec confirmedAtMs: 0.
Ce n’est ni une API synchrone de fin de LIVE ni une preuve d’ACK de fin côté serveur. Cela ne supprime pas tes traces persistées et ne peut pas annuler un gestionnaire déjà en cours. Désabonne l’interface séparément, protège les opérations tardives et conserve les traces. Le même client peut ensuite reconnecter ; répéter la déconnexion est sûr pour le nettoyage.
import type { TTLiveClient } from './combos-host-sdk';
function stopTikTok(client: TTLiveClient, unsubscribe: () => void) {
unsubscribe();
client.disconnect();
}Erreurs et récupération
Les échecs des méthodes de l’hôte rejettent avec un Error portant code et message en chaînes. Compare code, pas le message humain. La liste n’est pas exhaustive : les codes de l’hôte/backend peuvent être transmis. Les erreurs du cycle TikTok peuvent être de simples Error sans code ; getLiveStatus représente volontairement de nombreux échecs comme des états.
Distingue les décisions normales des échecs : checkSession() === false, connexion cancelled, autorisation DENIED et traduction needed: false sont des résultats résolus. La fonction suivante préserve cette distinction sans supposer une classe précise ni journaliser de secrets.
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) };
}
}| Code | Signification | Récupération |
|---|---|---|
unsupported | Méthode non annoncée par l’hôte | Masquer/désactiver la capacité facultative et garder le jeu de base |
timeout | Attente du SDK expirée | Terminer le chargement et proposer une nouvelle tentative manuelle ; ne pas supposer une annulation par l’hôte |
transport_failed | Échec d’envoi à l’hôte | Vérifier le lecteur compatible et garder l’interface de repli |
request_failed | Échec de l’hôte ou résultat invalide | Intercepter, examiner l’action et réessayer seulement si c’est sûr |
disposed | Document/client SDK détruit | Arrêter ses traitements et callbacks ; éviter une boucle de tentatives |
session_required | Session de compte indisponible | Proposer la connexion puis reprendre l’action voulue |
model_not_supported | Modèle refusé par l’hôte/backend | Utiliser un modèle pris en charge par l’intégration Cloud Ability |
100250001 | Validation de permission échouée | Vérifier le scope et le contexte fiable du jeu |
100260001 / 100260002 | Création/contexte de session invalide ou session invalide | Rétablir la partie/session autorisée ; ne pas inventer d’IDs ou de secrets |
100260004 | Autorisation de modèle IA absente | Respecter la décision et demander l’autorisation à l’hôte si disponible |
100260005 | Capacité du jeu désactivée | Faire vérifier sa disponibilité par le propriétaire ; répéter le login ne l’active pas |
Ces nombres sont des codes connus de l’hôte/backend, pas une garantie de disponibilité de Cloud Ability dans le Web actuel. Applique d’abord les règles propres à chaque méthode. Pour un code inconnu, affiche une erreur récupérable et n’enregistre que des diagnostics non sensibles.
reason et action de TikTok sont des champs d’état, pas des codes d’erreur de l’hôte. Le rejet d’un gestionnaire ne génère pas automatiquement un ACK d’échec. N’entoure pas des effets peut-être déjà produits avec catch(() => false). Un délai dépassé arrête uniquement l’attente du SDK ; aucune annulation publique de login, permission ou traduction n’existe. Évite les tentatives automatiques qui rouvrent une interface ou répètent une action incertaine.
Cycle de vie et limites d’intégration
- Lis les capacités une fois par document ; vérifie le compte courant avant chaque nouvelle action de compte.
- Lie connexion et permissions à une action du joueur. Traite annulation/refus sans rouvrir la même demande.
- Garde la traduction facultative et les sources visibles. Ignore les résultats d’interface asynchrones périmés quand une scène est retirée.
- Confie le client TikTok du document à un seul propriétaire. Abonne l’état, connecte un gestionnaire persistant et permets l’annulation pendant l’attente.
- Désabonne et déconnecte en quittant l’interaction. Préserve les traces d’exécution et efface les sessions sensibles à la fin de la partie/du compte.
window.combos n’a ni dispose() global, ni événement de changement de compte, ni contrôle d’annulation de login, ni délai global configurable. N’utilise pas de classes internes ou de routes HTTP non documentées pour combler ces absences. Le code du demo et ses limites de stockage sont des choix du jeu, pas des API supplémentaires.
Version, types et exemples complets
La déclaration TypeScript publique définit les types pour l’éditeur. Cette référence vérifie aussi la validation à l’exécution du SDK 1.1.0, les délais, les capacités Web, la traduction et le cycle TikTok. L’existence d’un type ne démontre pas sa disponibilité ; les versions futures du SDK/hôte peuvent évoluer.
- Comptes et localisation : boutons, reprise après connexion et actualisation sûre des textes.
- Créer un jeu TikTok : déclaration de cadeaux, projet complet, tests locaux, publication et préparation de la future intégration et validation LIVE.
- Télécharger Gift Arena : sources complètes, avec traitement transactionnel des commandes.
Les exemples sont vérifiés contre les types publics. Cette vérification et le simulateur local ne prouvent ni connexion réelle, ni accès Cloud Ability, ni livraison de cadeaux payants ; ces parcours nécessitent un hôte éligible, le compte adapté et un jeu enregistré lorsqu’un processus d’activation sera disponible.