Как настроить автоматическую генерацию и публикацию статей на WordPres

REST API в WordPress появился как дополнение для разработчиков мобильных приложений. Никто не планировал, что через несколько лет он станет входной точкой для автоматической публикации тысяч статей. Сам WordPress об этом до сих пор не знает. В документации раздел про REST API спрятан так глубоко, что подавляющее число администраторов сайтов даже не подозревают о его существовании.

WordPress принимает статьи по HTTP. Отправляете запрос с заголовком, текстом и рубрикой, и запись появляется на сайте без единого клика в админ-панели. Языковая модель генерирует текст по промпту. Между этими двумя возможностями лежит зазор, и почти все руководства его пропускают, заканчиваясь на словах «отправьте результат в API». Здесь я закрою этот зазор целиком. От установки Docker до момента, когда n8n по расписанию берёт тему из таблицы и публикует готовую статью с изображением и мета-описанием.

Всё описанное ниже работает бесплатно. Платить нужно только за VPS для круглосуточной работы и за API языковой модели, если выберете облачный вариант вместо локального. Но даже облачные варианты стоят копейки по сравнению с ручным написанием или заказом у копирайтеров.

Какие LLM API доступны без иностранной карты

Первый вопрос, на который стоит ответить до любой настройки. Нет смысла собирать pipeline, если на последнем шаге окажется, что вы не можете оплатить генерацию текста.

Ollama на своём сервере — без лимитов и без ключей

Ollama запускает языковые модели локально. Никаких API-ключей, никаких лимитов на количество запросов, никакой зависимости от внешних сервисов. Устанавливается одной командой, работает через HTTP на порту 11434. Вы отправляете промпт на localhost:11434/api/generate и получаете текст.

Статьи на русском хорошо генерируют Llama 3 8B, Mistral 7B, DeepSeek R1 distilled. Моделям на 7-8 миллиардов параметров хватит 8 ГБ оперативной памяти. Покрупнее, на 13-14 миллиардов, потребуют 16 ГБ и желательно видеокарту с VRAM.

Когда n8n крутится на том же сервере, что и Ollama, запросы идут по localhost, и задержки минимальны. Генерация одной статьи на 7B-модели занимает от тридцати секунд до пары минут в зависимости от длины и железа.

Ограничение одно. Ваш VPS должен потянуть и n8n, и модель одновременно. Минимальный VPS за 300-500 рублей в месяц с 2 ГБ RAM не подойдёт. Нужен сервер с 8+ ГБ, а такие стоят от 1500 рублей. Можно запустить Ollama на домашнем компьютере и пробросить порт, но тогда компьютер должен работать в момент срабатывания расписания.

YandexGPT и GigaChat оплата в рублях

Оба сервиса принимают рублёвые карты без ограничений. YandexGPT доступна через Yandex Cloud. Регистрация, привязка карты, создание сервисного аккаунта с IAM-токеном. Есть стартовый грант для новых аккаунтов, которого хватит на несколько сотен статей. После гранта тарификация в юнитах. YandexGPT Lite дешевле и быстрее, полная модель генерирует качественнее, но медленнее. Для конвейера статей Lite обычно достаточно.

GigaChat от Сбера работает по похожей схеме. Бесплатный тариф для физических лиц даёт ограниченное количество запросов в сутки, но для десяти-двадцати статей в день этого хватает. API совместим с форматом OpenAI, что упрощает настройку в n8n. Качество русского текста у обоих сервисов заметно выше, чем у англоязычных моделей, переведённых на русский. Они обучались на русскоязычных корпусах и лучше чувствуют грамматику, стилистику и контекст.

DeepSeek и Gemini API — дешёвые, но с ограничениями

DeepSeek предлагает самые низкие цены за токен среди всех облачных API. Генерация статьи на три тысячи слов обойдётся в доли цента. Регистрация работает без VPN, сам API доступен напрямую. С оплатой сложнее, потому что принимает только зарубежные карты. Обход через криптовалютные посредники или виртуальные карты возможен, но добавляет сложность.

