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

IM

Чаты и участники

Рабочая справка по чатам Bitrix24 через PHP: ChatTable, RelationTable, получение чата, поиск по внешней сущности и участники чата.

В коробочном PHP чат лучше рассматривать как запись в ChatTable, а участников — как записи в RelationTable. Сам чат и состав участников хранятся отдельно.

Чаты

Чат хранит общую информацию: ID, тип, название, внешнюю привязку, автора и служебные поля.

Что хранит ChatTable

Для чтения данных чата используется Bitrix\Im\Model\ChatTable. Это D7 ORM таблица модуля im.

Поле Что означает
ID ID чата. В REST часто используется как chat123, а в таблицах — просто 123.
TITLE Название чата.
TYPE Тип чата: личный, групповой, открытая линия и другие варианты.
ENTITY_TYPE Внешний тип привязки, например CRM, TASKS или другой модуль.
ENTITY_ID Внешний ID привязки. Формат зависит от модуля.
AUTHOR_ID Создатель чата, если применимо.

Получить чат по ID

<?php

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

Loader::includeModule('im');

/**
 * Получает чат по ID.
 */
function fetchChatById(int $chat_id): ?array
{
    $chat = ChatTable::getList([
        'select' => [
            'ID',
            'TITLE',
            'TYPE',
            'ENTITY_TYPE',
            'ENTITY_ID',
            'AUTHOR_ID',
        ],
        'filter' => [
            '=ID' => $chat_id,
        ],
        'limit' => 1,
    ])->fetch();

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

$chat = fetchChatById($chat_id);

print_r($chat);

Если ID пришёл из REST как chat123, перед запросом к таблице нужно убрать префикс chat.

/**
 * Преобразует dialog id в числовой ID чата.
 */
function parseChatId(string $dialog_id): int
{
    if (preg_match('/^chat(\d+)$/', $dialog_id, $matches)) {
        return (int) $matches[1];
    }

    return (int) $dialog_id;
}

$chat_id = parseChatId('chat123');

Найти чаты по внешней сущности

У чата может быть внешняя привязка через ENTITY_TYPE и ENTITY_ID. Это удобно для поиска CRM-чата, task-чата или чата своего модуля.

<?php

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

Loader::includeModule('im');

/**
 * Получает чаты по внешней сущности.
 */
function fetchChatsByEntity(string $entity_type, string $entity_id): array
{
    $chats = [];

    $chat_result = ChatTable::getList([
        'select' => [
            'ID',
            'TITLE',
            'TYPE',
            'ENTITY_TYPE',
            'ENTITY_ID',
        ],
        'filter' => [
            '=ENTITY_TYPE' => $entity_type,
            '=ENTITY_ID' => $entity_id,
        ],
        'order' => [
            'ID' => 'DESC',
        ],
    ]);

    while ($chat = $chat_result->fetch()) {
        $chats[] = $chat;
    }

    return $chats;
}

$chats = fetchChatsByEntity('CRM', 'DEAL|123');

print_r($chats);

Формат ENTITY_ID зависит от источника. Для CRM, задач и открытых линий лучше сначала вывести реальную запись чата и посмотреть значения на своём портале.

Участники

Участники чата хранятся отдельно от самого чата. Один чат — много записей в таблице связей.

Что хранит RelationTable

Для чтения участников используется Bitrix\Im\Model\RelationTable.

Поле Что означает
CHAT_ID ID чата.
USER_ID ID пользователя-участника.
MESSAGE_TYPE Тип диалога или сообщения для связи.
STATUS Статус участия.
LAST_ID Последнее прочитанное сообщение.
COUNTER Счётчик непрочитанных сообщений для пользователя.

Получить участников чата

<?php

use Bitrix\Main\Loader;
use Bitrix\Im\Model\RelationTable;
use Bitrix\Main\UserTable;

Loader::includeModule('im');

/**
 * Получает участников чата.
 */
function fetchChatUsers(int $chat_id): array
{
    $users = [];

    $relation_result = RelationTable::getList([
        'select' => [
            'CHAT_ID',
            'USER_ID',
            'STATUS',
            'COUNTER',
            'USER_NAME' => 'USER.NAME',
            'USER_LAST_NAME' => 'USER.LAST_NAME',
            'USER_LOGIN' => 'USER.LOGIN',
        ],
        'filter' => [
            '=CHAT_ID' => $chat_id,
        ],
        'runtime' => [
            'USER' => [
                'data_type' => UserTable::class,
                'reference' => [
                    '=this.USER_ID' => 'ref.ID',
                ],
            ],
        ],
        'order' => [
            'USER_ID' => 'ASC',
        ],
    ]);

    while ($user = $relation_result->fetch()) {
        $users[] = $user;
    }

    return $users;
}

$users = fetchChatUsers($chat_id);

print_r($users);

Проверить участие пользователя

<?php

use Bitrix\Main\Loader;
use Bitrix\Im\Model\RelationTable;

Loader::includeModule('im');

/**
 * Проверяет, состоит ли пользователь в чате.
 */
function hasUserInChat(int $chat_id, int $user_id): bool
{
    $relation = RelationTable::getList([
        'select' => [
            'CHAT_ID',
            'USER_ID',
        ],
        'filter' => [
            '=CHAT_ID' => $chat_id,
            '=USER_ID' => $user_id,
        ],
        'limit' => 1,
    ])->fetch();

    return is_array($relation);
}

$has_user = hasUserInChat($chat_id, $user_id);

var_dump($has_user);

Для добавления и удаления участников лучше использовать штатные методы мессенджера или REST-методы im.chat.user.*, а таблицы использовать в первую очередь для чтения и диагностики.

Источники