Недельный разбор качества и расходов

При подготовке урока мы спросили у CloseRouter, сколько потрачено за неделю. Шлюз ответил двумя числами: остаток на счёте 5,50 $ и расход 24,83 $ за всё время. Других ответов не нашлось: пять адресов вернули «не найдено», шестой упал с ошибкой. Недельный расход пришлось считать самим, как показания счётчика воды: записать сегодня, записать через неделю и вычесть. Из этого вырос сценарий, который за один запуск собирает разбор недели: деньги, журнал, контент-план и два поста, которые стоит прочитать глазами.

Чему научитесь в этом уроке:
• считать недельный расход на модели по двум снимкам баланса CloseRouter и прогноз «на сколько дней хватит»;
• собирать в одном сообщении последнюю запись журнала аналитики по каждому сценарию;
• видеть по статусам контент-плана упавший запуск;
• выбирать два случайных опубликованных поста и проверять их по трём вопросам.

Тридцать минут в неделю

В треке 2 недельный разбор вы делали руками: журнал запусков, страница расходов, тест, аудит промпта (урок «Раз в неделю: качество и расходы»). Привычка та же, но конвейеров теперь несколько, и ходить по кабинетам дольше. Поэтому всё, что можно посчитать, считает сценарий. Вам остаётся прочитать одно сообщение и два поста.

Разбор состоит из четырёх блоков:

  1. Деньги. Остаток в CloseRouter, расход за неделю и на сколько дней хватит остатка при таком расходе.
  2. Журнал аналитики. Последняя запись по каждому сценарию из таблицы, которую вы вели в модуле 4: статус, проверка, дата.
  3. Контент-план. Сколько тем опубликовано, ждёт в очереди, висит «в работе» и отклонено.
  4. Посты глазами. Два случайных опубликованных поста и три вопроса к каждому.
Четыре блока недельного разбора: «Деньги» — остаток CloseRouter, расход за неделю, на сколько дней хватит, меньше 14 дней — пополнить; «Сценарии» — последняя строка «Журнала аналитики» по каждому сценарию; «Контент-план» — опубликовано, в очереди, отклонено, «в работе» дольше ожидания — разобраться; «Глазами» — два случайных поста: факты верны, тон наш, есть призыв. Подпись: первые три блока считает код, четвёртый — только вы.

Модель в этом сценарии не нужна. Всё считает узел Code, поэтому разбор ничего не стоит и не выдумывает.

Деньги: почему нужны снимки

У CloseRouter в прогоне курса работал один адрес для проверки денег: GET https://api.closerouter.dev/v1/credits. Ответ выглядит так:

{"data":{"total_credits":5.50255426,"total_usage":24.82865836}}

total_credits это остаток на счёте, total_usage это расход за всё время. Остаток сошёлся с кабинетом. Адреса /v1/key, /v1/balance, /v1/auth/key и /v1/dashboard/billing/usage ответили 404 (не найдено), /v1/usage ответил 500 (ошибка на стороне шлюза). Расхода за неделю шлюз не отдаёт.

Поэтому сценарий раз в неделю записывает снимок: дату, расход за всё время и остаток. Расход за неделю равен разнице с прошлым снимком. Делим его на число дней между снимками и получаем расход в день. Остаток, делённый на расход в день, показывает, на сколько дней хватит денег. Если меньше чем на 14 дней, разбор напишет «пополнить».

Таблица снимков

Создайте таблицу данных: Personal → Data tables → Create data table, имя «Расход по неделям», три колонки: day (string, дата снимка в виде ГГГГ-ММ-ДД, например 2026-09-30: так её записывает сам сценарий), total_usage (number), balance (number).

Сценарий из семи узлов

