| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- // 快速烟测三平台 API 是否可用(江中采集前置验证)
- const https = require('https');
- const fs = require('fs');
- const os = require('os');
- const path = require('path');
- const TIKHUB = JSON.parse(fs.readFileSync(
- path.join(os.homedir(), '.openclaw', 'skills', 'xiaohongshu-search-notes', 'api-config.json'),
- 'utf8'
- )).endpoint.headers.Authorization.replace(/^Bearer\s+/, '');
- function httpJson(opts, body = null, timeout = 30000) {
- return new Promise((resolve) => {
- const req = https.request({ ...opts, timeout }, (res) => {
- const chunks = [];
- res.on('data', (c) => chunks.push(c));
- res.on('end', () => {
- const b = Buffer.concat(chunks).toString('utf-8');
- let j = null;
- try { j = JSON.parse(b); } catch (e) { /* ignore */ }
- resolve({ status: res.statusCode, body: b, json: j });
- });
- });
- req.on('error', (e) => resolve({ status: 0, err: e.message }));
- req.on('timeout', () => { req.destroy(); resolve({ status: 0, err: 'timeout' }); });
- if (body) req.write(body);
- req.end();
- });
- }
- async function main() {
- console.log('=== 1) XHS search_notes (TikHub) ===');
- const r1 = await httpJson({
- hostname: 'server.fmode.cn',
- path: '/thapi/v1/xiaohongshu/app/search_notes?keyword=' + encodeURIComponent('肝纯片') + '&page=1',
- method: 'GET',
- headers: { Accept: 'application/json', Authorization: 'Bearer ' + TIKHUB },
- });
- const items = r1.json?.data?.data?.items || [];
- console.log(` status=${r1.status} items=${items.length}`);
- if (items.length) {
- const n = items[0].note;
- console.log(` sample: ${(n?.title || n?.desc || '').slice(0, 60)} · cmts=${n?.comments_count}`);
- global._sampleNoteId = n?.id;
- }
- console.log('\n=== 2) XHS get_note_comments ===');
- if (global._sampleNoteId) {
- const r2 = await httpJson({
- hostname: 'server.fmode.cn',
- path: '/thapi/v1/xiaohongshu/app/get_note_comments?note_id=' + global._sampleNoteId + '&cursor=',
- method: 'GET',
- headers: { Accept: 'application/json', Authorization: 'Bearer ' + TIKHUB },
- });
- const c = r2.json?.data?.data?.comments || [];
- console.log(` status=${r2.status} comments=${c.length} has_more=${r2.json?.data?.data?.has_more}`);
- if (c.length) console.log(` sample: ${(c[0].content || '').slice(0, 80)} | ♥ ${c[0].like_count}`);
- }
- console.log('\n=== 3) Douyin search (voc-social POST) ===');
- // 读 voc-credentials.json 拿 vocToken
- const VOC = JSON.parse(fs.readFileSync(
- path.join(os.homedir(), '.openclaw', 'voc-credentials.json'), 'utf8'
- )).vocToken;
- const dyBody = JSON.stringify({
- keyword: '肝纯片',
- cursor: 0,
- sort_type: '1',
- publish_time: '0',
- content_type: '1',
- filter_duration: '0',
- search_id: '',
- backtrace: '',
- });
- const r3 = await httpJson({
- hostname: 'server.fmode.cn',
- path: '/api/voc-social/douyin/search/fetch_general_search_v2',
- method: 'POST',
- headers: {
- Accept: 'application/json',
- 'Content-Type': 'application/json',
- 'Content-Length': Buffer.byteLength(dyBody),
- Authorization: 'Bearer ' + VOC,
- },
- }, dyBody);
- console.log(` status=${r3.status}`);
- if (r3.json) {
- const topKeys = Object.keys(r3.json).slice(0, 10).join(',');
- console.log(` json top keys: ${topKeys}`);
- const sample = (r3.body || '').slice(0, 500);
- console.log(` body sample: ${sample}`);
- }
- console.log('\n=== 4) Sorftime ProductQuery (milk thistle) ===');
- const azBody = JSON.stringify({
- path: '/api/ProductQuery',
- method: 'POST',
- body: { Page: 1, Query: '1', QueryType: '7', Pattern: 'milk thistle' },
- query: { domain: 1 },
- });
- const r4 = await httpJson({
- hostname: 'server-msq.fmode.cn',
- path: '/api/sorftime/forward',
- method: 'POST',
- headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(azBody) },
- }, azBody, 45000);
- console.log(` status=${r4.status}`);
- if (r4.json) {
- const data = r4.json?.Data ?? r4.json?.data ?? r4.json;
- const prods = data?.Products || [];
- console.log(` products=${prods.length} PageCount=${data?.PageCount}`);
- if (prods.length) {
- console.log(` sample: ${prods[0].Asin} · ${(prods[0].Brand || '').slice(0, 20)} · $${((prods[0].SalesPrice || 0) / 100).toFixed(2)}`);
- }
- } else {
- console.log(` body sample: ${(r4.body || '').slice(0, 400)}`);
- }
- }
- main().catch((e) => console.error(e));
|