_probe-douyin-shape.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // 探测抖音 voc-social API 的响应结构(搜索 + 评论)
  2. const https = require('https');
  3. const fs = require('fs');
  4. const os = require('os');
  5. const path = require('path');
  6. const VOC = JSON.parse(fs.readFileSync(
  7. path.join(os.homedir(), '.openclaw', 'voc-credentials.json'), 'utf8'
  8. )).vocToken;
  9. function httpJson(opts, body = null) {
  10. return new Promise((res) => {
  11. const req = https.request({ ...opts, timeout: 45000 }, (x) => {
  12. const chunks = [];
  13. x.on('data', (c) => chunks.push(c));
  14. x.on('end', () => {
  15. const b = Buffer.concat(chunks).toString('utf-8');
  16. let j = null;
  17. try { j = JSON.parse(b); } catch (e) {}
  18. res({ status: x.statusCode, body: b, json: j });
  19. });
  20. });
  21. req.on('error', (e) => res({ status: 0, err: e.message }));
  22. req.on('timeout', () => { req.destroy(); res({ status: 0, err: 'timeout' }); });
  23. if (body) req.write(body);
  24. req.end();
  25. });
  26. }
  27. async function main() {
  28. console.log('=== 1) Douyin 搜索 "江中肝纯片" ===');
  29. const b = JSON.stringify({
  30. keyword: '江中肝纯片',
  31. cursor: 0, sort_type: '1', publish_time: '0', content_type: '1',
  32. filter_duration: '0', search_id: '', backtrace: '',
  33. });
  34. const r1 = await httpJson({
  35. hostname: 'server.fmode.cn',
  36. path: '/api/voc-social/douyin/search/fetch_general_search_v2',
  37. method: 'POST',
  38. headers: {
  39. 'Content-Type': 'application/json',
  40. 'Content-Length': Buffer.byteLength(b),
  41. Accept: 'application/json',
  42. Authorization: 'Bearer ' + VOC,
  43. },
  44. }, b);
  45. console.log('status:', r1.status);
  46. if (r1.json) {
  47. console.log('top keys:', Object.keys(r1.json));
  48. console.log('code:', r1.json.code);
  49. const d = r1.json.data;
  50. console.log('data keys:', d ? Object.keys(d) : 'none');
  51. if (d?.business_data) {
  52. console.log('business_data length:', d.business_data.length);
  53. const first = d.business_data[0];
  54. console.log('first wrapper keys:', Object.keys(first || {}));
  55. const info = first?.data?.aweme_info || first?.aweme_info;
  56. if (info) {
  57. console.log('first aweme_info.aweme_id:', info.aweme_id);
  58. console.log('first aweme_info.desc:', (info.desc || '').slice(0, 80));
  59. console.log('first aweme_info.statistics:', JSON.stringify(info.statistics).slice(0, 200));
  60. console.log('first aweme_info.author.nickname:', info.author?.nickname);
  61. // 找一个有评论的视频 id 作为下一步用
  62. global._awemeId = info.aweme_id;
  63. }
  64. }
  65. console.log('has_more:', d?.has_more);
  66. console.log('cursor:', d?.cursor);
  67. }
  68. // 2) 评论
  69. if (global._awemeId) {
  70. console.log('\n=== 2) Douyin 评论 ' + global._awemeId + ' ===');
  71. const r2 = await httpJson({
  72. hostname: 'server.fmode.cn',
  73. path: '/api/voc-social/douyin/app/v3/fetch_video_comments?aweme_id=' + global._awemeId + '&cursor=0&count=20',
  74. method: 'GET',
  75. headers: { Accept: 'application/json', Authorization: 'Bearer ' + VOC },
  76. });
  77. console.log('status:', r2.status);
  78. if (r2.json) {
  79. console.log('top keys:', Object.keys(r2.json));
  80. console.log('code:', r2.json.code);
  81. const d = r2.json.data;
  82. console.log('data keys:', d ? Object.keys(d) : 'none');
  83. if (d?.comments) {
  84. console.log('comments length:', d.comments.length);
  85. const c = d.comments[0];
  86. if (c) {
  87. console.log('first comment keys:', Object.keys(c));
  88. console.log('first comment text:', (c.text || '').slice(0, 100));
  89. console.log('first comment digg:', c.digg_count);
  90. }
  91. }
  92. console.log('cursor:', d?.cursor, 'has_more:', d?.has_more);
  93. } else {
  94. console.log('body:', (r2.body || '').slice(0, 400));
  95. }
  96. }
  97. }
  98. main();