voximplant 26.700.0 Ломающее

Voximplant 26.700.0: оценку качества связи убрали, у notifyAdmins() появился тип

3 мин чтения Устаревших API: 6

Ломающее обновление

Удалены или изменены публичные API — прикладной код может перестать работать.

Модуль телефонии voximplant 26.700.0 вышел в коробочный Битрикс24 11 сентября 2026 года, по данным официального канала «Битрикс24 changelog». Из карточки звонка убрали оценку качества связи вместе с её JS-событиями, у Im::notifyAdmins() появился тип параметра, а публичные константы SipStatusInformer теперь указывают на другие языковые фразы. Проверьте свой код, если у вас приложение на плейсменте фоновой карточки звонка, свои уведомления админам через модуль телефонии или внешняя АТС, которая грузит записи через telephony.externalCall.attachRecord.

Уберите подписки на оценку качества связи

В JS-расширении voximplant.phone-calls оценки качества связи больше нет. Из PhoneCallView удалили showQualityPopup(), closeQualityPopup(), _onQualityMeterClick(), колбэк qualityGraded и событие десктопа phoneCallViewOnQualityGraded. Из PhoneCallsController убрали обработчик, который отправлял в звонок команду gradeQuality.

Для приложений на плейсменте фоновой карточки звонка это ломающее изменение. Событие BackgroundCallCard::qualityMeterClick удалено из фонового воркера (src/view/background-worker/base-worker.js), а его десктопный вариант DesktopCallCardQualityMeterClick удалён из desktop-worker.js. Подписанное на них приложение этих событий больше не получит. Код, который сам вызывает showQualityPopup() или closeQualityPopup() у PhoneCallView, упадёт с TypeError, потому что этих методов больше нет.

Индикатор качества в карточке остался, но нажать на него нельзя. У .im-phone-call-btn-signal вместо cursor: pointer теперь стоит pointer-events: none, так что обработчик, повешенный на сам индикатор, тоже не сработает. Стили .im-phone-popup-rating* и фразу IM_PHONE_CALL_VIEW_RATE_QUALITY удалили.

Проверьте, что передаёте в Im::notifyAdmins()

Было notifyAdmins($notification, array $buttons = array()), стало notifyAdmins(string|array|null $notification, array $buttons = array()). Из файла с declare(strict_types=1) число или bool в первый параметр больше не передать, будет TypeError. Кроме строки метод принимает массив с ключами NOTIFY_MESSAGE, NOTIFY_TITLE, SUBJECT и PLAIN_TEXT.

Поменялось и то, что уходит админам:

  • null, '' и [] метод пропускает сразу, пустое уведомление больше не отправляется;
  • в CIMNotify::Add всегда передаётся NOTIFY_TITLE, а без своего заголовка подставится фраза VOXIMPLANT_NOTIFICATION_TITLE («Телефония»);
  • в PARAMS добавлены COMPONENT_ID => 'DefaultEntity' и COMPONENT_PARAMS с SUBJECT и PLAIN_TEXT. Если PLAIN_TEXT не передан, его получают из сообщения через \Bitrix\Im\Text::removeBbCodes().

Формат DefaultEntity уже используют уведомления других модулей, например mail (lib/integration/im/notification.php) и tasks (lib/integration/im/notification/usecase/taskcreatedv2.php). У Im::notifyChangeSipRegistrationStatus($notification) сигнатура прежняя, а поведение поменялось так же. Пустые сообщения он пропускает, остальные отправляет с заголовком в формате DefaultEntity.

Сам модуль тоже перешёл на массив. Команда контроллера NotifyAdmins в controller_hit.php принимает необязательные SUBJECT и TITLE. TITLE уходит в NOTIFY_TITLE, а если SUBJECT не пришёл, темой становится тот же TITLE.

Уведомление со своим заголовком и темой:

        <?php declare(strict_types=1);

namespace Vendor\Telephony\Service;

use Bitrix\Main\Loader;
use Bitrix\Voximplant\Integration\Im;

