Imopenlines 26.700.0–26.900.0: статистика V2 и новые контракты истории
Ломающее обновление
Удалены или изменены публичные API — прикладной код может перестать работать.
Открытые линии пришли одной пачкой из пяти версий: 26.700.0, 26.700.100, 26.800.0, 26.850.0 и 26.900.0. Главное для разработчика — REST-методы статистики V2 и событие, которое меняет текст перед отправкой клиенту. Главное для интеграций: imopenlines.session.history.get теперь отдаёт историю страницами, а проверки прав в коннекторах, роботе и REST-настройках линий стали строже.
Новое
Забирайте статистику через REST V2
Появились методы imopenlines.v2.Session.list, Session.Stat.get, Session.Transfer.list, Session.Rating.list, Operator.list и Stat.get: диалоги, показатели сессий, переводы, оценки, загрузка операторов и сводка за период.
BX24.callMethod('imopenlines.v2.Stat.get', {
dateFrom: '2026-10-01',
dateTo: '2026-10-31',
configIdList: [1, 3],
}, (result) => console.log(result.data()));
У Stat.get и Session.Rating.list период обязателен и не длиннее 366 календарных дней. Списки отдают по 50 записей, максимум 200, offset у Session.list и Session.Rating.list не больше 10000. Пакетная статистика принимает до 100 ID сессий, переводы до 50, списковый фильтр до 1000 значений. sessionsByHour содержит 24 часа в часовом поясе сервера.
Методы доступны пользователю интранета, если тариф проходит Limit::canUseReport(), а у пользователя есть право ENTITY_SESSION/ACTION_VIEW. Если тариф или права на линию не дают видеть оценку руководителя и комментарий, эти поля придут null. Недоступная сессия вернёт null-метрики, пустые агрегаты — нули.
Меняйте текст перед отправкой клиенту
Событие OnBeforeImopenlineMessageDeliver срабатывает прямо перед уходом сообщения во внешний канал, когда подпись оператора и преобразования транспорта уже применены. Обработчик получает MESSAGE_ID, MESSAGE, PARAMS и OPERATION (send или update) и кладёт новый текст в MESSAGE. Пустой текст игнорируется.
use Bitrix\Main\Event;
use Bitrix\Main\EventManager;
EventManager::getInstance()->addEventHandler(
'imopenlines',
'OnBeforeImopenlineMessageDeliver',
static function (Event $event): void {
if ($event->getParameter('OPERATION') !== 'send') {
return;
}
$text = (string) $event->getParameter('MESSAGE');
$event->setParameter('MESSAGE', $text . "\n\nОтвечаем с 9:00 до 18:00 по Москве");
}
);
История, оценки и отделы
История диалога открывается в отдельном слайдере V2: сообщения и закрепы ограничены сессией, старые страницы догружаются. Из JS слайдер открывает LinesHistoryApplication.openInSlider(), а StatisticsGridApplication подключает редактирование оценок в гриде. Права на историю, включая доступ через CRM, проверяются для переданного пользователя, а пустая CRM-привязка с ID 0 доступа больше не даёт.
Оценку руководителя и комментарий теперь правят в одном окне, ячейки статистики обновляются по Pull. Клиент может изменить свою оценку в окне последнего запроса до 20 раз, IMOL_TIME_LIMIT_VOTE=0 снимает срок. Повтор той же оценки не рассылает события и уведомления, а исправление не закрывает сессию второй раз.
Chat.addMembers принимает userIds и departmentIds, Department.list отдаёт отделы. Сотрудники отдела, включая руководителя, добавляются без дублей, нужен доступ к чату и действие Extend.
CRM-триггеры и мелкие API
Триггер исходящего сообщения срабатывает, когда канал принял сообщение или оно создано в клиентском livechat, и поздняя ошибка доставки его не отменяет. Служебные, скрытые и клиентские сообщения, а также сообщения ботов и роботов его не запускают. Триггер закрытия срабатывает на переходе CLOSED=N→Y, кроме spam и force, но при параллельном закрытии единственный вызов не гарантирован. Триггер нового сообщения боту возвращает configId даже без CRM.
Для своих расширений из imopenlines.v2.provider.service экспортируются HistoryLoadService, DepartmentService и VoteHeadService, из imopenlines.v2.lib.utils — resolveLineId и buildSendableImageLink. На PHP Tools\Url::getSafeExternalUrl() пропускает только абсолютные HTTP(S)-ссылки без управляющих символов, пробелов и обратного слеша, getSafeHost() достаёт из ссылки host. Common::isAgreementAvailable() проверяет, есть ли активное соглашение. Config::getList() принимает ACCESS_FILTER типа ConditionTree, который соединяется с вашим фильтром через AND, и тогда допустимы только ключи select, filter, order, limit, offset.
Что сломается
Листайте историю сессии страницами
Если установленный im поддерживает пагинацию, imopenlines.session.history.get отдаёт 50 сообщений по умолчанию и не больше 200. Интеграция, которая ждала всю историю одним ответом, получит только первую страницу. Перебирайте страницы по курсору:
// callMethod — ваша обёртка над BX24.callMethod, которая возвращает Promise с result.data()
let cursor = {};
let page;
do {
page = await callMethod('imopenlines.session.history.get', {
CHAT_ID: chatId, SESSION_ID: sessionId, LIMIT: 200, ...cursor,
});
messages.push(...Object.values(page.MESSAGE));
cursor = { LAST_ID: page.NEXT_ID, LAST_DATE: page.NEXT_DATE };
} while (page.HAS_NEXT_PAGE);
Последний запрос может вернуть пустую страницу: HAS_NEXT_PAGE считается по заполненности страницы. Со старым im метод отдаёт всё сразу, как раньше.
Замените вызовы API
Chat::sendPullUpdateSilentMode()удалён. Тихий режим ставятOperator::setSilentMode()илиSilentMode\PersonalSilentMode::set(), второй возвращаетboolи сам шлёт персональный Pull после записи.FinishServiceизimopenlines.v2.provider.serviceпереименован вSessionFinishServiceбез алиаса. Ошибки завершения теперь отклоняют Promise, уведомление показывает вызывающий код.imopenlines.v2.QuickReply.saveFromMessageвозвращает{id: …}вместо{result: true}. На PHPOperator::saveToQuickAnswers()отдаёт ID илиfalse, в JSQuickReplyService.saveFromMessage()— ID илиnull. НеобязательныйlineIdвыбирает линию, без него берётся активная сессия. Старый REST-обработчикRest::messageSaveToQuickAnswer()по-прежнему отвечаетtrue.Recent::getNonAnsweredLines()по умолчанию отдаёт не больше 100 чатов, предел меняет положительныйlimit.$userIdсталintуQueue\Event\All::returnNotAcceptedSessionsToQueue(),Queue\Event\Queue::returnNotAcceptedSessionsToQueue()иreturnSessionsUsersToQueueIsStartAbsence(). Вызов со строкой из файла соstrict_types=1упадёт сTypeError.
Проверьте права в коннекторах, роботе и REST
- В
extraконнектора принимаются толькоPORTAL_ID,EXTRA_URL,EXTRA_TARIFF,EXTRA_USER_LEVEL,EXTRA_PORTAL_TYPE,EXTRA_REGISTERиEXTRA_DEVICE_TYPE, причёмPORTAL_IDтолько отnetwork. Остальные поля молча отбрасываются. - Робот «Сообщение в открытую линию» проверяет файлы Диска с правами редактора при сохранении и импорте и с правами автора шаблона при выполнении, удалённые файлы отклоняет. Из
b_fileможно прикладывать файловые поля текущего документа и файловые результаты активити. Голые ID, переменные, константы и результаты REST-активити больше не пройдут, ошибка попадёт в журнал и таймлайн CRM. - REST
configGetтребуетConfig::canViewLine(),configListGetвсегда ограничивает список доступными линиями, даже безCHECK_PERMISSION,configAddтребует права изменения. Отказ —CONFIG_WRONG_USER_PERMISSION.imopenlines.widget.vote.sendтребует авторизации, чужая сессия даётVOTE_ERROR. - Аватар линии или оператора очереди можно взять только из своих свежих загрузок или из уже привязанных к линии. Включить соглашение без активного соглашения нельзя, а смена соглашения снова показывает предупреждение.
БД
В b_imopenlines_session добавлен nullable PORTAL_ID, в b_imopenlines_user_relation — SHOWN_AGREEMENT_ID (ORM-default 0, старое пустое значение отличает прежние записи). Замена пользователя сохраняет ID соглашения и пропускает некорректные записи с диагностикой imopenlines.session.replacement_user_code.
Мелочи и находки
- Действия CRM, история, закрепление, перехват и спам переехали в боковое меню. Завершение и спам спрашивают подтверждение только при
CONFIRM_CLOSE=Y. Закрытый для оператора диалог исчезает из списка и поиска, даже если ждёт оценки. - Скрытые сообщения и всё, что связано с CoPilot (его сообщения, упоминания, ответы ему, индикатор набора), клиенту не уходят. AI-оператор по умолчанию выключен, новый
Main\Config\Featureучитывает старую опциюY. - Списки
ENABLE_SYSTEM_MESSAGEиENABLE_INCOMING_IDEMPOTENCYвimconnectorвключают служебные сообщения и защиту от повторных внешних ID. Network передаёт стикеры черезIMOL_STICKER, другие каналы получают картинку файлом. Приветствие Network уходит, если у линии нет своегоFIRST_MESSAGE, аnetwork_welcome_allowed_listразрешает его принудительно. - Отчёты проверяют права и при прямом вызове API, Excel-экспорт экранирует формулы в
EXTRA_URLиEXTRA_DOMAIN. Очередь статистики обходится по ID с коммитом каждые 500 строк и оставляет ошибочные записи на повтор. - Первое сообщение виджета с файлом больше не теряет вложение.
Устаревшие и удалённые API в этой версии
| Символ | Статус | Чем заменять |
|---|---|---|
Bitrix\ImOpenLines\Chat::sendPullUpdateSilentMode()
|
Удалено |
Bitrix\ImOpenLines\Operator::setSilentMode()
|
imopenlines.v2.provider.service.FinishService
|
Удалено |
imopenlines.v2.provider.service.SessionFinishService
|