Antarmuka Third-Party
Bangun tool yang dapat dikendalikan BakoshApp: sajikan empat endpoint HTTP pada port lokal, dan program Anda bereaksi terhadap gift, like, follow, dan chat TikTok dan Kick.
BakoshApp dapat menjalankan aksi di dalam program Anda. Tool Anda menyajikan HTTP API kecil pada port lokal; BakoshApp membaca daftar aksi Anda dan memanggil salah satunya setiap kali event TikTok atau Kick cocok dengan pemicu pengguna. Apa pun yang dapat Anda kendalikan dari kode — lampu pintar, mikrokontroler, soundboard, game lain, bot Anda sendiri — dapat bereaksi terhadap live stream tanpa mod BakoshApp.
Bagaimana semuanya terhubung
- Tool Anda mendengarkan di
http://127.0.0.1:8833. - Pengguna menghubungkannya di Pengaturan → Third-Party (host dan port) dan memeriksanya dengan Uji koneksi.
- Pada tab Aksi milik sebuah mod, pengguna mengklik Tambah baru, memilih pemicu, lalu di Semua Aksi → Eksternal mengonfigurasi Third-Party Action: BakoshApp mengisi dua daftar dengan kategori dan aksi Anda.
- Pada setiap event yang cocok, BakoshApp memanggil tool Anda, dan kode Anda yang mengerjakan tugasnya.
Koneksinya satu arah: BakoshApp yang memanggil Anda, tidak pernah sebaliknya.
Port dan alamat
- 8833 adalah default. Pengguna dapat mengubahnya di Pengaturan → Third-Party; beri tahu pengguna Anda port mana yang harus dimasukkan jika Anda menggunakan port lain.
- 8832 tidak dapat digunakan: BakoshApp sendiri mendengarkan di situ (begitulah cara TikFinity menemukan BakoshApp), dan pengaturan akan menolaknya.
- Tidak ada autentikasi. Dengarkan di
127.0.0.1, bukan0.0.0.0, agar API tidak dapat dijangkau dari jaringan. - BakoshApp selalu menggunakan HTTP biasa.
Endpoint
Tool Anda harus menyajikan keempatnya. Setiap respons berupa JSON dengan member data.
1. Info aplikasi
Mengidentifikasi tool Anda. BakoshApp menampilkannya sebagai "Connected with Mock Tool 1.0 by Bakosh" di Pengaturan dan di configurator aksi.
GET /api/app/info
{ "data": { "name": "Mock Tool", "version": "1.0", "author": "Bakosh" } }2. Kategori
Daftar pertama pada configurator.
GET /api/features/categories
{
"data": [
{ "categoryId": "smart_device_control", "categoryName": "Control Smart Devices" },
{ "categoryId": "serial_port_control", "categoryName": "Control Serial Port" }
]
}3. Aksi
Daftar kedua: aksi-aksi dari satu kategori. categoryId di-URL-encode.
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" }
]
}Daftar menampilkan item Anda sesuai urutan Anda mengembalikannya. Aksi yang sudah disimpan pengguna tetapi tidak lagi Anda kembalikan akan tetap berada di bagian atas daftar, sehingga tidak berubah secara diam-diam.
categoryId dan actionId adalah satu-satunya yang disimpan BakoshApp untuk sebuah aksi yang dikonfigurasi. Jaga agar tetap stabil: mengganti nama id akan merusak setup yang sudah ada. Nama hanya untuk tampilan dan dapat berubah kapan saja.
4. Eksekusi
Dipanggil setiap kali event yang cocok menjalankan aksi.
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://…"
}
}Jawab dengan array data kosong setelah Anda menerima request:
{ "data": [] }Timing
- BakoshApp menunggu hingga 5 detik untuk ketiga endpoint GET dan 10 detik untuk
exec. Request yang gagal atau timeout tidak akan diulang. - Jika aksi memiliki Jumlah di atas 1, BakoshApp memanggil
execsebanyak itu, satu demi satu: menunggu jawaban Anda, lalu menunggu Interval baris tersebut, baru memanggil lagi. - Pemanggilan untuk baris yang sama datang satu per satu; baris yang berbeda dapat memanggil Anda secara paralel.
Jadi jawablah dengan cepat dan lakukan pekerjaan yang lambat di background — penonton dapat mengirim gift lebih cepat daripada pergerakan serial port.
Objek context
context mendeskripsikan event yang menjalankan aksi. Hanya field yang ada untuk event tersebut yang akan muncul — periksa dulu sebelum membacanya.
| Field | Tipe | Tersedia |
|---|---|---|
triggerTypeId | number | selalu — lihat di bawah |
eventType | string | selalu — gift, like, chat, follow, share, joined, subscribe, tikfinity, atau test |
source | string | selalu — eulerstream (TikTok), kick, tikfinity, atau test |
platform | string | event TikTok dan Kick — tiktok atau kick |
username | string | selalu — handle penonton |
nickname | string | event TikTok dan Kick — nama tampilan |
userId | string | event TikTok dan Kick |
profilePictureUrl | string | biasanya (link avatar TikTok kedaluwarsa) |
comment | string | pesan chat; di Kick juga pesan yang disertakan pada gift |
giftName | string | gift |
giftId | number | gift TikTok |
repeatCount | number | gift TikTok — gift dalam rentetan; langganan hadiah Kick — jumlah penerima |
diamondCount | number | gift — nilai dalam Diamonds (TikTok) atau harga dalam Kicks (Kick) |
coins | number | sama seperti diamondCount |
likeCount | number | like |
subMonth | number | langganan |
Event yang diteruskan dari TikFinity hanya membawa triggerTypeId (selalu 0), source, eventType, dan username.
Jenis pemicu
triggerTypeId adalah jenis pemicu yang dikonfigurasi pengguna, sehingga gift yang dipilih berdasarkan nama dan gift yang dicocokkan berdasarkan nilai dapat dibedakan:
| Id | Pemicu |
|---|---|
| 1 | Bagikan |
| 3 | Min-Maks (rentang nilai gift) |
| 4 | Hadiah |
| 6 | Bergabung |
| 7 | Like |
| 9 | Ikuti |
| 10 | Subscribe / Super Fan |
| 11 | Obrolan |
| 0 | TikFinity, atau lainnya |
Perlakukan id yang tidak dikenal sebagai 0; lebih banyak id dapat ditambahkan di kemudian hari.
Tombol Uji
Uji pada baris aksi (dan hotkey-nya) memanggil exec dengan data contoh: source dan eventType adalah test, triggerTypeId berasal dari pemicu baris tersebut, penontonnya adalah bakosh_app, dan giftnya adalah Rose (giftId 5655). Tidak ada platform.
Melaporkan masalah
Kembalikan message untuk mendeskripsikan apa yang salah:
{ "message": "Serial port COM3 is not available" }- Pada endpoint GET,
messageapa pun akan membuat BakoshApp menganggap jawabannya sebagai error, meskipun dengan HTTP 200. - Pada
exec,messageditulis ke console dan file log BakoshApp sebagai warning. Pengguna tidak akan mendapat pop-up.
Status error HTTP juga diperhatikan; tanpa message, log hanya menampilkan kode statusnya.
Bekerja dengan TikFinity juga
Interface ini cocok dengan third-party interface milik TikFinity — empat path dan nama field yang sama — sehingga satu tool dapat melayani keduanya. Port-nya berbeda: TikFinity mencari tool di 8832, yang ditempati BakoshApp selagi berjalan, jadi berikan BakoshApp port lain.
TikFinity adalah web app dan memerlukan header CORS (Access-Control-Allow-Origin: * dan sejenisnya) plus jawaban untuk preflight request OPTIONS. BakoshApp tidak memerlukannya, tetapi mengirimkannya tidak masalah. BakoshApp mengirim lebih banyak field context daripada TikFinity — abaikan yang tidak Anda pakai.
Contoh tool lengkap yang berfungsi
Tanpa dependency — simpan sebagai tool.mjs dan jalankan 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}`));Menguji tool Anda
- Jalankan tool Anda.
- Di BakoshApp, buka Pengaturan → Third-Party, periksa host dan port, lalu klik Uji koneksi. Anda akan melihat nama, versi, dan author dari tool Anda.
- Pada tab Aksi milik sebuah mod, klik Tambah baru, pilih pemicu, lalu klik Berikutnya. Di Semua Aksi → Eksternal, klik Configure di sebelah Third-Party Action, pilih kategori dan aksi Anda, lalu simpan.
- Klik Uji pada baris baru — tool Anda menerima
execdenganeventType: "test". - Mulai live dan periksa apakah event sungguhan masuk.
Jika configurator menampilkan "Tidak dapat terhubung! Periksa integrasimu.", periksa apakah tool mendengarkan di 127.0.0.1, apakah port-nya cocok dengan Pengaturan, dan apakah GET /api/app/info mengembalikan jawabannya di dalam data.