>_
automate_this
Г
Это демо
Потыкай, посмотри как устроено — а чтобы начать, заведи аккаунт: M0 бесплатно.

M0-09Поиск по дневнику

тренажёрfree
Представь: у тебя в базе сотни записей — заметки, заявки клиентов, описания товаров. Через месяц нужно быстро найти все где встречается определённое слово: имя клиента, проект, тема. Соберём бота, которому в Telegram пишешь слово, а он ищет по всей твоей таблице и присылает обратно все совпадения. Три ноды без AI — приёмник, поиск, ответ — а решает реальную задачу «найди мне всё про X».
#telegram#data-table#data-search#multi-item

Что собираем

Три ноды в одну линию. Telegram Trigger ловит поисковый запрос — слово, которое ты отправляешь боту. Нода Data table ищет по таблице дневника и возвращает только строки, где это слово встречается. Нода Telegram отправляет каждую найденную запись обратно тебе в чат.

Готовый воркфлоу: Telegram Trigger → Data table → Telegram, все три ноды в линейной цепочке
Итоговый воркфлоу

Шаги выполнения

1Получи токен у @BotFather

Создаём бота через @BotFather и получаем токен — токен нужен n8n, чтобы сообщения шли от имени именно твоего бота. Подробнее про @BotFather и токен — в шпаргалке ниже.

Этот шаг ты делаешь в Telegram-приложении, n8n пока даже не открывай.

📖@BotFather: как создать собственного бота в Telegramстатья · ~2 мин

@BotFather: как создать собственного бота в Telegram

@BotFather — это официальный бот Telegram, через которого создаются все остальные боты. Других способов завести бот нет: ни сайта, ни приложения, ни консоли — только переписка с этим аккаунтом.

Зачем это нужно

Чтобы любой workflow (в n8n, Make, на собственном бэкенде) мог слушать сообщения и отвечать от имени бота, ему нужен токен Bot API. Токен выдаётся при создании бота через @BotFather. Без токена ни одна интеграция с Telegram не заведётся: токен — это пара «логин-пароль» бота при общении с Telegram Bot API.

Как это работает

Открываешь Telegram, в поиске находишь аккаунт с username BotFather (галка подлинности рядом с именем — синяя), и пишешь ему как обычному собеседнику. Команды начинаются со слэша:

  • /newbot — создать нового бота. @BotFather спросит две вещи:
  • отображаемое имя (любое, может быть с пробелами и кириллицей) — то, что увидят пользователи в шапке чата;
  • username (только латиница, цифры, подчёркивание; обязательно заканчивается на _bot или bot) — постоянный идентификатор, по которому бот ищется и не меняется.
  • /mybots — список всех твоих ботов, доступ к настройкам (имя, описание, аватарка, команды, токен).
  • /revoke — отозвать старый токен и получить новый (если старый утёк).

После /newbot приходит сообщение с токеном — длинная строка вида 123456789:ABCdefGHI_jklMNO.... Это и есть тот самый Bot API token: его копируешь и сохраняешь в безопасное место (менеджер паролей, заметки с шифрованием) — но не в публичный репозиторий и не в чат.

Типичные ошибки

  • Потерять токен — @BotFather показывает токен один раз; чтобы получить его снова, нужно открыть /mybots → <твой бот> → API Token. Если не нашёл — можно сгенерировать новый через /revoke, но тогда старый перестанет работать во всех уже настроенных интеграциях.
  • Скинуть токен скриншотом / в открытый чат — токен даёт полный контроль над ботом. Любой, кто его увидит, может слать сообщения от имени бота и читать всё, что ему приходит. Если утёк — сразу /revoke.
  • Username без _bot на конце — @BotFather отклонит регистрацию; правило жёсткое, придётся подбирать ещё.
  • Перепутали username и отображаемое имя — отображаемое имя меняется в любой момент через /setname, а username меняется только пересозданием бота. Если задумывался серьёзный бот — username стоит выбрать осознанно.

Когда не подходит

Через @BotFather нельзя создать юзербот (бот, который ходит под обычным аккаунтом) — это уже не Bot API, а MTProto, и токен оттуда не подходит. Также @BotFather не нужен, если бот уже создан кем-то другим и тебе просто передали готовый токен — тогда сразу заводишь credential в нужном сервисе и работаешь с ним.

1.1
Найди @BotFather в Telegram

В Telegram найди аккаунт @BotFather (синяя галка подлинности рядом с именем). Открой с ним чат.

1.2
Отправь команду /newbot

В чате с @BotFather отправь команду /newbot.

Эта команда запускает диалог по созданию нового бота. Дальше @BotFather будет задавать вопросы по очереди — сначала про имя, потом про username.

1.3
Впиши отображаемое имя бота

На вопрос про имя (Alright, a new bot. How are we going to call it?) впиши любое отображаемое имя, например AI-помощник Вася.

Это имя пользователи будут видеть в шапке чата с ботом. Менять его потом можно через /setname — то есть запоминать намертво не нужно.

1.4
Придумай уникальный username бота