final class SipLinesAlert
{
    public function send(int $linesDown): void
    {
        if ($linesDown <= 0 || !Loader::includeModule('voximplant')) {
            return;
        }

        // Im::notifyAdmins($linesDown) с 26.700.0 бросит TypeError
        Im::notifyAdmins([
            'NOTIFY_TITLE' => 'SIP-линии',
            'SUBJECT' => 'Часть SIP-линий недоступна',
            'NOTIFY_MESSAGE' => sprintf('Недоступно линий: [b]%d[/b]', $linesDown),
            // PLAIN_TEXT соберётся из NOTIFY_MESSAGE без BB-кодов
        ]);
    }
}

    

Читайте SIP-фразы через константы SipStatusInformer

В Bitrix\Voximplant\SipStatusInformer у публичных констант SHORT_STATUS_FAILED, SHORT_STATUS_RECOVERED и LONG_STATUS_FAILED к значениям добавился суффикс _MSGVER_2. Значения констант — это ключи языковых фраз. Старые ключи SIP_SHORT_STATUS_INFORMER_FAILED_WITH_LINK, SIP_SHORT_STATUS_INFORMER_RECOVERED и SIP_LONG_STATUS_INFORMER_FAILED_WITH_LINK удалили из lang/ru и lang/en. Код, который берёт фразу по константе, получит новый текст, а код со старым ключом строкой получит пустое значение.

        <?php declare(strict_types=1);

namespace Vendor\Telephony\Sip;

use Bitrix\Main\Loader;
use Bitrix\Main\Localization\Loc;
use Bitrix\Voximplant\SipStatusInformer;

final class SipStatusText
{
    /** @param array<string, string> $substitutions */
    public function failed(array $substitutions): string
    {
        Loader::requireModule('voximplant');

        // вместо 'SIP_SHORT_STATUS_INFORMER_FAILED_WITH_LINK', которого больше нет
        return (string)Loc::getMessage(SipStatusInformer::SHORT_STATUS_FAILED, $substitutions);
    }
}

    

Вместе с ключом поменялся текст короткой фразы о восстановлении подключения. Фраза SIP_SHORT_STATUS_INFORMER_RECOVERED_MSGVER_2 подставляет #PROXY# и #LOGIN# вместо #PHONE_NAME# и по смыслу совпала с длинной SIP_LONG_STATUS_INFORMER_RECOVERED. При этом SipStatusInformer::getStatusRecoveredText() выбирает короткий вариант как раз тогда, когда #PHONE_NAME# не пуст, и имя телефона в текст теперь не попадает. Если собираете текст сами, передавайте в подстановки #PROXY# и #LOGIN#.

Проверьте загрузку записей через attachRecord

Сигнатура Bitrix\Voximplant\Rest\Helper::attachRecordWithUrl($callId, $recordUrl, $fileName = '') не изменилась, но результат вызова стал другим. Его вызывает REST-метод telephony.externalCall.attachRecord, когда передан RECORD_URL, поэтому изменение касается интеграций, которые отдают запись ссылкой.

Тип файла сначала определяется по содержимому через \CFile::GetContentType(). Заголовок Content-Type из ответа удалённого сервера берётся, только если нет функции mime_content_type и по содержимому получилось '' или application/octet-stream. Найденный тип уходит в \CFile::MakeFileArray($tempPath, $fileType). Разработчики объясняют это в комментарии к коду. Сервер за recordUrl выбирает тот, кто вызывает метод, поэтому Content-Type его ответа считается данными под контролем атакующего. Если fileinfo работает, application/octet-stream считается законным результатом для непрозрачных бинарных данных, и заголовок его не перебивает.

Потом новый private-метод ensureRecordFileExtension() дописывает к имени файла расширение по MIME-типу, а неразрешённое расширение заменяет. Раньше запись без .mp3, .flac или .wav в имени не проходила белый список расширений в RecordFile::isCorrectFromArray(), который вызывает \CFile::CheckFile(). Теперь она проходит, если содержимое распознано как audio/mpeg, audio/flac, audio/wav или их варианты. Для типов вне карты имя не меняется, и файл по-прежнему отклоняется.

