Думал, что автоматизирую линейный процесс: отдать материал издателю по RSS, найти опубликованный URL и добавить его в отчёт. RSS собрался быстро. А потом выяснилось, что почти каждый следующий шаг в этой цепочке умеет врать.

CMS может скачать изображение ещё при импорте. Referer — исчезнуть. Сканер может найти похожую страницу, а издатель — переписать заголовок, перенести картинку на свой CDN и опубликовать в неожиданном разделе.

Поэтому найденный URL перестал означать, что публикация состоялась.

Пришлось проектировать уже не RSS, а систему доказательств.

Забавно, что похожую ошибку я до этого пару лет совершал и на продуктовой стороне: довольно старательно метался по акселераторам, играл в lean canvas и пытался благодаря кастдевам найти уникальную бизнес‑модель. Пока искал незакрытые потребности, клиенты всё охотнее покупали уже имеющуюся, вполне не уникальную услугу, причём всё чаще и дороже. Это были не восторженные комментарии на созвонах, а повторные B2B‑заказы, рекомендации и растущее доверие.

Я развиваю онлайн‑сервис для работы с цифровыми СМИ. До открытия проекта долго работал в сфере управления цифровой репутацией и по ходу протестировал почти все российские и многие зарубежные сервисы рассылки пресс‑релизов. Иногда мы с коллегами по ORM‑агентствам перепродавали их услуги за x10, потому что заказчик платил не за кнопку «отправить релиз», а за готовность дать совет, контроль процесса, ответственность за результат и понятный отчёт с пояснениями человеческим языком. В России отчёты таких сервисов состоят из «релизоприёмников», небольших новостных сайтов, UGC‑блогов и платных публикаций, а итоговая ценность для клиента часто лежит в области SERM или подтверждения публичности. Для агентств, как оказалось, это практичный и недорогой способ добавить к результатам их дорогого абонентского консалтинга что‑то «осязаемое».

И недавно сошлись две мысли:
— Люди очень спокойно реагируют на готовое «идеальное решение», которое сами так называли на интервью.
— Повторные оплаты точнее любого кастдева показывают, какую проблему ты закрываешь.

В разных ситуациях я совершал одинаковую ошибку: принимал понятный сигнал за гарантию результата.

Что продавалось

Я публиковал исходный материал заказчика на сайте сервиса, затем руками рассылал его по наиболее мотивированным новостным сайтам. Для заказчика это и было подтверждаемым результатом: «вот ссылки на опубликованные материалы». Такой продукт хорошо ложится на описанную ранее логику платных публикаций и их применения в PR или SERM‑задачах. 

На тот момент 2N9HT уже был не просто каталогом услуг. На сайте были UGC‑публикации в профилях компаний, инструмент для проверки текста и другое. В открытой ленте выходили пресс‑релизы как небольших компаний, так и крупных международных брендов, но передача материалов внешним площадкам и сбор результата оставались ручными. 

Проблема была не в отсутствии продукта. Продукт существовал, но объяснялся кусками, а внутри ещё сильно опирался на ручную работу.

Когда лендинг превратился в спецификацию

Внятного лендинга под ключевую услугу не было. Зато внутри сайта уже накопилась половина решения, будущий костяк клиентской отчётности. Кстати, именно попытка сделать нормальную страницу услуги заставила меня описать путь целиком:)

Тогда лендинг перестал быть «маркетинговой страницей», начал работать как спецификация. Это было необходимо, ведь пока ты не можешь внятно ответить себе, что именно считаешь завершённой услугой — автоматизировать нечего.

Как RSS оказался простой частью

Темы и RSS неожиданно собрались без большой переделки. Как раз недавно добавил категоризацию записей поверх имеющейся ленты материалов. То есть уже была классификация контента и очевидный интерфейс для внешнего потребителя — издателя.

Поэтому я считаю главным результатом первой итерации систему тем и персональные RSS‑фиды по темам и их пересечениям. Не написание очередного RSS, а превращение классификации материалов в интерфейс для издателя. Для новостного сайта это важно. Он не хочет публиковать всё подряд: нужна была возможность подписаться на узкий набор тем и использовать фид как редакционный источник.

Казалось, что после появления RSS самая сложная часть позади.

Почему ссылка — ещё не конец

Только недавно осознал, что найти ссылку на чужом сайте — целая задача. А потом выяснилось, что даже найденная ссылка — далеко не конец процесса.

Вот как:

Ссылка найдена ≠ публикация подтверждена ≠ связана с заказом ≠ добавлена в отчёт ≠ видна клиенту.

Материал меняет несколько независимых состояний, прежде чем ссылка становится видной клиенту.
Материал меняет несколько независимых состояний, прежде чем ссылка становится видной клиенту.

Проще говоря, URL может появиться в системе разными путями: прислал издатель, нашёл оператор или подсветил сканер. Но сам адрес страницы не отвечает сразу на несколько вопросов: это точно нужный материал? Соответствует ли он версии, которую выдал RSS‑фид? К какому заказу относится? Должен ли уже попасть в клиентский отчёт? Без ответа на эти вопросы ссылка — только кандидат.

Здесь ломается прежняя модель:
Материал ➝ RSS ➝ Сайт издателя ➝ Ссылка ➝ Отчёт.

RSS отвечает на вопрос «чем мы поделились». Он почти ничего не говорит о том, что произошло дальше. Внешний сайт может поменять заголовок, сократить текст, переверстать HTML, сохранить картинку на своём CDN или опубликовать материал в другом разделе.

