probe-tikhub-douyin.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #!/usr/bin/env node
  2. /** 探测 TikHub 直连抖音 endpoint(绕过 APIG) */
  3. const fs = require('fs');
  4. const path = require('path');
  5. const os = require('os');
  6. const https = require('https');
  7. const xhsConf = JSON.parse(fs.readFileSync(path.join(os.homedir(), '.openclaw', 'skills', 'xiaohongshu-search-notes', 'api-config.json'), 'utf-8'));
  8. const TOKEN = xhsConf.endpoint.headers.Authorization.replace(/^Bearer\s+/, '');
  9. function req(opts, body) {
  10. return new Promise((resolve) => {
  11. const r = https.request(opts, (res) => {
  12. const chunks = [];
  13. res.on('data', (c) => chunks.push(c));
  14. res.on('end', () => resolve({ status: res.statusCode, body: Buffer.concat(chunks).toString('utf-8') }));
  15. });
  16. r.on('error', (e) => resolve({ status: 0, body: e.message }));
  17. r.setTimeout(30000, () => { r.destroy(); resolve({ status: 0, body: 'timeout' }); });
  18. if (body) r.write(body);
  19. r.end();
  20. });
  21. }
  22. // TikHub 官方 douyin endpoints(根据 tikhub.io 文档)
  23. const tries = [
  24. // Web 版
  25. ['/thapi/v1/douyin/web/fetch_general_search_result?keyword=乳酸菌素片&offset=0&count=20&sort_type=0&publish_time=0'],
  26. ['/thapi/v1/douyin/web/fetch_user_video_list?sec_user_id=&max_cursor=0&count=20'],
  27. // App 版
  28. ['/thapi/v1/douyin/app/v3/fetch_general_search?keyword=乳酸菌素片&cursor=0&sort_type=1&publish_time=180'],
  29. ['/thapi/v1/douyin/app/v1/fetch_general_search?keyword=乳酸菌素片&cursor=0'],
  30. // 别的可能的路径
  31. ['/thapi/v1/douyin/search/fetch_general_search_v2?keyword=乳酸菌素片&cursor=0'],
  32. ];
  33. (async () => {
  34. for (const [p] of tries) {
  35. const { status, body } = await req({
  36. hostname: 'server.fmode.cn',
  37. path: encodeURI(p),
  38. method: 'GET',
  39. headers: {
  40. Authorization: `Bearer ${TOKEN}`,
  41. Accept: 'application/json',
  42. },
  43. timeout: 30000,
  44. });
  45. const prev = body.slice(0, 200).replace(/\n/g, ' ');
  46. console.log(`[${status}] ${p.slice(0, 80)}...`);
  47. console.log(` ${prev}`);
  48. console.log('');
  49. await new Promise((r) => setTimeout(r, 1000));
  50. }
  51. })();