86 lines
2.6 KiB
Markdown
86 lines
2.6 KiB
Markdown
# Xianyu Per-Item Notifications + Feishu Clickable Links — 2026-05
|
|
|
|
## Context
|
|
|
|
BOSS reported two UX issues after initial link normalization:
|
|
|
|
1. Feishu still did not show reliable clickable product links.
|
|
2. 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:
|
|
|
|
```json
|
|
{
|
|
"perItem": true,
|
|
"maxNotifyItems": 10
|
|
}
|
|
```
|
|
|
|
Notification rendering now:
|
|
|
|
- Selects candidates by `verdict === 'recommend' || score >= minScore`.
|
|
- Sends up to `maxNotifyItems` items.
|
|
- Sends one message per item when `perItem !== false`.
|
|
- Uses explicit Feishu-compatible Markdown link syntax:
|
|
|
|
```md
|
|
[🔗 打开闲鱼商品](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:
|
|
|
|
```bash
|
|
cd /Users/chick/.Hermes/workspace/research/xianyu-hunter
|
|
node --check lib/notifier.mjs && node --check server.mjs
|
|
```
|
|
|
|
Dry-run without sending:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
# 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: true`
|
|
- `messages: [ ... ]`
|
|
- message text contains `[🔗 打开闲鱼商品](https://h5.m.goofish.com/item?id=...)`
|
|
- `results[].itemIndex` for each individual pushed item
|
|
|
|
## Notes
|
|
|
|
- `cfg.perItem === false` can still be used to send a bundled message for webhook channels if needed.
|
|
- `chatUrl` should remain a desktop IM URL; only user-facing product links use h5 mobile URLs.
|