← Назад к справке

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);

Источники