A city guide mined from Telegram chats by a local LLM: 499 places and events, 1,433 chat quotes, 26 reference articles, 19 routes, a map across 28 neighbourhoods. Telethon → LM Studio → SQLite → static on GitHub Pages. Zero spend on APIs and hosting.
Over two years the Russian-speaking Telegram chats of Chiang Mai accumulated about 290,000 messages — and hidden inside is everything a newcomer needs: a decent dentist, which waterfall runs in the dry season, when the Saturday market opens. Chat search can't surface it. The Chiang Mai Community Guide turns that stream into a catalogue: 499 places and events, 1,433 quotes from the chat, 26 reference articles, 19 routes and collections, a map across 28 neighbourhoods.
No cloud, no paid APIs. Three chats sync through Telethon by cursor; new messages are parsed by a local model in LM Studio (Gemma) on my Mac — extracting the place, category, neighbourhood, prices, tips and quotes. Strict mode: if the model is unavailable, the cursors don't move and the script exits with an error — so no message is ever lost silently.
Then SQLite: items, reviews, collections. Google Maps links are enriched by a geocoder with no API key — via the cid from Google's redirect it returns exact coordinates, rating, phone, website and opening hours; a result is accepted only when the identifier matches, so someone else's venue never sneaks in. On top — rule-based tags (coffee, breakfast, sauna and ice bath, yoga, with a view) for a second row of filters inside a category.
Publishing is static: export_static.py builds data.json, reviews.json, wiki.json, and GitHub Pages serves it all with no back end. A macOS LaunchAgent asks once a day whether to update, spins up the model, syncs and deploys.
No frameworks: Leaflet + OpenStreetMap for the map, marked for articles, hash routing — any screen is a shareable link: #/place/60, #/map?cat=nature, #/routes/7, #/wiki/visas.
Home — categories with counts, neighbourhoods, "near me", "open now", a strict veg filter (cafés and restaurants only), "popular in the chat". A "Today in Chiang Mai" panel: how many places are open right now, quick slices (breakfast, coffee, vegan, nature, sauna, evening) and the nearest events.
The place card is what neither Google Maps nor the chat has on its own: Google's photo and rating, hours and phone, and next to them — "what the chat says": prices, tips, warnings from messages, with mention counts. Buttons: directions, call, website, save, share.
Routes and collections are curated by hand — right in the code: "Doi Inthanon in a day", "Chiang Dao: mountains, hot springs and a night camping", "Monk's Trail and sunset on the mountain", "Friday night: craft, jazz and rock", "The Vegan Way", "Doctors people recommend", "Glamping and nights in the mountains". A route has a map with numbered stops, time, transport, budget and export to Google Maps.
The reference — 26 articles distilled from the chat: your first 7 days, visas and border runs, TM30, renting, bikes and fines, money and crypto, medicine and insurance, kids and schools, pets, sport. Under each article — places on the topic.
Events — from the chats, with dates, venue and poster; upcoming and past separately.
Most people open the guide on a phone from a link in the chat, so the cards, filters and map are built for a narrow screen first; RU/EN toggle, saved lists, photo gallery.
Idea, data and pipeline, local LLM processing, geocoder, database, front end, curation of routes and the reference. One person. 2026.