Try it in two minutes
- Watch the demo (3 min, spoken in French with English subtitles): https://youtu.be/3PdswmE0p9g
- Review a week like I do, on the demo board (nothing is saved or posted): https://grnbl-demo.byelior.dev
- Open the week's event pages, no WhatsApp needed: https://grnbl.pages.dev
- Join the WhatsApp community: https://chat.whatsapp.com/LqbkJA0oPhT4ptheJSHBMA
Inspiration
In my family, my mum is the one who finds the outings. Free concerts, concerts inside museums, small things we would never have seen otherwise. This October she found that the Tour Perret, a 1925 concrete tower in Grenoble that is normally a paid visit, was free on Sunday 18 October for the national architecture days, on booked time slots. The tourist office agenda did not list it. A local newspaper did.
I am in my last year of high school (homeschooled) and I work as a freelance developer on the side. I have lived in Grenoble since I was little, and my parents love cultural outings, so I discovered a lot of the city through them. My friends did not. Without someone like my mum, nobody thinks of going. The information is public, but it is spread across dozens of websites, and it is often found too late: a free visit is worthless if its slots filled up days before.
What is the specific problem, and how do you know it's real?
People around me miss free and cheap outings, and overpay for fuel, because finding them takes a person who checks dozens of sources every week. I know it is real because:
- I see it at home: my family goes to these things because one person looks for them. Families without that person do not.
- I measured it. For the week of 21 October, grnbl collected 1,092 upcoming events from 41 local sources. 68 of the walk-in outings that week were free, and 42 of those were judged worth going to. How many had you heard of?
- Fuel: on Monday 19 October, the official price feed showed up to 17 € of difference on one tank of E10 between stations of the same metropolitan area (up to 12 € for diesel). Nobody compares every day.
- The demand already exists: the Grenoble-Alpes Métropole WhatsApp channel has about 1,900 followers, but it only relays the Métropole's own news.
What it does
grnbl is a WhatsApp community for Grenoble with one group per topic. You join the groups you want and get a short post in plain French, like a message from a friend who checked everything for you.
- 🆓 Gratuit: free outings only.
- 🎭 Sorties: the best outings, paid ones included (concerts, shows, festivals).
- 👨👩👧 Famille: outings made for children.
- 🛍️ Bons plans: flea markets, jumble sales, ski swaps.
- 🏔️ Nature: hikes and mountain events.
- ⛽ Carburant: every morning, the 3 cheapest stations for each fuel in the area.
- 🚨 Alerts, in the community's announcement group: only serious ones (red weather warning, very bad air, the whole tram network stopped).
Each outings group gets two posts a week. "Book now" lists events that need booking, while there are still places. "This week" lists walk-in events of the coming days.
Timing is what I care about most. A tip is useless once the places are gone, so an event that needs booking is posted at least 4 days before, or as soon as booking opens, and a walk-in event the day before at the latest. A ten-day festival becomes one evening you can plan around.
A real example from the 21 October edition:
- The agenda (gre-mag.fr) says: "Foire de Grenoble, 30 October to 8 November, Alpexpo. 5 euros in presale until 29 October, 7 euros after."
- grnbl posted, in 🎭 Sorties, under "📅 Book now": "Foire de Grenoble. Friday 30 Oct. · Alpexpo. 👉 Book before Thursday 29 Oct." The code read the presale deadline. Book by Thursday and you pay 5 euros instead of 7.
I read every post before it goes out, but I only check about 11 lines per group, not 1,092 events. The lines come pre-ticked; if I remove one, a reserve takes its place.
It already runs. The first weekly edition was prepared on Tuesday 20 October and its posts went out on 21 and 22 October in the WhatsApp community. The fuel post has gone out every morning since 18 October (sent automatically until 21 October, pasted by hand since). The community is open to anyone, the jury included: https://chat.whatsapp.com/LqbkJA0oPhT4ptheJSHBMA
Who can use it
The people I built it for live in Grenoble and speak French, like my friends and their parents. So:
- Nothing to install and no account to create: it is WhatsApp, which they already have. Joining is one link, leaving is one tap.
- Plain French with short sentences, the date, the place and the price on every line, and one link to the official page.
- Text only, no images to decode, so a phone's screen reader can read every post.
- Without WhatsApp: every event of the week also has its own web page, with a "Book" button to the official page: https://grnbl.pages.dev (a browser can translate it).
- At most two posts a week per group, so nobody mutes it. Alerts go in the announcement group that every member gets, and they stay rare on purpose.
- Free and without ads. grnbl does not read the groups and stores nothing about the people in them.
The posts stay in French because that is the language of the people concerned and of every source. The board and this page are in English for the jury, with an English translation under each post.
Why it is not one more agenda
Grenoble already has agendas and official WhatsApp channels (Métropole, university), and town halls elsewhere use apps like PanneauPocket. Each one relays its own news. None of them merges the city's sources, removes the duplicates, picks the best, and tells you when to book. That is the part grnbl adds.
How we built it
I built it in one week, in Python 3 with the standard library only.
Once a week, on Tuesday, the pipeline:
- Collects 41 sources: the whole tourist office database, city and town agendas, concert halls, museums, the university, flea-market sites and 5 local newspapers. Sites with structured data (schema.org, The Events Calendar API) are read by code; plain pages are read by Claude Haiku. It also opens each event's own page to find booking dates ("ticket office opens on 7 October at 9:30").
- Merges duplicates, and turns repeated shows into one event with its dates.
- Gives each event a status in code: book now, opens soon, this week, later, too late, sold out.
- Has Claude Sonnet review each event (keep or drop, reason, score, free, for children), then decides in code which group gets it. A paid event can never reach the free group.
- Has Claude Sonnet act as editor for each group: it compares the 40 best candidates and writes a varied post, with a reason for each pick and 3 reserves. Code then checks that every name and number is on the event's page and that every weekday matches its date.
- Puts it on a review board, in English, with an English translation under each French post. At each group's slot, Discord reminds me and I paste the approved post into the group.
An hourly job runs the rest: the Tuesday preparation, a reminder 2 hours before a slot if a post is not approved, the daily fuel post, and the alert checks. An alert has to be seen twice in a row, at least 45 minutes apart, and it never goes out without my click.
Everything that must be guaranteed is code: booking deadlines, which group gets what, alert thresholds, never posting twice. The AI's answers change from one run to the next, so it only reads and judges text. Without it I would need thirty site-specific parsers.
Cost: the AI runs through the Claude Code CLI with its instructions and tools turned off (560 tokens of overhead per call instead of 31,067), with thinking off for Haiku, and with a cache so no page or verdict is sent twice. The 21 October edition used about 0.86 M input tokens and 0.32 M output tokens in all.
117 unit tests run offline (booking windows, group rules, schedule, outbox, parsing, sources).
Hosting: the weekly preparation takes under an hour; the rest of the week the hourly job only checks fuel and alerts. This week it runs on my Mac. The same folder runs in a container (Dockerfile) on any server, and the demo board for the jury is a static copy hosted online, so it works with my Mac off.
Challenges we ran into
The tourist office does not list the free Tour Perret visit at all, and many of its events show "January to December" when there are only a few sessions. I had to open every event page and read its list of sessions to know when something really happens.
No two of the 41 websites look alike. Some need many pages, some have broken certificates. Code reads the sites that publish structured data, and the AI reads the rest.
The AI sometimes adds things. I compared 44 posted lines of the trial run with their source pages: nothing was invented, but one line said "Tuesday 28 October" for a Wednesday. That is why the fact-check exists. It only checks that names and numbers are on the page and that weekdays match dates, so I still read every post.
My first board showed hundreds of events to review. I would never have done that every week. Now it is about 11 lines per group, already ticked.
There is no official way to post into WhatsApp community groups from a normal account. An unofficial client (Baileys) can do it, and I used it for my first test posts and the fuel post until 21 October. Then I read the rules again: it breaks WhatsApp's terms, so I removed it from the code. I now paste each approved post myself. It takes about a minute per group, and it means a person sees every post before the community does.
Accomplishments that we're proud of
- It runs on real data every week: 1,092 events from 41 sources, 427 kept, 74 picks over 5 groups, in under an hour, with no source failing.
- Real posts went out on schedule in a real WhatsApp community.
- Reviewing a week takes me a few minutes, not an evening.
What we learned
- Finding events was easy compared to knowing when to announce them.
- What must be guaranteed belongs in code. The AI is good at reading messy pages and judging what is worth it.
- Logging token use from the first run changed how I designed the pipeline.
- Before calling a fact "invented", check the page the code actually read. Two facts I first thought were made up were on the source pages.
What's next for grnbl
If grnbl ran in every French city, a family without "someone like my mum" would get the same tips we get: the free visit before the slots are gone, the cheaper presale, the cheapest fuel that morning.
Most of the work is already national:
- Fuel prices come from the government feed, which covers every station in France.
- Weather warnings come from Météo-France, for every département.
- Tourist offices in many regions publish on the same Apidae database grnbl already reads.
- Flea-market sites are organised by département, and many venues use The Events Calendar.
A new city is mostly a new list of sources. Of the 41 Grenoble sources, 8 use standard formats read by code (schema.org, The Events Calendar), 27 are plain pages that take one line each in the source list, 5 are newspapers, and only the tourist office has its own parser. One city costs about 0.86 M input and 0.32 M output tokens a week. The repo has a step-by-step guide: docs/NEW-CITY.md. The human part also scales: one local volunteer per city, a few minutes of review and about one minute of posting per group, the way town halls already post on PanneauPocket. Next steps:
- Short links to the event pages inside the posts, to count how many people go and book.
- An English group for international students, and an SMS version for people without WhatsApp.
- A small server so it runs without my Mac (the
Dockerfilealready runs it as is). - Growing through people who already reach Grenoble: local media, creators and associations sharing the community link. The demand is there: the Métropole's own WhatsApp channel has about 1,900 followers.
- Privacy: in a WhatsApp group, members can see each other's phone numbers today. WhatsApp has announced usernames, which would hide them.
Limits
- Posting is by hand (see Challenges). The unofficial sender was used until 21 October, then removed.
- My Mac is the server this week: if it is off at a slot, the work waits for the next hourly pass.
- Most agendas have no API, so grnbl reads public pages. It says who it is, follows each site's robots.txt (on 21 October none of the sites it reads forbade those pages), reads at most one page a second per site, keeps only facts and links back to the source. A site that changes its layout can still break a source.
- Nobody re-reads the events the AI review drops, so a good event it wrongly drops is never seen.
- It is a one-week prototype, built and run during the hackathon week.
AI use
grnbl was built with Claude Code as a pair programmer, and the product uses Claude Haiku and Claude Sonnet for reading and judging pages, as described above.
Built With
- atmo
- baileys
- claude
- claude-code
- claude-haiku
- claude-sonnet
- cloudflare-pages
- cloudflare-tunnel
- discord
- docker
- launchd
- meteo-france
- node.js
- openstreetmap
- prix-carburants
- python
- schema.org
- the-events-calendar
Log in or sign up for Devpost to join the conversation.