delirehberi/news
- title
- delirehberi/news
- type
- toolbox
- summary
- Агрегатор новостей на Cloudflare, ранжирующий HN, Lobsters и Reddit по сходству с вашими апвоутами
- tags
- typescript, cloudflare-workers, rss, embeddings, self-hosted, nostr, watchlist
- language
- TypeScript
- license
- MIT
- created
- 2026-07-23
- updated
- 2026-07-23
- lang
- ru
- translation_of
- delirehberi-news
- source_updated
- 2026-07-23
- translated
- 2026-09-01
- translator
- lllm/antigravity/gemini-3.7-flash-medium
Персональный агрегатор новостей, который по расписанию через cron забирает материалы из Hacker News, Lobsters и Reddit, строит эмбеддинги заголовков и ранжирует ленту по косинусному сходству с эмбеддингами того, за что вы голосовали раньше. Всё это работает внутри одного аккаунта Cloudflare: Workers для API и cron'а, D1 для реляционных данных, Vectorize для индекса, Workers AI для модели эмбеддингов. Именно поэтому концепция "self-hosted персонализированной ленты" выходит достаточно дешёвой, чтобы иметь смысл для одного человека.
Как устроен
Бэкенд написан на Hono под Cloudflare Workers, фронтенд - на Vite и Tailwind с развёртыванием на Pages; обе части развёртываются раздельно через Makefile. Сбор данных выполняет Worker по расписанию, опрашивающий API каждого источника; отдельные источники можно отключить через vars в wrangler.jsonc ("ENABLE_REDDIT": "false").
Ранжирование намеренно сделано простым. Каждая статья получает 768-мерный эмбеддинг от модели @cf/baai/bge-base-en-v1.5, который сохраняется в Vectorize вместе с метаданными, и оценивается по косинусному сходству с профилем, построенным по истории ваших апвоутов. Здесь нет поиска по ключевым словам и нет reranker'а - используются исключительно эмбеддинги, а не hybrid-search, поэтому система хорошо находит материалы в духе "похожее на это", но слепа к точным запросам по терминам. Чтобы всё заработало, профиль нужно предварительно наполнить: репозиторий предоставляет эндпоинты для импорта имеющихся апвоутов из Lobsters, Reddit или из сырого JSON-экспорта Hacker News, а дальше ежедневный cron подхватывает работу.
Необычная деталь - интеграция с Nostr. Браузерные расширения с поддержкой NIP-07 (Alby, nos2x) служат механизмом аутентификации: вместо создания аккаунта вы подписываете свои лайки собственным ключом, и та же идентификация позволяет подписчикам перепубликовывать вашу кураторскую ленту в публичные релеи Nostr. Таким образом, и сигнал персонализации, и площадка для публикации привязаны к pubkey в Nostr, а не к приложению.
Настройка
Развёртывание сводится к вызову цепочки целей make в вашем аккаунте Cloudflare:
make init # deps, .env and wrangler.jsonc templates, checklist
make db-init # create the D1 database
make vectorize-init # create the Vectorize index
# paste database_id and index_name into worker/wrangler.jsonc
make push-secrets # pipe local env vars into Cloudflare's secret store
make deploy # deploy-worker + deploy-frontend
Секреты берутся из переменных окружения, а не запрашиваются интерактивно:
export REDDIT_CLIENT_ID="..."
export REDDIT_CLIENT_SECRET="..."
export REDDIT_REFRESH_TOKEN="..."
export AUTHORIZED_NOSTR_PUBKEY="...hex..."
make push-secrets
Для работы требуются Node 22+ и аккаунт Cloudflare; расширение Nostr нужно только для возможностей NIP-07.
Ограничения
"Self-hosted" здесь означает владение своими данными на чужой платформе. Каждый компонент является продуктом Cloudflare, поэтому перенос куда-то ещё потребовал бы одновременной замены векторного хранилища, SQL-слоя, модели эмбеддингов и среды выполнения. Три источника захардкожены - это не RSS-ридер, и для произвольных сайтов больше подойдёт rsshub. Ранжирование становится полезным только после начального импорта, так что свежей установке без истории апвоутов попросту не с чем сопоставлять данные.
Это личный проект: 16 звёзд, один автор, последний коммит в начале июля 2026 года и ни одного релиза. Он выглядит скорее как выложенная в открытый доступ рабочая конфигурация автора, а не инструмент для широкого круга пользователей, поэтому отправляется в watchlist - архитектуру стоит перенять, даже если репозиторий забросят.
Репозиторий: github.com/delirehberi/news - ~16 звёзд, MIT, TypeScript.