AI System2026.05 —Solo developer

Tidings

A news pipeline that bundles each part of the day into a handful of topics, read on an iOS app and home-screen widget.

Python · GitHub Actions · Cloudflare Workers · D1 · Gemini API · Swift · SwiftUI · WidgetKit

Problem

News arrived through Discord, a reader app, an RSS digest and other apps all at once. The reader never stuck because it lacked Japanese sources, and the GAS backend halted entirely whenever a single feed failed.

Approach

Rebuilt the backend as Python batches on GitHub Actions with a Cloudflare Workers API and D1, added Japanese sources, and had Gemini bundle each time slot into topic clusters. Rebuilt the iOS app around those clusters and a home-screen widget.

Outcome

Around 90 feeds condensed into three digests a day of four to six clusters each, with no unread backlog carried over. A failing feed is skipped instead of stopping the run, and errors reach Discord once on failure and once on recovery.

Detail

A two-part system for taking in news without being flooded by it. The backend, news-pipeline, runs as Python batches on GitHub Actions: it fetches around 90 RSS feeds — AI and tech, world news, and Japanese sources such as Hatena Bookmark hot entries — scores each article with the Gemini API, and stores the results in Cloudflare D1. Fifteen minutes before 06:00, 12:00 and 18:00 JST, another batch groups everything that came in since the previous slot into four to six topic clusters, each with a one-line summary, and a Cloudflare Workers API serves the latest one. Discord delivery of the best articles is still part of it.

Each slot has its own role, and the source weighting follows it: the morning is for catching up on world news and major AI moves, noon for practical engineering topics, and the evening for enjoying interesting finds from Japanese sources. Unread articles don't carry over into the next slot, so the volume is capped by time of day rather than by trimming the variety down to a fixed count.

The reading side is a SwiftUI app, renamed from InfoPulse to Tidings — news that comes in with the tide of the day. The top screen lists the current slot's clusters; a cluster opens its articles, and an article opens in an in-app reader. A large home-screen widget shows the clusters at a glance, switches over at each slot, and deep-links into a cluster. Anything worth keeping goes to Obsidian by hand through Safari's Web Clipper, so the app itself stays a place for flow, not storage.

This replaced a Google Apps Script prototype after one feed's DNS error stopped the whole run and kept firing an error to Discord every ten minutes. The rebuild skips a failing feed instead of failing the batch, treats detailed summaries as optional, retries Gemini with backoff, and only notifies when the success state changes.