# πŸ›’ Grocy Shopping List Bridge Send ingredients from your Obsidian recipe notes straight into your [Grocy](https://grocy.info) shopping list. Works seamlessly with other recipe plugins β€” supports fuzzy product matching, auto-matching with thresholds, free-text items, and manual overrides. Buy Me A Coffee --- ## πŸš€ Quick Start 1. **Install**: Copy this plugin into `.obsidian/plugins/grocy-shoppinglist-bridge/` and enable it in Obsidian. 2. **Configure**: In plugin settings, set your **Grocy URL** and **API Key**. 3. **Use**: Open a recipe note β†’ click the πŸ›’ ribbon button β†’ ingredients appear in your Grocy shopping list. --- ## ✨ Features - Parse `## Ingredients` sections automatically (supports nested subheadings like `### Sauce`, `#### Marinade`). - Smart ingredient normalization: - `1 large egg` β†’ **eggs** - `3 cloves garlic (minced)` β†’ **garlic** - Fuzzy matching against Grocy's products with adjustable confidence. - Multiple fallback strategies when no match is found. - Manual overrides via inline annotations (`grocy_id`, `grocy:`). - Ribbon button + command palette support. - Works out-of-the-box with [Recipe Grabber](https://github.com/seethroughdev/obsidian-recipe-grabber). Imported recipes are parsed automatically. - Plays nicely with [Recipe View](https://obsidian-recipe-view.readthedocs.io/en/latest/). If you use the **HTML comment syntax** (``), Recipe View will hide the annotation from the rendered card. - Omit notes when `grocy_id` is used (configurable) -> Grocy increments cleanly by product/amount only. - Follow links(e.g. meal plan note) when the active note has no Ingredients section. Traverses linked notes up to a configurable depth. - Skip items with `grocy_id: 0` -> lets you ignore things like salt, water, or spices entirely. --- ## πŸ“₯ Installation 1. Download the repo. 2. Copy into your vault: ``` .obsidian/plugins/grocy-shoppinglist-bridge/ ``` 3. Reload community plugins in Obsidian. 4. Enable **Grocy Shopping List Bridge**. --- ## πŸ“‘ Usage ### Recipe note example ```markdown ## Ingredients - 1 large egg - 3 cloves garlic (minced) - 1 broccoli crown ### Sauce - 2 tbsp soy sauce - 1 tsp sesame oil ## Directions Mix and cook... ``` - Click the **πŸ›’ ribbon button** or run: ``` Grocy: Add ingredients to shopping list ``` - All bullet points under **Ingredients** (and its subheadings) are added. - Stops before the next top-level section (e.g. `## Directions`). --- ## βš™οΈ Settings | Setting | Description | |---------|-------------| | **Grocy URL** | Base URL of your Grocy (e.g. `http://localhost/grocy` or `https://your-domain/grocy`) | | **API Key** | Create in Grocy β†’ Settings β†’ Manage API keys | | **Shopping List ID** | Usually `1` unless you have multiple lists | | **Auto-confirm unique match** | If only one candidate matches, add automatically | | **Auto-match threshold** | Default `6` β€” top candidate score required for auto-add | | **Require score margin** | Default `2` β€” top candidate must be this many points above runner-up | | **Debug matching** | Log candidate scores & decisions to Obsidian console | | **No-match fallback** | What to do when no good product is found:
β€’ **Ask** (chooser + free-text option)
β€’ **Prompt free-text** (type a note)
β€’ **Free-text** (auto-add note)
β€’ **Skip** | | **Follow links when note has no Ingredients** | If enabled, will traverse linked notes and gather their Ingredients | | **Link follow depth** | How many levels of links to follow (default = 1, max = 5) | | **Omit note for annotated items** | If enabled, when `grocy_id` is present, only `product_id` (+amount) is sent, without the note | --- ## πŸ–ŠοΈ Forcing Matches (Annotations) If you want exact control over which Grocy product is used: ### By Grocy ID ```markdown - 2 tomatoes (grocy_id: 42) ``` Or with an HTML comment (**hidden in Recipe View**): ```markdown - 2 tomatoes ``` > ⚠️ Recipe View will display clean ingredients without showing the `grocy_id` comment, if using the HTML notation. > ⚠️ If "Omit note for annotated items" is enabled in settings, these entries will send only product + amount to Grocy (no note). ### By Product Name ```markdown - 1 chili pepper (grocy: jalapeΓ±o) ``` This forces the matcher to look for β€œjalapeΓ±o” specifically. ### Skipping items with grocy_id: 0 If you want to mark an ingredient so the plugin does not add it to Grocy (for example: salt, water, or spices), annotate it with: - Visible form: `- pinch of salt (grocy_id: 0)` - Hidden form (works with Recipe View): `- pinch of salt ` `grocy_id: 0` tells the plugin to skip that item entirely. --- ## πŸš€ Example Workflows ### Fully Automated - Auto-confirm unique = βœ… - Threshold = `6`, Margin = `2` - Fallback = **Free-text** β†’ Most items auto-add. Unmatched lines go in as notes. --- ### Semi-Automated - Auto-confirm unique = βœ… - Fallback = **Ask** β†’ Confident matches auto-add, ambiguous ones ask you. --- ### Manual Control - Auto-confirm unique = ❌ - Fallback = **Ask** β†’ You confirm every item via chooser. --- ## πŸ” Debugging - Enable **Debug matching** in settings. - Open **View β†’ Toggle Developer Tools β†’ Console** in Obsidian. - You'll see logs like: ``` Match: 1 large egg β†’ needle: eggs top: {id:12, name:"Eggs", score:11} Auto-matched β†’ Eggs ``` --- ## Changelog - 1.0.2: Skip products with `grocy_id: 0`. - 1.0.1: Follow links if `Ingredients` headline isn't present. - 1.0.0: Initial release