2.6 KiB
2.6 KiB
Xianyu Per-Item Notifications + Feishu Clickable Links — 2026-05
Context
BOSS reported two UX issues after initial link normalization:
- Feishu still did not show reliable clickable product links.
- Notifications should behave like the original project: each product should be pushed as its own message, not bundled into one long report-style message.
A key pitfall was that the running server.mjs process still used the old notifier module until the service was restarted. Always restart the Node service after patching notification rendering.
Implemented pattern
lib/notifier.mjs now defaults to:
{
"perItem": true,
"maxNotifyItems": 10
}
Notification rendering now:
- Selects candidates by
verdict === 'recommend' || score >= minScore. - Sends up to
maxNotifyItemsitems. - Sends one message per item when
perItem !== false. - Uses explicit Feishu-compatible Markdown link syntax:
[🔗 打开闲鱼商品](https://h5.m.goofish.com/item?id=<id>)
备用链接:https://h5.m.goofish.com/item?id=<id>
The backup plain h5 URL is kept because Feishu/clients sometimes vary in Markdown rendering.
Verification
After patching, run:
cd /Users/chick/.Hermes/workspace/research/xianyu-hunter
node --check lib/notifier.mjs && node --check server.mjs
Dry-run without sending:
node --input-type=module - <<'NODE'
import fs from 'fs';
import { buildAnalysis } from './lib/analyzer.mjs';
import { sendNotifications } from './lib/notifier.mjs';
const data = JSON.parse(fs.readFileSync('data/tasks.json','utf8'));
const task = data.at(-1);
const analysis = buildAnalysis(task, { limit: 3 });
const res = await sendNotifications(task, { ...analysis.summary, maxNotifyItems: 3 }, {
force: true,
config: { enabled: true, notifyOnlyGood: false, minScore: 0, perItem: true, maxNotifyItems: 3, channels: [] }
});
console.log(res.messages.join('\n\n---\n\n'));
NODE
Restart exact Node server process, then test through API:
# kill old node server.mjs PID, then start tracked/background process
PORT=3000 node server.mjs
curl -sS -X POST http://127.0.0.1:3000/api/notify-test \
-H 'Content-Type: application/json' \
-d '{"title":"xianyu-hunter 单商品链接测试"}' | python3 -m json.tool
Expected API response includes:
perItem: truemessages: [ ... ]- message text contains
[🔗 打开闲鱼商品](https://h5.m.goofish.com/item?id=...) results[].itemIndexfor each individual pushed item
Notes
cfg.perItem === falsecan still be used to send a bundled message for webhook channels if needed.chatUrlshould remain a desktop IM URL; only user-facing product links use h5 mobile URLs.