private-fishaudio-voice-clones.{userId}
Ход клонирования ваших голосов Fish Audio: событие на каждое изменение статуса клона, созданного через POST /voices/fishaudio/clones (или в кабинете). Право ключа — voices.read.
Параметры канала
Подставьте свои значения — они появятся и в имени канала, и в коде ниже, и в консоли. Никуда не отправляются и в адресе страницы не сохраняются.
числовой идентификатор владельца ключа, его отдаёт GET /user.
Имя канала для подписки
private-fishaudio-voice-clones.{userId}
В имени остались подстановки в фигурных скобках. Подписаться таким именем нельзя: сервер авторизует канал по точному совпадению.
import Pusher from 'pusher-js';
const pusher = new Pusher('7c4dd881d8116ac76fe89aff71d8c2ff', {
wsHost: 'ws.lumean.app',
wsPort: 443, wssPort: 443,
forceTLS: true,
enabledTransports: ['ws', 'wss'],
cluster: '',
channelAuthorization: {
endpoint: 'https://api.lumean.app/api/public/broadcasting/auth',
headers: { 'X-API-KEY': 'YOUR_API_KEY' },
},
});
const channel = pusher.subscribe('private-fishaudio-voice-clones.{userId}');
channel.bind('voice_clone.updated', (data) => {
console.log(data);
});import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
const echo = new Echo({
broadcaster: 'pusher',
key: '7c4dd881d8116ac76fe89aff71d8c2ff',
wsHost: 'ws.lumean.app',
wsPort: 443, wssPort: 443,
forceTLS: true,
enabledTransports: ['ws', 'wss'],
cluster: '',
authEndpoint: 'https://api.lumean.app/api/public/broadcasting/auth',
auth: { headers: { 'X-API-KEY': 'YOUR_API_KEY' } },
});
echo.private('fishaudio-voice-clones.{userId}')
// ведущая точка нужна в Laravel Echo; в pusher-js её нет
.listen('.voice_clone.updated', (e) => {
console.log(e);
});# pip install websocket-client requests
import json, requests, websocket
APP_KEY = "7c4dd881d8116ac76fe89aff71d8c2ff"
WS_URL = "wss://ws.lumean.app:443/app/" + APP_KEY + "?protocol=7&client=python&version=1.0"
CHANNEL = "private-fishaudio-voice-clones.{userId}"
ws = websocket.create_connection(WS_URL)
# 1. получаем socket_id из события pusher:connection_established
hello = json.loads(ws.recv())
socket_id = json.loads(hello["data"])["socket_id"]
# 2. авторизуем приватную подписку своим API-ключом
auth = requests.post("https://api.lumean.app/api/public/broadcasting/auth",
headers={"X-API-KEY": "YOUR_API_KEY"},
data={"socket_id": socket_id, "channel_name": CHANNEL},
).json()["auth"]
# 3. подписываемся и слушаем события
ws.send(json.dumps({"event": "pusher:subscribe",
"data": {"auth": auth, "channel": CHANNEL}}))
while True:
print(ws.recv())Пример payload
Канал: private-fishaudio-voice-clones.{userId}
Это пример из спецификации. Подключения нет, и оно не изображается: чтобы подписаться по-настоящему, нужен ваш API-ключ.
.voice_clone.updated
{
"voice_clone": {
"id": "<uuid>",
"provider": "fishaudio",
"display_name": "string",
"language": "ru",
"description": "string",
"status": "pending",
"voice_id": "string",
"attempts": 1,
"error": {
"reason": "string",
"message": "string"
},
"created_at": "<date-time>",
"completed_at": "<date-time>",
"failed_at": "<date-time>",
"banned_at": "<date-time>",
"ban_reason": "string"
}
}События канала: 1
У каждого события свой якорь, полная таблица payload с описаниями и перечислениями и пример формы. Имя показано в нотации Laravel Echo — с ведущей точкой.
.voice_clone.updated
Echo: .voice_clone.updated · pusher-js: voice_clone.updated
Клон голоса Fish Audio создан или сменил статус (pending → cloning → ready либо failed; archived после удаления; banned — заблокирован модератором). voice_id появляется только у ready — его кладут в tts_settings.voice_id шаблона Fish Audio.
Поля payload
voice_cloneобязательноеobject
Статус клона. banned — клон заблокирован модератором: в новые заказы не берётся и не удаляется, причина — в ban_reason.
Идентификатор голоса Fish Audio (строка из 32 hex-символов, не UUID) — значение для tts_settings.voice_id шаблона. Есть только у клона в статусе ready, иначе null.
errorобязательноеobject | null
processing_error, max_retries, network, timeout, dispatch_failed, unbanned
Причина блокировки клона модератором либо null.
Пример payload
{
"voice_clone": {
"id": "<uuid>",
"provider": "fishaudio",
"display_name": "string",
"language": "ru",
"description": "string",
"status": "pending",
"voice_id": "string",
"attempts": 1,
"error": {
"reason": "string",
"message": "string"
},
"created_at": "<date-time>",
"completed_at": "<date-time>",
"failed_at": "<date-time>",
"banned_at": "<date-time>",
"ban_reason": "string"
}
}Значения взяты из спецификации там, где они в ней есть; остальные — заглушки по типу поля. Это форма события, а не запись реального.
Все каналы и параметры подключения·POST /broadcasting/auth
Скормить страницу ИИ
спека 0.0.1