shangjian2023/dsh-rss-daily0

dsh-rss-daily

dsh plugin: daily RSS news digest from 46 curated sources, LLM-edited via the model already configured in dsh, delivered to your IM via webhook (ServerChan / PushDeer / WeCom / Telegram / Bark / gotify / custom).

包名
dsh-rss-daily
版本
0.1.0
许可证
MIT
最近更新
2026年8月22日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:shangjian2023/dsh-rss-daily

dsh-rss-daily

A dsh plugin that brings you a daily news digest — every morning, in your IM, from 46 curated RSS sources across tech / science / world / finance / humanities / dev.

What makes it different from a plain RSS reader:

  • Editor, not aggregator. A candidate pool of ~20 items is scored (source tier × recency × signal words), deduplicated (Jaccard + MD5 history), cross-checked against a multi-source event graph (newsflash, ≥3 independent outlets), then handed to the model already configured in your dsh for editorial selection: merge same-event reports, drop PR filler and weekly roundups, balance topics (max 2 per tag), and write one concrete fact line per item (≤45 chars, Chinese rendering for English news).
  • Zero extra LLM credentials. The editorial pass goes through ctx.llm — whatever model your dsh already uses. If the model call fails, it degrades to a deterministic rule-based selection, so the digest never misses a day.
  • Delivered where you read. Webhook push to ServerChan / PushDeer / WeCom bot / Telegram / Bark / gotify / any custom JSON endpoint.
  • Production-grade pipeline. Ported from a personal pipeline that has run daily since June 2026 through 9 revisions: per-source health tracking with adaptive timeouts, feed charset-mojibake repair, full-text enrichment for thin summaries, a 420s hard budget, idempotent two-phase send (fetch → outbox → deliver → confirm), and a 14-day dedup window.

Requirements

  • dsh with the web (or any long-running) profile
  • Python 3.9+ with feedparser: pip install feedparser
  • Node.js ≥ 18 (bundled with dsh)

Install

One command — dsh plugin add installs the package via pnpm and appends it to the profile's dsh.profile.bundles; the row itself comes from this package's cordis.patch.yml:

dsh plugin --profile web add github:shangjian2023/dsh-rss-daily

Restart dsh web and the schedule is live. For development from a local checkout: dsh plugin --profile web add /absolute/path/to/dsh-rss-daily (pnpm links it; run pnpm install in the checkout once).

Configure

Tune config by overlaying the row from the profile's patch layer ($DSH_HOME/profiles/web/cordis.patch.yml):

- insert:
    - id: rss-daily
      name: dsh-rss-daily
      config:
        time: "08:00"          # local time, daily
        targets:
          - type: serverchan   # ServerChan sendkey
            key: SCTxxxxxxxx
          - type: telegram
            token: "123456:ABC..."
            chatId: "-1001234567890"
KeyDefaultMeaning
enabledtruedaily schedule on/off (agent tool stays)
time"08:00"local HH:MM to run; a boot-time catch-up runs if missed by <12h
stateDir$DSH_HOME/rss-dailysources / dedup history / outbox live here
sourcesFilestateDir/sources.jsonyour source list; seeded from the bundled 46-source default on first run
digestItems8max items per digest
llmModeharnessharness (use dsh's model) or none (rule-based only)
llmProvider / llmModelfirst availableoverride which harness model edits the digest
footer""custom footer line
targets[][]delivery targets; delivered = at least one succeeded

Source entry shape (sources.json): { "name", "url", "category", "tier" (1–3) }. The bundled list was reachability-tested from mainland China; add sources freely — unhealthy ones auto-degrade for 24h after 3 consecutive failures and rotate back in.

Use

  • Automatic: every day at time, the digest is generated and pushed. Missed runs are caught up on boot.
  • In chat: ask the agent — it has an rss_daily tool (run / status / redo / deliver), e.g. "generate today's news digest now".
  • Headless / system cron: run the pipeline directly with any OpenAI-compatible endpoint:
python py/daily.py --state-dir ~/.rss-daily            # one-shot full run (rule mode)
RSS_LLM_ENDPOINT=https://api.deepseek.com/v1 \
RSS_LLM_KEY=sk-... RSS_LLM_MODEL=deepseek-chat \
python py/daily.py --state-dir ~/.rss-daily            # with LLM editing
python py/daily.py --stage confirm --state-dir ~/.rss-daily   # after delivery succeeded

Pipeline stages (advanced)

py/daily.py is independently scriptable and speaks single-line JSON on stdout:

python py/daily.py --stage fetch --state-dir DIR   # → {"status":"READY","prompt":...}
python py/daily.py --stage finalize --llm-reply FILE --state-dir DIR
python py/daily.py --stage confirm --state-dir DIR
python py/daily.py --stage status --state-dir DIR

The plugin itself uses exactly these stages: fetch produces the editor prompt, the plugin streams it through ctx.llm, finalize parses the reply (falling back to rule mode on garbage), then the plugin delivers and confirm marks the day done. Never confirm before successful delivery — confirmed items enter the 14-day dedup window permanently.

License

MIT