CRM
Записи таймлайна
Работа с записями таймлайна CRM: системные события, история карточки, привязки и отличие от дел.
Главная особенность: записи таймлайна не являются делами CRM. Поэтому методы
CCrmActivity и crm.activity.* подходят только для дел, но не для
системных записей вроде создания карточки, смены стадии или изменения связей.
Основные операции
Базовая работа с записями таймлайна: получить список записей, изменить запись или удалить её.
Получить записи таймлайна
Такой вариант получает записи, которые связаны с CRM-сущностью через поля
ASSOCIATED_ENTITY_TYPE_ID и ASSOCIATED_ENTITY_ID. Например,
можно найти записи, связанные со сделкой.
<?php
use Bitrix\Main\Loader;
use Bitrix\Crm\Timeline\Entity\TimelineTable;
const CRM_DEAL_TYPE_ID = \CCrmOwnerType::Deal;
Loader::includeModule('crm');
/**
* Получает записи таймлайна, связанные с CRM-сущностью.
*/
function fetchTimelineRecordsByAssociatedEntity(int $entity_id, int $entity_type_id): array
{
$timeline_records = [];
$timeline_result = TimelineTable::getList([
'select' => [
'ID',
'TYPE_ID',
'TYPE_CATEGORY_ID',
'CREATED',
'AUTHOR_ID',
'ASSOCIATED_ENTITY_TYPE_ID',
'ASSOCIATED_ENTITY_ID',
],
'filter' => [
'=ASSOCIATED_ENTITY_ID' => $entity_id,
'=ASSOCIATED_ENTITY_TYPE_ID' => $entity_type_id,
],
'order' => [
'ID' => 'ASC',
],
]);
while ($timeline_record = $timeline_result->fetch()) {
$timeline_records[] = $timeline_record;
}
return $timeline_records;
}
$timeline_records = fetchTimelineRecordsByAssociatedEntity($deal_id, CRM_DEAL_TYPE_ID); Этот способ удобен, когда нужно найти событие, которое напрямую связано с конкретной сущностью. Но он не всегда равен тому списку, который пользователь видит в таймлайне карточки.
Изменить запись таймлайна
Запись таймлайна можно изменить через TimelineTable::update(). Например,
так можно поправить дату записи, если сама карточка уже изменена, а запись в таймлайне
осталась со старой датой.
<?php
use Bitrix\Main\Loader;
use Bitrix\Main\Type\DateTime;
use Bitrix\Crm\Timeline\Entity\TimelineTable;
Loader::includeModule('crm');
/**
* Изменяет дату создания записи таймлайна.
*/
function updateTimelineRecordCreatedDate(int $timeline_record_id, DateTime $created_date): array
{
$update_result = TimelineTable::update(
$timeline_record_id,
[
'CREATED' => $created_date,
]
);
return [
'is_success' => $update_result->isSuccess(),
'error_messages' => $update_result->getErrorMessages(),
];
}
$created_date = new DateTime('01.04.2026 09:00:00');
$update_result = updateTimelineRecordCreatedDate($timeline_record_id, $created_date);
if ($update_result['is_success']) {
// Запись таймлайна обновлена
} else {
var_dump($update_result['error_messages']);
} Удалить запись таймлайна
Удалять записи таймлайна нужно осторожно. Это история карточки, и после удаления
событие может пропасть из интерфейса CRM. Перед удалением лучше сначала вывести запись
и проверить, что найден именно нужный ID.
<?php
use Bitrix\Main\Loader;
use Bitrix\Crm\Timeline\Entity\TimelineTable;
Loader::includeModule('crm');
/**
* Удаляет запись таймлайна.
*/
function deleteTimelineRecord(int $timeline_record_id): array
{
$delete_result = TimelineTable::delete($timeline_record_id);
return [
'is_success' => $delete_result->isSuccess(),
'error_messages' => $delete_result->getErrorMessages(),
];
}
$delete_result = deleteTimelineRecord($timeline_record_id);
if ($delete_result['is_success']) {
// Запись таймлайна удалена
} else {
var_dump($delete_result['error_messages']);
} Привязки
Привязки объясняют, почему запись таймлайна может отображаться в карточке CRM. Отдельно есть сама запись, отдельно — связь этой записи с карточкой.
Получить записи, которые видны в карточке
Если нужно получить именно те записи, которые отображаются в таймлайне карточки, лучше
идти через TimelineBindingTable. Сначала получаем ID записей из привязок,
потом сами записи из TimelineTable.
<?php
use Bitrix\Main\Loader;
use Bitrix\Crm\Timeline\Entity\TimelineTable;
use Bitrix\Crm\Timeline\Entity\TimelineBindingTable;
const CRM_DEAL_TYPE_ID = \CCrmOwnerType::Deal;
const TIMELINE_LIMIT = 20;
Loader::includeModule('crm');
/**
* Получает ID записей таймлайна, привязанных к CRM-карточке.
*/
function fetchTimelineRecordIdsByBinding(int $entity_id, int $entity_type_id): array
{
$timeline_record_ids = [];
$binding_result = TimelineBindingTable::getList([
'select' => [
'OWNER_ID',
],
'filter' => [
'=ENTITY_ID' => $entity_id,
'=ENTITY_TYPE_ID' => $entity_type_id,
],
'order' => [
'OWNER_ID' => 'ASC',
],
]);
while ($binding = $binding_result->fetch()) {
$timeline_record_ids[] = (int) $binding['OWNER_ID'];
}
return array_values(array_unique($timeline_record_ids));
}
/**
* Получает записи таймлайна по ID.
*/
function fetchTimelineRecordsByIds(array $timeline_record_ids, int $limit): array
{
if (empty($timeline_record_ids)) {
return [];
}
$timeline_records = [];
$timeline_result = TimelineTable::getList([
'select' => [
'ID',
'TYPE_ID',
'TYPE_CATEGORY_ID',
'CREATED',
'AUTHOR_ID',
'ASSOCIATED_ENTITY_TYPE_ID',
'ASSOCIATED_ENTITY_ID',
],
'filter' => [
'@ID' => $timeline_record_ids,
],
'order' => [
'CREATED' => 'DESC',
'ID' => 'DESC',
],
'limit' => $limit,
]);
while ($timeline_record = $timeline_result->fetch()) {
$timeline_records[] = $timeline_record;
}
return $timeline_records;
}
$timeline_record_ids = fetchTimelineRecordIdsByBinding($deal_id, CRM_DEAL_TYPE_ID);
$timeline_records = fetchTimelineRecordsByIds($timeline_record_ids, TIMELINE_LIMIT); Получить привязки записи
Так можно посмотреть, к каким CRM-сущностям привязана конкретная запись таймлайна. Это полезно, если событие видно не только в одной карточке.
<?php
use Bitrix\Main\Loader;
use Bitrix\Crm\Timeline\Entity\TimelineBindingTable;
Loader::includeModule('crm');
/**
* Получает привязки записи таймлайна.
*/
function fetchTimelineRecordBindings(int $timeline_record_id): array
{
$timeline_bindings = [];
$binding_result = TimelineBindingTable::getList([
'select' => [
'OWNER_ID',
'ENTITY_ID',
'ENTITY_TYPE_ID',
],
'filter' => [
'=OWNER_ID' => $timeline_record_id,
],
'order' => [
'ENTITY_TYPE_ID' => 'ASC',
'ENTITY_ID' => 'ASC',
],
]);
while ($timeline_binding = $binding_result->fetch()) {
$timeline_bindings[] = $timeline_binding;
}
return $timeline_bindings;
}
$timeline_bindings = fetchTimelineRecordBindings($timeline_record_id); Коротко про ASSOCIATED и BINDINGS
| Что смотреть | Где находится | Когда использовать |
|---|---|---|
ASSOCIATED_ENTITY_ID | TimelineTable | Когда нужно понять, с какой сущностью связано событие. |
ASSOCIATED_ENTITY_TYPE_ID | TimelineTable | Когда нужно отфильтровать события по типу сущности: сделка, лид, контакт и так далее. |
OWNER_ID | TimelineBindingTable | ID записи таймлайна, которая привязана к карточке. |
ENTITY_ID | TimelineBindingTable | ID карточки CRM, в которой отображается запись. |
ENTITY_TYPE_ID | TimelineBindingTable | Тип карточки CRM, в которой отображается запись. |
-
ASSOCIATED_ENTITY_IDиASSOCIATED_ENTITY_TYPE_IDописывают сущность, с которой связано событие. -
TimelineBindingTableописывает, в какой CRM-карточке запись должна отображаться. - Если нужно получить то, что видно в интерфейсе карточки, надёжнее начинать с привязок.
Практические случаи
Частые ситуации, где записи таймлайна приходится смотреть отдельно от дел CRM.
Дата создания карточки
Если изменить CREATED в самой карточке CRM, дата создания карточки
изменится. Но запись в таймлайне может остаться на прежней дате. Поэтому запись
таймлайна нужно обновлять отдельно.
Пример ниже получает первую запись таймлайна, связанную с карточкой, и меняет ей дату. Перед боевым запуском лучше сначала вывести найденную запись и проверить, что это именно событие создания.
<?php
use Bitrix\Main\Loader;
use Bitrix\Main\Type\DateTime;
use Bitrix\Crm\Timeline\Entity\TimelineTable;
const CRM_DEAL_TYPE_ID = \CCrmOwnerType::Deal;
const TIMELINE_CREATED_DATE = '01.04.2026 09:00:00';
Loader::includeModule('crm');
/**
* Получает первую запись таймлайна, связанную с CRM-сущностью.
*/
function fetchFirstTimelineRecordByAssociatedEntity(int $entity_id, int $entity_type_id): ?array
{
$timeline_record = TimelineTable::getList([
'select' => [
'ID',
'TYPE_ID',
'TYPE_CATEGORY_ID',
'CREATED',
'ASSOCIATED_ENTITY_TYPE_ID',
'ASSOCIATED_ENTITY_ID',
],
'filter' => [
'=ASSOCIATED_ENTITY_ID' => $entity_id,
'=ASSOCIATED_ENTITY_TYPE_ID' => $entity_type_id,
],
'order' => [
'ID' => 'ASC',
],
'limit' => 1,
])->fetch();
return is_array($timeline_record) ? $timeline_record : null;
}
/**
* Изменяет дату создания записи таймлайна.
*/
function updateTimelineRecordCreatedDate(int $timeline_record_id, DateTime $created_date): array
{
$update_result = TimelineTable::update(
$timeline_record_id,
[
'CREATED' => $created_date,
]
);
return [
'is_success' => $update_result->isSuccess(),
'error_messages' => $update_result->getErrorMessages(),
];
}
$created_date = new DateTime(TIMELINE_CREATED_DATE);
$timeline_record = fetchFirstTimelineRecordByAssociatedEntity($deal_id, CRM_DEAL_TYPE_ID);
if ($timeline_record === null) {
echo 'Запись таймлайна не найдена';
return;
}
$update_result = updateTimelineRecordCreatedDate((int) $timeline_record['ID'], $created_date);
if ($update_result['is_success']) {
echo 'Дата записи таймлайна обновлена';
} else {
var_dump($update_result['error_messages']);
} История стадий и связей
Через записи таймлайна можно смотреть не только создание карточки. В таймлайне могут быть перемещения по стадиям, добавление или удаление связей, комментарии и другие события.
Точные значения TYPE_ID лучше проверять на конкретном портале и конкретной
версии коробки. Для рабочей диагностики обычно сначала получают список записей, выводят
TYPE_ID, TYPE_CATEGORY_ID, CREATED и уже потом
делают точный фильтр.
<?php
use Bitrix\Main\Loader;
use Bitrix\Crm\Timeline\Entity\TimelineTable;
const CRM_DEAL_TYPE_ID = \CCrmOwnerType::Deal;
Loader::includeModule('crm');
/**
* Получает короткий список записей таймлайна для диагностики.
*/
function fetchTimelineRecordsForDebug(int $entity_id, int $entity_type_id): array
{
$timeline_records = [];
$timeline_result = TimelineTable::getList([
'select' => [
'ID',
'TYPE_ID',
'TYPE_CATEGORY_ID',
'CREATED',
'AUTHOR_ID',
'ASSOCIATED_ENTITY_TYPE_ID',
'ASSOCIATED_ENTITY_ID',
],
'filter' => [
'=ASSOCIATED_ENTITY_ID' => $entity_id,
'=ASSOCIATED_ENTITY_TYPE_ID' => $entity_type_id,
],
'order' => [
'CREATED' => 'ASC',
'ID' => 'ASC',
],
]);
while ($timeline_record = $timeline_result->fetch()) {
$timeline_records[] = $timeline_record;
}
return $timeline_records;
}
$timeline_records = fetchTimelineRecordsForDebug($deal_id, CRM_DEAL_TYPE_ID);
print_r($timeline_records);