Ecos Vivos - Spanish Regional News for Ukrainians
News aggregator that collects official press releases from Spanish regional governments, filters and translates them into Ukrainian with Claude, and publishes them after human review to regional Telegram channels and a bilingual PWA.
Overview
Ecos Vivos (ecosvivos.com) brings official regional news from Spain to Ukrainians who live there. Regional governments publish practical information about housing, benefits, documents, health, education, work, and transport in press releases. They write them in Spanish, Galician, or Valencian, and nobody translates them into Ukrainian.
The system reads official press portals, keeps only the news that matter in everyday life, translates and summarizes them, and publishes them after a human moderator approves each post. Readers get the news in regional Telegram channels and on a website that works in Ukrainian and Spanish.

The Challenge
People found out about a housing program or a new benefit after the deadline, or never. Ukrainian-language channels in Spain are mostly help chats and lifestyle content, and no one aggregates official regional news.
The hard parts were not the parsing:
Key Features
- Legal: every post must name the source, link the original, and show the date (Ley 37/2007 on reuse of public information)
- Accuracy: amounts and deadlines in a translation must match the original exactly
- Cost: most press releases are not useful for this audience, so paying a strong model to translate all of them is a waste
- Network: some government portals block cloud provider IP ranges or accept only Spanish exit IPs
Architecture
Everything runs on Cloudflare Workers in one npm workspaces monorepo:
Key Features
- Pipeline - a cron worker runs source adapters (RSS, HTML listings) as a Cloudflare Workflow and writes articles to D1
- LLM step 1 - a cheap model (Claude Haiku) filters every article: practical for Ukrainians or not, breaking or not
- LLM step 2 - a stronger model (Claude Opus) writes the Ukrainian title, Ukrainian and Spanish summaries, and the category, only for articles that passed the filter
- Moderation - a Telegram admin bot shows each candidate with approve and reject buttons; breaking news reaches the moderator at once, ordinary news comes as one evening digest; nothing goes out without a human
- Publishing - approved posts go to the regional Telegram channel and the site; national news fans out to all regions
- Site - Astro SSR PWA that reads D1 directly, with search, categories, push notifications without accounts, and uk/es locales
- Monitor and backups - health checks of sources and services, nightly D1 export to R2
Model names live in a settings table, not in code. The moderator can switch models, pause the pipeline, or change thresholds from the bot without a deploy.

Sources and the Relay
The project started in Galicia and now covers Galicia, Asturias, Cantabria, the Valencian Community, and a national section (La Moncloa, SEPE, ministries). Each region is a first-class entity, so a new region means new source adapters, not new code paths.
Some sources did not answer the production pipeline. Measurements showed different causes: one portal returned 403 only to the Cloudflare ASN, another accepted only Spanish exit IPs, and La Moncloa failed in about half of the runs from Cloudflare while it answered every request from Spain. The fix is a small relay on AWS Lambda in eu-south-2 (Spain). It fetches only the raw bytes of allowlisted feeds; all parsing and logic stay in the Workers pipeline.
Reliability
Things that made it work without supervision
- Pipeline runs, second-opinion checks, and backups are Cloudflare Workflows: a manual run from the bot no longer dies when the bot request ends
- Each step that costs money or cannot be undone is its own Workflow step, and D1 status checks protect against double work
- CI applies D1 migrations before the code deploy; migrations are additive only, destructive ones are blocked and applied by hand
- A daily LLM token budget that pauses the pipeline by itself, and rate limits on all public routes
- About 2,000 unit tests and 40 Playwright browser scenarios gate every deploy

Links
- Website: ecosvivos.com
- Telegram: Galicia, Asturias, Cantabria, Valencian Community
Lessons Learned
- Split the LLM work by cost - a cheap filter in front of an expensive translator cut spending without losing quality where it matters.
- Measure before you blame the other server - "their site is down" turned out to be a network path problem that only a Spanish exit IP could fix.
- Keep a human in the loop for public facts - a moderator approves every post, because a wrong amount or deadline hurts real people.