Проверенное имя записывается и в $fileName. В коде объяснено, что Диск берёт NAME, а не fileArray['name'], так что на Диск ляжет то имя, которое прошло проверку.

Белый список и перевод MIME-типов в расширения теперь доступны снаружи. RecordFile::getAvailableExtensions() возвращает mp3, flac, wav, а RecordFile::resolveExtensionByType() переводит MIME-тип в расширение: audio/mpeg и audio/mp3 в mp3, audio/flac и audio/x-flac в flac, audio/wav, audio/wave и audio/x-wav в wav. Для остальных типов он возвращает null.

        <?php declare(strict_types=1);

namespace Vendor\Pbx\Record;

use Bitrix\Main\Loader;
use Bitrix\Voximplant\Security\RecordFile;

final class RecordNameResolver
{
    public function resolve(string $callId, string $mimeType): ?string
    {
        Loader::requireModule('voximplant');

        $extension = RecordFile::resolveExtensionByType($mimeType);

        // null: тип вне карты, запись без расширения в имени attachRecord отклонит
        return $extension === null ? null : $callId . '.' . $extension;
    }
}

    

Триггеры звонков получили номер, направление и статус

CVoxImplantCrmHelper::StartCallTrigger() и StartMissedCallTrigger() теперь передают в \Bitrix\Crm\Automation\Trigger\CallTrigger::execute() и MissedCallTrigger::execute() кроме LINE_NUMBER ещё три ключа:

  • CALL_PHONE_NUMBER из $call->getCallerId();
  • CALL_DIRECTION, outgoing для CVoxImplantMain::CALL_OUTGOING и incoming для остальных;
  • CALL_STATUS из $call->getStatus(), одна из констант STATUS_* в lib/model/call.php: waiting, connecting, connected, enqueued, finished.

Пока эти ключи никто не читает. CallTrigger::checkApplyRules() сравнивает только LINE_NUMBER. Так и в crm 26.500.100, и в более новой crm 26.800.0. Похоже на заготовку под будущую версию crm. Если будете на них опираться, учтите, что incoming получают и обратный звонок (CALL_CALLBACK = 4), и переадресованный входящий (CALL_INCOMING_REDIRECT = 3), и CALL_INFO = 5.

