Одобрение и публикация

При подготовке курса черновик поста про новый сорт в кофейне «Зерно» пришёл в 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 } }];

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

Схема конца конвейера в n8n: Code «Черновик» → Telegram «Одобрение» с кнопками «Опубликовать» и «Отклонить» → If «Одобрено?». Ветка «да» раздваивается: в Telegram-канал (с фото или текстом) и HTTP Request «Во ВКонтакте», затем Data Table «Отметить в плане» со статусом published. Ветка «нет» ведёт в Data Table «Отклонено» со статусом rejected.

Канал в Telegram: бот как администратор

Публикует в канал ваш бот из трека 2 («Бот в Telegram»). Добавьте его в администраторы канала с правом публиковать сообщения. Без этого права Telegram его пост не примет.

Узлу нужен номер канала. Проще всего узнать его отдельным маленьким сценарием:

  1. Создайте сценарий с узлом Telegram Trigger (он срабатывает, когда боту что-то приходит). В поле Updates выберите channel_post, то есть сообщения в каналах.
  2. Запустите его на прослушивание и опубликуйте в канале любое сообщение.
  3. В пришедших данных найдите channel_post.chat.id. Это и есть номер канала, он начинается с -100.
  4. Сразу после этого выключите или удалите сценарий-узнавалку.
Не перебейте рабочего бота. Если бот из трека 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’. Что исправить?

АУвеличить Limit Wait Time до суток
БВыключить узел «Картинка»
ВСобирать текст черновика заранее в узле Code и передавать в «Одобрение» готовое поле
ГПоменять кнопки на «Да» и «Нет»

Подсказка: Ошибка возникает в выражении внутри сообщения. Откуда это выражение берёт данные?

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

Контрольный вопрос. Какое значение owner_id нужно указать в wall.post, чтобы пост вышел на стене сообщества с номером 123456?

А123456
Б-100123456
В-123456
ГНомер вашего личного чата

Подсказка: Вспомните, чем ВКонтакте отличает стену сообщества от стены человека.

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

Контрольный вопрос. Что нужно, чтобы бот публиковал посты в ваш Telegram-канал? Выберите все подходящие.

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

АКлюч сообщества ВКонтакте
ББот — администратор канала с правом публикации
ВНомер канала, который начинается с -100
ГПубличный, а не закрытый канал

Подсказка: Подумайте, что спрашивает 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.

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

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