grocery-bot

Log | Files | Refs | README

README.md (4211B)


      1 # Anton
      2 
      3 A self-hosted Telegram bot for tracking recipes, managing a weekly staples
      4 list, and generating grocery lists. Runs as a long-polling service — no
      5 public webhook or reverse proxy needed. See `CLAUDE.md` for coding
      6 conventions/hard constraints and `SPEC.md` for the original project plan.
      7 
      8 ## Setup
      9 
     10 ```bash
     11 python3 -m venv .venv
     12 .venv/bin/pip install -r requirements.txt
     13 cp .env.example .env   # then fill in TELEGRAM_BOT_TOKEN (get one from @BotFather)
     14 .venv/bin/python3 bot.py
     15 ```
     16 
     17 The SQLite database is created automatically on first run at the path set
     18 by `ANTON_DB_PATH` in `.env` (defaults to `anton.db` in the working
     19 directory).
     20 
     21 ## Testing
     22 
     23 ```bash
     24 .venv/bin/pytest
     25 ```
     26 
     27 Covers quantity parsing, grocery-list merge logic, category grouping, and
     28 the recipe-text parser. There's no automated coverage of the Telegram
     29 wiring itself — that needs manual testing against a real bot token.
     30 
     31 ## Commands
     32 
     33 - `/addrecipe` — add a recipe; the bot asks for a name, then you paste the
     34   ingredients (freeform text copied straight from a recipe site works, or
     35   the structured `<quantity> | <unit> | <name> | <category>` format for
     36   precise merging later). Long pastes can span multiple messages — send
     37   `/done` when finished, `/cancel` to abort.
     38 - `/recipes [tag/group/keyword]` — list recipes. `keto` filters by the
     39   auto-suggested keto tag; a manually-created group matches next (e.g.
     40   `/recipes slowcooker`); anything else searches recipe names. An exact
     41   name shows that recipe's ingredients instead of a list.
     42 - `/recipe <name>` — show one recipe's ingredients.
     43 - `/instructions <name>` — show one recipe's instructions.
     44 - `/instructions add <name>` — paste instructions for a recipe (replaces
     45   any existing ones); spans multiple messages the same way `/addrecipe`
     46   does, send `/done` when finished.
     47 - `/instructions delete <name>` — clear a recipe's instructions.
     48 - `/tag <group>` — list recipes tagged with a group (e.g. `/tag beef`).
     49 - `/tag add <group>` — create a new, empty group.
     50 - `/tag add <recipe name>, <group>` — tag a recipe with a group (creates
     51   the group if it doesn't exist yet).
     52 - `/tag remove <group>` — delete a group entirely, untagging it from
     53   every recipe.
     54 - `/tag remove <recipe name>, <group>` — untag one recipe, group stays.
     55 - `/tags` — list all groups and how many recipes are in each.
     56 - `/staples` — show the staples list.
     57 - `/staples add <item>` / `/staples remove <item>`.
     58 - `/grocerylist [recipe1, recipe2, ...]` — merge staples plus named
     59   recipes into one list, quantities summed where they can be, grouped by
     60   ingredient category (anything uncategorized lands in one plain
     61   leftover section rather than being guessed at).
     62 - `/add <item>` — freeform one-off add to the current grocery list.
     63 - `/clearlist` — reset the working grocery list.
     64 - `/random [tag]` — random recipe suggestion, optionally filtered.
     65 - `/help` — show the command list from inside Telegram.
     66 
     67 ## Known limitations
     68 
     69 - Ingredient merging (summing quantities across recipes/staples) only
     70   works for ingredients entered in the structured `qty | unit | name |
     71   category` format. Freeform-pasted ingredients (the common case) have no
     72   parsed quantity/unit, so they're never summed — they just show up as
     73   separate line items.
     74 - Keto tagging is a rough keyword heuristic (flags things like flour,
     75   sugar, rice, potato), not a real nutrition calculation. Always manually
     76   overridable.
     77 - No recipe-URL fetching — `/addrecipe` is paste-only.
     78 
     79 ## Deployment
     80 
     81 `anton-bot.service` (systemd unit) and `install.sh` are provided for
     82 deploying to a Proxmox LXC/VM, per `SPEC.md`. `install.sh` stages a full
     83 copy of the repo, installs dependencies, and runs the test suite against
     84 that staged copy — it only touches the live install and running service if
     85 those tests pass, so a broken update never overwrites a working one. Read
     86 the comments at the top of `anton-bot.service` for the manual steps
     87 (create a system user, set up `.env`, etc.) before running it:
     88 
     89 ```bash
     90 sudo ./install.sh
     91 ```
     92 
     93 Config (bot token, DB path) is always via `.env` / environment variables —
     94 never hardcoded, never committed (`.gitignore` excludes `.env` and `*.db`).