← Назад к заметкам

Заметки

После удаления лида у чата открытой линии может остаться CRM-привязка

Почему удаление лида из CRM не всегда очищает связь диалога открытой линии с CRM.

Если лид из открытой линии удалён, это ещё не значит, что чат полностью потерял связь с CRM. Перед повторным созданием лида нужно проверить старый CRM-контекст диалога.

Проблема

Лид, созданный из чата открытой линии, удалили из CRM. Потом по тому же чату нужно создать новый лид, но повторный вызов imopenlines.crm.lead.create работает не так, как ожидалось.

У диалога открытой линии может остаться техническая связь с CRM: сессия, чат, дело или привязки дела всё ещё хранят старый контекст. Из-за этого система может считать, что чат уже связан с CRM.

Обычно цепочка такая:

  • по чату открытой линии был создан лид;
  • у чата появилась CRM-привязка к лиду и делу;
  • лид удалили из CRM;
  • часть технических связей осталась;
  • повторный вызов imopenlines.crm.lead.create не создаёт новый лид ожидаемым образом;
  • перед повторным созданием нужно найти и очистить старую связь.

Проблема не в том, что удалённый лид продолжает существовать как обычная CRM-сущность. Чаще мешают оставшиеся связи между открытой линией, CRM-делом и чатом.

Что остаётся

Удаление лида не всегда очищает все связанные технические записи. Особенно если диалог открытой линии был связан не только с лидом, но и с CRM-делом.

У диалога открытой линии может быть отдельный CRM-контекст. Он нужен, чтобы связывать переписку с CRM и находить историю общения из карточки.

Проверять связь лучше не только по самому лиду. Следы могут остаться здесь:

  • в сессии открытой линии;
  • в данных чата;
  • в CRM-деле, созданном для диалога;
  • в привязках дела к CRM-сущностям;
  • во внутренних таблицах связей.

Названия таблиц и набор полей лучше проверять на конкретной версии коробки. Внутренняя структура может отличаться.

Если у чата уже есть CRM-контекст, повторное создание лида через imopenlines.crm.lead.create может не дать нового чистого лида.

Причина обычно в старых технических записях. Диалог всё ещё выглядит связанным с CRM, хотя сам лид уже удалён.

Поэтому перед повторным созданием нужно понять, где осталась связь: в чате, сессии, деле или привязках дела.

Решение

В коробочном Bitrix24 можно предварительно очистить CRM-контекст у сессии открытой линии и у чата. После этого лид создаётся уже без старой привязки.

Общая логика такая:

  • найти сессию открытой линии;
  • сбросить CRM-флаги у сессии;
  • очистить ID CRM-дела у сессии;
  • получить чат по CHAT_ID;
  • очистить CRM-данные в полях чата;
  • после этого отдельно запускать повторное создание лида.

Это работа с внутренними таблицами коробки. Перед применением нужен тестовый портал и резервная копия.

Пример кода

Пример очищает старую CRM-привязку у сессии открытой линии и у чата. Новый лид здесь не создаётся — это лучше делать отдельным шагом после проверки.

<?php

use Bitrix\Main\Loader;
use Bitrix\Im\Model\ChatTable;
use Bitrix\ImOpenLines\Model\SessionTable;

const IM_MODULE_ID = 'im';
const IMOPENLINES_MODULE_ID = 'imopenlines';

Loader::includeModule(IM_MODULE_ID);
Loader::includeModule(IMOPENLINES_MODULE_ID);

/**
 * Очищает старую CRM-привязку у сессии и чата открытой линии.
 */
function clearOpenLineCrmBinding(array $session): void
{
    $session_id = (int)($session['ID'] ?? 0);
    $chat_id = (int)($session['CHAT_ID'] ?? 0);

    if ($session_id <= 0 || $chat_id <= 0) {
        return;
    }

    clearSessionCrmContext($session_id);

    $chat = fetchChatById($chat_id);

    if ($chat === null) {
        return;
    }

    clearChatCrmContext($chat);
}

/**
 * Сбрасывает CRM-контекст сессии открытой линии.
 */
function clearSessionCrmContext(int $session_id): void
{
    SessionTable::update($session_id, [
        'CRM' => 'N',
        'CRM_CREATE' => 'N',
        'CRM_CREATE_LEAD' => 'N',
        'CRM_CREATE_COMPANY' => 'N',
        'CRM_CREATE_CONTACT' => 'N',
        'CRM_CREATE_DEAL' => 'N',
        'CRM_ACTIVITY_ID' => '',
    ]);
}