Google Gemini API имеет бесплатный тариф с лимитом в пятнадцать запросов в минуту и от ста до тысячи запросов в день в зависимости от модели. Для компактного конвейера хватает. Но доступность сервиса нестабильна, лимиты периодически урезаются, и рассчитывать на него как на единственный источник я бы не стал. В конце 2025 года бесплатный тариф ощутимо ограничили, и многие конвейеры, построенные на Gemini, перестали работать за одну ночь.

Мой выбор для старта. Ollama, если сервер позволяет, или GigaChat бесплатный тариф, если нужна облачная модель без затрат. После обкатки pipeline переход на YandexGPT или DeepSeek даст лучшее качество.

Как установить n8n через Docker на VPS

n8n работает как визуальный автоматизатор с открытым кодом. У него есть облачная версия n8n.cloud, но она требует иностранную карту и ограничивает количество выполнений. Self-hosted версия через Docker бесплатна, без лимитов, и вы полностью контролируете данные.

Docker и Docker Compose на Ubuntu — минимальный набор команд

Подключитесь к VPS по SSH. Если Docker ещё не установлен:

sudo apt update && sudo apt install -y docker.io docker-compose-plugin

sudo systemctl enable docker && sudo systemctl start docker

Проверьте, что Docker работает:

docker —version

docker compose version

Если вместо docker compose работает docker-compose через дефис, у вас старая версия. Для n8n подойдёт любая, но синтаксис команд будет немного отличаться.

docker-compose.yml для n8n с постоянным хранилищем

Создайте директорию и файл конфигурации:

mkdir -p ~/n8n-docker && cd ~/n8n-docker

nano docker-compose.yml

Содержимое файла:

yaml

version: ‘3.8’

services:

 n8n:

  image: n8nio/n8n

  restart: always

  ports:

   — «5678:5678»

  environment:

   — N8N_BASIC_AUTH_ACTIVE=true

   — N8N_BASIC_AUTH_USER=admin

   — N8N_BASIC_AUTH_PASSWORD=ваш_надёжный_пароль

   — N8N_HOST=ваш_домен_или_ip

   — N8N_PROTOCOL=https

   — GENERIC_TIMEZONE=Europe/Moscow

  volumes:

   — n8n_data:/home/node/.n8n

volumes:

 n8n_data:

Переменная N8N_BASIC_AUTH защищает интерфейс паролем. Без неё любой, кто знает IP вашего сервера, получит полный доступ к вашим workflow и credentials. GENERIC_TIMEZONE влияет на работу Schedule Trigger. Если не выставить московское время, расписание будет срабатывать по UTC.

Первый запуск и настройка доступа к интерфейсу

docker compose up -d

Через несколько секунд n8n станет доступен по адресу http://ваш_ip:5678. С Nginx или Caddy в роли обратного прокси можно повесить SSL и работать по https. Caddy проще всего, потому что получает сертификат автоматически. В Caddyfile достаточно двух строк:

n8n.ваш-домен.ru {

  reverse_proxy localhost:5678

}

После запуска Caddy сам получит сертификат Let’s Encrypt. В docker-compose.yml замените N8N_PROTOCOL на https и укажите домен в N8N_HOST.

При первом входе n8n попросит создать аккаунт владельца. После регистрации вы попадаете в редактор workflow. Пустой холст, на который будем добавлять ноды.

Как связать WordPress и Google Sheets с n8n

Пароль приложения WordPress и credentials в n8n

WordPress REST API требует аутентификации для записи. Проще всего использовать пароль приложения (Application Password). Зайдите в админ-панель WordPress, откройте Users → Profile, внизу найдите секцию «Application Passwords». Введите название (например, «n8n automation») и нажмите «Add New Application Password». WordPress покажет пароль один раз, скопируйте его сразу.

