При подготовке курса черновик поста про новый сорт в кофейне «Зерно» пришёл в Telegram с двумя кнопками. Я нажал «Опубликовать», и через несколько секунд пост появился в тестовом канале и на стене тестового сообщества ВКонтакте. Сам текст писали копирайтер и редактор, а решение «выпускать или нет» осталось за человеком. В этом уроке вы соберёте эту последнюю часть конвейера: одобрение, публикацию в два места и отметку в плане.
Чему научитесь в этом уроке:
• присылать себе черновик в Telegram с кнопками «Опубликовать» и «Отклонить»;
• узнать номер своего канала и сделать бота его администратором;
• публиковать пост на стене сообщества ВКонтакте ключом сообщества;
• отмечать тему в плане как опубликованную или отклонённую.
Подпись главреда на полосе
В газете готовую полосу перед печатью несут главному редактору. Он читает, ставит подпись или возвращает. Пока подписи нет, в типографию ничего не уходит. В конвейере роль полосы играет сообщение в Telegram, а роль подписи играет кнопка. Модели пишут быстро и без устали, но иногда ошибаются. Одно нажатие владельца стоит дешевле, чем удалять неудачный пост из двух соцсетей.
Черновик с кнопками
Кнопки делает узел Telegram в режиме Send and Wait for Response: он отправляет сообщение и останавливает сценарий, пока вы не нажмёте кнопку. Как он устроен, подробно разобрано в уроке трека 2 «Заявки». Здесь настройки такие:
- имя узла «Одобрение», Chat ID
<ваш номер>: номер вашего личного чата с ботом. Как его узнать, показано в уроке трека 2 «Бот в Telegram»; - Message:
{{ $json.msg }}, готовый текст черновика; - Response Type: Approval, тип кнопок Approve and Disapprove, подписи «Опубликовать» и «Отклонить»;
- Limit Wait Time: 2 часа, чтобы сценарий не висел вечно, если вы не ответили;
- Append n8n Attribution выключите, иначе внизу сообщения будет приписка n8n.
После него поставьте узел If с именем «Одобрено?» и условием {{ $json.data.approved }} is true. Ветка true ведёт к публикации, ветка false к отметке «отклонено».
Собирайте текст черновика заранее. На прогоне в сообщение для одобрения сначала вписали выражение, которое брало ссылку прямо из узла «Картинка». Когда картинка не сгенерировалась, узел «Одобрение» упал с ошибкойreading 'trim', и черновик вообще не пришёл. Поэтому перед одобрением стоит отдельный узел Code «Черновик». Он собирает текст, ссылку на картинку и пометку, есть ли картинка, а «Одобрение» берёт только готовоеmsg.
// Собираем текст черновика; картинка необязательна
const ed = $('Итог редактора').first().json;
const t = $('Следующая тема').first().json;
const img = $('Картинка').first().json;
const url = img && img.data && img.data[0] ? img.data[0].url : '';
const issues = (ed.issues || []).join('; ') || 'замечаний нет';
const msg = 'Черновик поста (' + t.date + ', ' + t.rubric + '):\n\n' + ed.text + '\n\nРедактор: ' + issues + '\nКартинка: ' + (url || 'не получена, пост уйдёт без фото');
return [{ json: { msg, url, hasImage: !!url } }];
В черновике вы видите не только пост, но и что исправил редактор, и есть ли картинка. Этого хватает, чтобы решить за полминуты.