/**
 * Получает чат по ID.
 */
function fetchChatById(int $chat_id): ?array
{
    $chat_result = ChatTable::getList([
        'select' => [
            'ID',
            'ENTITY_DATA_1',
            'ENTITY_DATA_2',
        ],
        'filter' => [
            '=ID' => $chat_id,
        ],
        'limit' => 1,
    ]);

    $chat = $chat_result->fetch();

    return is_array($chat) ? $chat : null;
}

/**
 * Очищает CRM-контекст в данных чата.
 */
function clearChatCrmContext(array $chat): void
{
    $chat_id = (int)($chat['ID'] ?? 0);

    if ($chat_id <= 0) {
        return;
    }

    $entity_data_1 = resetChatEntityData((string)($chat['ENTITY_DATA_1'] ?? ''));

    ChatTable::update($chat_id, [
        'ENTITY_DATA_1' => $entity_data_1,
        'ENTITY_DATA_2' => '',
    ]);
}

/**
 * Очищает CRM-часть ENTITY_DATA_1.
 */
function resetChatEntityData(string $entity_data_1): string
{
    if ($entity_data_1 === '') {
        return '';
    }

    return '';
}

В примере ENTITY_DATA_1 очищается полностью. Если в конкретном портале в этом поле хранятся ещё какие-то нужные данные, очистку нужно делать точечно.

Перед очисткой связи

Не стоит сразу чистить таблицы. Сначала нужно собрать картину: какой чат, какая сессия, какой лид и какое дело связаны между собой.

  • проверить CHAT_ID открытой линии;
  • найти последнюю сессию по этому чату;
  • посмотреть CRM-поля сессии;
  • проверить данные чата и его CRM-контекст;
  • найти CRM-дело, связанное с диалогом;
  • проверить привязки дела к удалённому лиду;
  • сделать резервную копию перед очисткой.

Очистку лучше выполнять отдельным административным скриптом, а не в обработчике события и не в публичном ajax-действии.

Посмотреть CRM-контекст сессии

Этот пример ничего не очищает. Он находит последнюю сессию открытой линии по чату и выводит CRM-поля, которые полезно увидеть перед повторным созданием лида.

<?php

use Bitrix\Main\Loader;
use Bitrix\ImOpenLines\Model\SessionTable;

const IMOPENLINES_MODULE_ID = 'imopenlines';
const CHAT_ID = 0;

Loader::includeModule(IMOPENLINES_MODULE_ID);

$session_data = fetchLastOpenLineSession(CHAT_ID);

if ($session_data === null) {
    echo 'Сессия открытой линии не найдена';

    return;
}

printSessionCrmContext($session_data);

/**
 * Получает последнюю сессию открытой линии по чату.
 */
function fetchLastOpenLineSession(int $chat_id): ?array
{
    if ($chat_id <= 0) {
        return null;
    }

    $session_result = SessionTable::getList([
        'select' => [
            'ID',
            'CHAT_ID',
            'CRM',
            'CRM_ENTITY_TYPE',
            'CRM_ENTITY_ID',
            'CRM_ACTIVITY_ID',
        ],
        'filter' => [
            '=CHAT_ID' => $chat_id,
        ],
        'order' => [
            'ID' => 'DESC',
        ],
        'limit' => 1,
    ]);

    $session_data = $session_result->fetch();

    return is_array($session_data) ? $session_data : null;
}

/**
 * Выводит CRM-контекст сессии.
 */
function printSessionCrmContext(array $session_data): void
{
    $context_data = [
        'SESSION_ID' => $session_data['ID'] ?? null,
        'CHAT_ID' => $session_data['CHAT_ID'] ?? null,
        'CRM' => $session_data['CRM'] ?? null,
        'CRM_ENTITY_TYPE' => $session_data['CRM_ENTITY_TYPE'] ?? null,
        'CRM_ENTITY_ID' => $session_data['CRM_ENTITY_ID'] ?? null,
        'CRM_ACTIVITY_ID' => $session_data['CRM_ACTIVITY_ID'] ?? null,
    ];

    echo '<pre>';
    print_r($context_data);
    echo '</pre>';
}

Если после удаления лида в сессии или чате всё ещё видны старые CRM-значения, значит перед повторным созданием лида нужно сначала разбирать эту привязку.