_smoke-jiangzhong-apis.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // 快速烟测三平台 API 是否可用(江中采集前置验证)
  2. const https = require('https');
  3. const fs = require('fs');
  4. const os = require('os');
  5. const path = require('path');
  6. const TIKHUB = JSON.parse(fs.readFileSync(
  7. path.join(os.homedir(), '.openclaw', 'skills', 'xiaohongshu-search-notes', 'api-config.json'),
  8. 'utf8'
  9. )).endpoint.headers.Authorization.replace(/^Bearer\s+/, '');
  10. function httpJson(opts, body = null, timeout = 30000) {
  11. return new Promise((resolve) => {
  12. const req = https.request({ ...opts, timeout }, (res) => {
  13. const chunks = [];
  14. res.on('data', (c) => chunks.push(c));
  15. res.on('end', () => {
  16. const b = Buffer.concat(chunks).toString('utf-8');
  17. let j = null;
  18. try { j = JSON.parse(b); } catch (e) { /* ignore */ }
  19. resolve({ status: res.statusCode, body: b, json: j });
  20. });
  21. });
  22. req.on('error', (e) => resolve({ status: 0, err: e.message }));
  23. req.on('timeout', () => { req.destroy(); resolve({ status: 0, err: 'timeout' }); });
  24. if (body) req.write(body);
  25. req.end();
  26. });
  27. }
  28. async function main() {
  29. console.log('=== 1) XHS search_notes (TikHub) ===');
  30. const r1 = await httpJson({
  31. hostname: 'server.fmode.cn',
  32. path: '/thapi/v1/xiaohongshu/app/search_notes?keyword=' + encodeURIComponent('肝纯片') + '&page=1',
  33. method: 'GET',
  34. headers: { Accept: 'application/json', Authorization: 'Bearer ' + TIKHUB },
  35. });
  36. const items = r1.json?.data?.data?.items || [];
  37. console.log(` status=${r1.status} items=${items.length}`);
  38. if (items.length) {
  39. const n = items[0].note;
  40. console.log(` sample: ${(n?.title || n?.desc || '').slice(0, 60)} · cmts=${n?.comments_count}`);
  41. global._sampleNoteId = n?.id;
  42. }
  43. console.log('\n=== 2) XHS get_note_comments ===');
  44. if (global._sampleNoteId) {
  45. const r2 = await httpJson({
  46. hostname: 'server.fmode.cn',
  47. path: '/thapi/v1/xiaohongshu/app/get_note_comments?note_id=' + global._sampleNoteId + '&cursor=',
  48. method: 'GET',
  49. headers: { Accept: 'application/json', Authorization: 'Bearer ' + TIKHUB },
  50. });
  51. const c = r2.json?.data?.data?.comments || [];
  52. console.log(` status=${r2.status} comments=${c.length} has_more=${r2.json?.data?.data?.has_more}`);
  53. if (c.length) console.log(` sample: ${(c[0].content || '').slice(0, 80)} | ♥ ${c[0].like_count}`);
  54. }
  55. console.log('\n=== 3) Douyin search (voc-social POST) ===');
  56. // 读 voc-credentials.json 拿 vocToken
  57. const VOC = JSON.parse(fs.readFileSync(
  58. path.join(os.homedir(), '.openclaw', 'voc-credentials.json'), 'utf8'
  59. )).vocToken;
  60. const dyBody = JSON.stringify({
  61. keyword: '肝纯片',
  62. cursor: 0,
  63. sort_type: '1',
  64. publish_time: '0',
  65. content_type: '1',
  66. filter_duration: '0',
  67. search_id: '',
  68. backtrace: '',
  69. });
  70. const r3 = await httpJson({
  71. hostname: 'server.fmode.cn',
  72. path: '/api/voc-social/douyin/search/fetch_general_search_v2',
  73. method: 'POST',
  74. headers: {
  75. Accept: 'application/json',
  76. 'Content-Type': 'application/json',
  77. 'Content-Length': Buffer.byteLength(dyBody),
  78. Authorization: 'Bearer ' + VOC,
  79. },
  80. }, dyBody);
  81. console.log(` status=${r3.status}`);
  82. if (r3.json) {
  83. const topKeys = Object.keys(r3.json).slice(0, 10).join(',');
  84. console.log(` json top keys: ${topKeys}`);
  85. const sample = (r3.body || '').slice(0, 500);
  86. console.log(` body sample: ${sample}`);
  87. }
  88. console.log('\n=== 4) Sorftime ProductQuery (milk thistle) ===');
  89. const azBody = JSON.stringify({
  90. path: '/api/ProductQuery',
  91. method: 'POST',
  92. body: { Page: 1, Query: '1', QueryType: '7', Pattern: 'milk thistle' },
  93. query: { domain: 1 },
  94. });
  95. const r4 = await httpJson({
  96. hostname: 'server-msq.fmode.cn',
  97. path: '/api/sorftime/forward',
  98. method: 'POST',
  99. headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(azBody) },
  100. }, azBody, 45000);
  101. console.log(` status=${r4.status}`);
  102. if (r4.json) {
  103. const data = r4.json?.Data ?? r4.json?.data ?? r4.json;
  104. const prods = data?.Products || [];
  105. console.log(` products=${prods.length} PageCount=${data?.PageCount}`);
  106. if (prods.length) {
  107. console.log(` sample: ${prods[0].Asin} · ${(prods[0].Brand || '').slice(0, 20)} · $${((prods[0].SalesPrice || 0) / 100).toFixed(2)}`);
  108. }
  109. } else {
  110. console.log(` body sample: ${(r4.body || '').slice(0, 400)}`);
  111. }
  112. }
  113. main().catch((e) => console.error(e));