// 探测抖音 voc-social API 的响应结构(搜索 + 评论) const https = require('https'); const fs = require('fs'); const os = require('os'); const path = require('path'); const VOC = JSON.parse(fs.readFileSync( path.join(os.homedir(), '.openclaw', 'voc-credentials.json'), 'utf8' )).vocToken; function httpJson(opts, body = null) { return new Promise((res) => { const req = https.request({ ...opts, timeout: 45000 }, (x) => { const chunks = []; x.on('data', (c) => chunks.push(c)); x.on('end', () => { const b = Buffer.concat(chunks).toString('utf-8'); let j = null; try { j = JSON.parse(b); } catch (e) {} res({ status: x.statusCode, body: b, json: j }); }); }); req.on('error', (e) => res({ status: 0, err: e.message })); req.on('timeout', () => { req.destroy(); res({ status: 0, err: 'timeout' }); }); if (body) req.write(body); req.end(); }); } async function main() { console.log('=== 1) Douyin 搜索 "江中肝纯片" ==='); const b = JSON.stringify({ keyword: '江中肝纯片', cursor: 0, sort_type: '1', publish_time: '0', content_type: '1', filter_duration: '0', search_id: '', backtrace: '', }); const r1 = await httpJson({ hostname: 'server.fmode.cn', path: '/api/voc-social/douyin/search/fetch_general_search_v2', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(b), Accept: 'application/json', Authorization: 'Bearer ' + VOC, }, }, b); console.log('status:', r1.status); if (r1.json) { console.log('top keys:', Object.keys(r1.json)); console.log('code:', r1.json.code); const d = r1.json.data; console.log('data keys:', d ? Object.keys(d) : 'none'); if (d?.business_data) { console.log('business_data length:', d.business_data.length); const first = d.business_data[0]; console.log('first wrapper keys:', Object.keys(first || {})); const info = first?.data?.aweme_info || first?.aweme_info; if (info) { console.log('first aweme_info.aweme_id:', info.aweme_id); console.log('first aweme_info.desc:', (info.desc || '').slice(0, 80)); console.log('first aweme_info.statistics:', JSON.stringify(info.statistics).slice(0, 200)); console.log('first aweme_info.author.nickname:', info.author?.nickname); // 找一个有评论的视频 id 作为下一步用 global._awemeId = info.aweme_id; } } console.log('has_more:', d?.has_more); console.log('cursor:', d?.cursor); } // 2) 评论 if (global._awemeId) { console.log('\n=== 2) Douyin 评论 ' + global._awemeId + ' ==='); const r2 = await httpJson({ hostname: 'server.fmode.cn', path: '/api/voc-social/douyin/app/v3/fetch_video_comments?aweme_id=' + global._awemeId + '&cursor=0&count=20', method: 'GET', headers: { Accept: 'application/json', Authorization: 'Bearer ' + VOC }, }); console.log('status:', r2.status); if (r2.json) { console.log('top keys:', Object.keys(r2.json)); console.log('code:', r2.json.code); const d = r2.json.data; console.log('data keys:', d ? Object.keys(d) : 'none'); if (d?.comments) { console.log('comments length:', d.comments.length); const c = d.comments[0]; if (c) { console.log('first comment keys:', Object.keys(c)); console.log('first comment text:', (c.text || '').slice(0, 100)); console.log('first comment digg:', c.digg_count); } } console.log('cursor:', d?.cursor, 'has_more:', d?.has_more); } else { console.log('body:', (r2.body || '').slice(0, 400)); } } } main();