Files
wiki-jokes/README.md
T

2.6 KiB

Wiki Jokes

5 jokes every day, generated by an LLM from Wikipedia's Today's Featured Article.

How it works

  • A scheduled job (06:00 Europe/Copenhagen, plus immediately on cold start) fetches the day's featured article from the Wikipedia REST feed and asks any OpenAI-compatible endpoint for exactly 5 jokes as JSON.
  • Jokes are stored in SQLite (/data/jokes.db) and served instantly — no LLM call at request time.
  • On failure: retries every 15 min, up to 3 attempts per day. If still failing, the page keeps showing the latest batch with a "stale" note.

Run

cp .env.example .env   # set OPENAI_BASE_URL / OPENAI_MODEL / OPENAI_API_KEY
docker compose up -d --build
# open http://localhost:8080

Configuration (env vars)

Var Default Purpose
OPENAI_BASE_URL https://api.openai.com/v1 OpenAI-compatible endpoint (e.g. llamaswap)
OPENAI_MODEL gpt-4o-mini Model name
OPENAI_API_KEY (empty) Bearer token (optional for llamaswap)
GENERATE_HOUR / GENERATE_MINUTE 6 / 0 Daily generation time
MAX_ATTEMPTS 3 Retry budget per burst
RETRY_MINUTES 15 Retry interval
SLOW_RETRY_MINUTES 60 Cooldown after budget exhausted, then retries resume
WIKIPEDIA_LANG en Wikipedia language for the feed
DB_PATH /data/jokes.db SQLite location (volume-mounted)

Endpoints

  • GET / — today's 5 jokes + link to the featured article
  • GET /trmnl.json — JSON feed for TRMNL e-ink displays (see trmnl-plugin/)
  • GET /health — JSON: whether today's jokes exist / retries exhausted

TRMNL e-ink feed

GET /trmnl.json returns the day's jokes in a shape ready for a TRMNL Private Plugin with the polling strategy:

{
  "refresh_interval": 900,
  "day": "2026-10-05",
  "stale": false,
  "article_title": "White-headed fruit dove",
  "article_url": "https://en.wikipedia.org/...",
  "jokes": [{"text": "..."}]
}

Optional access token: set TRMNL_TOKEN in .env; requests must then carry ?token=<token> or the header trmnl-token: <token> (put the token directly in TRMNL's polling URL or polling headers). Without the env var the endpoint is open — the jokes themselves are public anyway.

Setup on my.trmnl.com:

  1. Plugins → New private plugin. Strategy Polling, URL https://wiki-jokes.obahan.xyz/trmnl.json (+ token if enabled).
  2. Markup (Full layout): paste trmnl-plugin/full.liquid.
  3. Assign the plugin to your device's playlist.

The template was verified to render against the live payload with python-liquid (5 items, day, stale flag).