Канал в Telegram: бот как администратор
Публикует в канал ваш бот из трека 2 («Бот в Telegram»). Добавьте его в администраторы канала с правом публиковать сообщения. Без этого права Telegram его пост не примет.
Узлу нужен номер канала. Проще всего узнать его отдельным маленьким сценарием:
- Создайте сценарий с узлом Telegram Trigger (он срабатывает, когда боту что-то приходит). В поле Updates выберите
channel_post, то есть сообщения в каналах. - Запустите его на прослушивание и опубликуйте в канале любое сообщение.
- В пришедших данных найдите
channel_post.chat.id. Это и есть номер канала, он начинается с -100. - Сразу после этого выключите или удалите сценарий-узнавалку.
Не перебейте рабочего бота. Если бот из трека 2 уже отвечает в другом включённом сценарии с Telegram Trigger, новый триггер на того же бота может перехватить его сообщения, и рабочий бот замолчит. В прогоне курса этот случай не проверяли. Поэтому сценарий-узнавалку держите включённым только на минуту, пока не получите номер канала.
Дальше в конвейере за веткой true стоит If «Есть картинка?» с условием {{ $('Черновик').first().json.hasImage }} is true. Если картинка есть, работает узел Telegram Send Photo с именем «В Telegram-канал с фото»: Chat ID = номер канала, Photo = {{ $('Черновик').first().json.url }}, Caption (подпись) = выражение ниже. Если картинки нет, узел Send Message «В Telegram-канал текстом» отправляет только текст: Chat ID тот же, в Text то же выражение.
{{ $('Итог редактора').first().json.text + '\n\n(тестовый пост курса, кофейня выдуманная)' }}
Выражение берёт итоговый текст редактора и дописывает к нему пометку тестового поста. Брать текст из $json здесь нельзя: после узлов «Одобрение» и «Есть картинка?» в нём уже ответ на нажатие кнопки, а не пост. Когда перейдёте на рабочие канал и сообщество, уберите пометку из выражения во всех трёх местах: подпись, текст и сообщение для ВКонтакте.
ВКонтакте: пост от имени сообщества
У ВКонтакте нет готового узла публикации в n8n, поэтому пост отправляет узел HTTP Request, то есть обычный запрос по адресу. Чтобы ВКонтакте пустил запрос на стену, нужен ключ сообщества, что-то вроде пропуска от вашей группы. Получите его сами: в настройках сообщества раздел «Управление» → «Работа с API», создайте ключ. На прогоне у ключа были права «стена» и «фотографии».
Ключ сохраните в учётных данных n8n: тип Query Auth (ключ передаётся прямо в адресе запроса), имя параметра access_token, значение ключ. Узел «Во ВКонтакте» настройте так:
- метод POST, адрес
https://api.vk.com/method/wall.post; - Authentication: учётные данные Query Auth с ключом;
- параметры запроса:
owner_id= минус номер сообщества (например,-<номер сообщества>),from_group= 1,message= то же выражение с текстом и пометкой, что для Telegram,v= 5.199.
Минус перед номером говорит ВКонтакте, что стена принадлежит сообществу, а не человеку. from_group=1 подписывает пост названием сообщества. Заранее не было известно, хватит ли ключа сообщества для публикации на стене. Прогон показал, что хватает: пост вышел, и подписан он названием сообщества. Если запрос прошёл, в ответе будет response.post_id, номер нового поста.
Картинку в этой версии во ВКонтакте не отправляем, туда уходит только текст. Загрузку фото на стену в прогоне курса не проверяли.
Отметка в плане
После публикации в Telegram стоит Data Table «Отметить в плане»: Operation Update, таблица плана, в Conditions колонка id, условие equals, значение {{ $('Итог редактора').first().json.rowId }}. В полях для записи: status = published, post = {{ $('Итог редактора').first().json.text }}. В ветке false Data Table «Отклонено» настроен так же, только записывает status = rejected. Так таблица из урока 3.2 показывает, что вышло, что вы отклонили и что ещё ждёт очереди.
Что получилось на прогоне
Тестовых публикаций было две. Первую одобрили, пост вышел в канал и в сообщество, ВКонтакте вернул post_id 83. Во второй картинка не пришла, поэтому в канал пост ушёл текстом без фото, во ВКонтакте вышел с post_id 84, а строка плана получила статус published.
Правило безопасности. Первые запуски делайте в тестовый закрытый канал и тестовое сообщество, не в рабочие. К тексту дописывайте пометку «тестовый пост»; на прогоне это была строка «(тестовый пост курса, кофейня выдуманная)». Ключ сообщества и токен бота храните только в учётных данных n8n, не в тексте узлов и не в переписке. Опубликованное увидят подписчики, отменить это кнопкой нельзя.
Если не получилось
- Узел «Одобрение» падает с ошибкой reading ‘trim’. В поле Message стоит выражение, которое обращается к узлу, упавшему раньше. Соберите текст в Code «Черновик» и передавайте в «Одобрение» только
{{ $json.msg }}. - Черновик не приходит. Проверьте Chat ID: это номер вашего личного чата с ботом, и вы должны были хотя бы раз написать боту первым. Как узнать номер, показано в уроке трека 2 «Бот в Telegram».
- Бот не публикует в канал. Проверьте, что бот администратор канала с правом публикации и что номер канала начинается с -100.
- Рабочий бот трека 2 перестал отвечать. Скорее всего, включён сценарий-узнавалка с Telegram Trigger. Выключите или удалите его.
- Сценарий остановился, а вы не ответили. Истекли 2 часа ожидания. Пост не вышел, но и тема не вернётся в очередь сама: найдите её в таблице плана (статус rejected или in_progress, в прогоне курса этот случай не проверяли), поставьте status = new и запустите сценарий снова.
- ВКонтакте вернул ошибку вместо post_id. Сверьте минус перед номером сообщества, параметр
from_group=1и права ключа: нужна «стена».
Контрольный вопрос. Картинка не сгенерировалась, и узел «Одобрение» упал с ошибкой reading ‘trim’. Что исправить?
Подсказка: Ошибка возникает в выражении внутри сообщения. Откуда это выражение берёт данные?
На курсе задания проверяются автоматически. Подобрать курс
Контрольный вопрос. Какое значение owner_id нужно указать в wall.post, чтобы пост вышел на стене сообщества с номером 123456?
Подсказка: Вспомните, чем ВКонтакте отличает стену сообщества от стены человека.
На курсе задания проверяются автоматически. Подобрать курс
Контрольный вопрос. Что нужно, чтобы бот публиковал посты в ваш Telegram-канал? Выберите все подходящие.
Выберите все верные варианты.
Подсказка: Подумайте, что спрашивает Telegram, когда в канал пишет не человек, а бот.
На курсе задания проверяются автоматически. Подобрать курс
Задание. МИССИЯ «Подпись главреда». Допишите к своему конвейеру одобрение и публикацию: Code «Черновик», Telegram «Одобрение» с кнопками «Опубликовать» и «Отклонить», развилку If «Есть картинка?» на отправку с фото и текстом, публикацию в тестовый закрытый Telegram-канал и тестовое сообщество ВКонтакте, отметку в плане. Сделайте два запуска: один одобрите, другой отклоните. Приложите: (1) снимок схемы сценария; (2) снимок черновика с кнопками; (3) снимки опубликованного поста в канале и в сообществе; (4) post_id из ответа ВКонтакте; (5) снимок таблицы плана со статусами published и rejected. Принято, если: черновик пришёл с двумя кнопками и Limit Wait Time задан; публикация шла в тестовые канал и сообщество, в тексте есть пометка «тестовый пост»; пост во ВКонтакте вышел от имени сообщества и текстом; развилка «Есть картинка?» стоит перед отправкой в канал; сценарий-узнавалка номера канала выключен; одобренная тема отмечена published, отклонённая rejected; на снимках не видно ключа сообщества, токена бота и номера вашего личного чата.
Подсказка: Начните с отдельного сценария, который узнаёт номер канала, и одного ручного запуска с готовым текстом. Подключать черновик из конвейера удобнее, когда публикация уже работает.
✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.
На курсе задания проверяются автоматически. Подобрать курс
Что дальше
Теперь пост проходит путь от темы в плане до канала и сообщества, а вы нажимаете одну кнопку. В следующем уроке проверим конвейер на прочность: прогоним через него 10 тестовых тем и посмотрим, где модель сбивается с тона или выдумывает.
Итог:
• черновик приходит в Telegram с кнопками, ожидание ограничено 2 часами;
• текст черновика собирается заранее в Code, иначе упавшая картинка роняет одобрение;
• в канал публикует бот-администратор по номеру, который начинается с -100;
• во ВКонтакте пост уходит через wall.post с ключом сообщества и выходит от имени сообщества;
• таблица плана получает статус published или rejected.
