Разработчик из Habr собрал систему, которая автоматически отбирает новости по теме применения ИИ в энергосбережении и энергобезопасности и присылает в Telegram готовые заметки на русском языке. В основе — Google Apps Script, Google Таблица, Gemini API и Telegram Bot API. Отдельный сервер не понадобился: архитектура serverless, скрипт просыпается по триггеру, обрабатывает порцию данных и засыпает. Слово «сервер» здесь описывает роль системы, а не тип хостинга.
Потребность возникла из-за того, что обычные RSS-ридеры не подходят: фильтры пропускают рекламные тексты без технических подробностей и реальных KPI. Нужен отбор по смыслу — есть ли описание внедрения и с каким результатом. Отобранная новость превращается в короткую заметку с заголовком, сутью решения, достигнутыми показателями и ссылкой на первоисточник. Если источник не приводит чисел, бот должен так и написать: задача модели — извлечь заявленный результат, а не придумать экономию. Последнее решение остаётся за человеком: бот присылает черновик с кнопками «Опубликовать» и «Отклонить».
| Модель | Задача | RPM | RPD |
|---|---|---|---|
| Gemini 3.5 Flash-Lite | Отбор анонсов | 15 | 500 |
| Gemini 3.8 Flash | Генерация постов | 5 | 20 |
В таблице четыре листа: RSS со списком источников (около 100), NewsInbox с анонсами до отбора, NewsQueue с отобранными статьями и готовыми черновиками, Log с уже обработанными ссылками. Модели разделены по задачам. Gemini 3.5 Flash-Lite с лимитом RPM 15 и RPD 500 решает, подходит ли анонс. Gemini 3.8 Flash с лимитом RPM 5 и RPD 20 получает тексты уже отобранных статей и готовит посты. В текущей версии генерация Flash тоже объединяет несколько статей в один запрос, но запросы Flash выполняются последовательно. Параллельность реализована на этапе Lite.
Модели разделены: Gemini 3.5 Flash-Lite (RPM 15, RPD 500) отбирает анонсы, Gemini 3.8 Flash (RPM 5, RPD 20) готовит посты.
Узкое место обнаружилось на этапе отбора. В одной из версий бот успевал обработать за запуск только одну пачку. Фрагмент реального отчёта: «Оценено Lite: 10, Ожидают Lite (NewsInbox): 22, Время: подготовка 3 с; RSS 126 с; Lite 92 с, Перенос: Закончено время для Lite». Это не чистый benchmark модели, а измерение времени этапов скрипта, но результат для пользователя конкретный: часть анонсов снова остаётся ждать. У Apps Script есть ограничение времени выполнения — 6 минут на запуск. Поэтому экономия 80 секунд критична для выживания триггера, и задержка внешнего API влияет не только на то, когда появится результат, но и на объём работы, который вообще поместится в один запуск.
При последовательном вызове логика выглядит так: для каждой пачки анонсов формируется запрос, отправляется через UrlFetchApp.fetch, и пока ответ не получен, следующая пачка не отправляется. Но между пачками нет зависимости. Чтобы оценить новости № 11–20, модели не нужен результат оценки новостей № 1–10. Критерии отбора одинаковые, исходные тексты разные. Эти ожидания и перекрываются параллельными запросами. Разработчик показывает, как отправлять несколько независимых запросов к модели параллельно, и почему одна строка fetchAll() всё-таки не заменяет учёт квот и обработку ошибок.
Очереди нужны, чтобы пережить окончание времени запуска или сбой API. Анонс сохраняется до отбора, готовый пост — до отправки в Telegram. Если отправка не удалась, не нужно снова просить модель написать тот же текст. Свежесть контролируется отдельно: статьи с распознанной датой старше семи суток пропускаются, в том числе при повторной обработке очереди. Для материалов без даты ограничено время ожидания. Накопленная очередь не запрещает очередной сбор RSS.
Система собиралась два месяца с использованием ChatGPT и Gemini. Это типичный пример serverless-автоматизации, где вместо аренды сервера разработчик использует бесплатные квоты Google и возможности Apps Script. Ограничения — лимиты RPM и RPD у моделей, шестиминутный потолок выполнения скрипта и необходимость вручную следить за ошибками API. Но для задачи отбора сотни новостей в сутки такого набора хватает.

