Блог на сайте живёт по простому закону: статья, о которой никто не узнал, не существует. Написать разбор — половина работы, вторая половина начинается после кнопки «Опубликовать». Её обычно делают руками: скопировать заголовок, придумать подводку, открыть четыре приложения, вставить, проверить картинку. Двадцать минут на статью и один забытый анонс из трёх.
Здесь — разбор того, как это устроено у нас: статья выходит на сайт, и через пять минут анонс сам уходит в четыре канала. Без сервисов автопостинга, своим кодом, в четырёх разных механиках — потому что четыре площадки устроены по-разному, и общего способа для них нет.
Что именно автоматизировано
Задача формулируется в одну строку: человек нажимает «Опубликовать» в портале и больше ничего не делает.
Дальше без него происходит вот что. Сайт пересобирается и выкладывает страницу статьи. Робот убеждается, что страница действительно открывается. Выжидает пять минут. Проверяет, что сейчас не ночь. Отправляет анонс в Telegram, MAX и ВКонтакте — каждый в своём формате: где-то с картинкой, где-то текстом, и это зависит не от нас. Дзен в это время забирает статью сам, по ленте.
Параллельно уходит запрос в Яндекс.Вебмастер — «приходите за новой страницей». Про эту вторую цепочку отдельный разговор дальше, механика у неё своя.
Кнопки при этом никуда не делись: если анонс нужен раньше или в один конкретный канал, его можно отправить вручную. Автоматика — это поведение по умолчанию, а не единственный путь.
Где живёт текст блога
Прежде чем автоматизировать рассылку, надо решить, откуда берётся текст. Ответ у нас однозначный: источник правды один — портал.
Статья пишется в CMS, там же лежат обложка, описание, вопросы для микроразметки. Сайт — статика: страницы собираются заранее, и перед сборкой текст выкладывается из портала файлами, которые дальше обрабатываются штатным механизмом генератора.
Соблазн держать текст в двух местах — в базе и файлом в репозитории — заканчивается одинаково: при первой же правке мимо портала версии расходятся, и никто этого не замечает месяцами. Поэтому файл в репозитории помечен прямо в первой строке: «Сгенерировано из портала, править здесь бесполезно».
Из этого решения следует всё остальное. Раз текст один, то и анонс собирается из него же: заголовок, описание, обложка и адрес берутся из той самой записи, которую человек редактировал. Придумывать подводку отдельно не нужно.
Две механики: мы отправляем или у нас забирают
Четыре канала делятся на две группы, и это главное различие, которое определяет всё остальное.
Мы отправляем сами — через API. Telegram, MAX и ВКонтакте дают программный интерфейс: наш код формирует сообщение и посылает его в канал. Мы управляем моментом отправки, текстом и картинкой, знаем результат сразу — площадка отвечает, приняла она запись или отказала.
У нас забирают — через RSS. Дзен работает наоборот: он подключается к ленте на сайте и периодически ходит за новыми материалами сам. Мы не решаем, когда именно материал появится в канале, и не получаем ответа об успехе. Наше дело — держать ленту правильной и доступной.
Разница принципиальная и влияет на процесс. В первом случае ошибка видна немедленно и её можно исправить. Во втором — вы узнаёте о проблеме только по факту: материалов в канале нет, а почему — придётся выяснять по логам сервера, приходил ли робот и что получил.
| Telegram | MAX | ВКонтакте | Дзен | |
|---|---|---|---|---|
| Механика | API | API | API | RSS |
| Кто инициатор | мы | мы | мы | площадка |
| Картинка | из разметки страницы | файлом | нельзя | из ленты |
| Ответ об успехе | сразу | сразу | сразу | нет |
| Можно удалить отправленное | да | да | нет | — |
Telegram: Bot API и капризы превью
Самый простой из четырёх. Бот создаётся за минуту, добавляется в канал администратором с правом публикации, дальше — один вызов sendMessage с идентификатором канала и текстом.
Тонкость не в отправке, а в том, как выглядит результат. Анонс статьи — это сообщение со ссылкой, и превращает его в красивую карточку с картинкой сам Telegram: он ходит по ссылке и собирает карточку из разметки страницы. Отдельно картинку прикладывать не нужно, нужно правильно попросить:
parse_mode: 'HTML',
link_preview_options: {
prefer_large_media: true
}
Старый параметр disable_web_page_preview умеет только выключать превью и никак не влияет на его вид — из-за него ширина сообщений в канале «плавает»: одни анонсы с большой картинкой, другие с узкой полоской.
Главная грабля Telegram — кэш превью. Он запоминает карточку по адресу, и запоминает намертво. Достаточно, чтобы кто-нибудь открыл ссылку до того, как страница собралась, — и в канал уйдёт анонс с пустой карточкой, а исправить его правкой сообщения нельзя.
Мы поймали это на боевой статье: разбор вышел, а в канале — узкая полоска без обложки. Проверили всю цепочку: обложка в записи есть, картинка на странице отдаётся, робот не блокируется защитой сервера. Причина оказалась в кэше. Лечится сбросом через служебного бота @WebpageBot, причём с двух заходов: текст карточки обновился раньше картинки.
Чтобы не повторялось, отправка теперь проверяет страницу перед публикацией: запрашивает её и убеждается, что она отвечает и что в разметке есть og:image. Если картинки нет — анонс не уходит, а портал говорит человеку прямо: «На странице статьи нет картинки для карточки: Telegram запомнит анонс без обложки».
MAX: свой API и картинка файлом
MAX доступен с российского сервера напрямую, и это заметно упрощает жизнь. Механика отличается от Telegram: здесь картинка не собирается из разметки, а загружается файлом — в три шага.
Сначала запрашивается адрес для загрузки: POST /uploads?type=image. Затем на этот адрес многочастным запросом отправляется сам файл обложки. В ответ приходит маркер загруженного изображения, который и прикладывается к сообщению:
attachments: [{ type: 'image', payload: { token: <маркер> } }]
И только потом отправляется сообщение в канал: POST /messages?chat_id=<канал>.
Обложку мы берём с диска, а не по адресу сайта. Причина та же, что у Telegram, но с другой стороны: страница может быть ещё не собрана, а картинка в записи есть всегда. Лишняя зависимость от сборки в цепочке отправки не нужна.
ВКонтакте: ключ сообщества и картинка, которой нет
Здесь начинается самое интересное, и здесь же — история, которая стоила нам полутора дней и закончилась не тем, чего мы ждали.
Публиковать в сообщество можно двумя видами ключей: пользовательским (привязан к личному аккаунту человека) и ключом сообщества (привязан к самой группе). Ключ сообщества явно лучше: он не связан с конкретным человеком, не даёт доступа к личной переписке владельца и не отвалится, когда человек сменит пароль.
Публикация им работает штатно — wall.post с параметром from_group=1, запись выходит от имени сообщества без подписи автора.
А вот приложить к записи картинку ключом сообщества нельзя. Штатный метод загрузки фото на стену отвечает отказом:
[27] Group authorization failed: method is unavailable with group auth
Первый вывод напрашивается сам: не хватает прав. Мы его и сделали. Он неверный.
Права выданы все. Метод groups.getTokenPermissions показывает, что именно есть у ключа, и в нашем случае это photos, docs, messages, wall, manage, stories, market — полный список. Код 27 означает не нехватку прав, а то, что метод не работает с ключом сообщества в принципе. Сколько галочек ни ставь при выпуске ключа, ответ не изменится. Передача параметра group_id, который метод принимает, тоже ничего не меняет.
Это известная проблема, и она в трекере самого ВКонтакте. Обращение VKCOM/vk-api-schema#242 описывает ровно наш случай: ошибка 27 у ключа сообщества при выданном праве photos. Открыто 3 апреля 2026 года, ответа от ВКонтакте нет, обходного пути в обсуждении не предложено. Автор обращения замечает то же, что заметили мы: в документации метода нигде не сказано, что нужен пользовательский токен — поведение расходится с описанием.
Обходной путь, который выглядит рабочим, но им не является
Разбираясь, мы нашли связку, которая проходит все проверки:
photos.getMessagesUploadServer— открыт ключу сообщества и даёт адрес для загрузки;- многочастная отправка файла на этот адрес — проходит;
photos.saveMessagesPhoto— сохраняет фото, возвращает владельца, номер и десять размеров, то есть картинка полноценная;attachments: photo<владелец>_<номер>вwall.post— принимается, ответ содержит номер созданной записи.
Ни одного отказа на всём пути. Мы сочли способ рабочим и выпустили анонс — и он вышел без картинки. Стена молча игнорирует фото, сохранённое таким образом.
⚠️ Отсюда правило, за которое мы заплатили полутора днями: у ВКонтакте «запрос принят» не означает «получилось». Ответ с номером записи не говорит ничего о том, что увидит читатель. Проверять результат нужно тем же, чем его видит подписчик, — глазами в сообществе.
Остальные пути тоже проверены и закрыты. Вложение-ссылка отклоняется правилом link_photo_sizing_rule («No photo given»), хотя картинка на странице есть и доступна. Карточку из разметки страницы ВКонтакте, в отличие от Telegram, не разворачивает: ссылка в тексте остаётся голой строкой.
Итог: запись от имени сообщества выходит текстом со ссылкой. Картинка требует пользовательского токена — то есть привязки публикаций к личному аккаунту человека, со всеми вытекающими: такой ключ может писать на его личную стену и читать его данные. Это осознанный размен, и мы пока выбрали ключ сообщества.
Чего ключ сообщества не умеет вовсе
Это важнее обходных путей, потому что меняет процесс:
| Метод | Что значит |
|---|---|
wall.delete | отправленную запись нельзя удалить программно |
wall.edit | и нельзя отредактировать |
wall.get, wall.getById | нельзя прочитать даже собственную запись |
photos.getById | нельзя проверить загруженное фото |
stats.get | нельзя забрать статистику охватов |
Первые две строки — не мелочь. Ошибочный анонс убирается только руками через интерфейс сообщества. Мы столкнулись с этим дважды, проверяя картинки: тестовые записи создавались, а удалить их кодом не выходило.
Третья и четвёртая объясняют, почему проверка «глазами» — не лень, а единственный способ: прочитать свою же запись и убедиться, что в ней есть вложение, ключ сообщества не может.
Отсюда правило, которое стоит записать до первой ошибки: во ВКонтакте всё проверяется до отправки, а не после. Именно поэтому проверка страницы перед публикацией у нас общая для всех каналов.
Дзен: только RSS и требования к ленте
Дзен не даёт интерфейса для публикации со стороны. Единственный путь — трансляция материалов по RSS: канал привязывается к сайту, вы указываете адрес ленты, дальше он ходит за ней сам.
Первое условие — подтвердить права на сайт. Дзен предлагает несколько способов; мы выбрали файл-подтверждение в корне сайта как наименее навязчивый: он ничего не добавляет в разметку страниц.
Второе условие неочевидное: трансляция включается не сразу. Для подключения ленты каналу нужно набрать десять подписчиков — до этого пункт в настройках просто недоступен. И после подключения материалы появляются не мгновенно: заявка уходит на проверку, которая занимает несколько дней.
Третье — лента должна содержать полный текст статьи, а не анонс. С одним описанием материал не публикуется. Полный текст кладётся в отдельный элемент:
<content:encoded><![CDATA[ ... разметка статьи ... ]]></content:encoded>
Здесь три места, где ошибиться проще всего.
Все ссылки и картинки — абсолютные. В ленте нет базового адреса страницы, и относительный путь /blog/… превращается в битую ссылку на стороне площадки. Разворачивать нужно всё: и адреса ссылок, и картинки, и наборы размеров у них.
Тип картинки должен совпадать с файлом. У нас в теге вложения стояло image/png, а все обложки — JPEG. Лента при этом валидна, площадка вправе такую картинку просто отбросить, а вы будете гадать, почему материалы выходят без обложек. Тип теперь считается по расширению файла, а не пишется наугад.
Черновики в ленту не попадают. Это кажется очевидным ровно до того момента, когда закрытый предпросмотр, отправленный на согласование, уезжает в публичный канал.
Проверить, что площадка ленту забирает, можно по логам сервера: робот приходит с узнаваемым именем. У нас первый заход зафиксирован через сутки после подключения — запрос ленты и ответ 200. Это единственный доступный способ убедиться, что связка работает: сама площадка о своих визитах не отчитывается.
Расписание: почему не «сразу»
Самая простая автоматика — отправлять анонс в момент публикации. Она же самая неудачная, по трём причинам.
Между кнопкой и страницей стоит сборка сайта. Обычно пара минут, но она может задержаться или упасть. Анонс на несуществующую страницу уводит подписчиков на 404, и отменить это уже нельзя.
Поэтому робот, работающий раз в минуту, проверяет страницу, а не время публикации: дёргает адрес статьи и, получив 200, запоминает момент. Отсчёт идёт от этого момента, а не от нажатия кнопки.
Пять минут выдержки. Страница появилась — это ещё не значит, что всё на месте: обложка могла не докопироваться, кэш мог не обновиться. Пять минут — дешёвая страховка, которую читатель не заметит.
Окно 9:00–21:00. Ночное уведомление у подписчика раздражает сильнее, чем радует статья. Материал, доехавший ночью, ждёт утра — робот отправит его в девять.
И отдельно — что делать, если сборка так и не прошла. Через сутки ожидания робот перестаёт проверять и пишет ошибку в журнал. Молча ждать вечно хуже: человек уверен, что анонс ушёл, а его нет.
Как не отправить анонс дважды
Робот работает раз в минуту. Значит любая ошибка в логике «уже отправлено или нет» превращается в шестьдесят анонсов в час.
Защита простая: у каждой статьи по отметке на канал — отправлен ли анонс в Telegram, в MAX, во ВКонтакте. Отметка ставится после успешного ответа площадки, и статьи с отметкой робот не берёт вовсе.
Отметки раздельные не случайно. Каналы независимы: ВКонтакте может отказать, когда Telegram уже принял, и повторять нужно только неудавшийся — иначе подписчики Telegram получат анонс дважды.
И ещё одно решение, которое экономит много сил в будущем: отправку делает та же ручка, что и кнопка в портале. Не копия её кода, а именно она. Копия разъезжается с оригиналом на первой же правке формулировки, и вы получаете два разных анонса: один при ручной отправке, другой при автоматической.
Не только каналы: сказать поисковику, что страница появилась
Кнопка «Опубликовать» запускает не одну цепочку, а две. Про анонсы — всё описанное до этого. Вторая короче и незаметнее: адрес новой статьи отправляется на переобход в Яндекс.Вебмастер.
Смысл тот же, что у анонса, только адресат другой. Робот поисковика придёт на новую страницу и сам — по своему расписанию, которое может растянуться на недели. Запрос на переобход означает «приходи сейчас», и для свежей статьи это разница между «в поиске через день» и «в поиске через месяц».
Технически это один вызов: адрес ставится в очередь переобхода для своего сайта. Тонкости, как обычно, не в вызове.
Квота конечна — 150 адресов в сутки. Поэтому одна статья получает одну успешную отправку, а не отправляется при каждом сохранении. За один проход робота — не больше пяти адресов, чтобы разовая массовая правка не съела дневной лимит целиком.
Вебмастер принимает любой адрес, даже несуществующий. Мы это проверили: на заведомо отсутствующую страницу он отвечает «принято» и списывает квоту. То есть проверять, что страница действительно есть, приходится нам — иначе робот придёт на 404, а мы будем считать, что отправили.
Отправить один раз мало. Публикация делает одну попытку: не приняли — кончилась квота, Вебмастер был недоступен — и статья осталась ждать робота по его расписанию, а мы об этом даже не узнаем. Поэтому рядом работает добор: раз в десять минут он находит опубликованные статьи без успешной отметки и досылает.
Правка уже опубликованной статьи — отдельный случай, о котором забывают. Текст поменяли, а в поиске висит прежний: публикация была давно, второй раз статью никто не «публикует». Добор замечает, что статья изменена после последней отправки, и зовёт робота снова — но только когда правка реально доехала до сайта. Позвать раньше — значит привести робота на старую версию и потерять квоту: он уйдёт и вернётся не скоро.
Здесь работает тот же принцип, что и с анонсами: ловим состояние, а не событие. Не «сработало при публикации», а «опубликована, доступна и ещё не отправлена». Пропущенный запуск ничего не ломает — следующий доберёт. Автоматика, построенная на событиях, теряет всё, что случилось, пока она лежала.
Когда всё-таки нужен готовый сервис
Мы описали свой код, но было бы нечестно не сказать, где он не нужен.
Сервис автопостинга уместен, если каналов много и они разнородные, если публикуете десятки постов в неделю, если нужен календарь публикаций с несколькими редакторами, аналитика по всем площадкам в одном месте и очередь отложенных записей с ручной перестановкой.
Свой код выигрывает, когда каналов немного и они постоянные, когда анонс собирается из вашей же CMS и должен использовать именно её данные, когда важна связка с остальной системой (проверить страницу перед отправкой, поставить отметку в карточке статьи, записать ошибку в общий журнал) — и когда не хочется отдавать ключи от своих каналов посреднику.
У нас случай второй: анонс — часть конвейера публикации, а не отдельная задача. Отправка через чужой сервис означала бы, что проверить страницу перед отправкой уже нельзя, а именно эта проверка спасает от анонсов на 404.
Что из этого переносимо
Всё описанное — не разовая настройка под один сайт. Заново пишется только слой отправки: как конкретная площадка принимает сообщение и как приложить к нему картинку. Остальное переезжает как есть — источник правды в CMS, единая ручка отправки, робот с расписанием, проверка страницы до публикации, отметки по каналам и добор неудачных попыток.
Сколько времени займёт новая площадка, заранее сказать нельзя, и наш собственный пример это показывает лучше любых обещаний. Telegram и MAX заработали за вечер. ВКонтакте занял полтора дня и закончился тем, что картинку приложить нельзя вовсе — причём выяснилось это не сразу, а после анонса, который вышел без неё. Границы ключа выясняются не из документации, а из ответов API на живые запросы — и заложить это время в план честнее, чем рассчитывать, что всё будет как с предыдущей площадкой.
Кстати, о ленте: этот разбор тоже уедет по описанному конвейеру — сам, через пять минут после того, как страница появится на сайте. Если не уедет — значит, статья получилась про что-то другое.
Дополнение от 3 сентября 2026
Разбираясь с ВКонтакте дальше, мы нашли различение, которое стоит держать в голове с самого начала: ошибки 15 и 27 означают совершенно разное.
Поддержка ВКонтакте на вопрос про загрузку фотографий ответила советом подключить в сообществе раздел «Фотографии». Совет выглядел шаблонным — и оказался наполовину верным.
После включения разделов картина изменилась так:
| Метод | Было | Стало |
|---|---|---|
docs.getWallUploadServer | 15 «Access denied: User can’t upload docs to this group» | работает |
photos.getWallUploadServer | 27 «method is unavailable with group auth» | без изменений |
Ошибка 15 — это настройки сообщества, её снимает администратор одной галочкой в разделах. Ошибка 27 — тип ключа доступа, её не снимает ничто.
Практический вывод: увидев отказ на новом методе, сначала посмотрите на код. Пятнадцатая — повод пойти в настройки сообщества и вернуться. Двадцать седьмая — повод сразу планировать другой способ, не тратя день на настройки, которые ничего не изменят.
Заодно проверили обходной путь через документы: файл действительно загружается, ВКонтакте распознаёт его как изображение, но в записи он показывается строкой с именем файла, а не картинкой. Для анонса не годится — зато теперь известно, что прикладывать файлы к записям сообщество умеет.
Как наша статья про автопостинг сломала реальный автопостинг
В конце этой статьи было сказано: разбор уедет в каналы сам, а если не уедет — значит, вышел про что-то другое.
Он не уехал.
Статья про автопостинг сломала автопостинг.
Виноват пример. Чтобы показать, как устроена лента для Дзена, мы привели кусочек её разметки. А в нём есть символы, которые для ленты означают «текст здесь заканчивается».
Дальше просто: статья целиком уехала в ленту, лента дошла до этих символов в нашем примере и решила, что читать больше нечего. Половина ленты превратилась в мусор — начиная ровно с того места, где мы объясняем, как делать правильно.
Дзен на это не сказал ни слова. Канал подключён, лента открывается, публикаций ноль. Мы ждали обещанную проверку «в несколько дней».
Нашли случайно, починили двумя строками. Через пять минут в канале появились первые статьи — конвейер работал всё это время, ему просто подсовывали испорченный файл.
Что стоит запомнить: то, что вы показываете читателю как пример, потом проходит через ваши же трубы. И если площадка молчит — это ещё не значит, что всё в порядке. Теперь сборка сайта сама проверяет ленту и не выпускает её, если та не читается.
Коротко: частые вопросы
- Нужен ли платный сервис автопостинга, чтобы публиковать анонсы?
- Нет, если каналов немного и они постоянные. Telegram, MAX и ВКонтакте дают открытый программный интерфейс: анонс отправляется одним запросом. Сервис оправдан, когда площадок много, публикаций десятки в неделю и нужен общий календарь с несколькими редакторами. Свой код выигрывает, когда анонс — часть конвейера публикации: он может проверить страницу перед отправкой и поставить отметку в карточке статьи.
- Чем отличается публикация по API от трансляции по RSS?
- Направлением. По API мы отправляем сами: выбираем момент, видим ответ площадки и сразу знаем результат. По RSS площадка забирает материалы сама, когда сочтёт нужным, и ответа об успехе не даёт — узнать, приходил ли робот, можно только по логам сервера. Telegram, MAX и ВКонтакте работают по первому пути, Дзен — по второму.
- Почему анонс уходит не сразу после публикации статьи?
- Между кнопкой «Опубликовать» и появлением страницы стоит сборка сайта: обычно пара минут, но она может задержаться или упасть. Анонс на несуществующую страницу уводит подписчиков на 404, и отменить это нельзя. Поэтому робот сначала убеждается, что страница открывается, и только потом, выждав пять минут, отправляет анонс.
- Можно ли приложить картинку к записи ВКонтакте ключом сообщества?
- Нет. Штатный метод загрузки фото на стену отвечает ошибкой 27, и дело не в правах — ограничен сам метод, это известная проблема в трекере ВКонтакте (vk-api-schema, обращение 242, открыто с апреля 2026 без ответа). Обходная связка через загрузку для сообщений проходит все шаги без единого отказа, но стена такое фото не показывает. Вложение-ссылка отклоняется, карточку из разметки страницы ВКонтакте не разворачивает. Картинка требует пользовательского токена, то есть привязки публикаций к личному аккаунту.
- Что нужно, чтобы Дзен забирал статьи с сайта?
- Три вещи. Подтвердить права на сайт, набрать каналу десять подписчиков — до этого подключение ленты недоступно, — и отдавать в ленте полный текст статьи, а не описание: с одним анонсом материал не публикуется. После подключения заявка уходит на проверку, которая занимает несколько дней.
- Нужно ли сообщать поисковику о новой статье?
- Да, если хотите видеть её в поиске быстро. Робот придёт и сам, но по своему расписанию — это могут быть недели. Запрос на переобход в Яндекс.Вебмастере означает «приходи сейчас». Учитывайте два момента: квота ограничена (150 адресов в сутки), а Вебмастер принимает любой адрес, даже несуществующий, — он ответит «принято» и спишет квоту, поэтому проверять существование страницы приходится самим.
- Как не отправить один и тот же анонс дважды?
- Хранить отметку об отправке у самой статьи, отдельно по каждому каналу, и ставить её после успешного ответа площадки. Робот, работающий раз в минуту, статьи с отметкой не берёт. Отметки нужны раздельные: одна площадка может отказать, когда другая уже приняла, и повторять следует только неудавшуюся.