Узлы идут цепочкой, один за другим:

  1. Старт, узел запуска вручную.
  2. HTTP Request «Баланс CloseRouter» (узел, который обращается по адресу в интернете и получает ответ): метод GET, адрес https://api.closerouter.dev/v1/credits, учётные данные те же, что у модели (тип OpenAI).
  3. Data Table «Прошлые снимки»: таблица «Расход по неделям», действие Get, Return All. В Settings узла включите Execute Once, иначе узел выполнится столько раз, сколько строк пришло на вход. Если на пустой таблице сценарий остановился на этом узле, включите там же Always Output Data (отдать результат, даже если таблица пустая).
  4. Data Table «Журнал аналитики»: то же самое для таблицы «Журнал аналитики» из модуля 4.
  5. Data Table «Контент-план»: то же для таблицы контент-плана из модуля 3.
  6. Code «Разбор»: код ниже.
  7. Data Table «Снимок недели»: таблица «Расход по неделям», Insert, поля day {{ $json.day }}, total_usage {{ $json.total_usage }}, balance {{ $json.balance }}.

Код узла «Разбор» перенесите целиком, имена узлов в нём должны совпадать с вашими:

// Недельный разбор: всё считает код, модель не нужна
const cr = $('Баланс CloseRouter').first().json.data;
const snaps = $('Прошлые снимки').all().map(i => i.json).filter(s => s.day);
const prev = snaps.sort((a, b) => a.day < b.day ? 1 : -1)[0];
const today = new Date().toISOString().slice(0, 10);
const days = prev ? Math.max(1, Math.round((new Date(today) - new Date(prev.day)) / 864e5)) : null;
const spent = prev ? +(cr.total_usage - prev.total_usage).toFixed(2) : null;
const perDay = spent !== null && days ? spent / days : null;
const left = perDay > 0 ? Math.floor(cr.total_credits / perDay) : null;
const log = $('Журнал аналитики').all().map(i => i.json).filter(r => r.scenario);
const byScn = {};
for (const r of log) byScn[r.scenario] = r;
const plan = $('Контент-план').all().map(i => i.json).filter(r => r.status);
const cnt = s => plan.filter(r => r.status === s).length;
const pub = plan.filter(r => r.status === 'published' && r.post);
const sample = pub.sort(() => Math.random() - 0.5).slice(0, 2);
const lines = [
  'Разбор недели ' + today,
  '',
  'Деньги (CloseRouter): остаток ' + cr.total_credits.toFixed(2) + ' $' +
    (prev ? '; за ' + days + ' дн. потрачено ' + spent + ' $; хватит примерно на ' + (left ?? '—') + ' дн.' : '; первый снимок — расход за неделю будет в следующий раз'),
  (left !== null && left < 14) ? '⚠️ Остатка меньше чем на две недели — пополнить.' : '',
  '',
  'Сценарии (последняя запись в журнале):',
  ...Object.values(byScn).map(r => '— ' + r.scenario + ': ' + r.status + ', ' + r.check + ' (' + String(r.createdAt || '').slice(0, 10) + ')'),
  '',
  'Контент-план: опубликовано ' + cnt('published') + ', в очереди ' + cnt('new') + ', в работе ' + cnt('in_progress') + ', отклонено ' + cnt('rejected') + '.',
  cnt('in_progress') ? '⚠️ «В работе» висит ' + cnt('in_progress') + ' — проверить, не упал ли запуск.' : '',
  '',
  'Прочитать глазами (2 случайных поста):',
  ...sample.map(r => '— ' + r.topic + ': «' + String(r.post).slice(0, 160) + '…»'),
  'Вопросы к каждому: факты верны? тон наш? есть призыв?'
].filter((x, i, a) => x !== '' || a[i - 1] !== '');
return [{ json: { report: lines.join('\n'), day: today, total_usage: cr.total_usage, balance: cr.total_credits } }];

Что делает код по блокам. Берёт из ответа шлюза остаток и расход, находит самый свежий прошлый снимок и считает дни, расход и прогноз. Из журнала оставляет по одной последней записи на сценарий. Дату записи код берёт из createdAt: это служебная колонка с датой создания строки, n8n заполняет её в таблицах данных сам, заводить её не нужно. В контент-плане считает строки по статусам. Из опубликованных постов случайно выбирает два и показывает начало каждого, 160 знаков. На выходе поле report с текстом разбора и три поля для нового снимка.

Тревога «в работе»