На следующий вопрос (Good. Now let's choose a username for your bot.) придумай уникальный идентификатор латиницей, обязательно заканчивающийся на _bot или bot — например, vasya_ai_helper_bot.

Username — это адрес бота в Telegram (https://t.me/vasya_ai_helper_bot). В отличие от имени, изменить его после создания нельзя, и он должен быть уникальным во всём Telegram. Если @BotFather ответит, что username занят, придумай другой.

1.5
Сохрани токен в надёжное место

В ответ @BotFather пришлёт сообщение с токеном — длинная строка вида 123456789:ABCdefGHI_jklMNO.... Скопируй её и сохрани в надёжное место (менеджер паролей, личная заметка) — токен это полный доступ к боту, светить его нельзя.

🎯
Тренажёр модуля I-Telegram
Если впервые создаёшь Telegram-бота — пройди модуль про Telegram.
2Подключи Telegram Trigger

Первая нода workflow — Telegram Trigger. Она держит подписку на входящие сообщения твоего бота.

Каждый раз когда ты напишешь боту слово для поиска — Trigger получит это сообщение и запустит workflow.

2.1
Добавь Telegram Trigger

На пустом canvas нажми + → в поиске нод введи telegram → выбери Telegram → в разделе Triggers выбери On message.

📖Как добавить ноду в n8nстатья · ~2 мин

Добавление ноды на canvas

Чтобы продолжить цепочку, нужно вставить новую ноду после существующей или на пустой canvas. Для этого открывают панель выбора нод тремя способами: кнопка Open nodes panel в центре canvas, кнопка Add node на стрелке соединения и + на output-коннекторе любой ноды.

Панель называется What happens next?. В ней сразу видно категории и поле поиска.

Как это работает

  • Клик по Open nodes panel или Add node открывает список.
  • В поле Search nodes... вводят имя ноды или сервиса (например http, slack, schedule). Список фильтруется по мере ввода.
  • Навигация по категориям: AI, Action in an app, Data transformation, Flow, Core, Human review, Add another trigger.
  • Клик по названию ноды ставит её на canvas и сразу открывает панель Parameters.
  • На пустом canvas можно нажать клавишу Tab — откроется та же панель без клика мышью.

Первая нода любого воркфлоу должна быть триггером (Schedule Trigger, Webhook, Manual и подобные). Обычные ноды-действия в начало ставить нельзя.

Правило одной строкой
Первая нода — всегда триггер

Если первой стоит обычная нода-действие, воркфлоу не запустится. Начинай всегда с триггера.

Типичные ошибки

  • Поставил обычную ноду первой → воркфлоу не из чего стартовать → замени первую ноду на триггер из категории Core или через поиск.
  • Ищут ноду по русскому названию → список остаётся пустым → вводи английское имя сервиса в поле Search nodes....
  • Целятся мышью в мелкий + на стрелке → промахиваются → нажми Tab прямо на canvas.
  • Открывают категорию Add another trigger после уже существующей ноды → добавляют лишний триггер → для обычного шага используй поиск или категории Action in an app и Data transformation.
2.2
Добавь credential в Telegram Trigger

Открой ноду двойным кликом. В поле Credential нажми Create New Credential и вставь туда токен, который получил у @BotFather в шаге 1. Сохрани. Этот credential автоматически подцепится во всех нодах Telegram твоих workflow.

🔑Как добавить credential в n8nстатья · ~1 мин

Универсальный процесс добавления credential

Credential в n8n — это сохранённая «учётка» для подключения к сервису (API-ключ, OAuth-токен, логин/пароль и т.д.). Любая нода, которой нужна авторизация, выбирает credential из общего списка — поэтому добавлять его нужно один раз, а использовать можно из любого количества нод того же типа.

Пошагово

  1. В левом меню n8n открой раздел Credentials.
  1. Нажми кнопку Add credential (правый верхний угол).
  1. В поиске введи название нужного типа credential — например, OpenAI, Header Auth, Postgres, Google — и выбери его из списка.
  1. В шапке формы дай credential понятное имя — например, OpenAI школа или Postgres prod. По этому имени ты будешь выбирать его в нодах.
  1. Заполни поля формы. Какие именно — зависит от типа: для API-ключевых это обычно одно поле API Key, для Header Auth — Name и Value заголовка, для Postgres — host/port/database/user/password, для OAuth — запуск OAuth-flow по кнопке.
  1. Нажми Save. Готово — credential можно подключать к любой ноде, которая поддерживает этот тип.
Подсказка
Один credential — много нод

Один сохранённый credential можно использовать в неограниченном количестве нод одного типа. Если ключ протухнет — поменяй его в credential один раз, обновится во всех нодах сразу.

Кстати
Какие поля заполнять у конкретного типа

Этот гайд — про универсальный процесс. Какие поля и какие значения вводить у конкретного credential (OpenAI API, Header Auth, Postgres и т.д.) — смотри в inline-статье на этот тип, она будет рядом со ссылкой на текущую.

2.3
Проверь параметр Trigger On

В поле Trigger On должно стоять Message (по умолчанию) — нода будет срабатывать на каждое входящее текстовое сообщение.

⚙Типы update'ов в Telegram Trigger: что значит Message, Callback Query, Inline Queryстатья · ~2 мин

Типы update'ов в Telegram Trigger: что значит Message, Callback Query, Inline Query

Параметр Updates находится в Telegram Trigger → Parameters → Trigger On. Это выпадающий список с множественным выбором, каждый пункт которого соответствует одному типу события Bot API. По умолчанию включён только Message.

Когда бот получает обновление, n8n передаёт его дальше только если соответствующий тип отмечен. Невключённые типы просто игнорируются.

Зачем это нужно

Без явного выбора типов бот будет реагировать на всё подряд или, наоборот, пропускать нужные события. Например, нажатие inline-кнопки приходит отдельным типом и без галочки Callback Query до ноды не дойдёт.

Как это работает

Каждый выбранный тип добавляет своё поле в $json:

  • Message — обычное сообщение в чате. Данные лежат в $json.message.
  • Edited Message — исправленное сообщение. Поле $json.edited_message.
  • Callback Query — нажатие inline-кнопки. Полезная нагрузка в $json.callback_query.data.
  • Inline Query — запрос, когда пользователя упоминают через @ в любом чате.
  • Channel Post / Edited Channel Post — посты в канале, где бот является администратором.
  • Chosen Inline Result, Shipping Query, Pre Checkout Query, Poll, Poll Answer, My Chat Member, Chat Member — узкие случаи, используются редко.
Важно
Callback Query — отдельный тип

Если ждёшь нажатие кнопки, обязательно включи Callback Query. Без этой галочки событие молча пропускается.

Типичные ошибки

  • Отметили все галочки «на всякий случай» → воркфлоу срабатывает на лишние события → следующие ноды падают на отсутствующих полях $json.
  • Ожидают нажатие inline-кнопки, но оставили только Message → Callback Query игнорируется.
  • Пытаются прочитать текст отредактированного сообщения через $json.message.text → получают undefined, потому что данные находятся в $json.edited_message.text.

Когда не подходит

Если нужно обрабатывать только сообщения определённого формата или фильтровать по содержимому, используй ноду IF или Filter после триггера, а не отключай типы в Trigger On.

2.4
Проверь параметры ноды

Убедись, что параметры соответствуют таблице ниже.

Параметры Telegram Trigger
ПараметрЗначение
Credentialтвой Telegram Bot credential
Trigger OnMessage

Триггер добавлен. Теперь нужно получить от Telegram реальные данные.

Это позволит проверить работоспособность ноды и получить пример входящих данных, с которыми будет работать workflow.

2.5
Нажми на кнопку Execute workflow

После этого workflow перейдёт в режим тестового ожидания входящего события. n8n будет слушать триггер 2 минуты.

За это время нужно отправить сообщение в Telegram.

📖Кнопка «Execute workflow»: ручной запуск для тестированиястатья · ~2 мин

Кнопка ручного запуска для теста

В редакторе workflow внизу canvas есть большая оранжевая кнопка «Execute workflow». Это основной инструмент тестирования: один клик — и весь workflow прогоняется от триггера до конца, прямо в редакторе. На production это никак не влияет — даже если воркфлоу опубликован (Publish), кнопка запускает отдельный тестовый прогон.

Как это работает

  1. Нажимаешь Execute workflow внизу canvas.
  1. n8n запускает workflow от триггера. Ноды по очереди подсвечиваются: серая → жёлтая (выполняется) → зелёная (готово) или красная (ошибка). Внизу каждой ноды появляется счётчик пришедших на вход элементов.
  1. Клик по любой ноде после прогона — видишь её input и output. Это и есть отладка: где данные пропали или пришли не в том виде.
Запуск с середины
Кнопка ▶ на самой ноде

У каждой ноды на canvas есть своя маленькая кнопка ▶ (появляется при наведении). Она запускает только эту ноду на данных, которые лежат в её input от предыдущего прогона. Удобно, когда правишь одну ноду и не хочешь гонять весь workflow заново.

Особый случай: workflow с Chat Trigger

Если в workflow стоит триггер Chat Trigger (встроенный в n8n чат), правила для тестирования другие — Execute workflow появляется не сразу.

  • Когда у Chat Trigger ещё нет запиненных данных — внизу canvas вместо Execute workflow стоит кнопка Open chat. Клик открывает встроенный чат-виджет n8n: ты пишешь сообщение, оно идёт в триггер, workflow выполняется от события «новое сообщение в чате». Это и есть основной путь тестирования Chat Trigger.
  • Когда данные Chat Trigger запинены (через Pin data в Output триггера) — кнопка Open chat сменяется на привычную Execute workflow. n8n больше не ждёт нового сообщения в чате, а гоняет workflow на запиненных данных. Удобно для отладки downstream-нод без необходимости каждый раз писать в чат.

Логика та же что у обычных триггеров — если есть закреплённый тестовый вход, n8n показывает Execute workflow для запуска на нём; если нет — показывает способ получить реальное событие (для Chat Trigger это Open chat, для Webhook — Test URL и т.д.).

Типичные ошибки

  • Нажал кнопку, ничего не происходит → в воркфлоу нет триггера. Добавь триггер (для ручных тестов подойдёт Manual Trigger); если триггеров несколько, запусти нужный кнопкой ▶ на самой ноде.
  • Нода красная, дальше ничего не выполнилось → клик по ноде → вкладка с ошибкой. Прогон останавливается на первой упавшей ноде.
  • На ноде «0 items» и она не выполнилась → предыдущая нода вернула пустой массив. Это не ошибка, это «нечего обрабатывать». Смотри output предыдущей ноды.
🚩Publish и режимы воркфлоу в n8nстатья · ~2 мин

Два режима воркфлоу: Unpublished и Published

В n8n у воркфлоу два состояния. Unpublished — черновик: ты редактируешь и можешь запускать его только вручную через Execute workflow, триггеры молчат. Published — живая версия: триггеры включены, Schedule срабатывает по расписанию, Webhook и Form принимают запросы по Production URL, polling-триггеры (Telegram, Gmail) слушают обновления. Переключает между состояниями кнопка Publish в правом верхнем углу редактора.

Что включает Publish
  • Schedule-триггер — начинает запускаться по расписанию. В Unpublished не сработает ни разу.
  • Webhook / Form Trigger — Production URL начинает принимать запросы. До Publish этот URL возвращает 404.
  • Test URL у Webhook / Form — работает только пока ты нажал Execute workflow в редакторе. От статуса Publish не зависит.
  • Polling-триггеры (Telegram, Gmail и подобные) — начинают слушать события.
  • Воркфлоу-исполнитель — для триггеров берёт именно опубликованную версию, не текущее состояние редактора.
Главная тонкость
Без Publish триггеры молчат

Частая ошибка новичка: настроил Telegram Trigger, протестировал через Execute workflow — всё пришло, обрадовался. Закрыл редактор. Бот молчит. Потому что Telegram-вебхук и любая боевая активность триггеров включаются только после Publish. Test-режим Execute workflow живёт лишь пока редактор открыт и кнопка нажата.

Version Name и Describe changes — каждая публикация это новая версия

При нажатии Publish n8n показывает диалог с двумя полями:

  • Version Name — обязательное короткое имя версии. Любая строка, по которой ты потом узнаешь эту версию в истории. Хорошие примеры: журнал менеджера добавлен, webhook: новая схема заявки, fix: timezone for cron. Плохие: 123, update, асдф — через неделю ты не поймёшь что в этой версии было.
  • Describe changes (опционально) — что именно поменялось с прошлой версии. Это короткий журнал в свободной форме: «добавил Stretch-ветку ai-классификации жалоб», «починил Switch L2 — было kebab-case, стало snake_case». Заполняй обязательно для значимых правок — себе через месяц спасибо скажешь.

Каждая публикация создаёт новую версию workflow. История версий доступна через Versions (рядом с Editor/Executions) — можешь посмотреть какой код был на каждой версии, откатиться на любую из них одной кнопкой Restore. Это и есть встроенный git-подобный version control для воркфлоу.

Привычка
Маленькая правка → отдельный Publish с осмысленным именем

Кажется заманчивым копить много правок в одной публикации, чтобы не возиться с именами. На практике это плохо: если позже сломается какая-то ветка, и захочется откатиться — придётся откатить всё сразу, теряя другие изменения. Лучше публиковать мелкими шагами: подключил ветку — Publish с именем «ветка orders собрана»; залогировал действие — Publish с именем «orders + лог». Каждая версия = одно атомарное улучшение.

Sub-Workflow тоже публикуют

Воркфлоу, который вызывается из другого через Execute Workflow Trigger, тоже нужно публиковать. Родитель при вызове берёт последнюю опубликованную версию Sub-WF — если ты внёс правки и не нажал Publish, родитель их не увидит. Управляется той же кнопкой Publish.

Типичные ошибки

  • Поправил опубликованный воркфлоу, забыл Publish заново → триггеры исполняют старую версию. После каждой правки — Publish.
  • Дёргаешь Production URL у Unpublished воркфлоу → возвращает 404. Либо публикуй, либо открой редактор, нажми Execute workflow и шли на Test URL.
  • Хочешь временно остановить воркфлоу → нажми Unpublish. Триггеры замолкают, Production URL перестаёт принимать запросы. Чтобы запустить обратно — снова Publish.
2.6
Открой в Telegram чат со своим ботом

Если ботом ещё не пользовался — нажми Start.

2.7
Напиши боту слово для поиска

Напиши боту слово, которое точно встречается в твоих записях дневника — например, настроение. Бот ничего не ответит, но данные от Telegram придут в workflow.

Telegram Trigger с зелёной обводкой и галочкой после получения сообщения
Так выглядит нода после успешного выполнения
📖Структура Telegram Update: update_id, message, chat и fromстатья · ~3 мин

Update — обёртка одного события от Telegram

Объект Update приходит от Telegram Bot API каждый раз, когда происходит событие: новое сообщение, редактирование, нажатие кнопки. Внутри всегда лежит поле update_id и ровно одно поле с полезной нагрузкой.

update_id — это последовательный номер события. Каждое новое событие получает следующий номер. Поле нужно только чтобы отслеживать, какие обновления уже обработаны.

Полезная нагрузка может быть разной: message, edited_message, channel_post, callback_query, inline_query и другие. В одном Update присутствует только одно из этих полей.

Как это работает

Самое частое поле — message. Внутри него лежат:

  • message_id — уникальный номер сообщения внутри чата
  • from — объект User (кто отправил)
  • chat — объект Chat (куда сообщение попало)
  • date — unix-время
  • text, voice, photo, document — в зависимости от типа сообщения

Объект chat содержит:

  • id — идентификатор чата
  • type — private, group, supergroup или channel
  • title, username, first_name — названия и имена

Объект from (User) содержит:

  • id — идентификатор пользователя
  • is_bot — флаг, бот это или человек
  • first_name, username, language_code

В приватном чате chat.id и from.id совпадают. В группе или супергруппе они разные: chat.id — это идентификатор группы, from.id — идентификатор конкретного участника.

Ключ для хранения контекста диалога всегда chat.id. Если использовать from.id, в группе бот начнёт путать пользователей и отвечать не в тот чат.

Поле text существует только у текстовых сообщений. У голосового сообщения его нет — там будет поле voice. Если обратиться к message.text у голосового сообщения, значение будет отсутствовать.

Правило одной строкой
chat.id — ключ памяти диалога

В приватном чате chat.id и from.id равны. В группе они разные. Для хранения состояния диалога всегда бери chat.id.

Типичные ошибки

  • Перепутал from.id и chat.id — в личке выглядит одинаково, в группе бот отвечает не туда или ведёт себя странно → используй chat.id для ключей памяти.
  • Использовал update_id как идентификатор сессии — каждое сообщение даёт новый update_id, память диалога никогда не находит прошлое → бери chat.id.
  • Полез в message.text у голосового сообщения — поле отсутствует, выражение возвращает undefined → проверяй тип сообщения перед обращением к text.
  • Не учёл chat.type в группе — бот не видит все сообщения из-за privacy mode → либо добавляй @-упоминание, либо отключай privacy mode у BotFather.
📖JSON: формат данных, синтаксис и типыОткрыть
2.8
Запинь полученные данные

Это позволит использовать полученные данные при настройке следующих нод — без повторной отправки сообщений в Telegram.

📖Pin Data в n8n: как зафиксировать тестовый вход нодыстатья · ~2 мин

Pin Data в n8n: как зафиксировать тестовый вход ноды

Pin Data — это способ «прибить» к ноде заранее заготовленные данные, которые n8n будет подставлять вместо настоящего входа на каждом тестовом запуске. Полезно, когда дёргать реальный источник (внешний воркфлоу, веб-хук, API) на каждое нажатие Execute workflow неудобно или невозможно.

Зачем это нужно

Часто отлаживается не сам триггер, а ноды после него — логика, маппинг, запрос в базу. Чтобы не звать каждый раз источник данных (другой воркфлоу, бот, форму), удобнее один раз получить пример настоящего входа, зафиксировать его на триггере и потом крутить запуски сколько нужно.

Поэтому Pin Data — это инструмент разработчика на этапе сборки, не часть рабочего воркфлоу. В боевом режиме закреплённые данные перестают использоваться: n8n берёт реальный вход.

Как это работает

К любой ноде с выходом можно прикрепить «запинённый» JSON. После этого:

  • При запуске воркфлоу через UI (Execute workflow, тестовый прогон) n8n не вызывает саму ноду, а сразу выдаёт следующим нодам зафиксированные данные.
  • Pin Data привязана к конкретной ноде, не к workflow целиком — можно запинить триггер и оставить остальные ноды живыми.
  • На холсте у запинённой ноды появляется визуальный значок (булавка/иконка), чтобы не забыть, что данные «искусственные».

Удобнее всего пинить триггер: на нём поле выхода — то, что в боевом режиме приходит снаружи (Telegram-апдейт, тело веб-хука, поля Execute Workflow Trigger). Тестовый JSON собирают с теми же ключами, что отдаёт реальный источник.

К примеру
Где это встречается

К примеру, в Sub-Workflow с триггером Execute Workflow Trigger пин на триггере позволяет запускать сам Sub-WF кнопкой сверху и отлаживать ноды после триггера, не запуская вызывающий workflow. Иногда — пин ставят на ноде HTTP Request к платному API, чтобы при разработке не жечь квоту запросами «ещё разок проверить парсинг».

Типичные ошибки

  • Забыли про пин при отладке — в редакторе тестовые прогоны идут по закреплённым данным, а не по реальным, поэтому новый вход «не доходит». Боевому запуску пин не мешает, но перед проверкой на живых данных его лучше снять.
  • Структура запинённого JSON не совпадает с реальным — отладка проходит идеально, но в проде ломается на полях, которых не было в тестовом примере; делайте пин из реальной execution, а не «на глаз».
  • Запинили середину воркфлоу, забыли — переименовали поле в ноде до пина, а пин остался со старой структурой. Следующие ноды читают «фантомные» данные.
  • Pin Data перепутали с переменными среды — пин не передаётся между воркфлоу и не сохраняется при экспорте на другую инсталляцию n8n как «конфиг»; это именно отладочный фиксаж.

Когда не подходит

Pin Data не заменяет настоящие тесты — это удобство в редакторе, не автоматизация. Если нужна повторяемая проверка с разными входами, лучше делать отдельный тестовый workflow или мини-набор тест-кейсов; пин подходит, когда хочется быстро прогнать «один и тот же» сценарий N раз.

Воркфлоу после шага 2: Telegram Trigger добавлен, данные запинены
Воркфлоу после шага 2 — Telegram Trigger добавлен и протестирован
3Создай Data table с тестовыми записями

Перед настройкой поиска нужны данные — записи дневника в таблице. Чтобы не вводить их по одной вручную, мы импортируем готовый CSV-файл с 15 тестовыми записями за один шаг. Data table — встроенная в n8n таблица: задаёшь имя и колонки с типами, после чего любая нода на canvas может читать и писать строки.

🗄Data table в n8n: что это и когда использовать вместо базы данныхстатья · ~3 мин

Data table хранит данные внутри n8n

Data table — это встроенное хранилище, которое живёт прямо в n8n. Таблица не требует отдельного сервера или подключения к внешней базе. Она принадлежит проекту и доступна всем воркфлоу внутри него.

Каждая таблица состоит из колонок с именем и типом и строк с данными. Доступ к таблицам идёт через ноду Data table с ресурсом Row или Table.

Как это работает

Нода Data table находится в Sidebar через + Add node → Data table. В Parameters выбирают Resource (Row или Table) и Operation (Get, Insert, Update, Delete, Upsert).

Типы колонок ограничены четырьмя вариантами:

  • String
  • Number
  • Boolean
  • Date

Тип json отсутствует. Если нужно хранить сложные объекты, их записывают как String и разбирают позже в ноде Code.

Правило выбора
Data table или Postgres

До нескольких сотен строк и при необходимости ручной правки выбирай Data table. При тысячах строк, аналитике или частых параллельных записях переходи на Postgres.

Data table не поддерживает транзакции, JOIN между таблицами и индексы. Параллельные записи из разных триггеров могут перезаписывать друг друга или падать.

Типичные ошибки

  • Ожидают тип json в колонке → его нет → хранят JSON как String и парсят в Code при чтении.
  • Пишут счётчики и журналы из нескольких триггеров одновременно → конкурентная запись смешивается → переносят таблицу в Postgres.
  • Заводят Data table под тысячи строк и отчёты → отсутствие индексов и агрегаций тормозит → используют Postgres.
  • Рассчитывают на JOIN между таблицами → его нет → денормализуют данные в одну таблицу или переходят на Postgres.
3.1
Скачай CSV с тестовыми записями

Скачай файл с тестовыми записями дневника — mood-diary.csv. Сохрани его на компьютере.

Файл содержит 15 записей с двумя колонками: message (текст записи) и username (имя автора).

3.2
Создай новую Data table из CSV

В n8n открой вкладку Data tables своего проекта и нажми Create data table. В диалоге введи имя m0-09-mood-diary, переключись на режим Import CSV и загрузи скачанный файл. Убедись что галка My CSV file contains a header row стоит, нажми Create.

На следующем экране Set data table columns n8n определит две колонки message и username типа String. Нажми Create ещё раз — таблица создастся.

🗄Как создать Data table из CSV-файластатья · ~2 мин

Как создать Data table из CSV

В n8n можно создать таблицу не вручную по колонкам, а сразу импортом из CSV-файла. Удобно когда у тебя уже есть готовые данные — n8n определит колонки из заголовка CSV и зальёт строки одним действием.

  1. В своём проекте n8n открой вкладку Data tables. В правом верхнем углу нажми Create data table.
Вкладка Data tables в проекте n8n со списком существующих таблиц и кнопкой Create data table в правом верхнем углу
  1. Откроется диалог Create new data table. В поле Data table name * впиши имя новой таблицы — это обязательное поле.
  2. Под полем имени по умолчанию выбран режим From scratch (создать с нуля по колонкам). Переключи на Import CSV.
Диалог Create new data table: поле Data table name пустое, по умолчанию выбран режим From scratch, ниже опция Import CSV
  1. Под радио-кнопками появится дроп-зона Drop file here or click to upload. Перетащи в неё свой CSV-файл (или кликни по зоне и выбери файл в проводнике).
Диалог Create new data table с выбранным режимом Import CSV: пустая дроп-зона с иконкой файла и надписью Drop file here or click to upload, ниже галка My CSV file contains a header row
  1. После загрузки в дроп-зоне появится имя файла. Убедись что галка My CSV file contains a header row стоит — n8n возьмёт первую строку CSV как названия колонок. Если CSV без заголовка — сними галку, тогда n8n сгенерирует имена column_1, column_2 и т.д. сам.
  2. Нажми Create.
Диалог Create new data table: имя таблицы заполнено, выбран Import CSV, в дроп-зоне отображается имя загруженного файла, галка My CSV file contains a header row отмечена, активна кнопка Create
  1. Откроется второй шаг — Set data table columns. Сверху n8n покажет сообщение вида 'filename.csv' has been uploaded successfully. We found N columns and M rows — проверь что число колонок и строк совпадает с тем, что ты ждал.
  2. Под сообщением — список колонок: имя (из заголовка CSV) и определённый тип (String, Number, Boolean, Datetime; набор зависит от значений в колонке). Если тип определился неправильно — поменяй его в дропдауне Data Type напротив нужной колонки.
  3. Снять галку слева от колонки = пропустить эту колонку при импорте. По умолчанию все галки стоят.
  4. Нажми Create.
Диалог Set data table columns: вверху уведомление 'file uploaded successfully, found N columns and M rows', ниже список колонок с чекбоксами, полями ввода имени и дропдаунами Data Type, в правом нижнем углу кнопки Back и Create
  1. Готово. Откроется страница таблицы со всеми импортированными строками. Видно что к пользовательским колонкам n8n автоматически добавил служебные id, createdAt, updatedAt. Из этой страницы можно вручную добавить ещё строки (Add Row) или колонки (Add Column).
Открытая Data table после импорта: хлебные крошки Personal / Data tables / название таблицы, заголовок со столбцами id, message, username, createdAt, updatedAt, строки данных с автозаполненными метками времени
Не все колонки нашлись
n8n определил меньше колонок чем в CSV

Если на шаге Set data table columns колонок меньше, чем в твоём CSV — проверь:

  • В первой строке CSV все имена колонок перечислены через запятую без пропусков.
  • Значения с запятыми внутри обёрнуты в двойные кавычки: "текст, с запятой".
  • Файл сохранён в кодировке UTF-8.
  • Если CSV выгружен из Google Sheets — выгружай через Файл → Скачать → Значения, разделённые запятыми (.csv). Если открыть исходный CSV в Sheets как таблицу и выгрузить заново — Sheets может изменить формат данных.
3.3
Проверь параметры таблицы

Убедись, что параметры созданной таблицы соответствуют таблице ниже.

Параметры Data table
ПараметрЗначение
Имя таблицыm0-09-mood-diary
Колонка 1message — String (из CSV)
Колонка 2username — String (из CSV)
Автоколонки n8nid, createdAt, updatedAt (создаются автоматически, в CSV их нет)
4Настрой ноду Data table для поиска

Вторая нода workflow — Data table в режиме Get.

Она читает таблицу m0-09-mood-diary, которую ты только что создал, и возвращает только те строки, где значение колонки message содержит отправленное тобой слово. Если совпадений нет — нода возвращает пустой результат и workflow останавливается.

4.1
Добавь ноду Data table

Нажми на канвасе + справа от Telegram Trigger. В правой панели поиска нод введи data table → выбери Data table → в открывшемся подменю в разделе Actions выбери Get Row(s). Нода автоматически подключится к триггеру.

4.2
Выбери таблицу дневника

В поле Data table оставь режим From list и выбери из дропдауна таблицу m0-09-mood-diary, созданную в шаге 3.

4.3
Добавь условие фильтра

В секции Conditions нажми Add Condition. Появятся три поля.

Заполни их:

  • Column → выбери message
  • Condition → выбери Contains (Case-Insensitive)
  • Value → В панели Input слева раскрой Telegram Trigger → message → перетащи поле text в поле Value. Появится выражение {{ $('Telegram Trigger').item.json.message.text }}.

Contains (Case-Insensitive) найдёт совпадение независимо от регистра — например, «Настроение» и «настроение» для него одно и то же.

⚙Как достать строку из DataTable n8n по фильтрустатья · ~2 мин

Как достать строку из DataTable n8n по фильтру

DataTable в n8n — это таблица, которую можно вести прямо внутри проекта рядом с воркфлоу. Когда из такой таблицы нужно вытащить нужные строки (одну или несколько), используется операция Get с фильтром по условию.

Зачем это нужно

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

Как это работает

  1. В параметрах ноды Data table выбирается Resource: Row и Operation: Get.
  2. В поле Data table указывается имя таблицы.
  3. В блоке Filter → Conditions добавляется одно или несколько условий: имя колонки + оператор + значение.
  4. Значение фильтра почти всегда вводится в режиме выражения ={{ ... }}, чтобы взять его из предыдущей ноды (например, поле из триггера). Литералом фильтр пишется только когда значение известно заранее и никогда не меняется.
К примеру
Фильтр по выражению vs литерал

К примеру, если в таблице лежит конфиг под разные каналы (telegram, web, email), а имя канала приходит из триггера — в условии пишется ={{ $('Trigger').item.json.channel }}. Если бы стоял литерал telegram, при подключении второго канала пришлось бы дублировать ноду.

Типичные ошибки

  • Литерал вместо выражения — фильтр работает только для одного значения, нет повторного использования.
  • Опечатка в имени колонки — нода возвращает пусто, а ошибка молчаливая (нет «такой колонки нет»); проверять имя колонки буква в букву.
  • Не включён Always Output Data в Settings — при пустом результате нода не отдаёт ничего вниз, и следующая нода просто не запускается: выполнение остаётся зелёным, обрыв тихий. Если по бизнесу пустой результат — это валидное состояние, включают Always Output Data, чтобы получить один пустой элемент {}.
  • Несколько условий, не тот режим сочетания — у операции Get есть переключатель Must Match: Any Condition (подходит строка, где выполнено любое условие) или All Conditions (нужны все). Проверь, что выбран нужный.

Когда не подходит

Если в одной таблице нужно склеить данные из нескольких строк (агрегация, выборка) — лучше вытащить всё операцией Get без фильтра и свернуть нодой Aggregate или Code. Get с фильтром отдаёт все подходящие строки, каждую отдельным элементом, и не подходит для сложных запросов.

⚡Как передать данные из одной ноды в другую через drag-and-dropстатья · ~2 мин

Перетаскивание полей из Input panel

Когда нужно подставить значение из предыдущей ноды в параметр текущей, не пиши выражение вручную. Открой ноду двойным кликом. Слева откроется Input panel с деревом полей предыдущей ноды. Справа — node parameters.

Раскрой нужное поле в Input panel и перетащи его мышкой в parameter's field. n8n сам сформирует выражение и переключит поле из режима Fixed в Expression.

Как это работает

Input panel показывает данные из OUTPUT предыдущей ноды. Данные приходят в виде дерева: каждое поле можно раскрыть до примитива.

После drop в parameter's field появляется выражение в двойных фигурных скобках. n8n поддерживает два формата:

  • $json.<field> — когда данные идут напрямую из предыдущей ноды по главной ветке;
  • $('<NodeName>').item.json.<field> — когда нужно явно указать имя ноды-источника.

n8n сам определяет нужный item через item linking. Ручной поиск соответствия не требуется.

Поле автоматически окрашивается и переключается в режим Expression. Альтернатива — открыть expressions editor и написать то же выражение вручную. Результат идентичен.

Вложенные поля раскрываются через точку: $json.body.city.

Правило одной строкой
Перетаскивай только до примитива

Если перетащить объект-обёртку, в поле попадёт [object Object]. Всегда раскрывай дерево до конечного значения.

Типичные ошибки

  • Перетащил объект-обёртку вместо примитива → в поле уходит [object Object] → раскрой дерево до листа.
  • Дропнул в соседнее поле параметра (Text вместо Chat ID) → нода работает не на тех данных → визуально проверь куда легло выражение.
  • Переименовал ноду уже после drag-and-drop → expression $('старое имя') сломался → верни старое имя или перепиши выражение вручную.
  • Впечатал статичное значение через drag вместо обычного текста → лишнее выражение там где значение не меняется → для констант просто впечатывай текст.
  • Тащишь из ноды через ветку которая не выполнялась → expression вернёт undefined → проверь что нужная ветка реально дошла до текущей ноды.
📖Fixed и Expression — два режима любого поля ноды в n8nстатья · ~2 мин

Fixed и Expression — два режима любого поля ноды в n8n

Каждое поле в Parameters любой ноды работает в одном из двух режимов. В режиме Fixed значение отправляется ровно так, как ты его написал. В режиме Expression значение пересчитывается на каждом item по JavaScript-формуле внутри {{ }}.

Переключатель Fixed | Expression находится справа от поля. Слева — кнопка Focus parameter и три точки с пунктом Reset Value. Никакой шестерёнки и пункта Add Expression в n8n v2 уже нет.

Как это работает

Режим Fixed — значение статично. Ты пишешь текст, число или выбираешь опцию из списка, и нода отправит именно это.

Режим Expression — значение динамическое. n8n показывает знак = слева от поля, оранжевую подсветку, блок Result и Item, а также кнопку Edit Expression. Формула выполняется заново для каждого входящего item.

Переключить режим можно двумя способами:

  • кликнуть Expression в radiogroup справа от поля;
  • перетащить поле из панели Input прямо в целевое поле параметра — n8n сам включит Expression и подставит {{ $json.field }} или {{ $('Имя ноды').item.json.field }}.

Переключатель есть в текстовых полях, выпадающих списках и в resource locator (там он появляется третьим табом).

Выбирай Expression, когда значение зависит от данных или времени. Оставляй Fixed, когда значение всегда одинаковое.

Правило одной строкой
Режим выбирается справа от поля

Чтобы включить динамическое значение — кликни Expression справа или перетащи поле из Input. Чтобы вернуть статичное — кликни Fixed.

Типичные ошибки

  • Написал {{ $json.name }} в режиме Fixed → n8n отправит литеральную строку со скобками → переключи справа на Expression или перетащи поле из Input заново.
  • Переключил Expression → Fixed в resource locator → выбранный объект исчез → вернись в Expression и подставь id формулой или заново выбери из From list в Fixed.
  • Ищешь шестерёнку слева по старым инструкциям → её нет в n8n v2 → используй radiogroup Fixed | Expression справа от поля.
  • Перетащил поле из Input, но режим не сменился → отпустил над зоной Drag input fields here соседнего параметра → отпускай строго над нужным полем.
  • Написал формулу без знака = → n8n считает её текстом → кликни Expression справа, тогда = появится автоматически.
📖Что такое expression в n8n и как она читает значения из других нодстатья · ~2 мин

Что такое expression

В n8n expression — это маленький кусочек кода в фигурных скобках, который динамически подставляет значение в поле ноды. Записывается так:

{{ <выражение> }}

В поле интерфейса = перед выражением писать не нужно: поле в режиме Expression уже трактует содержимое как выражение, а знак = n8n сам добавляет в файле воркфлоу (JSON) как маркер. Если напечатать = самому, он попадёт в результат текстом (например, сообщение начнётся с «=🚨»). Если поле осталось в режиме Fixed, {{ ... }} запишется как обычный текст.

Внутри {{ }} пишется JavaScript-выражение. Самое частое — чтение значения из другой ноды.

Зачем нужны expressions

Каждое поле в параметрах ноды может быть либо фиксированным значением (например, URL https://api.example.com), либо expression'ом — формулой, которая считается на лету в момент исполнения ноды. Expressions нужны, когда значение зависит от данных, пришедших из предыдущей ноды.

К примеру
Где это встречается

К примеру, ты сделал ноду «прочитать строку из таблицы конфига», а следующая нода — HTTP Request к внешнему API. В URL этой HTTP-ноды можно подставить значение из конфига: {{ $('Get Config').item.json.api_url }} — n8n при каждом исполнении возьмёт актуальный URL из таблицы, а не зашитый в ноду.

Как читать значения из других нод

Базовая формула: {{ $('<имя_ноды>').item.json.<поле> }}

Разбор по частям:

  • $('<имя_ноды>') — обращение к ноде по имени (то, что написано на холсте под нодой). Имя — в одинарных кавычках, точно как на холсте.
  • .item — текущий элемент, который обрабатывается. У большинства нод элементов несколько (массив), item берёт тот, что соответствует текущей итерации.
  • .json — содержимое поля json элемента (там лежат все данные, которые нода вернула).
  • .<поле> — конкретное поле внутри json. Если поле вложенное — пишется через точку: .config.embedding_model.

Пошагово — как вставить expression в поле

  1. Наведи курсор на поле и переключи Fixed → Expression в правом верхнем углу поля (или просто начни вводить {{ — поле само перейдёт в режим expression).
  2. В появившемся окне (expression builder) — слева список нод воркфлоу, можно кликать по полям и они вставятся в формулу.
  3. Справа — preview: видно, какое значение получится прямо сейчас. Если красным — формула или путь к полю некорректные.
  4. Закрой окно, поле остаётся в режиме expression (синий фон + иконка fx).
Типичная ошибка
Поле в режиме `Fixed` вместо `Expression`

Если вставил {{ ... }} в поле, которое осталось в режиме Fixed, n8n запишет текст {{ ... }} как есть, и нода уйдёт делать HTTP-запрос на URL вроде {{ $('...').item.json.api_url }} буквально. Симптом — ошибка Invalid URL или 404 на странную строку. Лечение: переключи поле в Expression. И наоборот, = в начале вручную не печатай — он попадёт в результат.

Типичные ошибки

  • Имя ноды не совпадает. В формуле $('Get Config') имя должно точно совпадать с подписью ноды на холсте. Если переименовал ноду — старые expressions, ссылающиеся на неё, сломаются.
  • Путь к полю не существует. .item.json.embedding_dimensions упадёт с undefined, если у элемента такого поля нет. Проверка — посмотри preview в expression builder, он сразу показывает значение или ошибку.
  • Поле осталось в режиме Fixed. Самая частая ошибка — описана в callout выше.
  • Кавычки внутри {{ }}. Внутри expression строки оборачиваются одинарными кавычками: {{ 'Hello ' + $json.name }}; двойные тоже работают. Поля с кириллицей и пробелами читаются как $json["Имя"].

Когда expression не нужен

Иногда поле должно быть фиксированным. Например, метод HTTP-запроса (GET / POST) или имя коллекции, которое одинаково для всего воркфлоу — нет смысла читать его динамически. Простое правило: если значение меняется от итерации к итерации или зависит от пришедших данных — нужен expression; если значение постоянное — оставляй фиксированным.

📖$json или $('Имя ноды'): когда какая форма обращения к даннымстатья · ~2 мин

Две формы обращения — разница только в источнике

В n8n у одной и той же ноды есть две формы прочитать поле из данных воркфлоу:

{{ $json.business_idea }}
{{ $('Form Trigger').item.json.business_idea }}

Обе достают одно и то же значение, но смотрят в разные места:

  • $json — это выход ноды, которая стоит прямо перед текущей. Короткая форма для «возьми поле из предыдущей ноды».
  • $('Имя ноды') — это обращение к любой ноде воркфлоу по имени, в том числе к той, что стоит на 2-3-5 шагов раньше.

Когда писать какую

Правило простое:

  • Хочешь взять данные у предыдущей ноды (стрелка идёт прямо в текущую) — пиши $json.поле.
  • Хочешь дотянуться до ноды глубже по цепочке (между ней и текущей есть промежуточные ноды) — пиши $('Имя ноды').item.json.поле.
Пример
Цепочка из трёх нод

Цепочка: Form Trigger → OpenAI → Send Message.

В Send Message обращения к двум разным источникам выглядят так:

  • к ответу OpenAI (предыдущая нода): ={{ $json.output }}
  • к полю формы (нода на два шага назад): ={{ $('Form Trigger').item.json['Email'] }}

Если в Send Message написать ={{ $json['Email'] }} — поле не найдётся, потому что у OpenAI в выходе нет Email. Это типичная ошибка студентов.

Почему короткая форма вообще существует

$json — это просто синоним для $input.item.json, то есть «текущий обрабатываемый элемент входа». А вход текущей ноды формируется из выхода предыдущей. Поэтому $json.поле и $('Предыдущая нода').item.json.поле всегда дают одно и то же значение — пока стрелка идёт напрямую.

$('Имя ноды') нужна там, где короткая форма не справится: между источником и текущей нодой есть промежуточные шаги, которые этого поля уже не передают (например, OpenAI вернул только текст ответа, и поле формы Email к моменту Send Message живёт только в выходе Form Trigger).

Типичные ошибки

  • Написал $json.Email в ноде после OpenAI. OpenAI возвращает output, а не Email. Решение — обратиться по имени: $('Form Trigger').item.json['Email'].
  • Имя ноды в $('...') не совпадает с подписью на canvas. В expression имя — буквально то, что написано под нодой на canvas. Переименовал ноду — все старые expressions, ссылавшиеся на её прежнее имя, сломаются.
  • Забыл .item после имени ноды. Полная форма — $('Имя').item.json.поле. Без .item обращаешься не к данным, а к самой ноде как объекту — поле не найдётся.
4.4
Проверь параметры ноды

Убедись, что параметры соответствуют таблице ниже.

Параметры Data table
ПараметрЗначение
ResourceRow
OperationGet
Data tableFrom list + m0-09-mood-diary
Condition 1 → Columnmessage
Condition 1 → ConditionContains (Case-Insensitive)
Condition 1 → Value{{ $('Telegram Trigger').item.json.message.text }}
4.5
Запусти Execute step

Зайди в ноду Data table и нажми кнопку Execute step в правом верхнем углу.

📖Кнопка «Execute step»: запуск одной ноды без всего воркфлоустатья · ~2 мин

Запустить одну ноду, не дёргая весь workflow

Execute step — это кнопка внутри панели ноды (открывается двойным кликом по ноде). По смыслу — младший брат большой кнопки Execute workflow внизу холста: та запускает весь воркфлоу с начала, эта — только текущую ноду. Удобно, когда настраиваешь параметры и хочешь сразу видеть, что отдаёт нода, не перезапуская всю цепочку.

Как это работает

Когда ты жмёшь Execute step, n8n берёт уже существующие данные на входе ноды (output предыдущей ноды из последнего прогона) и прогоняет через эту ноду. Сама нода выполняется реально: HTTP-запрос уходит, запись в базу пишется, письмо отправляется. Это не «сухой прогон», а полноценное выполнение — только одного шага.

  • key: Execute workflow

value: Запускает весь воркфлоу от триггера. Нужен полный прогон с самого начала. Каждый раз заново дёргает все API.

  • key: Execute step

value: Запускает только эту ноду. Берёт вход из последнего output предыдущей ноды. Идеально для подбора параметров и отладки.

  • key: Когда работает

value: Только если на входе ноды есть данные с прошлого прогона. Если ни разу не запускал предыдущие — кнопка либо ничего не вернёт, либо упадёт «No input data».

Типичный сценарий: запустил весь воркфлоу один раз (Execute workflow), увидел что нода HTTP Request отдаёт не то, поправил поле URL, нажал Execute step — увидел новый результат за секунду. Предыдущие ноды повторно не выполнялись.

У триггеров кнопка называется иначе
Смысл тот же — запустить один шаг и получить тестовое событие

У некоторых триггерных нод n8n кнопка Execute step подписана по-другому, потому что у триггера нет «входа» — он сам должен сходить за событием. Например, у RSS Trigger она называется Fetch Test Event: клик подтянет последние записи из ленты и положит их на выход ноды как тестовый input для остального воркфлоу. Работает идентично Execute step обычной ноды — точно так же используется для отладки и подбора параметров без полного прогона.

Важно про побочные эффекты
Каждый Execute step — это реальный вызов

Нода с записью в базу или отправкой сообщения каждое нажатие Execute step делает реально: 5 нажатий = 5 записей / 5 писем. Для отладки таких нод используй тестовые данные или подменяй credentials.

Типичные ошибки

  • Жать Execute step на ноде, у которой ещё не было входных данных → «No input data», нода не запустится. Сначала прогони весь воркфлоу через Execute workflow или хотя бы триггер вручную, чтобы у каждой ноды появился output.
  • Использовать Execute step для проверки изменений в предыдущих нодах → текущая нода работает со старым output, изменения не подхватятся. Если поправил предыдущую ноду — перезапусти её, а потом уже текущую.
  • Тестировать ноду с побочным эффектом (запись в БД, отправка письма) на проде → каждый клик создаёт реальную запись. Использовать тестовый credential или временно подменять параметры на безопасные.
Воркфлоу после шага 4: Telegram Trigger → Data table, оба с галочками
Воркфлоу после шага 4 — Data table добавлен и протестирован
5Отправь найденные записи обратно через Telegram

Третья нода — Telegram в режиме Send a text message. Она возьмёт текст каждой найденной строки и отправит его тебе в Telegram.

Если Data table вернул несколько строк — n8n автоматически выполнит эту ноду для каждой строки отдельно. Ты получишь по одному сообщению на каждую найденную запись — никакой специальный цикл настраивать не нужно.

5.1
Добавь ноду Telegram

Нажми на канвасе + справа от Data table. В правой панели поиска нод введи telegram → выбери action-ноду Telegram → в открывшемся подменю в разделе Actions выбери Send a text message. Нода автоматически подключится к Data table.

📖Типы нод в n8n: триггеры, действия и sub-нодыстатья · ~2 мин

Три типа нод в n8n

Любая нода в n8n относится к одному из трёх типов: триггер, действие или sub-нода. Разница — в том, как нода включается в воркфлоу и какую роль играет в его исполнении. Понимание этой таксономии экономит время при сборке: сразу видно, что куда подключать.

1. Триггер — стартовая нода воркфлоу

Триггер запускает воркфлоу. У него нет входа слева, только выход справа. В воркфлоу триггер всегда первый и обычно один (исключения — несколько триггеров под разные источники запуска).

Примеры: Manual Trigger (запуск кнопкой Execute), Schedule Trigger (по расписанию), Webhook (по HTTP-запросу извне), Execute Workflow Trigger (запуск из другого воркфлоу), Telegram Trigger (новое сообщение в боте).

Внешний скрин ждёт ручной съёмки
Нода Schedule Trigger на canvas — без входа слева, с выходом справа, выделена как первая в цепочке
Снимается через screenshots/_external/MANIFEST.yaml.

2. Действие — основная рабочая нода

Действие — нода, которая что-то делает с данными: запрашивает API, читает БД, трансформирует JSON, отправляет сообщение. У неё есть вход слева и выход справа. Действий в воркфлоу обычно много, они выстраиваются в цепочку после триггера.

Примеры: HTTP Request, Postgres, Set, Code, IF, Merge, Telegram (отправить сообщение), OpenAI (вызвать модель). Сюда же относятся AI-родители: AI Agent, Qdrant Vector Store, Embeddings-родительский режим — это действия, к которым подключаются sub-ноды снизу.

Внешний скрин ждёт ручной съёмки
Нода HTTP Request на canvas — с входом слева и выходом справа, между Schedule Trigger и Set
Снимается через screenshots/_external/MANIFEST.yaml.

3. Sub-нода — поставщик ресурса для родителя

Sub-нода не стоит в основной цепочке. Она подключается к специальному кружку на нижней стороне родительской ноды (обычно AI-родитель) и поставляет ему ресурс: модель, эмбеддинги, инструмент, память.

Примеры: Chat Model OpenAI для AI Agent, Embeddings Cohere для Qdrant Vector Store, Postgres Chat Memory для AI Agent, любая нода в режиме «as Tool».

Внешний скрин ждёт ручной съёмки
AI Agent с подключёнными снизу sub-нодами Chat Model и Memory — sub-ноды расположены под родителем, не в основной цепочке
Снимается через screenshots/_external/MANIFEST.yaml.

Детали про sub-ноды — в отдельной шпаргалке «Что такое sub-нода в n8n и как её заменить».

Подсказка
Как отличить визуально

Триггер — нет «розетки» слева. Sub-нода — выход не справа, а сверху (соединяется с кружком под родителем). Всё остальное с обычными разъёмами слева-справа — действие.

Подводный камень
Одна нода — несколько режимов

Некоторые сервисы есть и как действие, и как sub-нода: например, OpenAI — это действие (запрос к API), а Chat Model OpenAI — sub-нода для AI Agent. При поиске в каталоге нод их две, имена похожи — выбирай по тому, что тебе нужно: дёрнуть API или подключить к AI-родителю.

5.2
Проверь credential

Открой ноду двойным кликом. В поле Credential должен стоять тот же Telegram Bot credential, что и в триггере (n8n подцепит его автоматически).

5.3
Заполни поле Chat ID

В панели Input слева переключись на секцию Telegram Trigger. Раскрой message → chat → перетащи поле id в поле Chat ID.

В поле появится выражение {{ $('Telegram Trigger').item.json.message.chat.id }}.

Это числовой идентификатор чата, куда нужно отправить ответ. Он берётся из Telegram Trigger, а не из Data table — потому что Data table ничего не знает о том, кто отправил запрос.

🔀Telegram: куда отвечать — в chat.id или from.idстатья · ~2 мин

Telegram: куда отвечать — в chat.id или from.id

В объекте Message от Telegram Trigger приходят два разных идентификатора: message.chat.id и message.from.id. Они совпадают только в личных чатах, а в группах и каналах ведут себя по-разному. От правильного выбора зависит, получит ли бот ответ и сохранится ли контекст разговора.

chat.id — это идентификатор места, куда отправлено сообщение. from.id — идентификатор человека, который его написал. В поле Chat ID любой ноды отправки Telegram всегда подставляется chat.id. from.id используют для проверки прав, ведения логов и хранения сессий по пользователю.

В приватном чате значения совпадают. В группе или супергруппе chat.id один на всех, а from.id у каждого участника свой. В каналах поле from обычно пустое, вместо него приходит sender_chat.

Как это работает

  • message.chat.id — целевой чат для ответа. В группах и каналах отрицательный: у супергрупп и каналов — с префиксом -100, у обычной группы — просто со знаком минус.
  • message.from.id — отправитель. Положительное число, одинаковое для пользователя во всех чатах.
  • При отправке сообщения боту в группе chat.id указывает на группу, from.id — на конкретного участника.
  • Ключ памяти AI Agent (Session ID = Define below) выбирай по задаче: chat.id — одна история на весь чат (в группе — общая для всех участников), from.id — своя история у каждого человека, и в группе, и в личке. В личном чате оба ключа дают одно и то же.
  • Бот не может начать диалог первым: попытка отправить по from.id из группы выдаст Forbidden: bot can't initiate conversation with a user.
Правило одной строкой
В Chat ID — всегда chat.id

В поле Chat ID ноды отправки подставляй chat.id. from.id используй только для фильтров доступа, ключей в БД и sessionId по пользователю.

Типичные ошибки

  • В Chat ID ноды Send Message подставлен {{ $json.message.from.id }} → в личке работает, в группе бот молчит или падает с Forbidden: bot can't initiate conversation with a user → замени на chat.id.
  • Ключ памяти бота в группе — chat.id, а бот отвечает каждому участнику про его дела → история общая на всех, и бот приписывает одному человеку то, что рассказал другой → ключ памяти — from.id. Общий контекст группы (бот ведёт один разговор со всеми) — наоборот, chat.id.
  • В БД хранят chat.id как идентификатор пользователя → при повторном сообщении из группы пользователь не находится → используй from.id для идентификации человека, chat.id — только для адреса чата.
  • Сохраняют отрицательный chat.id группы как id пользователя → логика авторизации ломается, потому что у личных чатов минусов быть не может → разделяй: минус = группа/канал, плюс = пользователь.
5.4
Заполни поле Text

В панели Input слева переключись на секцию Data table.

Найди поле message и перетащи его в поле Text.

В поле появится выражение {{ $json.message }}.

Это текст найденной записи дневника. Выражение берёт значение из поля message, которое пришло из предыдущей ноды Data table, и передаёт его дальше в Text.

⚙Multi-item processing в n8n: одна нода — несколько прогоновстатья · ~3 мин

Multi-item processing в n8n: одна нода — несколько прогонов

Когда предыдущая нода вернула N items (например, 3 строки из Data table) — следующая нода автоматически выполнится N раз: по одному прогону на каждый item. Никакого цикла настраивать не нужно, это нативное поведение n8n.

Как это работает

В каждом прогоне $json содержит данные ровно одного item — текущей строки. Так выражение {{ $json.name }} автоматически подставляет правильное значение для каждой записи.

Пример
3 строки → 3 сообщения в Telegram

Data table вернул 3 записи: Иван, Мария, Сергей. Следующая нода Telegram Send Message без дополнительных настроек выполнится 3 раза и отправит 3 отдельных сообщения — по одному на каждого. Это поведение по умолчанию.

Как поменять поведение

Часто такое поведение не нужно. Если нода-отправитель должна послать одно сводное сообщение — N прогонов = N лишних сообщений. На этот случай в n8n есть три инструмента.

1. Execute Once — переключатель в Settings ноды. Включаешь его — нода прогоняется ровно один раз, n8n даёт ей только первый item, остальные игнорируются. Подходит для нод-отправителей: Telegram, Email, HTTP Request — когда нужно одно действие на весь массив. Подробнее — [[n8n-execute-once]].

2. Run Once for All Items — режим у Code-ноды (выбирается в верхнем переключателе). В этом режиме внутри Code доступен весь массив через items, и нода возвращает результат за один прогон.

3. Агрегация через Loop / Merge / SplitInBatches — отдельные ноды-цикла. Нужны когда логика сложнее «взять первый» или «всё одним куском»: пакетная обработка, объединение веток, custom-агрегация.

Как достать весь массив из выражения

Внутри выражения {{ ... }} любая нода может прочитать весь входной массив целиком — через $input.all(). Это массив items, по которому можно вызвать .length, .map(), .filter() и любые JS-методы массивов.

{{ $input.all().length }}                       // сколько items пришло
{{ $input.all().map(i => i.json.name).join(', ') }}   // имена через запятую

Особенность: $input.all() читает массив до того, как Execute Once срезает его до первого item. Поэтому если на ноде Telegram стоит Execute Once и на вход пришло 3 items — $input.all().length вернёт 3, а не 1. Это удобно для сводных сообщений вида «Получено заявок: 3».

Когда полезно знать

  • Если кейс «N сообщений вместо одного» — это не баг, это поведение по умолчанию. Решение — Execute Once или Run Once for All Items.
  • Если нужно посчитать число входных items в Set / Telegram / любой ноде — $input.all().length в выражении.
  • Если нужна последовательная обработка с большим массивом и контролем — SplitInBatches.
5.5
Выключи Append n8n Attribution

Прокрути вниз до раздела Additional Fields. Нажми Add Field → выбери Append n8n Attribution → выключи переключатель (должен быть серый).

Это уберёт автоматическую подпись «This message was sent automatically with n8n», которую n8n добавляет в конец каждого сообщения по умолчанию.

⚙Append n8n Attribution: подпись в конце автоматических сообщенийстатья · ~2 мин

Append n8n Attribution: подпись в конце автоматических сообщений

Параметр Append n8n Attribution находится в ноде Telegram. По умолчанию он добавляет в конец каждого отправленного сообщения строку «This message was sent automatically with n8n».

Параметр спрятан: он появляется только после раскрытия Additional Fields. Значение по умолчанию — On, поэтому подпись появляется автоматически, если ничего не менять.

Зачем это нужно

Когда сообщение уходит реальному пользователю, упоминание n8n выглядит как реклама сервиса. Для тестовых и внутренних рассылок подпись иногда полезна — она сразу показывает источник. Для клиентских сообщений её отключают.

Как это работает

Параметр — простой переключатель внутри Additional Fields.

  • On (включён) — в конец текста дописывается фраза «This message was sent automatically with n8n».
  • Off (выключен, серый) — фраза не добавляется.

Чтобы добраться до переключателя, открой Parameters → Additional Fields → Add Field → выбери Append n8n Attribution.

Коротко
Когда выключать

Выключай для всех сообщений, которые получат живые люди вне команды. Оставляй включённым только в тестовых и внутренних сценариях.

Типичные ошибки

  • Параметр не виден на основном экране → ищут его в Parameters → нужно раскрыть Additional Fields через Add Field.
  • Оставили On для реальных пользователей → получатели видят упоминание n8n → переключи в Off, чтобы переключатель стал серым.
  • Перепутали с Parse Mode → правят соседний пункт → Parse Mode отвечает за форматирование, а Append n8n Attribution — только за подпись.
  • Выключили, но не проверили → подпись осталась → убедись, что переключатель серый.
5.6
Проверь параметры ноды

Убедись, что параметры соответствуют таблице ниже.

Параметры Telegram
ПараметрЗначение
Credentialтот же Telegram Bot, что в шаге 2
ResourceMessage
OperationSend Message
Chat ID{{ $('Telegram Trigger').item.json.message.chat.id }}
Text{{ $json.message }}
Append n8n Attributionoff

Нода настроена. Теперь нужно её протестировать.

5.7
Запусти Execute step

Зайди в ноду Telegram и нажми кнопку Execute step в правом верхнем углу.

В Telegram-чате с ботом появится сообщение с текстом найденной записи дневника.

Готовый workflow: Telegram Trigger → Data table → Telegram, все ноды с галочками
Готовый workflow после шага 5 — три ноды в линейной цепочке

Все, воркфлоу собран. Можешь потестировать его, а потом выполнить Stretch (задачу со звездочкой)

🚀Stretch

Сейчас бот на каждую найденную запись шлёт отдельное сообщение. Если в дневнике пять записей по слову — придёт пять сообщений подряд, чат раздувается, а понять «много нашлось или мало» можно только пролистав весь поток.

Сделай так, чтобы все найденные записи приходили одним сводным сообщением — списком, где каждая запись на новой строке (через пустую строку или разделитель). Если ничего не найдено — пусть бот ведёт себя как сейчас и просто ничего не присылает.

Тест-кейсы

ВходОжидаем
Отправь боту слово, которое точно есть в одной записи дневникаБот отвечает одним сообщением с текстом этой записи
Отправь боту короткое слово, которое входит в несколько записей (например, «и»)Бот присылает несколько отдельных сообщений — по одному на каждую найденную запись
Отправь боту несуществующее слово (например, «абракадабра123»)Бот молчит — нет совпадений, workflow останавливается на пустом результате Data table
Отправь слово в другом регистре (например, «Настроение» вместо «настроение»)При условии Contains (Case-Insensitive) находит независимо от регистра; при обычном Contains — нет
Помощь
Застрял где-то по ходу? Покажи в учебном чате скрин ноды и текст ошибки — разберёмся.
Написать в чат
Собрал воркфлоу? Сдай на ревью
Это демо — задачу можно прочитать целиком. Свой n8n, сдача на ревью и разбор открываются в аккаунте. Заведи аккаунт — модуль M0 бесплатно.

Можно аналитические cookie?

Аналитические cookie ставим только с твоего согласия: они помогают понять, что работает. Откажешься — аналитика обойдётся без них. Подробности — в политике обработки персональных данных.