Back to Projects

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.

Cloudflare Workers
Cloudflare Workflows
D1
R2
Drizzle ORM
Hono
Astro
TypeScript
Tailwind CSS 4
Claude API
Telegram Bot API
Web Push
AWS Lambda
Vitest
Playwright
Live Demo

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.

Ecos Vivos home page with regions and Telegram channels
Home page: four regions and a national section, each with its own Telegram channel

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.

Galicia section in Spanish with category filters and a deadline badge
Spanish version of a region: category filters, deadline badge, source, and a link to the original

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
Article page on mobile with a deadline and a point-by-point breakdown
Article page on mobile: deadline badge and a point-by-point breakdown generated after approval

Links

  • Website: ecosvivos.com
  • Telegram: Galicia, Asturias, Cantabria, Valencian Community

Lessons Learned

  1. Split the LLM work by cost - a cheap filter in front of an expensive translator cut spending without losing quality where it matters.
  2. 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.
  3. Keep a human in the loop for public facts - a moderator approves every post, because a wrong amount or deadline hurts real people.