Когда нужен этот сценарий
Этот сценарий подходит, когда вы не хотите писать webhook-обработчик вручную, а хотите поручить задачу Claude, Codex, Cursor Agent, Lovable или другому AI, который уже работает в кодовой базе.
В интерфейсе SeoSmith этот путь соответствует карточке «Вайбкод» в разделе интеграций, но по сути это сценарий подключения через AI-ассистента.
В обычном webhook-гайде разработчик сам пишет endpoint. Здесь ваша задача другая: правильно поставить задачу AI и проверить, что он не упростил безопасность и не встроил интеграцию в неправильное место проекта.
Какой минимальный контракт нужно сообщить AI
Безопасно раскрывать ИИ только эти части интеграции:
- путь endpoint:
/api/seosmith; - метод:
POST; - заголовок подписи:
X-SeoSmith-Signature: sha256=<hmac-hex>; - тип подписи: HMAC-SHA256 от raw body;
- секрет хранится в
SEOSMITH_WEBHOOK_SECRET; - payload содержит
event,articleиcompany.
Этого достаточно, чтобы AI корректно собрал endpoint в проекте клиента.
Готовый prompt для Claude/Codex
Ниже prompt, который можно дать Claude, Codex, Cursor Agent, Lovable или другому AI, работающему прямо в кодовой базе:
В моём проекте нужен серверный endpoint для приёма webhook-запросов от сервиса SeoSmith.
Добавь POST-роут по пути /api/seosmith, используя текущий стек, роутинг, ORM и паттерны проекта. Не создавай новый отдельный микросервис, если в проекте уже есть backend или server routes.
Webhook получает:
- Заголовок X-SeoSmith-Signature со значением вида sha256=<hmac-hex>
- JSON body вида:
{
"event": "article.published",
"article": {
"id": 123,
"title": "...",
"slug": "...",
"url": "...",
"short_answer": "...",
"insights": ["...", "...", "...", "..."],
"body_html": "Заголовок раздела
Основной текст статьи в HTML...
",
"meta": { "title": "...", "description": "...", "keywords": ["..."] },
"faq": [{ "q": "...", "a": "..." }],
"json_ld": "{...}",
"image_prompt": "...",
"alt_text": "..."
},
"company": {
"name": "...",
"site_url": "https://example.com"
}
}
Реализуй логику:
1. Прочитай тело как raw text или raw bytes ДО JSON.parse
2. Вычисли HMAC-SHA256 от raw body с ключом из env-переменной SEOSMITH_WEBHOOK_SECRET
3. Сравни с подписью из X-SeoSmith-Signature через безопасное compare, а не через обычный ==
4. Если подпись невалидна — верни 401
5. Если event не article.published — верни 200 JSON { ok: true, skipped: true }
6. Если event корректный — сохрани или обнови статью в уже существующей модели/таблице/коллекции публикаций проекта
7. Сохрани минимум поля: title, slug, short_answer, insights, body_html, meta_title, meta_description, meta_keywords, faq, json_ld
8. Для публичной страницы используй article.body_html как готовый HTML статьи
9. Если webhook пришёл повторно после правки статьи, обнови существующую публикацию по article.id или article.slug, а не создавай дубль
10. Верни 200 JSON { ok: true }
Ограничения безопасности:
- Не хардкодь никакие секреты
- Не отключай проверку подписи даже временно
- Не логируй полное значение SEOSMITH_WEBHOOK_SECRET
- Не принимай GET/PUT вместо POST
- Не делай endpoint публичной формой импорта без проверки подписи
- Не заменяй безопасное сравнение подписи на обычное ==
В конце:
1. Покажи полный URL endpoint, который получится после деплоя
2. Объясни, куда добавить SEOSMITH_WEBHOOK_SECRET локально и на сервере
3. Скажи, что после добавления env нужно перезапустить приложение или контейнер
4. Дай короткую инструкцию по проверке endpoint после деплоя
5. Объясни, по какому правилу проект обновляет существующую статью вместо создания дубля
Prompt для второй итерации, если AI пошел не туда
Если инструмент начал придумывать новый data model, собственный CMS или странную схему публикации, используйте уточняющий prompt:
Не изобретай новую архитектуру. Встрой webhook в уже существующую систему публикаций проекта. Сначала найди: - где в проекте уже хранятся публичные статьи, блог-посты или страницы - какой route pattern используется для публикаций - какая ORM-модель или таблица отвечает за контент После этого: - используй существующую модель публикаций, если она подходит - если модель отличается, добавь только минимальные поля для webhook-импорта - не трогай клиентские страницы без необходимости - не добавляй админку, если её нет Если не можешь однозначно определить существующую модель хранения статей — не импровизируй, а задай мне конкретный вопрос по текущей структуре проекта.
Универсальный prompt, чтобы статья сразу попадала в раздел блога
Если нужно, чтобы после webhook статья не просто сохранилась, а сразу появилась на странице раздела блога с карточкой и ссылкой, дайте AI такой prompt:
Он должен встроиться в уже существующий blog listing проекта: сохранить саму статью, обновить источник данных для страницы /blog или другого раздела публикаций и использовать уже существующие стили, шаблоны и клиентские скрипты без отдельного дублирования.
Встрой webhook SeoSmith в мой текущий проект так, чтобы каждая новая статья автоматически появлялась в публичном разделе блога проекта. Сделай это по правилам: 1. Используй существующую архитектуру проекта, текущий backend, router, ORM, CMS, файловую структуру или контентную папку. 2. Не создавай новый отдельный блог, новый frontend-раздел или параллельную CMS, если в проекте уже есть страница списка статей. 3. Найди, как в проекте сейчас формируется страница раздела блога: /blog, /articles, /insights или другой существующий route. 4. После приёма webhook article.published: - сохрани или обнови полную статью в существующей модели или файловой структуре публикаций; - сохрани slug, title, short_answer, insights, body_html, meta_title, meta_description, meta_keywords, faq, json_ld; - для публичной страницы используй article.body_html как готовый HTML статьи; - обеспечь, чтобы статья была доступна по публичному URL статьи; - выведи short_answer как отдельный короткий блок в начале статьи, если в проекте есть такой паттерн; - выведи insights как отдельный список «Главное из статьи», если проект поддерживает такие summary-блоки; - обеспечь, чтобы на странице раздела блога автоматически появилась карточка новой статьи со ссылкой на этот URL; - если webhook пришёл повторно после правки текста в SeoSmith, обнови существующую статью и её карточку по article.id или article.slug, не создавая дубль. 5. Для карточки статьи используй уже существующий шаблон списка статей, текущие CSS-классы, существующие UI-компоненты и текущие JS-скрипты проекта. Не создавай новый визуальный стиль, если в проекте уже есть карточки статей. 6. Если список блога строится из БД, обнови запрос/модель так, чтобы новая статья попадала в выборку. 7. Если список блога строится из файлов контента, создай файл в нужной папке и обнови механизм сборки или индекс, если это требуется. 8. Если проект использует статическую страницу index.html для раздела блога, автоматически обновляй её источник данных или пересобирай индекс так, чтобы новая карточка появлялась без ручного редактирования HTML. 9. Не ломай существующие стили и скрипты проекта. Новая статья и её карточка должны подтягивать те же CSS и JS, которые уже используются у существующих страниц блога. 10. Если в проекте нет отдельной страницы раздела блога, сначала найди ближайшую существующую страницу со списком публикаций и используй её. Если подходящей страницы нет, задай мне вопрос перед созданием новой структуры. Требования безопасности для webhook: - читать raw body до JSON.parse; - проверять HMAC-SHA256 подпись через SEOSMITH_WEBHOOK_SECRET; - сравнивать подпись только через безопасное compare; - не хардкодить секрет; - не отключать проверку подписи; - не делать endpoint открытым для любого JSON. В результате покажи: 1. Где именно в проекте теперь хранится статья. 2. Как именно обновляется страница раздела блога. 3. По какому URL открывается статья. 4. Почему карточка статьи автоматически появляется в списке блога. 5. Какие существующие стили, шаблоны или скрипты проекта были переиспользованы. 6. По какому правилу обновляется существующая статья вместо создания дубля.
Куда сохранять статью
Это зависит от архитектуры проекта. Универсального ответа нет, поэтому AI должен встроиться в уже существующую контентную модель или файловую структуру, а не изобретать новую CMS.
| Тип проекта | Куда сохранять | URL статьи |
|---|---|---|
| Next.js / Nuxt с БД | Таблица articles или posts в существующей БД проекта |
/blog/[slug] или другой уже существующий динамический роут |
| Next.js / Nuxt с MDX | Файл /content/blog/{slug}.mdx или аналогичная папка контента |
/blog/[slug] через файловый роутинг |
| Laravel / Django | Таблица posts или articles в текущей доменной модели |
/blog/{slug} или текущий path публикаций |
| Headless CMS | Существующая коллекция статей через API CMS | Зависит от текущего роутинга проекта |
| Статический сайт | Файл в папке контента, например /content/posts/{slug}.md |
Появится после пересборки сайта |
Пусть AI использует article.id как внешний ключ, а article.slug как запасной идентификатор. Если webhook пришёл повторно после правки текста, AI должен обновить существующую публикацию и карточку списка, а не создавать ещё одну запись.
Безопасная структура обработчика
Хороший AI-результат должен стремиться к такой структуре:
| Шаг | Что должно происходить |
|---|---|
| 1. Вход | Получить POST-запрос и raw body без потери исходного содержимого |
| 2. Верификация | Проверить наличие env-секрета и сравнить HMAC-SHA256 подпись |
| 3. Валидация | Проверить event и базовую структуру article/company |
| 4. Маппинг | Преобразовать payload в поля доменной модели проекта |
| 5. Сохранение | Создать или обновить публикацию по article.id или slug |
| 6. Ответ | Вернуть короткий JSON-ответ без внутренних деталей |
Что AI не должен делать
- Хардкодить
SEOSMITH_WEBHOOK_SECRETв код, примеры или commit. - Логировать полный raw payload вместе с секретом или подписью.
- Сохранять статью без проверки подписи «на время дебага».
- Делать endpoint доступным для любого JSON без HMAC-проверки.
- Менять основной контентный pipeline проекта, если достаточно добавить один route.
- Создавать отдельную таблицу для статьи, если в проекте уже есть blog/posts/pages.
Самая опасная ошибка — когда AI делает «работающую демку» и временно убирает проверку подписи. Такой endpoint нельзя оставлять ни на минуту в проде.
Какие поля действительно важны для сохранения
Даже если проект хранит статьи в своей форме, AI должен постараться не потерять эти данные из webhook:
article.idкак внешний идентификатор для update существующей статьи;titleиslug;short_answerиinsights;bodyкак готовый HTML;meta.titleиmeta.description;meta.keywords;faq;json_ld.
body может приходить в markdown-формате, поэтому AI не должен вставлять его на страницу как сырой текст. Сначала нужно преобразовать markdown-заголовки, списки и служебные блоки в HTML.
image_prompt и alt_text можно хранить как дополнительные поля или метаданные, если проект реально будет их использовать.
Как объяснить AI деплой и проверку
После генерации кода AI должен не только написать route, но и выдать понятный план запуска:
- как задеплоить изменения;
- куда добавить
SEOSMITH_WEBHOOK_SECRETлокально и на сервере; - что приложение нужно перезапустить после изменения env;
- какой конечный URL endpoint нужно вставить в SeoSmith.
Финальная проверка перед сохранением коннектора
- Endpoint существует по HTTPS.
- Он принимает только POST.
- В коде есть HMAC-SHA256 по raw body.
- Используется безопасное compare для подписи.
- Секрет читается из env, а не хранится в коде.
- Есть понятная точка сохранения статьи в структуру проекта клиента.