Есть ресурсы, которые как-то не принято считать. Например, время рутинной работы сотрудников. Конечно, если это не программист, час которого стоит пару сотен долларов. Хотя автоматизация маленьких рутинных операций может сложиться в итоге в значительную экономию ресурсов. Еще один плюс автоматизации рутины — вам не придется сочинять регламенты и обучать новых сотрудников выполнению этих операций.
Расскажем о том, как упростили ведение канала в Телеграм для проекта «Делис Архив».
Спойлер: автоматическую отправку в Телеграм новостей с сайта реализовали на 100% за один (1) день.
Задача: репост статей с сайта в Тг-канал
Запрос клиента звучал так: можно ли автоматически постить в Телеграм-канал компании любые новые статьи, которые будут публиковаться на сайте?
Новый модуль должен был работать понятным образом:
- При добавлении очередной новости на сайте можно задать Телеграм-канал, в который она будет отправляться.
- Пост должен содержать заголовок, текст, изображение (если оно есть) и активную ссылку на статью.
- У контент-менеджера должна быть возможность отключить автоматическую отправку для конкретной новости при ее создании.
Автоматизация помогла бы сократить время на такую «републикацию», высвободив до 1 часа ежедневно, а это 20+ часов в месяц.
Мы провели анализ требований, затем определились с тем, какие инструменты нам понадобятся для решения задачи. На тестирование и отладку ушло всего несколько часов.
Стек технологий
Для реализации задачи мы использовали стандартные технологии и инструменты:
- PHP: основной язык разработки, на котором написан сайт.
- Битрикс: платформа, на которой работает сайт.
- API Telegram: для отправки сообщений и изображений в Телеграм-канал.
Для выполнения HTTP-запросов к API Telegram был выбран HTTPClient. Это логичный выбор, поскольку HTTPClient поддерживает различные HTTP-методы (GET, POST, PUT, DELETE и т.д.) и хорошо совместим с PHP.
Особенности разработки: подстраховать ошибки и подчистить текст
На этапе разработки нужно было учесть несколько ключевых аспектов:
Чтобы избежать отправки сообщений в случае ошибочного сохранения новости в админ-панели Битрикса, было решено использовать дополнительное поле RESULT для проверки. Задача поля — проверить, был ли элемент успешно сохранен в инфоблоке.
Для идентификации нужного инфоблока мы использовали IBLOCK_ID. В нашем случае — это инфоблок новостей с ID 27. Такая фильтрация по инфоблоку важна, потому что нам нужно точно определить, с каким инфоблоком будет работать система, исключая доступ к нецелевым данным. Так мы упрощаем процесс выборки информации и улучшаем производительность системы.if ($arFields['RESULT'] > 0 && $arFields['IBLOCK_ID'] == 27) { // Проверка успешного сохранения и ID инфоблока
Кроме того, чтобы контент-менеджер мог вручную разрешить или запретить автоматическую отправку конкретной новости, мы добавили в инфоблок свойство SEND_TG.
Сам текст новости должен был корректно отображаться в Тг-канале, для чего потребовалось преобразовать его внешний вид. Например, новость может содержать специальные символы, представленные в HTML формате (& вместо & или <br> для переноса строк). Для корректного отображения этих символов в Телеграме необходимо преобразовать их в обычные текстовые символы — в коде для этого используется функция html_entity_decode, которая отвечает за такое преобразование.$properties = CIBlockElement::GetProperty($arFields['IBLOCK_ID'], $arFields['ID'], array(), array('CODE' => $propertyCode));
while ($property = $properties->Fetch()) {
if ($property['VALUE_ENUM'] == 'Да') {
$sendToTelegram = true;
break;
}
}
Если новость содержит изображение, оно должно отправляться вместе с подписью.$newsDetail = str_replace('<br>', "\n", $arFields['PREVIEW_TEXT']);
$newsDetail = html_entity_decode($newsDetail);
Для отслеживания статуса отправки мы реализовали запись логов в отдельный инфоблок, чтобы мониторить успешность отправки и выявлять возможные ошибки на каждом этапе процесса.
Как выглядит результат
Как выглядит анонс новости, опубликованной на сайте
Как выглядит код
Ниже приведен код, с помощью которого выполняется задача по автоматической публикации новостей в Телеграм-канал. Код добавляется в событие OnAfterIBlockElementAdd, которое срабатывает после добавления нового элемента в инфоблок новостей.
Скачать полную версию скрипта можно здесь.
.webp)
Актуальный код скрипта
Важные пояснения к коду
Если собираетесь воспользоваться нашим кодом, обратите внимание на эти моменты.
Здесь регистрируется обработчик события OnAfterIBlockElementAdd, который будет вызывать функцию sendNewsToTelegram после добавления нового элемента в инфоблок. Если этого не сделать, новые статьи, добавленные на сайт, не будут автоматически публиковаться в Телеграм-канал, а вся автоматизация процесса, описанная в коде, не будет работать.AddEventHandler("iblock", "OnAfterIBlockElementAdd", "sendNewsToTelegram");
Что касается обработки изображения, то и здесь есть несколько подводных камней. Вот как выглядит фрагмент кода, отвечающий за этот процесс:
Если с сохранением изображения через CFile::SaveFile возникают проблемы, нужно анализировать логи. Внимательно следите за тем, как формируется URL изображения ($newsImageUrl) — он должен включать правильный протокол, домен и путь. Кроме того, API Телеграма может вернуть ошибку при попытке отправки изображения (например, из-за недоступности сервера или неправильного формата данных).$newsImageArray = $arFields['PREVIEW_PICTURE'];
$newsImageUrl = '';
$newsImagePath = '';
if ($sendToTelegram) {
if (!empty($newsImageArray) && is_array($newsImageArray)) {
$arImage = [
"name" => $newsImageArray["name"],
"type" => $newsImageArray["type"],
"tmp_name" => $newsImageArray["tmp_name"],
"size" => $newsImageArray["size"],
"MODULE_ID" => "iblock"
];
$newsImageId = CFile::SaveFile($arImage, "iblock");
if ($newsImageId) {
$newsImage = CFile::GetFileArray($newsImageId);
if ($newsImage) {
$newsImageUrl = $newsImage['SRC'];
$newsImagePath = $_SERVER['DOCUMENT_ROOT'] . $newsImageUrl;
}
}
}
// Отправка изображения с подписью в Телеграмм
if ($newsImageUrl) {
$sendPhotoUrl = "https://api.telegram.org/bot$telegramBotToken/sendPhoto";
$photoData = [
'chat_id' => $chatId,
'photo' => $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['SERVER_NAME'].$newsImageUrl,
'caption' => "<b>$newsTitle</b>\n\n $newsDetail\n\n $link",
'parse_mode' => 'HTML'
];
$httpClient = new HttpClient();
$responsePhoto = $httpClient->post($sendPhotoUrl, $photoData);
$httpCodePhoto = $httpClient->getStatus();
} else {
У вас остались вопросы по технической реализации такого решения? Приходите в МОАB, мы знаем, как решать такие задачи и готовы проконсультировать.

