Работаю с REST API Bitrix24 регулярно, и один из первых методов, который трогаю в интеграциях с воронкой продаж, это crm.timeline.comment.add. Он добавляет текстовую запись в ленту сделки, лида, контакта или компании без создания задачи, ответственного или дедлайна. На практике через него фиксирую события из внешних систем: оплату из T‑Bank, статус посылки от СДЭК, сообщение из aiogram-бота или заявку с Tilda-формы. Всё это оседает прямо в истории карточки, и менеджер видит контекст, не открывая соседние сервисы.
Зачем нужен crm.timeline.comment.add и чем он отличается от активности
В Bitrix24 лента сделки собирает три типа записей: активности через crm.activity.add (звонки, встречи, задачи с ответственным и сроком), системные события от самой платформы (смена стадии, создание счёта, изменение суммы) и комментарии. Комментарий не требует ответственного, планового времени и статуса выполнения, это просто текстовая пометка с автором и датой создания.
Использую comment, когда факт нужно зафиксировать, но никому не нужно закрывать его как задачу: пришёл платёж, изменился статус доставки, клиент написал в чат поддержки. Activity беру, когда кого-то в CRM нужно к чему-то обязать: перезвонить клиенту, отправить документы, провести встречу. У активности есть поля RESPONSIBLE_ID и DEADLINE, и она попадает в раздел «Дела» у ответственного сотрудника, а комментарий туда не попадает и не создаёт уведомление о задаче.
Например, у интернет-магазина на WooCommerce с оплатой через T‑Bank эквайринг настроен так: при смене статуса заказа на «оплачен» вебхук магазина сразу шлёт crm.timeline.comment.add в связанную сделку Bitrix24 с суммой и номером платежа. Заводить отдельную активность на менеджера тут незачем, ему нужно просто видеть факт оплаты в истории, а не выполнять действие.
На практике смешивать методы не стоит. Если через n8n или бота заводить активности вместо комментариев для каждого технического события, список дел у менеджеров быстро зарастает записями, которые не требуют реального действия, и он перестаёт быть рабочим инструментом.
Обязательные и опциональные поля метода
Метод принимает единственный параметр fields с вложенным набором значений. Из обязательных, по сути, три поля, остальное можно не передавать вовсе.
| Поле | Обязательное | Что указываем |
|---|---|---|
ENTITY_ID |
да | ID сделки, лида, контакта или компании, к которой крепим запись |
ENTITY_TYPE |
да | тип сущности: deal, lead, contact, company, quote, invoice |
COMMENT |
да | текст комментария, поддерживает BB-код: [B], [I], [URL] |
AUTHOR_ID |
нет | ID пользователя, от чьего имени показать запись, по умолчанию берётся владелец вебхука |
FILES |
нет | вложения к комментарию, массив пар «имя файла + содержимое» |
В тексте COMMENT можно использовать перенос строки и базовую разметку BB-кодом: [B]жирный[/B], [URL=адрес]текст[/URL]. HTML-теги внутри текста не воспринимаются как разметка и выводятся как обычные символы, этим поле отличается от некоторых других полей CRM, где HTML допустим.
AUTHOR_ID передаю, когда запись физически создаёт скрипт интеграции, но по смыслу должна выглядеть как пометка конкретного менеджера, например при переносе истории переписки из старой CRM с сохранением прежнего ответственного.
ENTITY_TYPE указываю строго строчными буквами. Заглавная буква или опечатка в названии типа не даёт явную ошибку валидации, метод просто не находит сущность и возвращает ошибку поиска, что на отладке путает больше, чем прямой отказ.
| ENTITY_TYPE | Сущность | Пример ID |
|---|---|---|
| deal | сделка | 481 |
| lead | лид | 152 |
| contact | контакт | 90 |
| company | компания | 34 |
| quote | коммерческое предложение | 7 |
Результат вызова, поле result, это ID созданного комментария (COMMENT_ID). Сохраняю его в лог интеграции: пригодится, если позже нужно поправить текст через crm.timeline.comment.update или убрать запись через crm.timeline.comment.delete.
Запрос через вебхук: примеры на bash и PHP
Для одиночной интеграции хватает входящего вебхука, без регистрации полноценного приложения. В портале захожу в раздел «Разработчикам», вкладка «Другое», пункт «Входящий вебхук», выбираю права crm и получаю ссылку вида https://портал.bitrix24.ru/rest/1/код_вебхука/. К ней добавляю имя метода и параметры запроса.
curl -X POST \
"https://портал.bitrix24.ru/rest/1/XXXXXXXXXXXXXXXX/crm.timeline.comment.add.json" \
-H "Content-Type: application/json" \
-d '{
"fields": {
"ENTITY_ID": 481,
"ENTITY_TYPE": "deal",
"COMMENT": "Оплата поступила через T-Bank, счёт закрыт, сумма 48000 руб."
}
}'
Тот же вызов на PHP, если комментарий формируется внутри собственного бэкенда, например при обработке вебхука от эквайринга или скрипта на сайте.
$webhook = 'https://портал.bitrix24.ru/rest/1/XXXXXXXXXXXXXXXX/';
$fields = [
'ENTITY_ID' => 481,
'ENTITY_TYPE' => 'deal',
'COMMENT' => 'Курьер СДЭК доставил заказ, статус закрыт.',
];
$ch = curl_init($webhook . 'crm.timeline.comment.add.json');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['fields' => $fields]));
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
echo $result['result']; // ID нового комментария, пригодится для update и delete
Перед тем как встраивать вызов в боевой скрипт, проверяю его в тестере запросов портала (тот же раздел «Разработчикам»): там видно точную структуру ответа и текст ошибки, если с правами или полями что-то не так, это быстрее, чем ловить проблему в логах уже работающей интеграции.
Ответ в обоих случаях содержит result с ID новой записи и блок time с деталями по времени выполнения запроса. При ошибке вместо result придёт error и error_description с человекочитаемым текстом причины, его и смотрю первым делом при отладке.
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Как прикрепить файл к комментарию таймлайна
Поле FILES принимает массив вложений, где каждый элемент это пара: имя файла и его содержимое в base64. Формат такой же, как у других методов Bitrix24, работающих с файлами напрямую через REST, без предварительной загрузки на диск отдельным запросом.
На практике так прикладываю акт от СДЭК или счёт из T‑Bank прямо к сделке: менеджеру не нужно искать документ в почте, он открывает карточку и сразу видит вложение в комментарии. Но для файлов от нескольких мегабайт такой подход утяжеляет тело запроса почти на треть из-за кодирования в base64, и вебхук может упереться в лимит размера тела запроса. Вложения свыше 5-10 МБ через это поле не гоняю вообще: у части конфигураций веб-сервера тело POST-запроса и так обрезано настройками nginx или php.ini. В таких случаях загружаю файл на Диск через disk.folder.uploadfile, а в текст комментария вставляю уже готовую ссылку на файл, это надёжнее и быстрее для клиента.
Лимиты запросов и типичные ошибки
У вебхуков и приложений общий лимит на частоту запросов: около 2 запросов в секунду в среднем и пул на всплеск примерно в 50 запросов, дальше начинают приходить ошибки превышения лимита. Если нужно быстро залить историю из старой CRM или из выгрузки CSV, комментарии лучше отправлять через batch-метод: до 50 вызовов crm.timeline.comment.add за один HTTP-запрос вместо отдельного запроса на каждую строку, так лимит расходуется в разы медленнее.
При превышении лимита в ответе приходит QUERY_LIMIT_EXCEEDED, и правильная реакция скрипта, не долбить метод повторным вызовом сразу, а подождать секунду и повторить запрос, иначе очередь только растёт и следующие вызовы тоже начинают падать.
Из ошибок, с которыми сталкивался чаще всего:
ENTITY_IDуказывает на сделку, которая уже удалена или недоступна вебхуку по правам, метод возвращает ошибку поиска сущности.ENTITY_TYPEнаписан с заглавной буквы или с опечаткой (Deal вместо deal), из-за этого сущность не находится, хотя ID указан верно.- у вебхука не хватает прав на CRM, тогда приходит access_denied и текст про недостаточные права доступа.
COMMENTпустой или не передан вовсе, метод отклоняет запрос ещё на этапе валидации полей.
Автоматизация комментариев из внешних систем
Чаще всего этот метод дёргаю не руками, а из сценариев автоматизации. Из aiogram-бота, привязанного к сделке через сохранённый ENTITY_ID, пересылаю сообщения клиента в таймлайн, чтобы менеджер видел переписку без переключения в Telegram. Из формы на Tilda после crm.item.add (или устаревшего, но пока доступного crm.lead.add) тем же запросом записываю в таймлайн UTM-метки и данные о странице, с которой пришла заявка: это удобнее, чем заводить под них отдельные пользовательские поля, которые потом придётся поддерживать.
У одного клиента в n8n собран сценарий с СДЭК: каждые 15 минут workflow опрашивает статус посылки по номеру заказа, и как только статус меняется на «вручена», находит сделку и пишет комментарий в таймлайн без участия менеджера. Похожий сценарий, только с оплатой вместо доставки, у клиентов на WooCommerce и T‑Bank эквайринге.
Если события идут из нескольких систем сразу: эквайринг, доставка, мессенджер, проще не плодить отдельный скрипт под каждый вебхук, а собрать их в одном сценарии через настройку автоматизации в n8n. HTTP-нода дёргает crm.timeline.comment.add по общей логике, а ветвление по источнику события делается прямо в визуальном редакторе, без правок кода при добавлении нового канала.
Частые вопросы
Чем crm.timeline.comment.add отличается от crm.activity.add?
Comment создаёт простую текстовую запись без ответственного и срока. Activity создаёт задачу, звонок или встречу с полями RESPONSIBLE_ID и DEADLINE, которая попадает в раздел «Дела» сотрудника и требует закрытия. Для фиксации факта без действия использую comment, для постановки задачи, которая требует реакции человека, activity.
Можно ли изменить или удалить комментарий после отправки?
Да. ID, который метод возвращает в result, передаю в crm.timeline.comment.update для правки текста или в crm.timeline.comment.delete для удаления записи. Без сохранённого ID искать нужный комментарий среди остальных придётся через crm.timeline.comment.list с фильтром по ENTITY_ID, что заметно медленнее.
Видит ли клиент комментарий, добавленный через REST?
Нет, лента сделки, лида, контакта или компании доступна только сотрудникам портала с правами на карточку. Внешний контакт эту запись не увидит ни в почте, ни в мессенджере, если только вы сами не продублируете текст ему отдельным сообщением вручную.
Можно ли скрыть комментарий от части сотрудников?
На уровне отдельной записи в таймлайне такой настройки нет, видимость определяется правами доступа ко всей сделке или лиду целиком. Если нужно разграничить именно комментарии, обычно выношу такие данные в отдельное пользовательское поле с собственными правами доступа либо во внешний лог, не привязанный к таймлайну CRM.