probe-douyin.js 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/usr/bin/env node
  2. /** 排查抖音搜索返回结构 */
  3. const fs = require('fs');
  4. const path = require('path');
  5. const os = require('os');
  6. const https = require('https');
  7. const vocToken = JSON.parse(fs.readFileSync(path.join(os.homedir(), '.openclaw', 'voc-credentials.json'), 'utf-8')).vocToken;
  8. function req(opts, body) {
  9. return new Promise((resolve, reject) => {
  10. const r = https.request(opts, (res) => {
  11. const chunks = [];
  12. res.on('data', (c) => chunks.push(c));
  13. res.on('end', () => resolve({ status: res.statusCode, body: Buffer.concat(chunks).toString('utf-8') }));
  14. });
  15. r.on('error', reject);
  16. r.setTimeout(30000, () => { r.destroy(); reject(new Error('timeout')); });
  17. if (body) r.write(body);
  18. r.end();
  19. });
  20. }
  21. (async () => {
  22. const tries = [
  23. // Try 1: current script's POST shape
  24. {
  25. name: 'POST /api/voc-social/douyin/search/fetch_general_search_v2',
  26. opts: {
  27. hostname: 'server.fmode.cn',
  28. path: '/api/voc-social/douyin/search/fetch_general_search_v2',
  29. method: 'POST',
  30. headers: {
  31. Authorization: `Bearer ${vocToken}`,
  32. 'Content-Type': 'application/json',
  33. Accept: 'application/json',
  34. },
  35. },
  36. body: JSON.stringify({ keyword: '乳酸菌素片', cursor: 0, sort_type: '1', publish_time: '180' }),
  37. },
  38. // Try 2: GET with query params (like xhs)
  39. {
  40. name: 'GET /api/voc-social/douyin/search/fetch_general_search_v2?keyword=乳酸菌素片',
  41. opts: {
  42. hostname: 'server.fmode.cn',
  43. path: `/api/voc-social/douyin/search/fetch_general_search_v2?keyword=${encodeURIComponent('乳酸菌素片')}&cursor=0&sort_type=1&publish_time=180`,
  44. method: 'GET',
  45. headers: {
  46. Authorization: `Bearer ${vocToken}`,
  47. Accept: 'application/json',
  48. },
  49. },
  50. },
  51. ];
  52. for (const t of tries) {
  53. console.log(`\n=== ${t.name} ===`);
  54. try {
  55. const { status, body } = await req(t.opts, t.body);
  56. console.log(`status: ${status}`);
  57. console.log(`body[0:400]: ${body.slice(0, 400)}`);
  58. try {
  59. const j = JSON.parse(body);
  60. const keys = Object.keys(j);
  61. console.log(`JSON top keys: ${keys.join(', ')}`);
  62. if (j.data) console.log(` data type: ${Array.isArray(j.data) ? 'Array(' + j.data.length + ')' : typeof j.data}, keys: ${Array.isArray(j.data) ? '[]' : Object.keys(j.data).join(', ')}`);
  63. } catch (e) { /* ignore */ }
  64. } catch (e) {
  65. console.log(`ERROR: ${e.message}`);
  66. }
  67. await new Promise((r) => setTimeout(r, 1500));
  68. }
  69. })();