The Hickory Herald — personalized news digest feedback server
  • Python 84.3%
  • HTML 13.4%
  • Dockerfile 2.3%
Find a file
2026-07-11 12:43:37 -04:00
app fix: add nolog parameter to feedback endpoints 2026-07-10 17:12:08 -04:00
tests fix: add nolog parameter to feedback endpoints 2026-07-10 17:12:08 -04:00
.env.example feat: default HERALD_LOG_LEVEL to info, add .env.example 2026-07-11 12:43:37 -04:00
.gitignore feat: feedback server MVP 2026-07-09 15:48:29 -04:00
.python-version feat: feedback server MVP 2026-07-09 15:48:29 -04:00
docker-compose.yml feat: default HERALD_LOG_LEVEL to info, add .env.example 2026-07-11 12:43:37 -04:00
Dockerfile feat: default HERALD_LOG_LEVEL to info, add .env.example 2026-07-11 12:43:37 -04:00
pyproject.toml feat: feedback server MVP 2026-07-09 15:48:29 -04:00
README.md feat: add API key auth for POST /api/stories 2026-07-10 08:14:43 -04:00
ruff.toml feat: feedback server MVP 2026-07-09 15:48:29 -04:00
uv.lock feat: feedback server MVP 2026-07-09 15:48:29 -04:00

The Hickory Herald

A twice-daily personalized news digest delivered to Telegram. Curates 42 RSS feeds across 9 categories, generating real 2-3 paragraph summaries with a feedback loop that learns your preferences over time.

Architecture

Component Purpose
Feedback Server (this repo) FastAPI + SQLite server tracking likes/dislikes per story
Feed Collection Pipeline RSS fetcher + OPML parser (cron jobs)
LLM Curation Layer Dedup, summarize, categorize, rank (Hermes cron)
Digest Delivery Telegram formatting, morning/evening editions
Analytics Engine Topic affinity, source quality, recommendations

Feedback Server

The feedback server provides click-tracking for the news digest. Each story in the digest gets two links:

  • /r/{story_id} — "Read More" thumbs-up → logs a like, redirects to the source article
  • /d/{story_id} — "Not For Me" thumbs-down → logs a dislike, shows the feedback dashboard

Running Locally

uv sync
uv run uvicorn app.main:app --reload

API Endpoints

Method Path Description
GET /health Health check
POST /api/stories Register a new story
GET /r/{story_id} Thumbs-up → redirect
GET /d/{story_id} Thumbs-down → dashboard
GET /dashboard Feedback stats overview

Testing

uv run pytest

Deployment

# Clone and deploy with Docker Compose
git clone git@git.flora.family:cody/hickory-herald.git
cd hickory-herald

# Set your API key (used to protect POST /api/stories)
echo "HERALD_API_KEY=$(openssl rand -hex 32)" > .env

docker compose up -d

The SQLite database persists at /main/appdata/herald/herald.db on the host. Container is named herald and exposed on port 8000, matching the Caddy config for herald.flora.family.

API Authentication

Write endpoints (POST /api/stories) require an X-API-Key header matching the HERALD_API_KEY environment variable. Public endpoints (/r/, /d/, /dashboard, /health) are unauthenticated.

Project Status

See The Hickory Herald on Taiga for epics and user stories.