Утром владелец «Кодиума» открывает Telegram и хочет одной строкой понять, как прошли вчерашние сутки: сколько заявок, откуда, на какие курсы. Листать файл на Диске он не будет. В прогоне курса такой отчёт сделали двумя путями, и оба раза главной ловушкой оказались часы: сервер живёт по Гринвичу, а владелец по Москве. Вторая ловушка тише: новая колонка «Источник» появилась только в новых файлах, а в рабочем файле её не было.
Чему научишься в этом уроке:
• поставить ежедневный отчёт в 9:00 по Москве кодом (таймер systemd) или в n8n (Schedule Trigger);
• проверить по списку таймеров, что время верное, а не на три часа позже;
• добавить колонку в существующий файл и не потерять старые строки;
• честно сказать заказчику, какие данные задним числом не восстановить.
Что приходит владельцу
Уведомлений теперь два вида. Первое приходит сразу после заявки, с пометкой «Источник: сайт» или от бота, как в П1. Второе приходит раз в день и считает итоги. В прогоне ручной запуск отчёта в n8n прислал вот такое сообщение:
📊 Заявки за 09.10.2026 — всего 6;
по источникам: бот 5, сайт 1;
по курсам: Python 4, Пока не знаю 1, Нейросети 1;
всего в файле 9
Отчёт берёт данные из того же zayavki.xlsx на Яндекс Диске. Отдельной базы для отчёта нет: файл скачивается, программа считает строки за вчерашний день и отправляет итог владельцу. Имена и телефоны в отчёт не попадают, только числа.

