Interface Third-Party
Créez un outil que BakoshApp peut piloter : exposez quatre endpoints HTTP sur un port local, et votre programme réagira aux cadeaux, likes, follows et messages du chat de TikTok et Kick.
BakoshApp peut exécuter des actions dans votre programme. Votre outil expose une petite API HTTP sur un port local ; BakoshApp lit votre liste d'actions et en appelle une chaque fois qu'un événement TikTok ou Kick correspond au déclencheur de l'utilisateur. Tout ce que vous pouvez piloter par du code — lampes connectées, microcontrôleur, soundboard, autre jeu, votre propre bot — peut réagir à un live sans mod BakoshApp.
Comment tout s'articule
- Votre outil écoute sur
http://127.0.0.1:8833. - L'utilisateur le connecte dans Paramètres → Third-Party (hôte et port) et le vérifie avec Tester la connexion.
- Dans l'onglet Actions d'un mod, l'utilisateur clique sur Ajouter nouveau, choisit un déclencheur et, dans Toutes les actions → Externes, configure une Third-Party Action : BakoshApp remplit deux listes avec vos catégories et vos actions.
- À chaque événement correspondant, BakoshApp appelle votre outil, et votre code fait le travail.
La connexion est à sens unique : BakoshApp vous appelle, jamais l'inverse.
Port et adresse
- 8833 est la valeur par défaut. L'utilisateur peut la modifier dans Paramètres → Third-Party ; si vous utilisez un autre port, indiquez à vos utilisateurs lequel saisir.
- Le port 8832 est inutilisable : BakoshApp lui-même y écoute (c'est ainsi que TikFinity trouve BakoshApp), et le paramètre le refuse.
- Il n'y a pas d'authentification. Écoutez sur
127.0.0.1, et non sur0.0.0.0, pour que l'API ne soit pas accessible depuis le réseau. - BakoshApp utilise toujours du HTTP en clair.
Endpoints
Votre outil doit exposer les quatre. Chaque réponse est un JSON contenant un membre data.
1. Infos de l'application
Identifie votre outil. BakoshApp l'affiche sous la forme « Connecté à Mock Tool 1.0 par Bakosh » dans les Paramètres et dans le configurateur d'action.
GET /api/app/info
{ "data": { "name": "Mock Tool", "version": "1.0", "author": "Bakosh" } }2. Catégories
La première liste du configurateur.
GET /api/features/categories
{
"data": [
{ "categoryId": "smart_device_control", "categoryName": "Control Smart Devices" },
{ "categoryId": "serial_port_control", "categoryName": "Control Serial Port" }
]
}3. Actions
La deuxième liste : les actions d'une catégorie. categoryId est encodé pour l'URL.
GET /api/features/actions?categoryId=smart_device_control
{
"data": [
{ "actionId": "turn_lights_on", "actionName": "Turn Lights On" },
{ "actionId": "turn_lights_off", "actionName": "Turn Lights Off" }
]
}Les listes affichent vos éléments dans l'ordre où vous les renvoyez. Une action déjà enregistrée par l'utilisateur mais que vous ne renvoyez plus reste en haut de la liste, pour qu'elle ne change pas à son insu.
categoryId et actionId sont les seules données que BakoshApp enregistre pour une action configurée. Gardez-les stables : renommer un id casse les configurations existantes. Les noms ne servent qu'à l'affichage et peuvent changer à tout moment.
4. Exécution
Appelé chaque fois qu'un événement correspondant exécute l'action.
POST /api/features/actions/exec
{
"categoryId": "smart_device_control",
"actionId": "turn_lights_on",
"context": {
"triggerTypeId": 4,
"eventType": "gift",
"source": "eulerstream",
"platform": "tiktok",
"userId": "123456789",
"username": "testuser",
"nickname": "Test User",
"giftName": "Rose",
"giftId": 5655,
"repeatCount": 3,
"diamondCount": 1,
"coins": 1,
"profilePictureUrl": "https://…"
}
}Répondez avec un tableau data vide une fois la requête acceptée :
{ "data": [] }Délais
- BakoshApp attend jusqu'à 5 secondes pour les trois endpoints GET et 10 secondes pour
exec. Une requête qui échoue ou expire n'est pas renvoyée. - Si l'action a une Quantité supérieure à 1, BakoshApp appelle
execautant de fois, l'une après l'autre : il attend votre réponse, puis l'Intervalle de la ligne, puis rappelle. - Les appels d'une même ligne arrivent un par un ; des lignes différentes peuvent vous appeler en parallèle.
Répondez donc vite et faites le travail lent en arrière-plan — les spectateurs peuvent envoyer des cadeaux plus vite qu'un port série ne peut suivre.
L'objet context
context décrit l'événement qui a exécuté l'action. Seuls les champs qui existent pour cet événement sont présents — vérifiez-les avant de les lire.
| Champ | Type | Présent |
|---|---|---|
triggerTypeId | number | toujours — voir ci-dessous |
eventType | string | toujours — gift, like, chat, follow, share, joined, subscribe, tikfinity ou test |
source | string | toujours — eulerstream (TikTok), kick, tikfinity ou test |
platform | string | événements TikTok et Kick — tiktok ou kick |
username | string | toujours — l'identifiant du spectateur |
nickname | string | événements TikTok et Kick — le nom affiché |
userId | string | événements TikTok et Kick |
profilePictureUrl | string | généralement (les liens d'avatar TikTok expirent) |
comment | string | messages du chat ; sur Kick, aussi le message joint à un cadeau |
giftName | string | cadeaux |
giftId | number | cadeaux TikTok |
repeatCount | number | cadeaux TikTok — nombre de cadeaux dans la série ; abonnements offerts sur Kick — nombre de destinataires |
diamondCount | number | cadeaux — valeur en diamants (TikTok) ou prix en Kicks (Kick) |
coins | number | identique à diamondCount |
likeCount | number | likes |
subMonth | number | abonnements |
Les événements relayés par TikFinity ne contiennent que triggerTypeId (toujours 0), source, eventType et username.
Types de déclencheurs
triggerTypeId est le type du déclencheur configuré par l'utilisateur ; on distingue ainsi un cadeau choisi par son nom d'un cadeau reconnu par sa valeur :
| Id | Déclencheur |
|---|---|
| 1 | Partage |
| 3 | Min-Max (plage de valeur du cadeau) |
| 4 | Cadeau |
| 6 | Arrivé |
| 7 | Like |
| 9 | Suivre |
| 10 | Subscribe / Super Fan |
| 11 | Chat |
| 0 | TikFinity, ou tout le reste |
Traitez les id inconnus comme 0 ; d'autres pourront être ajoutés.
Le bouton Tester
Tester sur la ligne de l'action (et son raccourci clavier) appelle exec avec des données d'exemple : source et eventType valent test, triggerTypeId provient du déclencheur de la ligne, le spectateur est bakosh_app et le cadeau est une Rose (giftId 5655). Il n'y a pas de platform.
Signaler les problèmes
Renvoyez un message pour décrire ce qui n'a pas fonctionné :
{ "message": "Serial port COM3 is not available" }- Sur les endpoints GET, la présence d'un
messagefait que BakoshApp traite la réponse comme une erreur, même avec un HTTP 200. - Sur
exec, lemessageest écrit dans la console et le fichier journal de BakoshApp sous forme d'avertissement. L'utilisateur ne voit aucune fenêtre contextuelle.
Les statuts d'erreur HTTP sont également pris en compte ; sans message, le journal n'affiche que le code de statut.
Fonctionner aussi avec TikFinity
L'interface correspond à l'interface third-party de TikFinity (mêmes quatre chemins, mêmes noms de champs), si bien qu'un seul outil peut servir les deux. Les ports diffèrent : TikFinity cherche les outils sur le port 8832, que BakoshApp occupe tant qu'il tourne ; attribuez donc un autre port à BakoshApp.
TikFinity est une application web : elle a besoin des en-têtes CORS (Access-Control-Allow-Origin: * et consorts) ainsi que de réponses aux requêtes preflight OPTIONS. BakoshApp n'en a pas besoin, mais les envoyer ne pose aucun problème. BakoshApp envoie plus de champs context que TikFinity — ignorez ceux dont vous ne vous servez pas.
Un outil complet et fonctionnel
Aucune dépendance — enregistrez-le sous tool.mjs et lancez node tool.mjs :
import http from 'node:http';
const PORT = 8833;
const APP_INFO = { name: 'Mock Tool', version: '1.0', author: 'Bakosh' };
const CATALOG = [
{
categoryId: 'smart_device_control',
categoryName: 'Control Smart Devices',
actions: [
{ actionId: 'turn_lights_on', actionName: 'Turn Lights On' },
{ actionId: 'turn_lights_off', actionName: 'Turn Lights Off' },
],
},
];
// Wildcard CORS keeps the same tool usable from TikFinity as well.
const CORS = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': '*',
};
const send = (res, status, body) => {
res.writeHead(status, { 'Content-Type': 'application/json', ...CORS });
res.end(JSON.stringify(body));
};
const readBody = (req) =>
new Promise((resolve) => {
let raw = '';
req.on('data', (c) => { raw += c; });
req.on('end', () => { try { resolve(JSON.parse(raw || '{}')); } catch { resolve({}); } });
});
// Your actual work goes here. Return a string to report a problem.
function runAction(categoryId, actionId, context) {
console.log(`${categoryId}/${actionId} fired by ${context.username ?? 'someone'} on ${context.platform ?? context.source}`);
// turnLightsOn() …
return null;
}
http.createServer(async (req, res) => {
const url = new URL(req.url, `http://127.0.0.1:${PORT}`);
if (req.method === 'OPTIONS') { // preflight (TikFinity only)
res.writeHead(204, CORS);
return res.end();
}
if (req.method === 'GET' && url.pathname === '/api/app/info') {
return send(res, 200, { data: APP_INFO });
}
if (req.method === 'GET' && url.pathname === '/api/features/categories') {
return send(res, 200, {
data: CATALOG.map(({ categoryId, categoryName }) => ({ categoryId, categoryName })),
});
}
if (req.method === 'GET' && url.pathname === '/api/features/actions') {
const cat = CATALOG.find((c) => c.categoryId === url.searchParams.get('categoryId'));
return send(res, 200, { data: cat ? cat.actions : [] });
}
if (req.method === 'POST' && url.pathname === '/api/features/actions/exec') {
const body = await readBody(req);
const problem = runAction(body.categoryId ?? '', body.actionId ?? '', body.context ?? {});
return problem ? send(res, 200, { message: problem }) : send(res, 200, { data: [] });
}
send(res, 404, { message: `No such endpoint: ${url.pathname}` });
}).listen(PORT, '127.0.0.1', () => console.log(`Listening on http://127.0.0.1:${PORT}`));Tester votre outil
- Lancez votre outil.
- Dans BakoshApp, ouvrez Paramètres → Third-Party, vérifiez l'hôte et le port, puis cliquez sur Tester la connexion. Vous devriez voir le nom, la version et l'auteur de votre outil.
- Dans l'onglet Actions d'un mod, cliquez sur Ajouter nouveau, choisissez un déclencheur et cliquez sur Suivant. Dans Toutes les actions → Externes, cliquez sur Configure à côté de Third-Party Action, choisissez votre catégorie et votre action, puis enregistrez.
- Cliquez sur Tester sur la nouvelle ligne — votre outil reçoit un
execaveceventType: "test". - Lancez votre live et vérifiez que les vrais événements arrivent.
Si le configurateur affiche « Connexion impossible ! Vérifiez votre intégration. », vérifiez que l'outil écoute sur 127.0.0.1, que le port correspond à celui des Paramètres et que GET /api/app/info renvoie sa réponse dans data.