Мелочи и находки

  • Ссылка на документацию в компоненте voximplant.config.edit теперь ведёт на статью helpdesk с кодом 19420080. Если подключён модуль ui, адрес строит \Bitrix\UI\Util::getArticleUrlByCode('19420080') с доменом по языку интерфейса (для ru это helpdesk.bitrix24.ru), без ui остаётся https://helpdesk.bitrix24.com/open/code_19420080/. Раньше в зависимости от языка и наличия модуля bitrix24 ссылка вела на курсы dev.1c-bitrix.ru или на bitrixsoft.com.
  • В install/js/voximplant/voximplant.min.js обновили Web SDK VoxImplant, строка версии сменилась с 4.13.1-3005 на 4.13.4-3014.
  • phone-calls.bundle.min.css раньше лежал неминифицированным (1451 строка), теперь он собран в одну строку. Отсюда почти все 1911 удалённых строк в статистике диффа.
  • VERSION_DATE у 26.700.0 (2026-07-27 18:03:09) раньше, чем у предыдущей версии 26.600.100 (2026-08-26 16:43:15).
  • В русской фразе SIP_LONG_STATUS_INFORMER_FAILED_WITH_LINK_MSGVER_2 после \n остались лишние пробелы перед «Логин» и «Код ошибки».
  • У 13 файлов сняли бит исполнения (100755 → 100644), среди них controller_hit.php, lib/integration/im.php, lib/security/recordfile.php, lib/sipstatusinformer.php, изменённые JS-исходники phone-calls/src и языковые файлы sipstatusinformer.php и phone-calls/lang/*/config.php.
  • Deprecated-пометок в релизе нет, схема БД не менялась.

Что делать

  1. Поищите в JS своих приложений и шаблонов qualityMeterClick, DesktopCallCardQualityMeterClick, phoneCallViewOnQualityGraded, qualityGraded и showQualityPopup и уберите подписки и вызовы.
  2. Найдите вызовы Im::notifyAdmins() из файлов со strict_types=1 и проверьте, что туда уходит строка, массив или null. Для своего заголовка передавайте массив с NOTIFY_TITLE, иначе админ увидит «Телефония».
  3. Замените строки SIP_SHORT_STATUS_INFORMER_FAILED_WITH_LINK, SIP_SHORT_STATUS_INFORMER_RECOVERED и SIP_LONG_STATUS_INFORMER_FAILED_WITH_LINK в своём коде на константы SipStatusInformer.
  4. Если внешняя АТС отдаёт записи ссылкой, прогоните telephony.externalCall.attachRecord на тестовом портале с записью без расширения в имени и посмотрите, под каким именем она легла на Диск.

Устаревшие и удалённые API в этой версии

Символ Статус Чем заменять
voximplant.phone-calls: BackgroundCallCard::qualityMeterClick Удалено —
voximplant.phone-calls: DesktopCallCardQualityMeterClick Удалено —
voximplant.phone-calls: PhoneCallView.showQualityPopup() Удалено —
voximplant.phone-calls: PhoneCallView.closeQualityPopup() Удалено —
voximplant.phone-calls: PhoneCallView.setCallback('qualityGraded') Удалено —
voximplant.phone-calls: phoneCallViewOnQualityGraded Удалено —

Читайте дальше

ui 26.687.0 Рутинное Свежее

UI 26.687.0: триал VibePlus в облаке и дизайн чипа TintedBitrixGpt

`Bitrix\UI\Controller\InfoHelper` при активации демо сначала спрашивает у модуля bitrix24, включён ли старт VibePlus, и если да, запускает триал VibePlus вместо обычного демо тарифа. Ветка срабатывает только при подключённом модуле bitrix24 и определённой константе `BX24_HOST_NAME`. В `ui.system.chi...

1 мин
ui 26.675.0 Ломающее Свежее

UI 26.675.0: ui.actionpanel переехал в бандл, а rich_text по-новому обходится с квадратными скобками

Модуль ui 26.675.0 собран 26 августа 2026. Из PHP поменялись `Converter` и `Whitelist` в `Bitrix\UI\Format\BBCode`, и пользовательские поля типа `rich_text` теперь иначе сохраняют и индексируют текст с квадратными скобками. На фронтенде старую панель групповых действий `ui.actionpanel` перевели на б...

4 мин
ui 26.650.0 Рутинное Свежее

UI 26.650.0: клавиатура в пикере реакций и аудио во вьюере

Релиз на 2 МБ, из PHP в нём только `config.php` расширений и номер версии. Пикером реакций теперь можно управлять с клавиатуры (роль `menu`, стрелки, Escape), у него появились опции `priorityReaction` и `contextAction` и методы `focus()` и `destroy()`. Если пикер привязан к кнопке, ссылке или элемен...

1 мин
ui 26.600.0 Ломающее Свежее

UI 26.600.0: параллельная и presigned-загрузка файлов, поле rich_text и Bootstrap JS 4.6

Дифф UI 26.600.0 даже без языковых файлов и `.min.js` весит 19 МБ, и почти весь этот объём занимают пересобранные бандлы и вендорные библиотеки (один mermaid дал 136 тысяч строк). Из содержательного загрузчик файлов научился принимать части параллельно и отдавать их браузеру для загрузки прямо в S3....

7 мин
Мы используем файлы cookie для улучшения работы сайта. Продолжая использовать сайт, вы соглашаетесь с нашей политикой конфиденциальности.
AI Домовой

AI Домовой История

на связи

пишет…
Нет истории чатов
AI Домовой

Нужна авторизация

Войдите, чтобы задавать вопросы AI Домовому.

Войти