// 创作者数据中转网关(voc-e-commerce)。用于抖音星图、小红书蒲公英(PGY)的创作者侧 // 结构化数据接口(创作者搜索、画像、受众/粉丝分布、内容与评论关键词、笔记/视频绩效、 // 报价与性价比等)。鉴权、计费、错误分类、重试逻辑全部复用社媒网关(voc-gateway)的 // 共享实现,只是根地址不同;对外不暴露任何上游数据供应商名称。 const { buildGatewayUrl, requestJson, classifyApiError, redactSecret, unwrapData } = require('./voc-gateway'); const ECOMMERCE_GATEWAY_ROOT = 'https://server.fmode.cn/api/voc-e-commerce'; function resolveEcommerceRoot(baseUrl) { return String( baseUrl || process.env.VOC_ECOMMERCE_API_BASE_URL || process.env.VOC_ECOMMERCE_GATEWAY_URL || ECOMMERCE_GATEWAY_ROOT ).replace(/\/$/, ''); } // 与 callSocialGateway 完全一致的「优先 newapi sk-、鉴权失败回退 sessionToken」逻辑, // 只是走 voc-e-commerce 根地址。402(余额不足)/403(无权限)不回退。 async function callEcommerceGateway({ proxyPath, method = 'GET', query = {}, body, token, fallbackToken, baseUrl, retries = 3 } = {}) { const root = resolveEcommerceRoot(baseUrl); const url = buildGatewayUrl(root, proxyPath, query); const upper = String(method || 'GET').toUpperCase(); const requestOptions = { method: upper, body: upper === 'GET' ? undefined : body, retries }; try { return await requestJson(url, token, requestOptions); } catch (error) { const canFallback = fallbackToken && fallbackToken !== token && error && error.kind === 'auth'; if (!canFallback) throw error; return requestJson(url, fallbackToken, requestOptions); } } module.exports = { ECOMMERCE_GATEWAY_ROOT, resolveEcommerceRoot, buildGatewayUrl, classifyApiError, redactSecret, unwrapData, requestJson, callEcommerceGateway };