В n8n откройте Settings → Credentials → Add Credential → WordPress. Введите URL сайта (https://ваш-сайт.ru), логин администратора и пароль приложения. Не обычный пароль от админки, а именно тот, который только что сгенерировали. Нажмите Save и Test, чтобы n8n проверил подключение.

Тест провалился? Проверьте две вещи. Во-первых, REST API может быть отключен плагином безопасности. Wordfence и подобные инструменты иногда блокируют доступ к /wp-json/. В настройках файрвола ищите пункт «Disable REST API» и убедитесь, что он выключен. Во-вторых, .htaccess на некоторых shared-хостингах обрезает заголовок Authorization, без которого аутентификация не работает. Добавьте в .htaccess строку RewriteRule .* — [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] перед правилами WordPress.

Сервисный аккаунт Google и структура таблицы с темами

Google Sheets подключается к n8n через сервисный аккаунт Google Cloud. Нужно создать проект в Google Cloud Console, включить Google Sheets API, создать сервисный аккаунт, скачать JSON-ключ. Затем расшарить нужную таблицу на email сервисного аккаунта (он выглядит как name@project.iam.gserviceaccount.com).

В n8n добавьте credential типа Google Sheets API и загрузите JSON-ключ.

Структура таблицы минимальна. Четыре столбца, каждый со своей функцией. topic (тема статьи), keywords (ключевые слова для промпта), status (пусто / published / error), published_url (ссылка на опубликованную запись). n8n будет читать первую строку со статусом «пусто», обрабатывать и менять статус на published после успешной публикации.

Как написать промпт, который даёт разные тексты каждый раз

Промпт определяет разницу между «работающим конвейером» и «генератором мусора». Техническая настройка n8n занимает час. Написание хорошего промпта может занять дни.

Почему стандартный промпт генерирует одинаковые статьи

Типичный промпт из руководств выглядит так. «Напиши статью на тему {topic}. Статья должна быть информативной и полезной». Результат предсказуем. Вступление с общими словами, три раздела с подзаголовками, заключение с призывом. Каждый текст будет структурно идентичен предыдущему.

Языковая модель по умолчанию генерирует наиболее вероятное продолжение. Без дополнительных инструкций вероятное продолжение всегда одинаковое. Модель не «ленится» и не «упрощает». Она делает ровно то, что просили, и генерирует среднестатистический текст.

Переменные, рандомизация стиля и контроль структуры

Разнообразие закладывается на нескольких уровнях. Кроме темы, передавайте через таблицу ключевые слова, желаемый тон (разговорный / аналитический / инструкция), целевую длину, количество разделов. Чем точнее входные данные, тем меньше модель додумывает сама.

Рандомизация внутри промпта работает ещё лучше. Добавьте в таблицу столбец style с вариантами «подробный с примерами», «краткий и практичный», «аналитический с цифрами», «разговорный с личным опытом». n8n будет подставлять разные стили для разных тем. Пять вариантов стиля на двадцать тем дают сто комбинаций, и ни одна пара статей не будет структурно идентичной. Параметр temperature в запросе к модели тоже влияет на разнообразие. Значение 0.7 даёт предсказуемый, но ровный текст. Значение 1.0-1.2 добавляет случайности в выбор слов и конструкций. Я держу temperature на 0.9 как компромисс между читаемостью и разнообразием.

Отдельно стоит контроль формата ответа. Модель должна вернуть не просто текст, а размеченный ответ с заголовком, мета-описанием, slug (URL-частью) и телом статьи. Без разметки парсинг превращается в гадание.

Шаблон промпта с подстановкой данных из таблицы

Рабочий промпт:

Ты автор технических статей. Напиши статью на тему: {{ $json.topic }}

Ключевые слова для использования: {{ $json.keywords }}

Стиль: {{ $json.style }}

Длина: 1500-2500 слов

Верни ответ строго в таком формате:

===TITLE===

Заголовок статьи

===SLUG===

url-chast-na-latinice

===META===

Мета-описание до 160 символов

===BODY===

Полный текст статьи в HTML с подзаголовками <h2> и <h3>

Требования к тексту:

— Подзаголовки должны быть сформулированы как поисковые запросы

— Избегай списков из трёх пунктов, используй другое количество

— Чередуй длинные и короткие абзацы

— Не начинай статью со слов «В современном мире» или аналогичных клише

— Каждый абзац должен содержать конкретную информацию, а не общие слова

Двойные фигурные скобки представляют синтаксис n8n для подстановки данных из предыдущего нода. {{ $json.topic }} вытянет значение из столбца topic текущей строки Google Sheets. Вот как выглядит сырой ответ модели, если промпт сработал правильно:

===TITLE===

Как настроить кэширование в Nginx для WordPress

===SLUG===

kak-nastroit-keshirovanie-nginx-wordpress

===META===

Пошаговая настройка FastCGI-кэша в Nginx для WordPress. Конфигурация, очистка кэша и исключения для админ-панели.

===BODY===

<h2>Зачем кэшировать WordPress через Nginx</h2>

<p>WordPress генерирует каждую страницу заново при каждом запросе. На сайте с десятью посетителями в час разницы нет. На сайте с тысячей…</p>

<h2>Как включить FastCGI-кэш в конфигурации Nginx</h2>

<p>Откройте конфигурационный файл…</p>

Парсер из Code node разрежет этот ответ по маркерам ===TITLE===, ===SLUG=== и так далее. Каждая часть попадёт в отдельное поле JSON и пойдёт дальше по цепочке нодов. Если модель забудет один из маркеров или переставит их местами, regex вернёт пустую строку, и IF node остановит публикацию.

На практике модели забывают маркеры примерно в одном случае из двадцати. Чаще проблема в другом: модель добавляет текст до первого маркера (вступительную фразу вроде «Конечно, вот ваша статья»). Regex из примера выше справляется с этим, потому что ищет содержимое между маркерами, а не от начала строки.

Вот как выглядит сырой ответ модели, когда промпт сработал правильно:

===TITLE===

Как настроить резервное копирование WordPress на свой сервер

===SLUG===

rezervnoe-kopirovanie-wordpress-na-server

===META===

Пошаговая настройка автоматических бэкапов WordPress с помощью плагинов и cron без платных сервисов

===BODY===

<h2>Зачем делать бэкапы на свой сервер, а не в облако</h2>

<p>Облачные сервисы резервного копирования удобны ровно до момента,

когда они меняют тарифы или закрываются…</p>

<h2>Какой плагин выбрать для серверных бэкапов</h2>

<p>UpdraftPlus в бесплатной версии умеет отправлять копии

по FTP и SFTP на любой внешний сервер…</p>

Парсер в Code node разберёт этот текст по разделителям и передаст каждое поле в следующий нод. Если модель вернёт что-то без разделителей или переставит их местами, парсинг вернёт пустые строки, и IF node отловит сбой.

Когда модель игнорирует формат (а с дешёвыми моделями бывает регулярно), помогает добавить в промпт строку «Ответ должен начинаться с ===TITLE=== без какого-либо текста до него». Небольшие модели вроде Mistral 7B иногда добавляют приветствие или пояснение перед разметкой, и эта инструкция убирает проблему.

Как собрать весь workflow в n8n по шагам

Откройте редактор workflow в n8n и начинайте добавлять ноды слева направо.

От Schedule Trigger до получения темы из таблицы

Первый нод в цепочке, Schedule Trigger, задаёт, когда workflow запускается. Настройте на нужный интервал, будь то раз в час, раз в день или раз в неделю. Для тестирования поставьте «Every 5 minutes», после отладки переключите на рабочее расписание.

Второй нод, Google Sheets (Read Rows). Укажите spreadsheet ID и лист. В фильтре задайте условие, где столбец status равен пустой строке. Нод вернёт все непубликованные темы. Чтобы обрабатывать по одной за запуск, добавьте после него нод Limit с параметром 1. Так workflow за одно срабатывание опубликует одну статью, а следующую возьмёт при следующем запуске.

Запрос к LLM и парсинг ответа в Code node

Третий нод, HTTP Request. Для Ollama задайте метод POST, URL http://localhost:11434/api/generate, тело JSON:

{

 «model»: «llama3»,

 «prompt»: «ваш промпт с подстановками»,

 «stream»: false

}

YandexGPT и GigaChat настраиваются иначе. Отличаются URL, заголовки авторизации и формат тела, но принцип тот же. POST-запрос с промптом, разница только в деталях.

Четвёртый нод, Code. Здесь происходит парсинг ответа модели. LLM вернёт текст с разделителями ===TITLE===, ===SLUG=== и так далее. JavaScript-код в Code node разбирает ответ на части:

const text = $input.first().json.response;

const getSection = (name) => {

 const regex = new RegExp(`===${name}===\s*([\s\S]*?)(?====|$)`);

 const match = text.match(regex);

 return match ? match[1].trim() : »;

};

return [{

 json: {

  title: getSection(‘TITLE’),

  slug: getSection(‘SLUG’),

  meta: getSection(‘META’),

  body: getSection(‘BODY’),

  row_number: $input.first().json.row_number

 }

}];

Если модель отклонится от формата (а она будет отклоняться), парсинг вернёт пустые значения. Добавьте после Code node проверку через IF node с условием «title is not empty». Если пусто, записать error в статус и перейти к следующей теме.

Загрузка изображения и создание записи через REST API

Об этом шаге забывают почти все руководства по автоматизации WordPress. Запись без изображения выглядит неполноценно и в админке, и в поисковой выдаче. Загрузка изображения требует HTTP Request с методом POST на https://ваш-сайт.ru/wp-json/wp/v2/media. Заголовок Content-Disposition: attachment; filename=»image.jpg», тело содержит бинарные данные изображения. В ответ WordPress вернёт JSON с полем id. Запомните его, вам понадобится media_id.

Откуда брать изображения, отдельный вопрос. Можно заранее загрузить набор картинок и хранить URL в таблице, использовать API фотостоков (Unsplash, Pexels) или генерировать через AI-сервис. Для старта проще всего добавить столбец image_url в таблицу с прямыми ссылками на подходящие изображения. Unsplash API бесплатен до пятидесяти запросов в час и возвращает прямую ссылку на файл, которую n8n может скачать через HTTP Request и передать в WordPress. Для старта проще всего добавить столбец image_url в таблицу с прямыми ссылками на подходящие изображения.

Следующий нод, WordPress (Create Post) или HTTP Request на /wp-json/wp/v2/posts. Параметры:

{

 «title»: «{{ $json.title }}»,

 «content»: «{{ $json.body }}»,

 «status»: «draft»,

 «slug»: «{{ $json.slug }}»,

 «featured_media»: media_id,

 «categories»: [id_рубрики]

}

Я ставлю status: draft, а не publish. Автопубликация без проверки ведёт к проблемам, о которых расскажу ниже.

ID рубрики можно узнать через GET-запрос к /wp-json/wp/v2/categories или просто посмотреть в админке WordPress. Откройте рубрику, и в URL страницы редактирования будет tag_ID=число.

Обновление статуса в таблице после публикации

Последний нод, Google Sheets (Update Row). Обновите столбец status на «published» и запишите URL созданной записи в столбец published_url. Номер строки у вас уже есть, он передаётся через всю цепочку с первого нода чтения.

Ошибки на любом этапе перехватывает Error Trigger нод в n8n. Он записывает «error» в статус, чтобы workflow не застрял на одной и той же теме в бесконечном цикле.

Почему автопубликация без проверки портит сайт

Конвейер работает. Темы уходят из таблицы, черновики появляются в WordPress. Возникает соблазн переключить status с draft на publish и забыть. Я настоятельно рекомендую этого не делать.

Публикация в черновики и ручная проверка перед выпуском

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

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

Признаки AI-текстов, которые замечают поисковые системы

Поисковые алгоритмы не ищут AI-тексты напрямую. Они фиксируют паттерны, характерные для автоматической генерации. Однородная длина абзацев, повторяющаяся структура (тезис, пояснение, вывод в каждом блоке), отсутствие авторской позиции, избыточное использование переходных фраз вроде «стоит отметить» и «в заключение».

Сайт, на котором все статьи написаны одной моделью с одним промптом, выглядит для поискового робота как ферма контента. Даже если каждая отдельная статья нормального качества, совокупность создаёт сигнал однотипности.

Ротация промптов и разнообразие как защита от фильтров

Добавьте в таблицу несколько вариантов промптов и переключайтесь между ними. Меняйте не только стиль, но и структурные инструкции. Один промпт просит начать с примера, другой с вопроса, третий с факта. Меняйте указание на длину и количество подзаголовков.

Чередование LLM-провайдеров тоже помогает. Тексты от YandexGPT и от Ollama с Mistral будут отличаться по стилистике даже при идентичном промпте. Разнообразие на уровне модели работает лучше, чем разнообразие на уровне инструкций.

Но самый действенный приём другой. Добавляйте в каждую статью хотя бы два-три абзаца, написанные вручную. Личное наблюдение, нестандартный пример, комментарий к спорному утверждению. Поисковые системы ценят уникальный авторский вклад, и его невозможно сымитировать промптом.

Что ломается после первой недели работы

Первый запуск проходит гладко. Проблемы начинаются при длительной работе, и они всегда одни и те же. Токены и ключи API истекают. IAM-токен Yandex Cloud живёт двенадцать часов. Workflow, который срабатывает раз в сутки, будет проваливаться через раз. Проще всего создать отдельный workflow, который обновляет токен по расписанию и сохраняет его в n8n static data. Или использовать API-ключ вместо IAM-токена, где провайдер позволяет.

Google Sheets имеет лимит на количество запросов API. Конвейер из десяти-двадцати статей в день в квоту не упрётся, но при масштабировании до сотен таблица станет узким местом. На этом этапе стоит перенести данные в PostgreSQL или SQLite на том же сервере. Docker-контейнер n8n тоже может упасть после обновления системы или при нехватке дискового пространства. Добавьте в cron проверку через docker inspect -f ‘{{.State.Running}}’ n8n-docker-n8n-1, которая вернёт true или false, и по результату можно автоматически перезапускать контейнер.

Ollama при обновлении моделей иногда меняет формат ответа или поведение генерации. После каждого обновления прогоните тестовый запрос и проверьте, что парсинг в Code node всё ещё работает. Таблица Google Sheets тоже растёт незаметно. Через пару месяцев в ней тысячи строк, нод чтения замедляется. Переносите обработанные строки в отдельный лист-архив.

[√] VPS с Docker и n8n запущен

[√] WordPress подключён через пароль приложения

[√] Google Sheets связана через сервисный аккаунт

[√] LLM API настроен (Ollama / YandexGPT / GigaChat)

[√] Промпт с переменными написан и протестирован

[√] Workflow собран: Trigger → Sheets → LLM → Parse → Upload Image → Create Post → Update Status

[√] Error handling добавлен: IF-проверка и Error Trigger

[ ] Публикация переключена с draft на publish (только после ручной проверки первых десяти статей)

[ ] Ротация промптов и стилей настроена

[ ] Мониторинг работы контейнера добавлен в cron

[ ] Архивирование обработанных строк из таблицы

#программирование #разработка #IT #технологии #софт #лайфхаки #полезное

Оставьте комментарий