Почему изображение не вернуло мне ссылку

Первая гипотеза — использовать уже существующий трекинг изображений. Если картинка остаётся у нас на сервере, внешний сайт обращается за ней при загрузке страницы. Казалось, что достаточно зафиксировать запрос и получить URL публикации из Referer.
Но такой сигнал не закрывает задачу. CMS может скачать изображение ещё во время импорта и сохранить его в своей медиа‑библиотеке. Файл может запросить сервер, бот или система предпросмотра — ещё до появления публичной страницы. CDN может начать раздавать локальную копию, а браузер или политика сайта — не передать Referer. В итоге запрос изображения либо не содержит адреса публикации, либо вообще не доказывает, что публикация вышла.

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

Поэтому загрузка изображения осталась полезным техническим сигналом, но не подтверждением публикации и не гарантией получения адреса. Сканер решает только часть проблемы: он способен предложить похожую страницу, но до проверки она остаётся кандидатом.

Сервисы синдикации пресс‑релизов — западные аналоги таких систем — решают проблему, добавляя в копии ссылку на оригинальную публикацию. Я увидел у такой модели существенные ограничения, поэтому от неё отказался.

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

Как реализовал

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

При фактической выдаче айтема в персональный фид система стала сохранять контекст выдачи: материал, заказ, фид, заголовок, отрывок текста, GUID, asset token, домен издателя и время. Если публикация позже изменится, сравнивать внешнюю страницу с текущей версией будет поздно. Нужен снэпшот того, что издатель реально получил.

Небольшой пример RSS‑айтема:

<item>
  <guid>feeditem:anon-001</guid>
  <title>Компания N запустила новый продукт</title>
  <link>https://2n9ht.example/post/anon</link>
  <description><![CDATA[Короткий фрагмент текста…]]></description>
  <pubDate>Tue, 08 Jul 2026 10:15:00 +0300</pubDate>
</item>

А так может выглядеть снэпшот записи в feed_items:

{
  "feed_item_id": "anon-001",
  "order_id": "anon-order",
  "post_id": "anon-post",
  "guid": "feeditem:anon-001",
  "title_snapshot": "Компания N запустила новый продукт",
  "excerpt_snapshot": "Короткий фрагмент текста…",
  "asset_token": "asset-anon",
  "publisher_domain": "publisher.example",
  "served_at": "2026-07-08T10:15:00+03:00"
}

Саму внешнюю запись мы перестали считать «готовым размещением», а ручной путь подтверждения публикаций остался. Это не слабость системы, а страховка. В спорных случаях оператор или издатель вводит URL, система загружает страницу, сравнивает заголовок и фрагмент текста, сохраняет признаки совпадения и только после этого меняет статус. Такой путь не требует обязательного «пикселя», исходной картинки или обратной ссылки. Это особенно важно, если издатель всё‑таки перезаливает изображение или переписывает часть HTML. Во второй части как раз разберу, что способен дать трекинг просмотров изображения и почему подписанное уведомление о публикации от CMS может быть сильным, но всё равно лишь дополнительным доказательством, а не источником истины.

Кроме того, подтверждённую публикацию нужно ещё провести в существующий отчёт. Суть проверки можно описать так:

if ($placement_is_confirmed
    && $order_is_paid
    && $order_has_required_service
    && !$report_link_exists) {
    add_link_to_report();
}

А ещё появилась регулярная сверка. Если публикация подтверждена, а строки в отчёте нет, почасовая фоновая задача повторно проверяет связь и восстанавливает разорванную цепочку.

Полный путь удалось пройти штатными средствами: от выдачи материала в персональный RSS и сохранения снэпшота до кандидата, ручного подтверждения, связи с заказом и появления ссылки в отчёте клиенту.

Что это дало, чему научило и что будет дальше

В конечном счёте первая итерация дала не волшебный RSS‑движок, а понимание двух вещей: где заканчивается доставка данных и начинается подтверждённый результат и почему автоматизация начинается не с транспорта, а с определения результата. Пока не решено, что именно считается подтверждённой публикацией и когда она становится частью результата выполнения услуги, любой RSS — просто удобный способ поделиться данными.

Выводы:

  1. Начинать не с канала доставки, а с определения результата. Для этой услуги результат — не «новость разослана», а «публикация подтверждена, связана с заказом и можно показать клиенту».

  2. Нельзя смешивать состояния. Распознанная публикация, кандидат на попадание в отчёт, подтверждённая и добавленная в отчёт — это не одни и те же ссылки, даже если хочется упростить схему. К тому же новость может успешно проходить по всем пунктам, но при этом у неё могут не трекаться просмотры.

  3. Переданную версию материала — сохраняем отдельно. Без снэпшота потом невозможно честно сравнивать внешнюю страницу с тем, что получил издатель.

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

  5. Надёжный путь ручного подтверждения нужен раньше, чем полная автоматизация. Иначе спорные случаи будут копиться без адекватного безопасного решения.

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

Во второй части разберу как раз ту половину задачи, до которой в этой статье только дошли. Почему отказались от обязательной ссылки на источник, что доказывает трекинг запросов изображений, когда полезен сканер. Зачем нужно подписанное уведомление от CMS и почему оно должно оставаться лишь дополнительным доказательством. 

Интересно сравнить, как это устроено в разных CMS. Расскажите в комментариях, как ваш импортёр обрабатывает изображения, canonical URL и ссылки на источник, переданные через RSS.