Тема, взятая конвейером, получает статус in_progress (уроки 3.3 и 5.1) и держит его всё время, пока черновик ждёт вашего одобрения. Потом статус меняется на published или rejected. Значит, «в работе» само по себе ещё не тревога: черновик может просто ждать кнопки. Разбор отмечает любую тему в работе отдельной строкой. Сначала посмотрите в Telegram, не ждёт ли черновик ответа. Если не ждёт, а тема висит в работе дольше срока ожидания одобрения (2 часа, урок 3.6) или с прошлого запуска конвейера, запуск, скорее всего, упал посередине. Откройте журнал запусков этого сценария и найдите, на каком шаге он остановился.

Два поста глазами

Код не знает, верны ли факты и похож ли текст на ваш бренд. Поэтому в конце разбора два случайных поста и три вопроса к каждому: факты верны? тон наш? есть призыв? Случайный выбор нужен, чтобы вы не читали каждую неделю один и тот же удачный пост. Начало в 160 знаков только напоминает, о чём пост: прочитайте его целиком в канале. Если хоть на один вопрос ответ «нет», вернитесь к брендбуку и промпту копирайтера из модуля 3.

Что показал прогон

Первый запуск, таблица снимков пустая. Разбор показал остаток и строку «первый снимок — расход за неделю будет в следующий раз». В таблице появилась первая строка.

Проверка подложным снимком. Ждать неделю, чтобы проверить арифметику, не обязательно. В прогоне в таблицу вручную добавили строку с датой 2026-09-30 и расходом на 0,70 $ меньше настоящего. Разбор написал: «за 7 дн. потрачено 0.7 $; хватит примерно на 55 дн.». Сверяем: 0,70 $ за 7 дней это 0,10 $ в день, остаток 5,50 $ делим на 0,10 и округляем вниз, выходит 55. Подложную строку после проверки удалили, настоящий снимок от 7 октября оставили точкой отсчёта.

Код берёт самый свежий снимок. Если в таблице уже есть строка за сегодня, расход посчитается от неё, а подложная строка останется без дела. Для проверки временно уберите сегодняшнюю строку или проверяйте до первого настоящего запуска. Дату подложной строки пишите так же, как сценарий: ГГГГ-ММ-ДД, например 2026-09-30. После проверки удалите подложную строку: точкой отсчёта станет строка за сегодня, которую записал разбор. И не запускайте разбор дважды в одну неделю без нужды: каждый запуск пишет новый снимок, и следующая разница выйдет почти нулевой. Лишнюю строку удалите руками.

Чего разбор не умеет. Число сбоев за неделю сценарий не считает: журнал запусков n8n из сценария доступен только с ключом n8n API, а этот ключ создаёт владелец учётной записи n8n. В прогоне его не было. Пока сбои видны в чате уведомлений из урока 5.1, просмотрите его за неделю.

Расписание и отправка в Telegram

В прогоне курса разбор запускали вручную: расписание и отправку в Telegram не настраивали. Сделать это можно так же, как в треке 2, в уроке «Отчёт собственнику за неделю». Замените «Старт» на Schedule Trigger (запуск по расписанию), например понедельник, 10:00. После «Разбора» добавьте узел Telegram с действием Send Message: Chat ID <ваш номер>, текст {{ $json.report }}. Подключение бота разобрано в уроке «Бот в Telegram». В прогоне курса эту связку для разбора не проверяли, поэтому первый запуск по расписанию проверьте: пришло ли сообщение и появилась ли новая строка в «Расходе по неделям».

Если не получилось

  • «Баланс CloseRouter» отвечает ошибкой доступа. Проверьте, что в узле выбраны те же учётные данные, что у модели, и адрес заканчивается на /v1/credits. Другие адреса шлюза в прогоне не работали.
  • При первом запуске разбор не дошёл до конца, узлы после «Прошлых снимков» серые. Таблица снимков пустая. Включите в узле «Прошлые снимки» Settings → Always Output Data и запустите снова.
  • Разбор повторился несколько раз или строки журнала задвоились. В одном из узлов Data Table не включён Execute Once.
  • Код падает с ошибкой «Cannot read properties of undefined». Имя узла в коде не совпадает с вашим. Сверьте «Баланс CloseRouter», «Прошлые снимки», «Журнал аналитики», «Контент-план» буква в букву.
  • Расход 0 и «хватит примерно на —». Последний снимок сделан сегодня же. Удалите лишнюю строку в «Расходе по неделям».
  • Блок «Прочитать глазами» пустой. В контент-плане нет строк со статусом published и текстом поста в колонке post. Пока конвейер не публиковал, это нормально.
  • В блоке сценариев пусто. В журнале аналитики нет записей с заполненной колонкой scenario. Проверьте, что сценарии модуля 4 пишут в журнал.

