Im 26.1000.0–26.1100.0: формы в сообщениях ботов, список команд и новый ответ delete/update
Ломающее обновление
Удалены или изменены публичные API — прикладной код может перестать работать.
За один прогон в эталон приехали три версии im: 26.1000.0, 26.1050.0 и 26.1100.0. Боты получили формы прямо в сообщении и REST со списком команд чата, а im.v2.Chat.Message.delete и update теперь отвечают объектом вместо true. В 26.1100.0 закрыты две дыры, одна из них открывала доступ к файлам чужого чата. Мобильная часть разобрана в immobile 26.1200.0.
Новое
Пришлите форму вместо пяти вопросов в чате (26.1000.0)
В конструкторе блоков сообщения появился блок формы с полями пяти типов: однострочный и многострочный текст, выпадающий список, радиокнопки и чекбоксы. Отправляет форму новая кнопка RequestButton. Блок работает за опцией im:message_form_block_available. По умолчанию она выключена, и без неё Builder::build() вернёт ошибку FORM_BLOCK_NOT_AVAILABLE.
<?php declare(strict_types=1);
use Bitrix\Im\V2\Chat;
use Bitrix\Im\V2\Message;
use Bitrix\Im\V2\Public\Message\BlocksBuilder\Builder;
use Bitrix\Im\V2\Public\Message\BlocksBuilder\Field\Buttons;
use Bitrix\Im\V2\Public\Message\BlocksBuilder\Field\Buttons\ButtonLine;
use Bitrix\Im\V2\Public\Message\BlocksBuilder\Field\Buttons\RequestButton;
use Bitrix\Im\V2\Public\Message\BlocksBuilder\Field\FormFields;
use Bitrix\Im\V2\Public\Message\BlocksBuilder\Field\FormFields\MultilineTextField;
use Bitrix\Im\V2\Public\Message\BlocksBuilder\Field\FormFields\SelectField;
$chat = Chat::getInstance($chatId);
$fields = FormFields::create()
->addField(SelectField::create('priority', 'Срочность', [
['id' => 'low', 'label' => 'Подождёт'],
['id' => 'high', 'label' => 'Горит'],
]))
->addField(MultilineTextField::create('details', 'Что случилось', 'Опишите проблему'));
$buttons = Buttons::create()->addButtonLine(
ButtonLine::create()->addButton(RequestButton::create('Отправить', 'support_ticket', id: 'send'))
);
$result = (new Builder($chat))->addFormBlock($fields, $buttons, 'ticket')->build();
if ($result->isSuccess()) {
$chat->sendMessage(
(new Message())->setAuthorId($botId)->setBlocksBuilder($result->getBlocksBuilder())
);
}
Клиент отправляет форму методом im.v2.Chat.Message.Block.Form.submit. Сервер сверяет значения со схемой блока и отвечает ошибкой на неизвестное поле, отключённое поле или вариант, которого нет в списке. Модуль ответ не хранит и только бросает событие im:OnMessageFormSubmit, а если автор сообщения бот, ещё и REST-события onImBotFormSubmit и onImBotV2FormSubmit. Webhook-бот подписывается на V2-событие при регистрации и при imbot.v2.Bot.update с webhookUrl. Боту, зарегистрированному до 26.1000.0, подписку нужно обновить этим вызовом. В payload приходят actionId, blockId, buttonId, values, сообщение, чат и пользователь.
<?php declare(strict_types=1);
use Bitrix\Main\Event;
use Bitrix\Main\EventManager;
EventManager::getInstance()->addEventHandler('im', 'OnMessageFormSubmit', static function (Event $event): void {
if ($event->getParameter('actionId') !== 'support_ticket') {
return;
}
// ['priority' => 'high', 'details' => '...'], у чекбокса массив id вариантов
$values = $event->getParameter('values');
if (($values['details'] ?? '') === '') {
return; // обязательность полей проверяете сами
}
$userId = (int)$event->getParameter('userId');
// создаём обращение от имени $userId
});
Получите команды чата одним запросом (26.1100.0)
REST im.v2.Chat.Command.list возвращает slash-команды, видимые в конкретном чате, и данные ботов, которым они принадлежат. Отвечает метод только участникам. Скрытая связь, которая остаётся после выхода из открытого чата, участием не считается. Какие команды видны в чате, теперь решает один класс CommandAccessPolicy, и для списка, и для выполнения при отправке. Список кешируется на час для каждого чата. Popup по «/» в веб-мессенджере включает опция chat_bot_commands_available, гостям и открытым линиям он не показывается, а сам REST-метод опцию не проверяет.
Публикуйте в канал из бизнес-процесса (26.1100.0)
Действие «Отправить пост в канал» (ImSendChannelPostActivity) публикует пост от имени сотрудника: текст и до 100 файлов. Длинный текст делится на части, но не больше чем на 20. Если текст в них не укладывается, действие пост не отправит и вернёт ошибку. Наружу действие отдаёт JSON с постами, статус success, partial или error и текст ошибки. Оно доступно только в новом нодовом дизайнере, а автора проверяет через модуль humanresources, без которого вернёт ошибку. В БУС этого модуля нет. Текст режет Bitrix\Im\Integration\Bizproc\Splitter::split(), который закрывает парные BBCode-теги в конце части и открывает их заново в следующей. Его можно вызывать и из своего кода.
Остальное новое
im.v2.Chat.Task.createByAiсоздаёт задачу через AI по выбранным сообщениям (26.1000.0). Опцияai_task_creation_from_messages_available, нужен модуль ai.- Для BitrixGPT появились остановка генерации
im.v2.Copilot.Generation.stopи политика файлов: txt, md, csv, xlsx, xls, docx, pdf, jpg, jpeg, png, webp, до 5 МБ и до 10 штук на сообщение. Политику проверяет и старыйim.disk.file.commit(26.1000.0). CIMChat::GetLastMessageLimit()получил keyset-пагинацию по паре(DATE_CREATE, ID)через параметры$limit,$lastIdи$lastDate(26.1100.0).- У
ExternalChat\Configпоявился флагuseDefaultRecentSection, и тип изim:OnRegisterExternalChatTypesможет показываться в общих «Недавних». ОбработчикOnFilterUsersByAccessExternalChat<ТипЧата>может вернутьuserIdsToKeepRelations, чтобы связи пользователей без доступа не удалялись (26.1050.0). - Папка «Вайбкод» для чатов Вайбкод-приложений (26.1050.0) закрыта опциями и требует модуль vibecodeconnector, которого в БУС нет.
Что сломается
Проверяйте result.result после delete и update (26.1000.0)
im.v2.Chat.Message.delete и im.v2.Chat.Message.update раньше возвращали "result": true, теперь "result": {"result": true}. Код вида if (response.result === true) после обновления решит, что запрос не прошёл.
Уберите пробелы из имён команд (26.1100.0)
CommandTable отклоняет имена команд с пробелами и управляющими символами, поэтому Bitrix\Im\Command::register() с именем help admin теперь вернёт false. Уже сохранённые команды с такими именами из списка команд пропадут. Имя можно проверить заранее:
<?php declare(strict_types=1);
use Bitrix\Im\Model\CommandTable;
if (!CommandTable::isNameValid($name)) {
$name = preg_replace('/[\p{C}\p{Z}]+/u', '_', trim($name)); // help_admin
}
Замените удалённый API
В 26.1100.0 из IDepartment и BaseDepartment удалён getColleagues(). Замена: getColleagueIdsByUserId(int $userId, ?int $limit = null, string $order = 'DESC'), пользователя теперь передают явно.
В 26.1050.0 удалили константу RecentConfigManager::EXTERNAL_CHAT_USE_DEFAULT_RECENT_SECTION. Вместо неё у каждого типа внешнего чата флаг ExternalChat\Config::$useDefaultRecentSection.
Что заметят пользователи
- В открытых линиях исключать участников может любой участник чата, кроме ботов, коннекторов и экстранет-пользователей. Клиента-коннектора исключить нельзя (26.1000.0).
- Из чата отдела теперь можно удалить участника, которого добавила синхронизация со структурой, если структура его больше не держит. После удаления чат переспрашивает структуру и при необходимости возвращает человека (26.1000.0).
- Опции
collab_preview_source_enabledиattach_chat_to_project_availableпо умолчанию включены. Если функции не нужны, выставьте имN(26.1000.0). - Гость, который перешёл из чата на публичную страницу портала, выходит из гостевой сессии. Вернуться можно по ссылке-приглашению (26.1100.0).
- MCP-инструменты мессенджера для AI-ассистента в 26.1000.0 спрятали за опцией
mcp_tools_enabled, а в 26.1100.0 выключатель убрали. По умолчанию доступны все 11 инструментов, включая создание чатов и исключение участников. Это касается только порталов с модулем aiassistant, в БУС его нет.
Обновитесь ради закрытых дыр
- 26.1100.0:
im.v2.Chat.loadиim.v2.Chat.Message.listвыдавали вызвавшему доступ к быстрой отдаче файлов чата, не проверяя права на сам чат. Префильтры контроллера — обработчики одного события и друг друга не останавливают. ОтказCheckEntityAccessблокировал тело экшена, а фильтр, выдающий доступ, всё равно отрабатывал. Если в ваших контроллерах есть префильтры с побочными эффектами, проверяйте права внутри них. - 26.1100.0: пробел в имени команды превращал её в команду с аргументом. По комментарию в коде,
/help adminзапускалhelpс аргументомadminот имени отправителя. - 26.1000.0: гостевой REST разбирал имена методов в batch иначе, чем исполнитель
CRestProvider::methodsBatch(). Комментарий в коде называет такое расхождение обходом белого списка. Теперь разбор одинаковый, аim.chat.leaveвнутри batch запрещён.
Мелочи и находки
- В
Extranet::getGroup()раннийreturnпослеstartDataCache()иstartTagCache()оставлял открытыми буфер и стек тегов, и все теги, зарегистрированные позже, прилипали к этому кешу (26.1100.0). Перед выходом теперь вызываютсяabortTagCache()иabortDataCache(). Поищите такой же выход в своих компонентах. CHTTP::urlAddParamsзаменили наUri::addParams(26.1000.0). Чтобы Uri не закодировал шаблон#ID#, вim_chat.phpсначала подставляют__ID__, а потом меняют его черезstr_replace.- Курсор очереди HR-синхронизации хранится в ManagedCache (26.1000.0). По комментарию в коде, в
Optionего не держат, потому что каждая запись опции стоит строки вb_option, сброса всего кеша опций модуля и двух событий.
Устаревшие и удалённые API в этой версии
| Символ | Статус | Чем заменять |
|---|---|---|
Bitrix\Im\V2\Integration\HumanResources\Department\IDepartment::getColleagues()
|
Удалено |
Bitrix\Im\V2\Integration\HumanResources\Department\IDepartment::getColleagueIdsByUserId()
|
Bitrix\Im\V2\Integration\HumanResources\Department\BaseDepartment::getColleagues()
|
Удалено |
Bitrix\Im\V2\Integration\HumanResources\Department\BaseDepartment::getColleagueIdsByUserId()
|
Bitrix\Im\V2\Recent\Config\RecentConfigManager::EXTERNAL_CHAT_USE_DEFAULT_RECENT_SECTION
|
Удалено |
Bitrix\Im\V2\Chat\ExternalChat\Config::$useDefaultRecentSection
|