IM
Сообщения, файлы и поиск
Рабочая справка по сообщениям Bitrix24 через PHP: MessageTable, LinkFileTable, получение истории, файлы и поиск по тексту сообщений.
Сообщения чата хранятся отдельно от чата. Для чтения истории обычно используют
MessageTable, для файлов — связи сообщений с файлами, а для быстрого поиска —
индекс сообщений.
Сообщения
Сообщение — это запись с ID чата, автором, датой и текстом.
Что хранит MessageTable
Для чтения сообщений используется Bitrix\Im\Model\MessageTable.
| Поле | Что означает |
|---|---|
ID | ID сообщения. |
CHAT_ID | ID чата. |
AUTHOR_ID | ID автора. Для системных сообщений может быть 0. |
MESSAGE | Текст сообщения. |
DATE_CREATE | Дата создания. |
NOTIFY_EVENT | Служебное событие уведомления, если сообщение связано с notify. |
Получить сообщения чата
<?php
use Bitrix\Main\Loader;
use Bitrix\Im\Model\MessageTable;
Loader::includeModule('im');
/**
* Получает последние сообщения чата.
*/
function fetchChatMessages(int $chat_id, int $limit): array
{
$messages = [];
$message_result = MessageTable::getList([
'select' => [
'ID',
'CHAT_ID',
'AUTHOR_ID',
'MESSAGE',
'DATE_CREATE',
'NOTIFY_EVENT',
],
'filter' => [
'=CHAT_ID' => $chat_id,
],
'order' => [
'ID' => 'DESC',
],
'limit' => $limit,
]);
while ($message = $message_result->fetch()) {
$messages[] = $message;
}
return array_reverse($messages);
}
$messages = fetchChatMessages($chat_id, 50);
print_r($messages); Исключить системные сообщения
Для анализа пользовательской активности часто нужно убрать системные сообщения:
например, сообщения с AUTHOR_ID = 0.
<?php
use Bitrix\Main\Loader;
use Bitrix\Im\Model\MessageTable;
Loader::includeModule('im');
/**
* Получает пользовательские сообщения чата.
*/
function fetchUserChatMessages(int $chat_id, int $limit): array
{
$messages = [];
$message_result = MessageTable::getList([
'select' => [
'ID',
'CHAT_ID',
'AUTHOR_ID',
'MESSAGE',
'DATE_CREATE',
],
'filter' => [
'=CHAT_ID' => $chat_id,
'>AUTHOR_ID' => 0,
],
'order' => [
'ID' => 'DESC',
],
'limit' => $limit,
]);
while ($message = $message_result->fetch()) {
$messages[] = $message;
}
return array_reverse($messages);
}
$messages = fetchUserChatMessages($chat_id, 50);
print_r($messages);
Если нужно убрать конкретные служебные события, добавь фильтр по
NOTIFY_EVENT после проверки реальных значений на своём портале.
Файлы
Файлы в сообщениях обычно хранятся отдельно, а сообщение содержит связь с файлом.
Файлы в сообщениях
В REST-истории сообщений файлы возвращаются отдельным объектом. В коробке для
диагностики можно смотреть связи сообщений с файлами через таблицы модуля
im.
Получить связи с файлами
Пример ниже — рабочая заготовка для поиска файлов по ID сообщений. На конкретной версии
коробки проверь фактические поля LinkFileTable.
<?php
use Bitrix\Main\Loader;
use Bitrix\Im\Model\LinkFileTable;
Loader::includeModule('im');
/**
* Получает связи сообщений с файлами.
*/
function fetchMessageFileLinks(array $message_ids): array
{
if (empty($message_ids)) {
return [];
}
$file_links = [];
$file_link_result = LinkFileTable::getList([
'select' => [
'ID',
'CHAT_ID',
'MESSAGE_ID',
'FILE_ID',
'DISK_FILE_ID',
],
'filter' => [
'@MESSAGE_ID' => $message_ids,
],
'order' => [
'MESSAGE_ID' => 'ASC',
'ID' => 'ASC',
],
]);
while ($file_link = $file_link_result->fetch()) {
$file_links[] = $file_link;
}
return $file_links;
}
$file_links = fetchMessageFileLinks($message_ids);
print_r($file_links); Поиск
Для простого поиска можно фильтровать сообщения, для быстрого — использовать индекс.
Поиск через MessageTable
Простой вариант подходит для небольшого объёма или служебной проверки. Для больших чатов он может быть тяжёлым.
<?php
use Bitrix\Main\Loader;
use Bitrix\Im\Model\MessageTable;
Loader::includeModule('im');
/**
* Ищет сообщения по подстроке.
*/
function searchMessagesByText(int $chat_id, string $text, int $limit): array
{
$messages = [];
$message_result = MessageTable::getList([
'select' => [
'ID',
'CHAT_ID',
'AUTHOR_ID',
'MESSAGE',
'DATE_CREATE',
],
'filter' => [
'=CHAT_ID' => $chat_id,
'%MESSAGE' => $text,
'>AUTHOR_ID' => 0,
],
'order' => [
'ID' => 'DESC',
],
'limit' => $limit,
]);
while ($message = $message_result->fetch()) {
$messages[] = $message;
}
return $messages;
}
$messages = searchMessagesByText($chat_id, 'договор', 20);
print_r($messages); Полнотекстовый поиск
Для поиска по большим объёмам сообщений используется индекс сообщений. В коробке часто
смотрят в сторону таблицы b_im_message_index и полнотекстового поиска.
<?php
use Bitrix\Main\Application;
use Bitrix\Main\Loader;
Loader::includeModule('im');
/**
* Ищет сообщения через полнотекстовый индекс.
*/
function searchIndexedMessages(string $query, int $limit): array
{
$connection = Application::getConnection();
$sql_helper = $connection->getSqlHelper();
$safe_query = $sql_helper->forSql($query);
$limit = max(1, min($limit, 100));
$sql = "
SELECT
MESSAGE_ID,
CHAT_ID
FROM b_im_message_index
WHERE MATCH(SEARCH_CONTENT) AGAINST ('{$safe_query}' IN BOOLEAN MODE)
ORDER BY MESSAGE_ID DESC
LIMIT {$limit}
";
$rows = [];
$result = $connection->query($sql);
while ($row = $result->fetch()) {
$rows[] = $row;
}
return $rows;
}
$rows = searchIndexedMessages('+договор*', 20);
print_r($rows); Перед использованием проверь структуру индекса на своём портале: название поля с текстом и наличие FULLTEXT-индекса могут отличаться в зависимости от версии модуля.