probe-tts-paths.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. #!/usr/bin/env node
  2. // C 组重试:TikTok Shop 正确路径探测(/api/v1/tiktokshop/* 等变体)
  3. const fs = require('fs'), path = require('path'), os = require('os'), https = require('https');
  4. const TOKEN = JSON.parse(fs.readFileSync(path.join(os.homedir(), '.openclaw', 'skills', 'xiaohongshu-search-notes', 'api-config.json'), 'utf-8')).endpoint.headers.Authorization.replace(/^Bearer\s+/, '');
  5. function get(p, params = {}) {
  6. const qs = Object.entries(params).filter(([, v]) => v !== '' && v != null).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&');
  7. const full = qs ? `${p}?${qs}` : p;
  8. return new Promise((r) => {
  9. const req = https.request({ hostname: 'api.tikhub.io', path: full, method: 'GET', headers: { Authorization: 'Bearer ' + TOKEN, Accept: 'application/json' } }, (res) => {
  10. let b = ''; res.on('data', (c) => b += c); res.on('end', () => { try { r({ s: res.statusCode, j: JSON.parse(b) }); } catch { r({ s: res.statusCode, j: { raw: b.slice(0, 200) } }); } });
  11. });
  12. req.on('error', (e) => r({ s: 0, j: { err: e.message } }));
  13. req.setTimeout(15000, () => { req.destroy(); r({ s: 0, j: { err: 'to' } }); });
  14. req.end();
  15. });
  16. }
  17. const PATHS = [
  18. // Apifox 文档里的 TikTok-Shop-Web-API 猜测
  19. { p: '/api/v1/tiktokshop/fetch_search_products_v1', q: { keyword: 'milk thistle', region: 'US', page: 1 } },
  20. { p: '/api/v1/tiktokshop/fetch_search_products_v3', q: { keyword: 'milk thistle', region: 'US', page: 1 } },
  21. { p: '/api/v1/tiktokshop/search_products_v1', q: { keyword: 'milk thistle', region: 'US' } },
  22. { p: '/api/v1/tiktokshop/search_products_v3', q: { keyword: 'milk thistle', region: 'US' } },
  23. { p: '/api/v1/tiktok_shop/search_products_v1', q: { keyword: 'milk thistle', region: 'US' } },
  24. { p: '/api/v1/tiktok_shop/fetch_search_products_v1', q: { keyword: 'milk thistle', region: 'US' } },
  25. { p: '/api/v1/tikhub/tiktok_shop/search_products', q: { keyword: 'milk thistle' } },
  26. { p: '/api/v1/tts/search_products_v1', q: { keyword: 'milk thistle', region: 'US' } },
  27. { p: '/api/v1/tts/search_products_v3', q: { keyword: 'milk thistle', region: 'US' } },
  28. { p: '/api/v1/tts/fetch_hot_selling_products', q: { region: 'US' } },
  29. // 或许是 tiktok 大前缀下?
  30. { p: '/api/v1/tiktok/shop_web/search_products_v1', q: { keyword: 'milk thistle' } },
  31. { p: '/api/v1/tiktok/shop_web/fetch_search_products_v1', q: { keyword: 'milk thistle' } },
  32. { p: '/api/v1/tiktok/shop_web/fetch_search_products_v3', q: { keyword: 'milk thistle' } },
  33. // 其他可能
  34. { p: '/api/v1/tiktok/tts/search_products_v1', q: { keyword: 'milk thistle' } },
  35. { p: '/api/v1/tiktok/web/tts_search_products_v1', q: { keyword: 'milk thistle' } },
  36. ];
  37. (async () => {
  38. for (const x of PATHS) {
  39. const r = await get(x.p, x.q);
  40. const msg = r.j.message || r.j.msg || r.j.raw || r.j.err || '';
  41. const tag = r.s === 200 ? '✓' : (r.s === 404 ? '—' : '?');
  42. console.log(`${tag} ${r.s.toString().padEnd(4)} ${x.p} ${String(msg).slice(0, 80)}`);
  43. if (r.s === 200 && r.j.data) {
  44. console.log(' data keys:', Object.keys(r.j.data).slice(0, 6));
  45. }
  46. await new Promise((r) => setTimeout(r, 400));
  47. }
  48. })();