Контрольный вопрос. Как сценарий узнаёт расход на модели за неделю?

АЗапрашивает у CloseRouter отчёт за 7 дней
БВычитает расход за всё время из прошлого снимка из сегодняшнего
ВСчитает запуски сценариев и умножает на цену
ГСпрашивает модель, сколько она потратила

Подсказка: Вспомните счётчик воды и то, какие числа отдаёт адрес /v1/credits.

На курсе задания проверяются автоматически. Подобрать курс

Контрольный вопрос. В понедельник разбор пишет, что одна тема висит «в работе». Черновиков на одобрение в Telegram нет, тема в работе с прошлого запуска конвейера. Что это скорее всего значит?

АЧерновик ждёт вашего одобрения
БТема отклонена
ВЗапуск конвейера упал посередине, и строку нужно разобрать
ГПост вышел дважды

Подсказка: Когда тема получает статус in_progress и что должно произойти, чтобы он сменился?

На курсе задания проверяются автоматически. Подобрать курс

Контрольный вопрос. Что недельный разбор в прогоне курса НЕ делал? Выберите все верные варианты.

Выберите все верные варианты.

АПоказывал остаток на счёте CloseRouter
БСчитал число сбоев за неделю
ВСам отправлялся в Telegram по расписанию
ГВыбирал два случайных опубликованных поста

Подсказка: Что требует ключа n8n API, а что не настраивали в прогоне?

На курсе задания проверяются автоматически. Подобрать курс

Задание. МИССИЯ «Разбор недели». Создайте таблицу «Расход по неделям» и соберите сценарий из семи узлов: «Старт», «Баланс CloseRouter», «Прошлые снимки», «Журнал аналитики», «Контент-план», «Разбор», «Снимок недели». Запустите его первый раз, это первый снимок. Через неделю запустите ещё раз. Если ждать не хотите, проверьте арифметику подложным снимком: оставьте в таблице только строку с датой на 7 дней раньше сегодняшней (в виде ГГГГ-ММ-ДД) и расходом на небольшую сумму меньше настоящего, запустите разбор, затем удалите подложную строку. Прочитайте целиком два поста, которые выбрал разбор. Приложите: (1) текст первого разбора; (2) текст второго разбора и пометку, настоящий был прошлый снимок или подложный; (3) ваш расчёт «на сколько дней хватит» по числам из разбора; (4) по каждому из двух постов ответы на три вопроса: факты верны, тон ваш, есть призыв; (5) если настроили расписание и отправку в Telegram, приложите сообщение, которое пришло. Принято, если: в сценарии семь узлов, код «Разбор» перенесён без изменений, кроме имён узлов; у узлов Data Table включён Execute Once; первый разбор показывает «первый снимок»; во втором есть расход за число дней и прогноз, и ваш расчёт с ним совпадает; подложный снимок удалён; по двум постам есть ответы на все три вопроса; номер чата и ключи не показаны.

Подсказка: Если второй разбор показал расход 0, проверьте, какая строка в таблице снимков самая свежая.

✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.

На курсе задания проверяются автоматически. Подобрать курс

Что дальше

Разбор готов, но пока он прошёл одну проверку. В уроке 5.4 конвейеры работают сами три недели, а разбор по понедельникам показывает, что пора править.

Итог:
• CloseRouter отдаёт только остаток и расход за всё время, недельный расход сценарий считает по двум снимкам;
• прогноз: остаток делим на расход в день, тревога при запасе меньше 14 дней;
• тема «в работе» повод проверить: если черновик не ждёт одобрения, а тема висит с прошлого запуска, запуск упал;
• два случайных поста вы читаете сами: факты, тон, призыв;
• сбои за неделю смотрите в чате уведомлений, сценарий их без ключа n8n API не считает.

← Назад  ·  ↑ В начало урока  ·  ⌂ В начало курса  ·  Вперёд →

Школа Виктора Комлева