Справочник API Combos SDK
SDK 1.1.0 · Проверено 2026-10-13. Это JavaScript API для игр, доступный через window.combos. Здесь описаны все 10 глобальных методов и 4 метода клиента TikTok: точные входные данные, результат, поведение при ошибках и пример. Полную игру можно создать по уроку TikTok, а подключение интерфейса описано в разделе аккаунты и локализация.
Вызовы проходят через хост Combos. Это методы JavaScript, а не REST-эндпоинты: игре не нужны базовый URL API, ключ API, HTTP-оболочка статуса или вручную составленные сообщения postMessage. Promise возвращает сам результат без внешнего поля data.
Среда выполнения и настройка TypeScript
Совместимый плеер Combos внедряет SDK. Не подключай второй скрипт среды выполнения и не перезаписывай window.combos. На отдельном сайте или в локальном предпросмотре глобальный объект может отсутствовать: проверяй его в браузерном коде и сохраняй базовую игру доступной. Не обращайся к window при серверном рендеринге.
Для подсказок редактора сохрани публичные объявления типов как combos-host-sdk.d.ts рядом с исходниками игры и включи каталог в проект TypeScript. Файл содержит только типы. Примеры с 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() | Проверить состояние взаимодействия | Запрос сессии, затем до 5 секунд на HTTP |
client.onStatusChange(listener) | Подписаться на состояние | Синхронно |
client.disconnect() | Остановить клиент | Синхронно |
Первый вызов хоста может дополнительно занять до 3 секунд на определение возможностей. Это пределы ожидания SDK, а не гарантии сервиса. Публичные методы не принимают timeout, AbortSignal, callback успеха или дополнительные параметры личности.
Проверка доступности перед вызовом
Используй init().methods, а не просто наличие функции. Текущий Web-хост поддерживает checkSession и login; getUserInfo зависит от доверенного контекста игры, requestI18n — от перевода в хосте Play, а TikTok — от возможности хоста и зарегистрированного контекста запуска. Старые Web- и App-хосты могут отличаться.
Текущий Web-хост не объявляет getSetting, authorize, openSetting и getCloudAbilitySession. Их контракт описан для хостов, которые явно их объявляют. Публикация игры не активирует Cloud Ability или TikTok автоматически. Метод, отсутствующий в списке возможностей, отклоняет Promise с unsupported до отправки своего запроса хосту.
getTTLiveSession — имя внутренней возможности. Проверь его перед getTTLiveClient(); публичного метода combos.getTTLiveSession() нет. Глобальный API также не содержит logout, универсального request, облачного сохранения, оплаты, таблицы лидеров или регистрации подарков.
Инициализация и аккаунты
combos.init()
combos.init(): Promise<ICombosHostInitResult>
Параметры: нет. Вход обязателен: нет. Результат: Promise с methods, массивом названий поддерживаемых возможностей. Метод не выполняет вход, не открывает интерфейс и не запускает 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. Метод не открывает окно входа. 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 аккаунта, пароль или токен. Вход обязателен: нет. Эффект: при необходимости открывает вход через хост. Вызывай по действию игрока и отключай запустивший элемент на время ожидания.
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 | Идентичность приложения игры; не URL Post и не переданный игрой ID проекта |
openId | Обязательная непустая string | Идентичность игрока в этом приложении; используй вместе с appId |
nickName | Обязательная string, может быть пустой | Отображаемое имя; предусмотри замену |
avatarUrl | Обязательная string, может быть пустой | Аватар; используй замену при отсутствии или ошибке загрузки |
locale | Обязательная непустая string | Сохранённый публичный язык игрока, например en или zh-CN; текущий язык продукта, если сохранённого нет |
Ответ не содержит email, телефон, ID пользователя платформы, токен входа или сессию Cloud Ability. Не связывай личности разных приложений по openId и не используй ответ браузеру как доказательство аутентификации для своего сервера. Отображай строки как текст, не HTML. Отсутствующие идентификаторы, нестроковые отображаемые поля и другие некорректные результаты дают request_failed; хост/backend могут вернуть дополнительные коды.
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-обработка убирает внешние пробелы у locale, пропускает пустые/нестроковые тексты, удаляет дубликаты и отправляет перевод пакетами по 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-backend могут возвращать { needed: false }. SDK также преобразует некорректные результаты перевода в эту ветку. Неподдерживаемый метод и тайм-аут транспорта могут отклонить Promise. Для каждого отсутствующего или пустого перевода оставляй оригинал. Применяй через 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.
}
}Необязательные API Cloud Ability
Эти четыре метода не объявлены текущим 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-срок истечения в миллисекундах; фиксированный TTL не гарантирован |
API не принимают ID пользователя, устройства, проекта, Post или экземпляра игры. Хост предоставляет доверенный контекст и управляет окнами входа/разрешений. Выполняй его условия сессии перед защищёнными действиями. Не запускай запросы разрешений циклически после отказа.
combos.getSetting()
combos.getSetting(): Promise<ICombosHostAuthSetting>
Параметры: нет. Тайм-аут: 10 секунд. Читает решения текущего игрока для текущей игры без открытия настроек. Возвращает ICombosHostAuthSetting; {} допустим при отсутствии решения ai_model.
SDK сохраняет только известный scope ai_model. Если он присутствует, необходимы разрешение/отказ и конечный decidedAtMs; некорректная запись даёт request_failed. Не приравнивай отсутствие scope к отказу и не используй устаревшее решение после изменения настроек игроком.
{
"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'; без значения по умолчанию, wildcard, массива scope или решения от вызывающей стороны. Тайм-аут: 5 минут. Интерактивным запросом управляет хост; запускай его по действию игрока.
Возвращает одну запись авторизации, не все настройки. AUTHORIZATION_DECISION_DENIED — обычный успешный результат Promise. Продолжай защищённое действие только после GRANTED; отказ не повод автоматически спрашивать снова. Результат cancelled не предусмотрен. Закрытие окна интерпретируй по фактической записи или ошибке, а не по статусам login. Неподдерживаемый хост, некорректная запись, транспортная ошибка и тайм-аут отклоняют 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. Объект для незаметной выдачи разрешений не принимается.
Обнови UI по полученным настройкам, включая отсутствующий или запрещённый scope. Результат не является boolean, отдельной записью разрешения или статусом входа. Применяется та же проверка записей, что у getSetting(). Неподдерживаемый метод, некорректный ответ и сбои хоста/транспорта отклоняют Promise. Отдельного статуса отмены 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 } для текущей игры. Вызов не открывает разрешения и не подтверждает доступ ко всем моделям ИИ. Обрабатывай ошибки сессии, разрешений и доступности возможностей хоста.
Храни секрет в памяти и используй только с интеграцией Cloud Ability, документированной этим хостом. Не помещай его в логи, скриншоты, URL, локальное хранилище или исходный код. Проверяй срок, получай новую сессию при необходимости и удаляй старую при смене игрока/игры. Нет refreshToken, параметра TTL или гарантии универсальной аутентификации backend. Некорректный результат даёт 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 этой игры, а не общим статусом LIVE стримера. Он отвечает за транспорт, heartbeat, обновление сессии и переподключение. Игра отвечает за инструкции, эффекты, долговременную дедупликацию и достоверные результаты. В полном уроке есть сопоставление подарков, публикация, подготовительные материалы и запускаемый проект.
combos.getTTLiveClient()
combos.getTTLiveClient(): TTLiveClient
Параметры: нет. Результат: TTLiveClient синхронно, без сетевого запроса при получении. Повторные вызовы возвращают тот же экземпляр для этого документа SDK/игры; не создавай конкурирующие контроллеры в разных компонентах.
Проверь getTTLiveSession в списке возможностей, как в примере. Сам объект не подтверждает поддержку, вход, зарегистрированный запуск или соединение. Перед реальным подключением выполни поток работы с аккаунтом. Ключи провайдера, секреты CAS, launchData и WebSocket URL обрабатываются внутри; параметров для их передачи здесь нет.
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>. Публичная сигнатура не имеет опций комнаты, стримера, токена, переподключения или тайм-аута.
Возвращает Promise<void> после кадра готовности потока. Это не доказательство эффекта подарка или постоянной связи; следи за состоянием отдельно. Восстановление может оставлять Promise незавершённым неограниченно долго. Предоставь остановку до ожидания. Повторный connect, когда подключение уже запрошено, использует ожидающее Promise или сразу завершается; исходный обработчик не заменяется. Перед сменой обработчика отключись.
Отсутствие onCommand отклоняет Promise обычным Error. Явное отключение или терминальное состояние до готовности также отклоняют ожидающее Promise. Временные транспортные/сессионные сбои обычно запускают восстановление, а не немедленный отказ. Разные ID команд могут вызывать асинхронные обработчики параллельно; упорядочивай изменения общего состояния или используй транзакции.
interface TTLiveConnectOptions {
onCommand: (command: TTLiveCommand) => boolean | Promise<boolean>;
}
interface TTLiveCommand {
messageId: string;
instruction: string;
count: string;
timestamp: string;
}| Поле callback | Тип и проверка | Ответственность игры |
|---|---|---|
messageId | Непустая string, не более 256 символов в SDK 1.1.0 | Непрозрачный ключ идемпотентности; сохраняй результат вместе с эффектом |
instruction | string | Сверяй с объявленными инструкциями; SDK не проверяет каталог подарков |
count | Строка десятичных цифр без потери точности больших целых | Проверяй бизнес-ограничения до преобразования; не используй Number вслепую. Парсер допускает ноль и начальные нули |
timestamp | string | Представление времени источника; публичный тип не гарантирует единицы или формат. Не доказывает идентичность или порядок |
Пример иллюстрирует команду, а не API регистрации подарков. Callback не содержит ID зрителей, имён, цен или реальных ID подарков. count — количество сопоставленной инструкции, не обязательно число подарков или их стоимость в монетах.
{
"messageId": "example-command-001",
"instruction": "gift_flash",
"count": "3",
"timestamp": "1791800000"
}| Результат обработчика | Поведение SDK |
|---|---|
true или Promise с true | Сообщает об успехе; возвращай только после фиксации эффекта и записи выполнения |
false или Promise с false | Сообщает об определённом отказе/сбое, например неподдерживаемой инструкции без эффекта |
| Исключение, отклонённое Promise или не-boolean | Исход неизвестен, ACK не отправляется; SDK переподключается и команда может прийти повторно |
Дедупликация в памяти ограничена и очищается явным отключением или перезагрузкой документа. Она не гарантирует долговременное выполнение строго один раз. Атомарно сохраняй messageId, эффект и результат; для дубликатов возвращай сохранённый результат. Не возвращай false после частичного эффекта с неизвестным исходом. Пример Gift Arena использует транзакцию.
Эта вспомогательная функция сразу предоставляет отмену и регистрирует обработку ошибок. Передай настоящий обработчик команд и UI-callback без исключений; 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 секунд плюс начальное определение возможностей при необходимости), затем применяет лимит 5 секунд к HTTP-запросу статуса.
Сетевые, 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 | Unix-миллисекунды последнего подтверждённого запуска/heartbeat TikTok; 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
Параметры: обязательный синхронный listener с TTLiveStatus. Результат: функция отписки. Listener сразу вызывается с текущим состоянием, затем при изменении полей; новая отметка heartbeat может вызвать обновление без изменения state.
Отписывайся при удалении владеющего интерфейса. Удаление listener не отключает клиент; отключение не удаляет listeners. Не выбрасывай исключения внутри: немедленный вызов может передать ошибку потребителя наружу. Пример выводит протокольные значения для отладки; локализуй рабочие сообщения.
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.
Это не синхронный API завершения трансляции TikTok и не доказательство серверного ACK завершения. Метод не удаляет сохранённые записи и не отменяет уже выполняющийся обработчик. Отписывай интерфейс отдельно, защищай запоздавшие игровые операции и сохраняй долговременные записи. Тот же клиент может подключиться снова; повторное отключение безопасно для очистки.
import type { TTLiveClient } from './combos-host-sdk';
function stopTikTok(client: TTLiveClient, unsubscribe: () => void) {
unsubscribe();
client.disconnect();
}Ошибки и восстановление
Методы хоста отклоняют Promise с Error, содержащим строковые code и message. Сравнивай code, не текст сообщения. Список неполный: коды хоста/backend могут передаваться дальше. Ошибки жизненного цикла TikTok могут быть обычными Error без code; 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 уничтожен | Остановить его работу и callbacks, не повторять в цикле |
session_required | Сессия аккаунта недоступна | Предложить вход и затем повторить исходное действие |
model_not_supported | Хост/backend отклонил модель | Использовать модель, поддержанную интеграцией Cloud Ability |
100250001 | Ошибка проверки запроса разрешения | Проверить scope и доверенный игровой контекст хоста |
100260001 / 100260002 | Некорректное создание/контекст сессии или недействительная сессия | Восстановить разрешённую игру/сессию, не придумывая ID или секреты |
100260004 | Нет разрешения на модель ИИ | Уважать решение и использовать авторизацию хоста при поддержке |
100260005 | Возможность игры закрыта | Владелец должен проверить доступность; повторный вход не активирует функцию |
Числовые коды известны у хоста/backend, но не гарантируют Cloud Ability в текущем Web-хосте. Сначала применяй правила доступности метода. Для неизвестных кодов показывай восстанавливаемую ошибку и сохраняй только нечувствительную диагностику.
reason и action TikTok — поля состояния, не коды ошибок хоста. Отклонение обработчика не формирует автоматически ACK неудачи. Не оборачивай уже возможные эффекты в catch(() => false). Тайм-аут хоста лишь прекращает ожидание SDK; публичной отмены входа, авторизации или перевода нет. Избегай автоматических повторов, заново открывающих UI или повторяющих действие с неизвестным исходом.
Жизненный цикл и границы интеграции
- Прочитай возможности один раз на документ; проверяй текущий аккаунт перед каждым новым действием аккаунта.
- Привяжи вход и разрешения к действиям игрока. Обрабатывай отмену/отказ без повторного открытия того же окна.
- Сохраняй перевод необязательным, а исходный текст видимым. Отбрасывай устаревшие асинхронные UI-результаты при удалении сцены.
- Назначь одного владельца TikTok-клиента документа. Подпишись на состояние, подключи обработчик с долговременным учётом и разреши отмену во время ожидания.
- Отпишись и отключись при выходе из взаимодействия. Сохраняй записи выполнения и удаляй чувствительные сессии по окончании игры/работы с аккаунтом.
У window.combos нет общего dispose(), события смены аккаунта, средства отмены входа или глобальной настройки тайм-аута. Не заполняй эти пробелы вызовами внутренних классов или недокументированных HTTP-маршрутов. Скачиваемый demo и ограничения его хранилища — решения игры, а не дополнительные API SDK.
Версия, типы и полные примеры
Публичные объявления TypeScript определяют типы для редактора. Справочник также сверяет проверки SDK 1.1.0 во время выполнения, тайм-ауты, возможности Web-хоста, перевод и жизненный цикл TikTok. Наличие типа не подтверждает доступность в среде выполнения; будущие версии SDK/хоста могут изменить поведение.
- Аккаунты и локализация: кнопки, продолжение после входа и безопасное обновление текстов.
- Создать TikTok-игру: декларация подарков, полный проект, локальные тесты, публикация и подготовка будущей интеграции и проверки LIVE.
- Скачать Gift Arena: полный код с транзакционной обработкой команд.
Примеры проверены по публичным типам. Эта проверка и локальный симулятор не подтверждают реальный вход, доступ Cloud Ability или доставку платных подарков; для этого нужны подходящий хост, аккаунт и зарегистрированная игра, когда появится процесс активации.