Часы сервера и часы владельца
Представь, что ты ставишь будильник на телефоне, который лежит у друга в Лондоне. Скажешь «разбуди в девять», и он зазвонит в девять по Лондону. Сервер «Кодиума» стоит в Амстердаме, и часы у него идут по всемирному времени (UTC). Ты уже встречал это в П1, когда в уведомлениях время съезжало на три часа (урок 2.5). Для отчёта решение то же: явно сказать программе, в каком поясе считать девять утра.
Путь «код»: таймер systemd
Службу systemd ты уже знаешь по боту: она держит программу запущенной круглосуточно. У systemd есть и будильник, он называется таймер (timer). Таймер раз в день запускает короткую службу, та отправляет отчёт и завершается. В прогоне задание агенту было таким (адрес сервера заменён):
Последняя часть задачи «Интеграции»: каждый день в 9:00 по Москве владелец получает в Telegram отчёт за вчера по файлу zayavki.xlsx на Диске: всего заявок, по источникам и по курсам, плюс сколько всего в файле. Сделай это в проекте отдельным скриптом и таймером systemd (kodium-otchet.service + kodium-otchet.timer, OnCalendar с часовым поясом Europe/Moscow, Persistent=true, пользователь bot) на сервере <адрес сервера>. Тест на подсчёт. Выложи, включи таймер, запусти службу отчёта один раз вручную (systemctl start kodium-otchet) и покажи systemctl list-timers по kodium-otchet и журнал отчёта.
Три детали в задании работают на тебя. «OnCalendar с часовым поясом Europe/Moscow» говорит будильнику, что девять утра московские. «Persistent=true» значит: если сервер был выключен в 9:00, отчёт уйдёт сразу после включения, а не пропадёт. Ручной запуск через systemctl start нужен, чтобы не ждать до утра и увидеть результат сейчас.
Агент справился за 4,8 минуты. Проверка показала в списке таймеров строку NEXT «Sat 2026-10-10 06:00:00 UTC». Пугаться не надо: это и есть 9:00 по Москве, записанные часами сервера. Наутро таймер сработал сам в 06:00:03 по UTC, и отчёт пришёл владельцу.
Проверить сам можешь двумя командами на сервере:
systemctl list-timers kodium-otchet
journalctl -u kodium-otchet
В журнале после ручного запуска должна быть строка «Отчёт отправлен владельцу». Журнал читай целиком, а не только последнюю строку: в уроке 3.6 разберём, что ещё нашлось в этом журнале.
Путь «n8n»: Schedule Trigger
В n8n будильник называется Schedule Trigger (запуск по расписанию), это первый узел второго сценария. Готового файла для отчёта нет, собираешь его сам, переиспользуя узлы из урока 3.4. В прогоне сценарий «Кодиум: отчёт по заявкам 9:00» устроен так:
- Schedule Trigger. Расписание cron:
0 9 * * *. - HTTP Request «Ссылка на скачивание». Настройки как в уроке 3.4: GET
https://cloud-api.yandex.net/v1/disk/resources/download, Header Auth «T1 Яндекс Диск», Querypath=disk:/Кодиум/zayavki.xlsx. - HTTP Request «Скачать файл». GET
{{ $json.href }}, Response Format: File. - Extract From File. Operation: XLSX.
- Code «Посчитать за вчера». Код попроси у Claude Code заданием ниже.
- Telegram. Учётные данные «T1 бот Кодиум», Chat ID твой, Text:
{{ $json.text }}.
Я собираю в n8n сценарий отчёта по заявкам. Напиши код на JavaScript для узла Code «Посчитать за вчера», без лишних объяснений. На вход строки файла zayavki.xlsx из узла Extract From File, колонки Дата (ДД.ММ.ГГГГ ЧЧ:ММ по Москве), Имя, Курс, Телефон, Источник. Посчитай заявки за вчерашний день по Москве: всего, по источникам, по курсам, плюс сколько всего строк в файле. Верни один элемент с полем text, например: «📊 Заявки за 09.10.2026 — всего 6; по источникам: бот 5, сайт 1; по курсам: Python 4; всего в файле 9». Имена и телефоны в text и в лог не выводи.
Запись 0 9 * * * читается так: ноль минут, девятый час, каждый день, каждый месяц, любой день недели. Девять часов чего? Это решает часовой пояс в настройках сценария (Settings, поле Timezone). В прогоне там стоял Europe/Moscow; сценарий собирали программно, поэтому где ровно это поле в интерфейсе, мы не проверяли. Без пояса n8n возьмёт пояс по умолчанию, и отчёт уедет на другое время. Проверь пояс до включения сценария, пробный отчёт получи ручным запуском, затем включи сценарий (Publish).
Подробнее о сценариях по расписанию рассказывает урок трека 2 про утренний брифинг: сценарий по расписанию в n8n.
Колонка «Источник» в существующем файле
Теперь вторая ловушка. Когда агент делал приём заявок с формы, он добавил в код колонку «Источник». Тесты прошли, заявка с формы дошла. А в файле на Диске шапка осталась старой: Дата, Имя, Курс, Телефон. Заявки с сайта стало не отличить от заявок из бота.
Причина знакомая по П1, где в базе не нашлось поля consent_at. Новая колонка добавлялась только при создании нового файла. Рабочий файл уже существовал, и код его шапку не трогал. Такую доработку существующих данных под новую структуру называют миграцией: как переезд шкафа в новую квартиру, где полки уже другие.
Задание агенту в прогоне:
Проверил файл zayavki.xlsx на Диске: колонки «Источник» в нём нет — шапка осталась старая (Дата, Имя, Курс, Телефон), и заявки с сайта не отличить от заявок из бота. Похоже, колонку добавляешь только при создании нового файла. Почини так, чтобы при каждой выгрузке, если в существующем файле нет колонки «Источник», она добавлялась в шапку, а старым строкам проставлялось «бот». Добавь тест на существующий файл со старой шапкой. Запусти тесты, обнови обе службы на сервере <адрес сервера>, отправь одну тестовую заявку с формы curl-ом и покажи шапку и последние строки файла на Диске (телефоны замаскируй).
Агент работал 8 минут. Шапка обновилась, старым строкам проставилось «бот». Но среди старых строк были две ранние заявки с сайта, пришедшие до починки. Они тоже получили «бот», потому что источник у них нигде не хранился. Восстановить его задним числом нельзя. Заказчику так и говорим: «Две заявки до 10 октября помечены как бот, хотя пришли с сайта; дальше учёт точный». Честная оговорка дешевле, чем отчёт, которому потом не верят.
Правило: добавил поле в код, сразу спроси себя, что будет со старым файлом или старой базой. Проверяй глазами настоящий файл на Диске, а не только тесты.
Если не получилось
- В списке таймеров NEXT показывает 06:00 UTC → всё верно, это 9:00 по Москве при часах сервера в UTC.
- NEXT показывает 09:00 UTC → в OnCalendar не указан пояс Europe/Moscow; отчёт придёт в полдень по Москве. Попроси агента добавить пояс.
- Отчёт в n8n пришёл не в 9:00 → в настройках сценария не тот часовой пояс; отчёта нет совсем → сценарий не включён (Publish).
- В файле нет колонки «Источник», хотя тесты зелёные → колонка добавляется только в новый файл; нужна миграция существующего файла.
- Ручной запуск отчёта прошёл, а утром ничего → таймер не включён; в задании должно быть «включи таймер», в выводе list-timers таймер должен быть в списке.
Контрольный вопрос. На сервере в UTC ты выполнил systemctl list-timers kodium-otchet и видишь NEXT «06:00:00 UTC». Что это значит?
Подсказка: Сколько часов разница между UTC и Москвой?
На курсе задания проверяются автоматически. Решить первое задание бесплатно → · Подобрать курс
Контрольный вопрос. После починки колонки «Источник» две ранние заявки с сайта помечены «бот». Что делаешь?
Подсказка: Хранился ли где-нибудь источник у этих заявок до починки?
На курсе задания проверяются автоматически. Решить первое задание бесплатно → · Подобрать курс
Контрольный вопрос. Зачем в задании агенту стоит Persistent=true?
Подсказка: Что случится с пропущенным будильником без этой настройки?
На курсе задания проверяются автоматически. Решить первое задание бесплатно → · Подобрать курс
Задание. МИССИЯ «Отчёт в 9:00». 1. Выбери путь: код или n8n (тот, которым собирал приём формы). 2. Код: дай агенту задание из урока, проверь systemctl list-timers kodium-otchet и журнал после ручного запуска. n8n: собери сценарий отчёта со Schedule Trigger и часовым поясом Europe/Moscow, запусти вручную. 3. Сломай и почини (путь «код»): попроси агента временно убрать пояс из OnCalendar, посмотри NEXT в списке таймеров, верни пояс и убедись, что NEXT снова показывает 06:00 UTC. В n8n: открой настройки сценария, убедись, что стоит Europe/Moscow, запусти сценарий вручную и найди этот запуск в списке исполнений. Где n8n показывает время следующего запуска, мы не проверяли. 4. Проверь, что в существующем zayavki.xlsx есть колонка «Источник» и у старых строк она заполнена. Принято, если: приложен снимок отчёта в Telegram; снимок вывода list-timers до и после починки пояса (или снимок настроек сценария n8n с Europe/Moscow и исполнения ручного запуска); снимок шапки zayavki.xlsx с колонкой «Источник» (телефоны закрыты).
Подсказка: Если NEXT показывает 09:00 UTC, отчёт уедет на полдень по Москве.
✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.
На курсе задания проверяются автоматически. Решить первое задание бесплатно → · Подобрать курс
Что дальше
Поток работает и отчитывается. Следующий урок о том, что в нём может сломаться и протечь, и как объяснить заказчику, сколько эта автоматизация стоит и когда окупится.
Итог:
• ежедневный отчёт в 9:00 по Москве работает кодом или в n8n;
• ты умеешь читать время в списке таймеров с учётом UTC;
• колонка «Источник» есть в рабочем файле, а про невосстановимые данные заказчик знает.
