tiktok-live-api 1.2.11 → 1.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/demo.mjs +236 -62
- package/package.json +1 -1
package/bin/demo.mjs
CHANGED
|
@@ -15,9 +15,9 @@ const REACT_TEMPLATE = [
|
|
|
15
15
|
"",
|
|
16
16
|
"export default function TikTokLiveComponent() {",
|
|
17
17
|
" const [events, setEvents] = useState([]);",
|
|
18
|
-
" const [username, setUsername] = useState('
|
|
18
|
+
" const [username, setUsername] = useState('gbnews');",
|
|
19
19
|
" const [apiKey, setApiKey] = useState('demo_tiktokliveapi_public_2026');",
|
|
20
|
-
" const [inputUsername, setInputUsername] = useState('
|
|
20
|
+
" const [inputUsername, setInputUsername] = useState('gbnews');",
|
|
21
21
|
" const [connected, setConnected] = useState(false);",
|
|
22
22
|
" const clientRef = useRef(null);",
|
|
23
23
|
"",
|
|
@@ -59,7 +59,7 @@ const REACT_TEMPLATE = [
|
|
|
59
59
|
" <form onSubmit={handleConnect} style={{ display: 'flex', flexDirection: 'column', gap: '16px', marginBottom: '24px' }}>",
|
|
60
60
|
" <div>",
|
|
61
61
|
" <label style={{ display: 'block', fontSize: '0.875rem', fontWeight: 500, marginBottom: '6px' }}>TikTok Username</label>",
|
|
62
|
-
" <input type=\"text\" value={inputUsername} onChange={(e) => setInputUsername(e.target.value)} style={{ width: '100%', padding: '8px 12px', borderRadius: '6px', border: '1px solid #d1d5db', boxSizing: 'border-box' }} placeholder=\"e.g.
|
|
62
|
+
" <input type=\"text\" value={inputUsername} onChange={(e) => setInputUsername(e.target.value)} style={{ width: '100%', padding: '8px 12px', borderRadius: '6px', border: '1px solid #d1d5db', boxSizing: 'border-box' }} placeholder=\"e.g. gbnews\" />",
|
|
63
63
|
" </div>",
|
|
64
64
|
" <div>",
|
|
65
65
|
" <label style={{ display: 'block', fontSize: '0.875rem', fontWeight: 500, marginBottom: '6px' }}>API Key</label>",
|
|
@@ -95,7 +95,7 @@ const VUE_TEMPLATE = [
|
|
|
95
95
|
' <form @submit.prevent="handleConnect" style="display: flex; flex-direction: column; gap: 16px; margin-bottom: 24px">',
|
|
96
96
|
" <div>",
|
|
97
97
|
' <label style="display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 6px">TikTok Username</label>',
|
|
98
|
-
' <input type="text" v-model="inputUsername" style="width: 100%; padding: 8px 12px; border-radius: 6px; border: 1px solid #d1d5db; box-sizing: border-box" placeholder="e.g.
|
|
98
|
+
' <input type="text" v-model="inputUsername" style="width: 100%; padding: 8px 12px; border-radius: 6px; border: 1px solid #d1d5db; box-sizing: border-box" placeholder="e.g. gbnews" />',
|
|
99
99
|
" </div>",
|
|
100
100
|
" <div>",
|
|
101
101
|
' <label style="display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 6px">API Key</label>',
|
|
@@ -119,53 +119,52 @@ const VUE_TEMPLATE = [
|
|
|
119
119
|
"</template>",
|
|
120
120
|
"",
|
|
121
121
|
"<script setup>",
|
|
122
|
-
"import { ref,
|
|
122
|
+
"import { ref, onMounted, onUnmounted } from 'vue'",
|
|
123
123
|
"",
|
|
124
|
-
"const inputUsername = ref('
|
|
125
|
-
"const activeUsername = ref('
|
|
124
|
+
"const inputUsername = ref('gbnews')",
|
|
125
|
+
"const activeUsername = ref('gbnews')",
|
|
126
126
|
"const apiKey = ref('demo_tiktokliveapi_public_2026')",
|
|
127
|
+
"const connected = ref(false)",
|
|
127
128
|
"const events = ref([])",
|
|
129
|
+
"let ws = null",
|
|
128
130
|
"",
|
|
129
|
-
"
|
|
130
|
-
"try { if (typeof useTikTokLive !== 'undefined') hook = useTikTokLive; } catch (e) { }",
|
|
131
|
-
"const proxyUsername = { replace: (r, s) => (activeUsername.value || '').replace(r, s) }",
|
|
132
|
-
"const tiktok = hook ? hook(proxyUsername, { apiKey, autoConnect: false }) : { connected: ref(false), allEvents: ref([]) }",
|
|
133
|
-
"const connected = tiktok.connected",
|
|
134
|
-
"",
|
|
135
|
-
"watch(() => tiktok.allEvents.value, (all) => {",
|
|
136
|
-
" if (all && all.length) {",
|
|
137
|
-
" const last = all[all.length - 1];",
|
|
138
|
-
" if (last.type === 'chat') addEvent(`💬 ${last.data.user.uniqueId}: ${last.data.comment}`)",
|
|
139
|
-
" if (last.type === 'gift') addEvent(`🎁 ${last.data.user.uniqueId} sent ${last.data.giftName}`)",
|
|
140
|
-
" if (last.type === 'like') addEvent(`❤️ ${last.data.user.uniqueId} liked`)",
|
|
141
|
-
" if (last.type === 'member') addEvent(`👋 ${last.data.user.uniqueId} joined`)",
|
|
142
|
-
" if (last.type === 'connected') addEvent('✅ Connected successfully!')",
|
|
143
|
-
" if (last.type === 'disconnected') addEvent('❌ Disconnected from stream.')",
|
|
144
|
-
" }",
|
|
145
|
-
"}, { deep: true })",
|
|
146
|
-
"",
|
|
147
|
-
"watch(() => tiktok.error ? tiktok.error.value : null, (e) => {",
|
|
148
|
-
" if(e) addEvent('⚠️ Error: ' + e)",
|
|
149
|
-
"})",
|
|
150
|
-
"",
|
|
151
|
-
"const addEvent = (str) => {",
|
|
131
|
+
"function addEvent(str) {",
|
|
152
132
|
" events.value.push(str)",
|
|
153
|
-
" if(events.value.length > 50) events.value.shift()",
|
|
133
|
+
" if (events.value.length > 50) events.value.shift()",
|
|
154
134
|
"}",
|
|
155
135
|
"",
|
|
156
|
-
"
|
|
157
|
-
" if (
|
|
136
|
+
"function connectStream() {",
|
|
137
|
+
" if (ws) { ws.close(); ws = null }",
|
|
158
138
|
" events.value = []",
|
|
139
|
+
" connected.value = false",
|
|
159
140
|
" activeUsername.value = inputUsername.value",
|
|
160
|
-
"
|
|
161
|
-
" if (
|
|
162
|
-
"
|
|
141
|
+
" const user = (activeUsername.value || '').replace(/^@/, '')",
|
|
142
|
+
" if (!user) return",
|
|
143
|
+
" const key = apiKey.value || ''",
|
|
144
|
+
" try {",
|
|
145
|
+
" ws = new WebSocket('wss://api.tik.tools?uniqueId=' + user + '&apiKey=' + key)",
|
|
146
|
+
" } catch (e) { addEvent('⚠️ Connection failed: ' + e.message); return }",
|
|
147
|
+
" ws.onopen = () => { connected.value = true; addEvent('✅ Connected to @' + user) }",
|
|
148
|
+
" ws.onclose = () => { connected.value = false; ws = null; addEvent('❌ Disconnected') }",
|
|
149
|
+
" ws.onerror = () => { addEvent('⚠️ WebSocket error') }",
|
|
150
|
+
" ws.onmessage = (evt) => {",
|
|
151
|
+
" try {",
|
|
152
|
+
" const msg = JSON.parse(evt.data)",
|
|
153
|
+
" const t = msg.event || ''",
|
|
154
|
+
" const d = msg.data || {}",
|
|
155
|
+
" const u = d.user ? d.user.uniqueId : ''",
|
|
156
|
+
" if (t === 'chat') addEvent('💬 ' + u + ': ' + d.comment)",
|
|
157
|
+
" else if (t === 'gift') addEvent('🎁 ' + u + ' sent ' + (d.giftName || 'a gift'))",
|
|
158
|
+
" else if (t === 'like') addEvent('❤️ ' + u + ' liked')",
|
|
159
|
+
" else if (t === 'member') addEvent('👋 ' + u + ' joined')",
|
|
160
|
+
" } catch (e) {}",
|
|
163
161
|
" }",
|
|
164
162
|
"}",
|
|
165
163
|
"",
|
|
166
|
-
"
|
|
167
|
-
"
|
|
168
|
-
"})",
|
|
164
|
+
"const handleConnect = () => { connectStream() }",
|
|
165
|
+
"",
|
|
166
|
+
"onMounted(() => { connectStream() })",
|
|
167
|
+
"onUnmounted(() => { if (ws) ws.close() })",
|
|
169
168
|
"</script>"
|
|
170
169
|
].join('\n') + "\n";
|
|
171
170
|
|
|
@@ -194,10 +193,12 @@ if (!isInteractive) {
|
|
|
194
193
|
console.log(" 1) " + C.cyan + "Watch Live Terminal Demo" + R);
|
|
195
194
|
console.log(" 2) " + C.green + "Scaffold a Nuxt 3 (Vue) App" + R);
|
|
196
195
|
console.log(" 3) " + C.blue + "Scaffold a Next.js (React) App" + R);
|
|
197
|
-
console.log(" 4) " + C.yellow + "Scaffold a Vite (React) App" + R
|
|
196
|
+
console.log(" 4) " + C.yellow + "Scaffold a Vite (React) App" + R);
|
|
197
|
+
console.log(" 5) " + C.mag + "Scaffold a Plain Node.js Project" + R);
|
|
198
|
+
console.log(" 6) " + C.pink + "Scaffold a Python Project" + R + "\n");
|
|
198
199
|
|
|
199
200
|
function promptAction() {
|
|
200
|
-
rl.question(" Choose [1-
|
|
201
|
+
rl.question(" Choose [1-6]: ", (answer) => {
|
|
201
202
|
handleMenu(answer.trim());
|
|
202
203
|
});
|
|
203
204
|
}
|
|
@@ -208,7 +209,7 @@ if (!isInteractive) {
|
|
|
208
209
|
return runDemo();
|
|
209
210
|
}
|
|
210
211
|
|
|
211
|
-
if (!['2', '3', '4'].includes(choice)) {
|
|
212
|
+
if (!['2', '3', '4', '5', '6'].includes(choice)) {
|
|
212
213
|
console.log(" " + C.red + "Invalid choice." + R);
|
|
213
214
|
return promptAction();
|
|
214
215
|
}
|
|
@@ -216,6 +217,11 @@ if (!isInteractive) {
|
|
|
216
217
|
rl.question("\n Target directory (e.g. ./my-app) [./tiktok-live-project]: ", (dir) => {
|
|
217
218
|
dir = dir.trim() || './tiktok-live-project';
|
|
218
219
|
|
|
220
|
+
if (choice === '6') {
|
|
221
|
+
rl.close();
|
|
222
|
+
return runScaffold(choice, dir, 'pip');
|
|
223
|
+
}
|
|
224
|
+
|
|
219
225
|
console.log("\n Select Package Manager:");
|
|
220
226
|
console.log(" 1) npm " + D + "(Default)" + R);
|
|
221
227
|
console.log(" 2) yarn");
|
|
@@ -242,6 +248,8 @@ function runScaffold(choice, targetDir, pm) {
|
|
|
242
248
|
const isNuxt = choice === '2';
|
|
243
249
|
const isNext = choice === '3';
|
|
244
250
|
const isVite = choice === '4';
|
|
251
|
+
const isNode = choice === '5';
|
|
252
|
+
const isPython = choice === '6';
|
|
245
253
|
const fullPath = path.resolve(process.cwd(), targetDir);
|
|
246
254
|
|
|
247
255
|
const npxCmd = pm === 'bun' ? 'bunx' : (pm === 'pnpm' ? 'pnpm dlx' : 'npx');
|
|
@@ -251,7 +259,11 @@ function runScaffold(choice, targetDir, pm) {
|
|
|
251
259
|
console.log("\n " + B + "🚀 Scaffolding project into " + targetDir + " using " + pm + "..." + R + "\n");
|
|
252
260
|
|
|
253
261
|
try {
|
|
254
|
-
if (
|
|
262
|
+
if (isNode) {
|
|
263
|
+
if (!fs.existsSync(fullPath)) fs.mkdirSync(fullPath, { recursive: true });
|
|
264
|
+
} else if (isPython) {
|
|
265
|
+
if (!fs.existsSync(fullPath)) fs.mkdirSync(fullPath, { recursive: true });
|
|
266
|
+
} else if (isNuxt) {
|
|
255
267
|
execSync(npxCmd + ' nuxi@latest init "' + targetDir + '" --packageManager ' + pm, { stdio: 'inherit' });
|
|
256
268
|
} else if (isNext) {
|
|
257
269
|
execSync(npxCmd + ' create-next-app@latest "' + targetDir + '" --js --eslint --tailwind --app --src-dir --import-alias "@/*" --use-' + pm, { stdio: 'inherit' });
|
|
@@ -260,11 +272,174 @@ function runScaffold(choice, targetDir, pm) {
|
|
|
260
272
|
execSync(createCmd + ' "' + targetDir + '" -- --template react', { stdio: 'inherit' });
|
|
261
273
|
}
|
|
262
274
|
|
|
263
|
-
if (
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
|
|
275
|
+
if (isNode) {
|
|
276
|
+
// ── Plain Node.js Starter Kit ──
|
|
277
|
+
const pkgJson = {
|
|
278
|
+
name: path.basename(fullPath),
|
|
279
|
+
version: '1.0.0',
|
|
280
|
+
type: 'module',
|
|
281
|
+
scripts: { start: 'node index.mjs', dev: 'node --watch index.mjs' },
|
|
282
|
+
dependencies: {}
|
|
283
|
+
};
|
|
284
|
+
fs.writeFileSync(path.join(fullPath, 'package.json'), JSON.stringify(pkgJson, null, 2) + '\n');
|
|
285
|
+
|
|
286
|
+
console.log("\n " + B + "📦 Installing " + C.cyan + "tiktok-live-api" + B + " SDK..." + R + "\n");
|
|
287
|
+
execSync(installCmd, { cwd: fullPath, stdio: 'inherit' });
|
|
288
|
+
|
|
289
|
+
fs.writeFileSync(path.join(fullPath, 'index.mjs'), [
|
|
290
|
+
"import { TikTokLive } from 'tiktok-live-api';",
|
|
291
|
+
"",
|
|
292
|
+
"// ── Configuration ───────────────────────────────────────",
|
|
293
|
+
"const USERNAME = 'gbnews'; // TikTok @username",
|
|
294
|
+
"const API_KEY = 'demo_tiktokliveapi_public_2026'; // Get yours at https://tik.tools",
|
|
295
|
+
"",
|
|
296
|
+
"// ── Connect ─────────────────────────────────────────────",
|
|
297
|
+
"const client = new TikTokLive(USERNAME, { apiKey: API_KEY });",
|
|
298
|
+
"",
|
|
299
|
+
"client.on('connected', () => {",
|
|
300
|
+
" console.log('\\n✅ Connected to @' + USERNAME + '\\n');",
|
|
301
|
+
"});",
|
|
302
|
+
"",
|
|
303
|
+
"client.on('chat', (data) => {",
|
|
304
|
+
" console.log(`💬 ${data.user.uniqueId}: ${data.comment}`);",
|
|
305
|
+
"});",
|
|
306
|
+
"",
|
|
307
|
+
"client.on('gift', (data) => {",
|
|
308
|
+
" console.log(`🎁 ${data.user.uniqueId} sent ${data.giftName} x${data.repeatCount}`);",
|
|
309
|
+
"});",
|
|
310
|
+
"",
|
|
311
|
+
"client.on('like', (data) => {",
|
|
312
|
+
" console.log(`❤️ ${data.user.uniqueId} liked (total: ${data.totalLikeCount})`);",
|
|
313
|
+
"});",
|
|
314
|
+
"",
|
|
315
|
+
"client.on('member', (data) => {",
|
|
316
|
+
" console.log(`👋 ${data.user.uniqueId} joined`);",
|
|
317
|
+
"});",
|
|
318
|
+
"",
|
|
319
|
+
"client.on('roomUserSeq', (data) => {",
|
|
320
|
+
" console.log(`👀 Viewers: ${data.viewerCount}`);",
|
|
321
|
+
"});",
|
|
322
|
+
"",
|
|
323
|
+
"client.on('disconnected', () => {",
|
|
324
|
+
" console.log('\\n❌ Disconnected\\n');",
|
|
325
|
+
"});",
|
|
326
|
+
"",
|
|
327
|
+
"client.on('error', (err) => {",
|
|
328
|
+
" console.error('⚠️ Error:', err.message);",
|
|
329
|
+
"});",
|
|
330
|
+
"",
|
|
331
|
+
"console.log('🔄 Connecting to @' + USERNAME + '...');",
|
|
332
|
+
"client.connect().catch((err) => {",
|
|
333
|
+
" console.error('Failed to connect:', err.message);",
|
|
334
|
+
" process.exit(1);",
|
|
335
|
+
"});",
|
|
336
|
+
].join('\n') + '\n');
|
|
337
|
+
|
|
338
|
+
fs.writeFileSync(path.join(fullPath, 'README.md'), [
|
|
339
|
+
'# TikTok Live - Node.js Starter',
|
|
340
|
+
'',
|
|
341
|
+
'A ready-to-run Node.js project connecting to TikTok LIVE streams.',
|
|
342
|
+
'',
|
|
343
|
+
'## Quick Start',
|
|
344
|
+
'',
|
|
345
|
+
'```bash',
|
|
346
|
+
'node index.mjs',
|
|
347
|
+
'```',
|
|
348
|
+
'',
|
|
349
|
+
'## Configuration',
|
|
350
|
+
'',
|
|
351
|
+
'Edit `index.mjs` to change:',
|
|
352
|
+
'- `USERNAME` — the TikTok @username to watch',
|
|
353
|
+
'- `API_KEY` — get your own at [tik.tools](https://tik.tools)',
|
|
354
|
+
'',
|
|
355
|
+
'## Events',
|
|
356
|
+
'',
|
|
357
|
+
'The demo listens for: `chat`, `gift`, `like`, `member`, `roomUserSeq`.',
|
|
358
|
+
'See the [full docs](https://www.npmjs.com/package/tiktok-live-api) for all available events.',
|
|
359
|
+
'',
|
|
360
|
+
].join('\n'));
|
|
361
|
+
|
|
362
|
+
} else if (isPython) {
|
|
363
|
+
// ── Python Starter Kit ──
|
|
364
|
+
fs.writeFileSync(path.join(fullPath, 'main.py'), [
|
|
365
|
+
'"""TikTok Live - Python Starter Kit"""',
|
|
366
|
+
'',
|
|
367
|
+
'import asyncio',
|
|
368
|
+
'import json',
|
|
369
|
+
'import websockets',
|
|
370
|
+
'',
|
|
371
|
+
'# ── Configuration ───────────────────────────────────────',
|
|
372
|
+
"USERNAME = 'gbnews' # TikTok @username",
|
|
373
|
+
"API_KEY = 'demo_tiktokliveapi_public_2026' # Get yours at https://tik.tools",
|
|
374
|
+
'',
|
|
375
|
+
'',
|
|
376
|
+
'async def main():',
|
|
377
|
+
' """Connect to TikTok LIVE and print events."""',
|
|
378
|
+
' uri = f"wss://api.tik.tools?uniqueId={USERNAME}&apiKey={API_KEY}"',
|
|
379
|
+
' print(f"🔄 Connecting to @{USERNAME}...")',
|
|
380
|
+
'',
|
|
381
|
+
' try:',
|
|
382
|
+
' async with websockets.connect(uri) as ws:',
|
|
383
|
+
' print(f"✅ Connected to @{USERNAME}\\n")',
|
|
384
|
+
' async for raw in ws:',
|
|
385
|
+
' try:',
|
|
386
|
+
' msg = json.loads(raw)',
|
|
387
|
+
' event = msg.get("event", "")',
|
|
388
|
+
' data = msg.get("data", {})',
|
|
389
|
+
' user = data.get("user", {}).get("uniqueId", "?")',
|
|
390
|
+
'',
|
|
391
|
+
' if event == "chat":',
|
|
392
|
+
' print(f"💬 {user}: {data.get(\"comment\", \"\")}")',
|
|
393
|
+
' elif event == "gift":',
|
|
394
|
+
' print(f"🎁 {user} sent {data.get(\"giftName\", \"a gift\")} x{data.get(\"repeatCount\", 1)}")',
|
|
395
|
+
' elif event == "like":',
|
|
396
|
+
' print(f"❤️ {user} liked (total: {data.get(\"totalLikeCount\", 0)})")',
|
|
397
|
+
' elif event == "member":',
|
|
398
|
+
' print(f"👋 {user} joined")',
|
|
399
|
+
' elif event == "roomUserSeq":',
|
|
400
|
+
' print(f"👀 Viewers: {data.get(\"viewerCount\", 0)}")',
|
|
401
|
+
' except json.JSONDecodeError:',
|
|
402
|
+
' pass',
|
|
403
|
+
' except Exception as e:',
|
|
404
|
+
' print(f"⚠️ Error: {e}")',
|
|
405
|
+
'',
|
|
406
|
+
'',
|
|
407
|
+
'if __name__ == "__main__":',
|
|
408
|
+
' asyncio.run(main())',
|
|
409
|
+
].join('\n') + '\n');
|
|
410
|
+
|
|
411
|
+
fs.writeFileSync(path.join(fullPath, 'requirements.txt'), 'websockets>=12.0\n');
|
|
412
|
+
|
|
413
|
+
fs.writeFileSync(path.join(fullPath, 'README.md'), [
|
|
414
|
+
'# TikTok Live - Python Starter',
|
|
415
|
+
'',
|
|
416
|
+
'A ready-to-run Python project connecting to TikTok LIVE streams.',
|
|
417
|
+
'',
|
|
418
|
+
'## Quick Start',
|
|
419
|
+
'',
|
|
420
|
+
'```bash',
|
|
421
|
+
'pip install -r requirements.txt',
|
|
422
|
+
'python main.py',
|
|
423
|
+
'```',
|
|
424
|
+
'',
|
|
425
|
+
'## Configuration',
|
|
426
|
+
'',
|
|
427
|
+
'Edit `main.py` to change:',
|
|
428
|
+
'- `USERNAME` — the TikTok @username to watch',
|
|
429
|
+
'- `API_KEY` — get your own at [tik.tools](https://tik.tools)',
|
|
430
|
+
'',
|
|
431
|
+
'## Events',
|
|
432
|
+
'',
|
|
433
|
+
'The demo listens for: `chat`, `gift`, `like`, `member`, `roomUserSeq`.',
|
|
434
|
+
'',
|
|
435
|
+
].join('\n'));
|
|
436
|
+
|
|
437
|
+
console.log("\n " + B + "📦 Installing " + C.cyan + "websockets" + B + "..." + R + "\n");
|
|
438
|
+
try { execSync('pip install websockets', { cwd: fullPath, stdio: 'inherit' }); } catch (e) {
|
|
439
|
+
console.log(" " + C.yellow + "Note: run 'pip install -r requirements.txt' manually if pip failed." + R);
|
|
440
|
+
}
|
|
267
441
|
|
|
442
|
+
} else if (isNuxt) {
|
|
268
443
|
const isNuxt4 = fs.existsSync(path.join(fullPath, 'app', 'app.vue')) || !fs.existsSync(path.join(fullPath, 'app.vue'));
|
|
269
444
|
const baseApp = isNuxt4 ? path.join(fullPath, 'app') : fullPath;
|
|
270
445
|
|
|
@@ -276,21 +451,14 @@ function runScaffold(choice, targetDir, pm) {
|
|
|
276
451
|
fs.writeFileSync(appVue, [
|
|
277
452
|
'<template>',
|
|
278
453
|
' <main style="min-height: 100vh; background: #f9fafb; padding-top: 40px;">',
|
|
279
|
-
' <
|
|
454
|
+
' <ClientOnly>',
|
|
455
|
+
' <TikTokLive />',
|
|
456
|
+
' </ClientOnly>',
|
|
280
457
|
' </main>',
|
|
281
458
|
'</template>'
|
|
282
459
|
].join('\n') + '\n');
|
|
283
|
-
|
|
284
|
-
const nuxtConfig = path.join(fullPath, 'nuxt.config.ts');
|
|
285
|
-
if (fs.existsSync(nuxtConfig)) {
|
|
286
|
-
let config = fs.readFileSync(nuxtConfig, 'utf8');
|
|
287
|
-
if (config.includes('defineNuxtConfig({')) {
|
|
288
|
-
config = config.replace('defineNuxtConfig({', "defineNuxtConfig({\n modules: ['tiktok-live-nuxt'],\n");
|
|
289
|
-
fs.writeFileSync(nuxtConfig, config);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
460
|
} else {
|
|
293
|
-
console.log("
|
|
461
|
+
console.log("\n " + B + "📦 Installing " + C.cyan + "tiktok-live-api" + B + " SDK..." + R + "\n");
|
|
294
462
|
execSync(installCmd, { cwd: fullPath, stdio: 'inherit' });
|
|
295
463
|
|
|
296
464
|
if (isNext) {
|
|
@@ -337,10 +505,16 @@ function runScaffold(choice, targetDir, pm) {
|
|
|
337
505
|
console.log("\n " + C.green + "✔ Project successfully scaffolded!" + R + "\n");
|
|
338
506
|
console.log(" " + B + "Next steps:" + R);
|
|
339
507
|
console.log(" cd " + targetDir);
|
|
340
|
-
if (
|
|
341
|
-
console.log("
|
|
508
|
+
if (isPython) {
|
|
509
|
+
console.log(" python main.py\n");
|
|
510
|
+
} else if (isNode) {
|
|
511
|
+
console.log(" node index.mjs\n");
|
|
512
|
+
} else {
|
|
513
|
+
if (isVite && pm !== 'bun') {
|
|
514
|
+
console.log(" " + pm + " install");
|
|
515
|
+
}
|
|
516
|
+
console.log(" " + devCmd + "\n");
|
|
342
517
|
}
|
|
343
|
-
console.log(" " + devCmd + "\n");
|
|
344
518
|
|
|
345
519
|
} catch (err) {
|
|
346
520
|
console.error("\n " + C.red + "Error during scaffolding:" + R, err.message);
|
|
@@ -354,7 +528,7 @@ async function runDemo() {
|
|
|
354
528
|
const WS_BASE = 'wss://api.tik.tools';
|
|
355
529
|
const DEMO_KEY = 'demo_tiktokliveapi_public_2026';
|
|
356
530
|
const CHANNELS = [
|
|
357
|
-
'
|
|
531
|
+
'gbnews', 'cgtnofficial', 'france24_en',
|
|
358
532
|
'weathernewslive', 'gbnews', 'bbcnews',
|
|
359
533
|
'skynews', 'tv_asahi_news', 'abc7chicago', 'thairath_news',
|
|
360
534
|
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiktok-live-api",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.13",
|
|
4
4
|
"description": "Unofficial TikTok LIVE API Client — Real-time chat, gifts, viewers, battles, and AI live captions from any TikTok livestream. Managed WebSocket API with 99.9% uptime.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|