Third-Party-Schnittstelle
Baue ein Tool, das BakoshApp steuern kann: Stelle vier HTTP-Endpunkte auf einem lokalen Port bereit, und dein Programm reagiert auf Geschenke, Likes, Follows und Chat von TikTok und Kick.
BakoshApp kann Aktionen in deinem Programm ausführen. Dein Tool stellt auf einem lokalen Port eine kleine HTTP-API bereit; BakoshApp liest deine Liste von Aktionen und ruft eine davon auf, sobald ein TikTok- oder Kick-Event zum Trigger des Nutzers passt. Alles, was du per Code steuern kannst – smarte Lampen, ein Mikrocontroller, ein Soundboard, ein anderes Spiel, dein eigener Bot –, kann ohne BakoshApp-Mod auf einen Livestream reagieren.
So greift alles ineinander
- Dein Tool lauscht auf
http://127.0.0.1:8833. - Der Nutzer verbindet es unter Einstellungen → Third-Party (Host und Port) und prüft es mit Verbindung testen.
- Im Tab Aktionen eines Mods klickt der Nutzer auf Neu hinzufügen, wählt einen Trigger und konfiguriert unter Alle Aktionen → Extern eine Third-Party Action: BakoshApp füllt zwei Listen mit deinen Kategorien und Aktionen.
- Bei jedem passenden Event ruft BakoshApp dein Tool auf, und dein Code erledigt die Arbeit.
Die Verbindung ist einseitig: BakoshApp ruft dich auf, nie umgekehrt.
Port und Adresse
- 8833 ist der Standard. Der Nutzer kann ihn unter Einstellungen → Third-Party ändern; wenn du einen anderen Port verwendest, sag deinen Nutzern, welchen sie eintragen sollen.
- 8832 ist nicht nutzbar: Dort lauscht BakoshApp selbst (so findet TikFinity BakoshApp), und die Einstellung lehnt diesen Port ab.
- Es gibt keine Authentifizierung. Lausche auf
127.0.0.1, nicht auf0.0.0.0, damit die API aus dem Netzwerk nicht erreichbar ist. - BakoshApp verwendet immer einfaches HTTP.
Endpunkte
Dein Tool muss alle vier bereitstellen. Jede Antwort ist JSON mit einem Feld data.
1. App-Info
Identifiziert dein Tool. BakoshApp zeigt es in den Einstellungen und im Aktions-Konfigurator als „Verbunden mit Mock Tool 1.0 von Bakosh“ an.
GET /api/app/info
{ "data": { "name": "Mock Tool", "version": "1.0", "author": "Bakosh" } }2. Kategorien
Die erste Liste im Konfigurator.
GET /api/features/categories
{
"data": [
{ "categoryId": "smart_device_control", "categoryName": "Control Smart Devices" },
{ "categoryId": "serial_port_control", "categoryName": "Control Serial Port" }
]
}3. Aktionen
Die zweite Liste: die Aktionen einer Kategorie. categoryId ist URL-kodiert.
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" }
]
}Die Listen zeigen deine Einträge in der Reihenfolge, in der du sie zurückgibst. Eine Aktion, die der Nutzer bereits gespeichert hat, die du aber nicht mehr zurückgibst, bleibt oben in der Liste, damit sie sich nicht unbemerkt ändert.
categoryId und actionId sind alles, was BakoshApp für eine konfigurierte Aktion speichert. Halte sie stabil: Eine umbenannte ID macht bestehende Einrichtungen kaputt. Namen dienen nur der Anzeige und können sich jederzeit ändern.
4. Ausführen
Wird jedes Mal aufgerufen, wenn ein passendes Event die Aktion ausführt.
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://…"
}
}Antworte mit einem leeren data-Array, sobald du die Anfrage angenommen hast:
{ "data": [] }Zeitverhalten
- BakoshApp wartet bei den drei GET-Endpunkten bis zu 5 Sekunden und bei
execbis zu 10 Sekunden. Eine fehlgeschlagene oder abgelaufene Anfrage wird nicht wiederholt. - Steht bei der Aktion unter Anzahl ein Wert über 1, ruft BakoshApp
execentsprechend oft nacheinander auf: Es wartet auf deine Antwort, dann auf das Intervall der Zeile und ruft dann erneut auf. - Aufrufe für dieselbe Zeile kommen einzeln nacheinander; verschiedene Zeilen können dich parallel aufrufen.
Antworte also schnell und erledige langsame Arbeit im Hintergrund – Zuschauer können Geschenke schneller senden, als ein serieller Port hinterherkommt.
Das context-Objekt
context beschreibt das Event, das die Aktion ausgelöst hat. Es sind nur Felder vorhanden, die es für dieses Event gibt – prüfe sie, bevor du sie liest.
| Feld | Typ | Vorhanden |
|---|---|---|
triggerTypeId | Zahl | immer – siehe unten |
eventType | String | immer – gift, like, chat, follow, share, joined, subscribe, tikfinity oder test |
source | String | immer – eulerstream (TikTok), kick, tikfinity oder test |
platform | String | TikTok- und Kick-Events – tiktok oder kick |
username | String | immer – der Benutzername (Handle) des Zuschauers |
nickname | String | TikTok- und Kick-Events – der Anzeigename |
userId | String | TikTok- und Kick-Events |
profilePictureUrl | String | meistens (TikTok-Avatar-Links laufen ab) |
comment | String | Chatnachrichten; bei Kick auch die an ein Geschenk angehängte Nachricht |
giftName | String | Geschenke |
giftId | Zahl | TikTok-Geschenke |
repeatCount | Zahl | TikTok-Geschenke – Geschenke in der Serie (Streak); verschenkte Kick-Abos – Anzahl der Empfänger |
diamondCount | Zahl | Geschenke – Wert in Diamanten (TikTok) oder Preis in Kicks (Kick) |
coins | Zahl | wie diamondCount |
likeCount | Zahl | Likes |
subMonth | Zahl | Abos |
Von TikFinity weitergeleitete Events enthalten nur triggerTypeId (immer 0), source, eventType und username.
Trigger-Typen
triggerTypeId ist der Typ des Triggers, den der Nutzer konfiguriert hat. So lassen sich ein per Name gewähltes Geschenk und ein über seinen Wert erkanntes Geschenk unterscheiden:
| ID | Trigger |
|---|---|
| 1 | Teilen |
| 3 | Min–Max (Wertbereich des Geschenks) |
| 4 | Geschenk |
| 6 | Beigetreten |
| 7 | Like |
| 9 | Folgen |
| 10 | Subscribe / Super Fan |
| 11 | Chat |
| 0 | TikFinity oder alles andere |
Behandle unbekannte IDs wie 0; es können weitere hinzukommen.
Der Button „Test“
Test in der Aktionszeile (und ihr Tastenkürzel) ruft exec mit Beispieldaten auf: source und eventType sind test, triggerTypeId stammt vom Trigger der Zeile, der Zuschauer ist bakosh_app und das Geschenk ist eine Rose (giftId 5655). platform fehlt.
Probleme melden
Gib eine message zurück, um zu beschreiben, was schiefgelaufen ist:
{ "message": "Serial port COM3 is not available" }- Bei den GET-Endpunkten wertet BakoshApp jede Antwort mit einer
messageals Fehler, selbst bei HTTP 200. - Bei
execwird diemessageals Warnung in die Konsole und die Logdatei von BakoshApp geschrieben. Der Nutzer bekommt kein Pop-up.
HTTP-Fehlerstatus werden ebenfalls berücksichtigt; ohne message zeigt das Log nur den Statuscode.
Zusammen mit TikFinity nutzen
Die Schnittstelle entspricht der Third-Party-Schnittstelle von TikFinity – dieselben vier Pfade und Feldnamen –, sodass ein Tool beide bedienen kann. Die Ports unterscheiden sich: TikFinity sucht Tools auf Port 8832, den BakoshApp belegt, solange es läuft – gib BakoshApp also einen anderen Port.
TikFinity ist eine Web-App und braucht CORS-Header (Access-Control-Allow-Origin: * und Co.) sowie Antworten auf OPTIONS-Preflight-Anfragen. BakoshApp braucht sie nicht, aber sie mitzusenden schadet nicht. BakoshApp sendet mehr context-Felder als TikFinity – ignoriere die, die du nicht nutzt.
Ein vollständiges, funktionierendes Tool
Ohne Abhängigkeiten – speichere es als tool.mjs und starte 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}`));Dein Tool testen
- Starte dein Tool.
- Öffne in BakoshApp Einstellungen → Third-Party, prüfe Host und Port und klicke auf Verbindung testen. Du solltest Name, Version und Autor deines Tools sehen.
- Klicke im Tab Aktionen eines Mods auf Neu hinzufügen, wähle einen Trigger und klicke auf Weiter. Klicke unter Alle Aktionen → Extern neben Third-Party Action auf Configure, wähle deine Kategorie und Aktion und speichere.
- Klicke in der neuen Zeile auf Test – dein Tool erhält einen
exec-Aufruf miteventType: "test". - Geh live und prüfe, ob echte Events ankommen.
Meldet der Konfigurator „Verbindung fehlgeschlagen! Prüfe deine Integration.“, prüfe, ob das Tool auf 127.0.0.1 lauscht, ob der Port mit den Einstellungen übereinstimmt und ob GET /api/app/info seine Antwort innerhalb von data zurückgibt.