PasiLunch website

PasiLunch puts local Pasila lunch menus in one place. I built it because checking several restaurant sites every morning was a boring way to spend ten minutes, and every menu was formatted differently.

The scraping problem

Restaurant sites are messy. Some have tidy HTML lists. Others mix Finnish and English, hide prices in strange places, or turn weekly notes and dietary labels into a parsing problem. A strict scraper quickly becomes a pile of exceptions.

The app scrapes each source, uses Cheerio for HTML and xml2js where a source is structured, then normalises names, prices, language, and categories. When selectors are not enough, Gemini via @google/genai cleans up the result. I would not use an LLM for a clean, deterministic input. Restaurant menus are neither.

Where decisions land

Slack was the obvious place for it. The command lets the team check menus where the lunch decision already happens. The web view is there when someone wants to browse.

Stack

Express, JavaScript, Cheerio, xml2js, dotenv, Slack’s Web API package, and Gemini through @google/genai.

Where it stands

PasiLunch is only as stable as the sites it reads. A redesign can break a selector. I would make source health more visible and add better diagnostics for missing or stale menus.