Перейти к основному контенту

Контакт-Центр. Как вернуть лида в нужный сценарий

https://pm.metarex.ru/issues/8192

Работа

здесьчат-бота, описанынаписанного новыена изменения по КЦ, их нужно будет не публиковать отдельной страницей документации, а внести в имеющуюся страницу по контакт центру, а отдельнуюконструкторе, - это ужепоследовательное можновыполнение действий. Вклиниваясь в диалог бота, оператор меняет его контекст, полностью прерывая сценарную ветку, не зависимо от того был ли перевод предусмотрен по логике или это произошло по решению человека-оператора.

Прерывание сценария - это прерывания сессии диалога или другими словами сброс диалога. Это происходит в нескольких случаях:

    Если в скрипте, в который попал пользователь, нет переходов дальше, т.е. команды прерываются и образуется тупик.  Если в скрипте стоит команда СТОП. Если пользователю пришли рассылка или триггер также без продолжающих сценарий переходов. Если пользователю живой человек написал сообщение через интерфейс лида. Если живой человек забрал диалог из КЦ.

    В этой статье будет сформулироватьрассмотрено новость по релизу

    ps: документацию нужно будет существенно корректировать, нужно будет все переформулировать и перестроить структуру документа, данный же документ необходимрешение для тестированияработы ичат-бота пониманияв новогосвязке функционала.

    с


    image.png

    contact-center-improverments-1.png


    КЦ.

    1.  ИнформационнаяБазовые панель.команды.

    Здесь выводятся все основные данные по лиду.

    Email и телефон выводятся на основе атрибутов лида sys_email и sys_phone

    Аватар и имя лида кликабельны, при нажатии открывается страница админ панели с сообщениями по лиду, на которой можно отредактировать лид.


    2. Кликабельная шапка лида.

    Открывает / Скрывает информационную панель по лиду

    На PC: По умолчанию информационная панель по лиду автоматически открывается при смене лида. Но если ее закрыть, то при открытии другого лида она также останется свернутой. Т.е. состояние панели запоминается (как в Telegram)

    На мобильном устройстве панель открывается на весь экран, при открытии страницы с сообщениями лида панель всегда свернута. Для открытиякорректной всегда нужно нажимать на шапку лида.


    3. Фильтр лидов по имени (как в Telegram, но пока без поиска по содержимому самих сообщений).

    Ищется только совпадение указанного текста в имени (ID в поиске не участвует)

    При поиске по имени (как и при поиске по любому другому параметру) активная панель автоматически переключается на "Поиск", а панель "Все" скрывается.

    После очистки всех параметров поиска, панель "Все" будет возвращена, а панель "Поиск" скрыта.

    ps: при нажатии на написать письмо можно сделать выбор шаблона и отправку письмо по SMTP, но это не имеет смысла, тк обратное письмо мы не получим, тут лучше рассмотреть вариант интеграции с Хэлп Деском. Можно даже рассмотреть вариант, чтобы открытая страница Лида имела несколько вкладок, например: Сообщения, Письма (отобржать IFRAME стороннего хэлп дэска), Заявки (отображать IFRAME сторонней CRM или наши Тикеты), Звонки (отображать IFRAME стороннего колл центра).


    4. Расширенный поиск лидов.

    При нажатии на кнопку подписанную как "4" на первом скрине откроется форма, на которой можно указать дополнительные параметры поиска и отредактировать текущий фильтр.

    image.png

    Эту же форму можно открыть нажав на область с выводом текущих, примененных фильтров для поиска лидов, т.е. на любую область с подписью "Результаты поиска", за исключением нажатия на крестики. Эти крестики необходимы для сброса всех параметров (крестиком в правой части) поиск или сброса поиска по конкретному параметру (крестиком слева от названия параметра)


    image.png


     Возвращаемся к форме расширенного поиска

    image.png

    Поиск по ID - можно искать точным соответствием (по умолчанию) или вхождением указанного числа в ID (если представить ID лида в виде строки). Для регулирования точного совпадения / вхождения - отдельная галка 

    Поиск по имени - вхождение указанного текста в имени Лидов

    Поиск по тэгам - поиск лидов по вхождению указанных сроки (через запятую) в имена тэго (т.е. не точное соответсвие имени тэга, а вхождение указанных строк в имена тэгов). Здесь можно указывать несколько тэгов. 

    Условие соединения тэгов указывается в отдельном поле ниже.

    Доступно 2 варианта 

    - или (по умолчанию)

    это значит что будет выполнен поиск лидов у которых есть любой из указанных тэгов

    - и

    это значит что будет выполнен поиск лидов у которых есть все указанные тэги

    Кнопки формы - Сбросить (идентична крестику сброса фильтра в  блоке с заголовком "Результаты поиска")


    Т.е. пока есть 3 критерия поиска по ID, по Имени, по Тэгам. Эти три группы в будущем можно будет визуально выделить рамкой на форме, чтобы было понятно что галка - точное совпадение относистя к ID, а выподающий список к поиску по тэгам.

    В дальнейшем сюда могут быть добавлены другие необходимые фильтры и параметры, например:


    Фильтр по

    Бот, Канал, Мессенджер
    Галка - Передан Оператору
    Галка - Отключена реакция бота (is_mute)
    Дата создания
    Последняя активность
    Последнее входящее сообщение
    По дате последнего сообщения оператора

    Сортировать по Дате создания / Последней активности / Дате посл вх сообщения / Дате посл сообщ оператора

    можно добавить все поля которые есть на странице лидов


    5. Панель результатов поиска

    Суть панели описана выше (о подмене панелей "Все" на "Поиск" при выполнении фильтрации). В документации можно не выделять отдельный раздел для нее.

    Здесь были перепробованы различные варианты построения фильтрации, например фильтровать по всем вкладкам или только по вкладке Все, но вариант с отдельном панелью оказался самым простым и понятным и без накрученной логики.


    6. Цветовая индикация лидов.

    Цветовая индикация лидов была переработана, чтобы лиды требующие реакции, не выглядели как светофор.

    Подсвечивается теперь только левая часть лида с аватаром, а правая только если лид активен, т.е. когда открыли страницу по лиду.

    В основном это сделано, тк на  разноцветных плашках было сложно чтото читать и теперь туда добавлено отображение последнее сообщение лида, прочесть которое было довольно сложно.


    7. URL 

    Этот пункт в документации не нужен

    Теперь в URL отражены параметры текущей, открытой страницы лида и все примененные фильтры расширенного поиска лидов:


    - show:

    текущий открытий Лид, что позволяет обновлять страницу и возвращаться к текущему лиду (а также решает проблему сброса открытого лида, при изменении размера страницы КЦ на PC)

    show, это скрытый фильтр по ID, который при старте мессенджера запускает следующий алгоритм:

      ждет загрузку текущих вкладок и фильтра ищет лид на вкладках, если есть, кликает на него и открывает сообщения лида если лид не найден на вкладках, то посылает аякс на бэк, ищет лид и добавляет его в начало списка на вкладку Все, кликает на него и открывает сообщения лида

      технические детали: здесь было перепробовано множество вариантов, в том числе и использование видимого фильтра по id для текущего открытого лида, но все они конфликтуют по логике, например, открытый лид начинает участвовать как фильтр, необходимо его сбрасывать вручную после обновления страницы (поэтому был добавлен быстрый сброс отдельных параметров примененного фильтра через крестик слева от параметра), либо если есть фильтр по другим параметром и открытая страница лида, то после обновления к фильтру по параметрам добавляется ID лида, что сужает выборку до 1 лида), в общем текущий вариант использования дополнительного параметра show отдельно от видимого фильтра id является самым оптимальным


      - id:

      для поиска по id.

      работает в комбинации с параметров id_eq=0 (для неточного соответствия по ID лида) - про id_eq упоминать в доке не нужно (если все таки будет упоминаться про структуру URL)


      - name

      имя лида


      - tags

      тэги перечисленные через запятую


      - tags_condition=or/and

      условие соединения тэгов



      8. Последнее сообщение по лиду

      последнее входящее по лиду (текст или нажатая кнопка)

      последнее исходящее от оператора

      исходящее от бота не выводится, тк не обладает информативностью и будет только мешать

      image.png

      (PS: последнее сообщение хранится в поле leads.last_message)

      9. Индикаторы информирующие об ожидании загрузки

      (в документации этот пункт не нужен)

      image.png

      Анимация отображается при старте КЦ. А также при применении фильтра.

      Также были добавлена анимация в подвале при выполнении скроллинга (но она скрыта сейчас), ввиду особенностей скроллинга - почти любе перелистывание списка лидов приводит к этой анимации, тк у нас лиды грузятся не когда достигли конца списка, а начинают грузиться раньше (как в Telegram), чтобы пока ты листаешь вниз, уже была подгружена следующая порция лидов, иначе если грузить только при достижении конца списка, то скроллинг даже 200 лидов занимает очень долгое время.


      10. Страница - Настройки КЦ.


      image.png

      Опции:

      10.1. Отправлять сообщение о подключении оператора к диалогу

      По умолчанию включена

      Это информационное сообщение, отправляемое лиду, о том что Оператор подключился к диалогу, отправляется когда оператор нажимает на кнопку Начать диалог в КЦ. Т.е. это не информирование о переводе на оператора, скрипт перевод на оператора с информацией о том что бот отключен, ожидайте оператора, все равно нужно создавать.
      Суть этой опции - жалоба клиента о то что Лиды не понимали с кем общаются и продолжали говорить с оператором, считая что это бот.
      Если вывод имени оператора включен, то лиду отправляется сообщение 
      Оператор {NAME} подключился к диалогу
      Если вывод имени оператора отключен, то
      Оператор подключился к диалогу
      имя оператора берется из настроек Личного кабинета пользователя (оператора)
      10.2. Отправлять сообщение о выходе оператора из диалога
      По умолчанию выключена. Не рекомендуется включать если есть бот, тк после отправки этого информационного сообщения будет скрыто меню в виджете, имеет смысл использовать только без бота с скриптами. 
      Событие возникает при нажатии оператором на кнопку Выйти из диалогу в КЦ или на выйти и отметить диалог решенным
      Примеры отправляемых сообщений:
      Если вывод имени оператора включен, то лиду отправляется сообщение 

      Оператор {NAME} вышел из диалога


      Если вывод имени оператора отключен, то
      Оператор вышел из диалога


      10.3. Отображать информацию об операторе в начале сообщения

      По умолчанию включена
      Клеить или нет к каждому исходящему сообщению оператора его имя. Чтобы было понятно кто пишет сообщение бот или оператора.

      Если отображение имени оператора включено, то в сообщении лиду выводится
      {NAME}: Здраствуйте, чем могу помочь?
      если отображение имени отключено, то
      Оператор: текст сообщения

      имя оператора подгружается из настроек Личного кабинета пользователя (оператора), поэтому необходимо установить имена операторов компактными, без лишних символов, и без никнейма в скобках


      10.4. Отображать имя оператора в информационных сообщениях


      По умолчанию включена

      Опция отображать или нет имя оператора: 

      - при подключении оператора к диалогу

      -в сообщениях от оператора

      -при выходе оператора из диалога


      Технические детали (не для докуменатции):

      Опции по бизнесу хранятся в новой таблице business_attributes (была такая ранее не использовалась, текущая таблица новая, старая за основу не бралась, также удалена неиспользуемая таблица business_entites на которую ранее ссылалась business_attributes, такая таблица избыточна). Это keyvalue таблицы, primary key по ID, в отличии от user_attributes, user_attributes в дальнейшем будет переработан, тк как оказалось работать с составным PK в Laravel только доп. проблемы, он не заточен на это, плюс проще кэшировать сущности и оперировать с ними по ID.

      Все опции по бизнесу кэшируются в Redis для такого чтобы не было проблем нагрузки при работе операторов с КЦ.

      Очищаются опции, при сохранении формы Настройки КЦ, а также просто при открытии страницы Настройки КЦ, чтобы данные на форме всегда были актуальны. При работе же оператора с КЦ, эти опиции грузятся из кэша.


      11. Отчеты 


      11.1. ОТЧЁТ ПО ДИАЛОГАМ ПЕРЕВЕДЕННЫМ НА ОПЕРАТОРОВ

      image.png

      по всем диалогам лидов, которые переводились на оператора, отчет с пагинацией

      доступен экспорт отчета в csv, при экспорте выгружаются все данные, без пагинации


      этот отчет идет вторым в списке, но для понимания логики расчетом имеет смысл рассмотреть его первым, тк другой отчет строится на основе него (а этот является второстепенным, который получился при решении задачи по статистике, также возможно для клиентов которые хотят сами анализировать KPI по операторам имеет смысл использовать именно этот отчет, чтобы загружать его в свою систему аналитики и строить отчеты)


      Логика построения отчета

      - отбираются все диалоги, которые были переведены на оператора (т.е. событие запроса оператора в бота лидом)

      - на каждое событиеработы перевода находим первый ответ оператора (причем смотрим чтобы дата ответа оператора была >= даты перевода на оператора)

      берем первый ответ оператора, а не нажатие кнопку Начать диалог, тк в таком случае отчет будет некорректен если включено авто распределение диалогов по операторам. Минусы подхода: KPI по первому ответу может сподвигнуть операторов писать короткие первые сообщения, при необходимости можно вывести в отчет - первое сообщение оператора, если это будет критично

      - считаем разницу по времени между переводом на оператора и первымобратно сообщениемв отчат-бота оператораобязательно должны быть созданы 2 скрипта:

        Перевод на оператора. В котором происходит запрос вопроса или контактных данных и, собственно, сам перевод.

        Однако если чат-бот работает полностью автономно, то этого скрипта может и не быть.

          Возврат в бота. С типом Возврат, в котором происходит передача боту и развилка по сценариям. 

          image.png

          2.  Работа в КЦ.

          В целях помощи лиду оператор может в любой момент диалога с ботом забрать его себе, нажав кнопку Начать общение.

          image.png

          Диалог бота будет прерван и вернется только когда оператор его завершит.

          image.png

          В момент завершения сработает скрипт Возврат в бота с типом Возврат.

          3.  Возврат в выбранный сценарий.

          Для того чтобы иметь возможность переводить бота в определенный сценарий/скрипт, необходимо подготовить скрипт возврата: добавить в него команду проверки условия переменной.

          image.png

          1 команда отвечает за возврат диалога боту - этоубирает галку параметра Чат с оператором у лида.
          2 команда - текст, сообщающий лиду о том, что с ним снова общается бот.
          3 команда работает только если у лида проставлена определенная переменная (которую проставит оператор).
          4 команда работает также только при наличии этой команды и запрещает переход дальше, чтобы успел сработать запущенный переход из 3 команды.
          5 команда - стандартный переход по сценарию возврата, обычно это главное меню бота.

          //Условие команды
          if (lead.getAttr('сценарий')) {
          return true;
          }
          
          /*Условие проверяет, есть времяли откликав (далеепеременной значение или там null. Если значение нет, то комнада не запустится*/
          
          //Тело команды
          let scriptNum = lead.getAttr('сценарий');  //присвоение переменной в код запуска скрипта
          
          bot.runScriptForLead(scriptNum, leadId, null, false);  //код запуска скрипта по его номеру в конструкторе
          Как присвоить переменную? 

          Для этого оператору понадобится Кликабельная шапка лида в КЦ.

          image.png

          Ниже в информационном поле лида можно посмотреть, какие переменные уже присвоены. Перейдя в лида, необходимо создать переменную со значением-номером скрипта.

          image.png

          image.png

          Где взять номер скрипта? 

          Номер скрипта прописан в URL конструктора 

          image.png

          Именно в него перейдет лид, после возврата в бота, если получитьномер суммарноебудет времясохранен всехв заявокпеременной операторалида.

          и
          Пример
          разделить

          image.png

          image.png

          image.png

          Ответы на количествовопросы
          диалогов,

          1. тоМожно получимли среднееназвать времяпеременную откликане посценарий?

          оператору)

          Можно, переменную разработчик/оператор бота может назвать как удобно. ВАЖНО, чтобы эти названия полностью совпадали, иначе код не запуститься

          2. Как потом работать с этим лидом? Надо ли удалять значение переменной?

          Значение переменной нужно удалить либо в шаге, в который вы перебрасываете лида, либо просто в основной точке бота, например, в главном меню. Для этого нужно использовать функцию присвоения нулевого значения.

          Техническое описание логики работы (вырезано из комментариев к коду, не для документации):

               * 1. Из таблицы botlogs получаем все события перевода на оператора за указанный период
               *  Из botlos записи получаем время создания записи - это время идентично открытию диалона
               * operator_id должен быть NULL указан в данном событии,
               *   иначе это событие приема диалога из КЦ оператором, а не перевод на оператора ботом
               *
               * bot_id IN (...) AND is_event=1 AND bot_event_type_id=60 AND operator_id IS NULL
               *
               * 2. По dialog_id в botlogs ищем первый ответ от оператора.
               * Причем запрос делаем не по каждому диалогу, а с помощью IN dialog_id (список id из п1)
               * Фильтруем события у которых дата < даты перевода на оператора
               *
               * Для статистики по отправке первого сообщения лиду оператором КЦ по данному диалогу:
               * sql для поиска EVENT_TYPE_ON_OPERATOR_MESSAGE = 3:
               * is_event=0 AND bot_event_type_id=3  // AND operator_id IS NOT NULL
               * order by id asc LIMIT 1
               *
               * Если нужна статистика по нажатию на Начать диалог оператором КЦ
               * sql для поиска EVENT_TYPE_ON_OPERATOR_JOINED = 230:
               * is_event=1 AND bot_event_type_id=230 // AND operator_id IS NOT NULL
               * order by id asc LIMIT 1
               * Но такой запрос не выполняется, по причине, что сюда попадают события автоназначения заявки оператору
               * Или события когда оператор подключился к диалогу без перевода на оператора
               *
               * -----
               *
               * Также в csv можно выгрузить сами диалоги
               * Или предоставлять их по апи, доп запросом
               *
               * -----
               *
               * Что можно посчитать дополнительно, помимо выгрузки по каждому диалогу:
               *
               * Статистика по каждому оператору:
               * - Среднее время отклика на диалог
               * - Среднее время общения с оператором
               * - Среднее количество вх/исх сообщений на диалог
               * - Всего диалогов
               * - Диалогов в день
               *
               * TODO: Для отчета можно сделать Флаг:
               *   С какой точки считать начала отлкика на диалог оператором:
               *     -  с момента написания первого сообщения оператором
               *     - с момента нажатия кнопки - Начать общение (подходит для кейсов без автоназначения заявок)
               *    В csv же можно выгружать обе даты
                  /*
                  SELECT
                      --DISTINCT "dialog_id"
                    id, dialog_id, bot_id, lead_id, bot_event_type_id, operator_id, created_at
                  FROM
                      botlogs
                  WHERE
                    bot_id IN (32,114,763,764,798,812,1031,1039,1040,1042,1043,1045,1046,1047,1067,1068,1069) AND
                    is_event=1 AND
                    bot_event_type_id=60 AND
                    operator_id IS NULL
                  ORDER BY
                      id ASC
                  LIMIT 100
                  */
          
                  // 1. Из таблицы botlogs получаем все события перевода на оператора за указанный период
                  //    Из botlos записи получаем время создания записи - это время идентично открытию диалона
                  // Далее оставляем только первое событие по каждому диалогу из этой выборки
                  $botlogsQuery = Botlog
                      ::select([
                          'botlogs.id',
                          'botlogs.dialog_id',
                          'botlogs.bot_id',
                          'bots.name AS bot_name',
                          'botlogs.lead_id',
                          'leads.name AS lead_name',
                          'botlogs.bot_event_type_id',
                          'botlogs.operator_id',
                          'botlogs.created_at',
                          'dialogs.created_at as dialog_opened_at',
                          'dialogs.state_id as current_dialog_state_id',
                          'dialogs.updated_at as dialog_closed_at'
                      ])
                      ->whereIn('botlogs.bot_id', $botsIn)
                      ->where('botlogs.is_event', 1)
                      ->where('botlogs.bot_event_type_id', BotEventTypeModel::EVENT_TYPE_ON_LEAD_FORWARDED_TO_OPERATOR)
                      ->whereNull('botlogs.operator_id')
                      ->leftJoin('dialogs', 'dialogs.id', '=', 'botlogs.dialog_id')
                      ->leftJoin('bots', 'bots.id', '=', 'botlogs.bot_id')
                      ->leftJoin('leads', 'leads.id', '=', 'botlogs.lead_id')
                      //::select(['botlogs.dialog_id'])
                      //->distinct()
                      //->orderBy('botlogs.dialog_id')
                      ->orderBy('botlogs.bot_id')
                      ->orderBy('botlogs.dialog_id')
                      ->orderBy('botlogs.lead_id')
                      ->orderBy('botlogs.id')
          
                      //->limit(100) // !!!
                  ;
          // Данные о всех сообщениях от оператора по каждому из диалогов
          $sql = '
              SELECT
                  botlogs2.*, users.name AS operator_name
              FROM (
                  SELECT
                    -- RANK() OVER (PARTITION BY "dialog_id" ORDER BY id ASC) n, 
                    id, bot_id, lead_id, operator_id, is_event, 
                    dialog_id, bot_event_type_id, 
                    operator_outgoing_text, 
                    created_at 
                  FROM
                      botlogs as botlogs1
                  WHERE
                      bot_id IN (' . implode(',', $botsIn) . ') AND
                      dialog_id in (' . implode(',', $dialogIds) . ') AND
                      is_event = 0 AND  
                      bot_event_type_id = ' . BotEventTypeModel::EVENT_TYPE_ON_OPERATOR_MESSAGE . '
                  ORDER BY id ASC
              ) AS botlogs2
              LEFT JOIN users AS users ON users.id = botlogs2.operator_id
              -- WHERE
              --    n = 1
              ORDER BY id ASC
              
              далее
              
          Пропускаем событие если такой диалог уже есть в списке.
          В отчет пападает только событие первого ответа оператора    
              
          исключаем события, дата которых раньше чем дата перевода на оператора
          для случаев, когда есть ответы операторов, еще до события перевода
          например когда лид сам вернул в бота, не дождавшись оператора и затем опять запросил поддержку оператора
          




          11.2.  ОТЧЁТ ПО АКТИВНОСТИ ОПЕРАТОРОВ

          image.png


          по всем операторам участвующим в диалогах, отчет без пагинации

          в дальнейшем можно вывести всех зарегистрированных операторов бизнеса + по тем кто принимал заявки (на случай если удалили роль у оператора)

          доступен экспорт отчета в csv


          Отчет строится на основе - отчёта по диалогам переведенным на операторов

          Из первого отчета получаем суммарные данные по каждому оператору. Затем суммарное время отклика по оператору делим на количество таких диалогов по оператору, получаем среднее время отклика.


          Технические детали (не для документации):

          Для формирования отчета необходима информация о всех диалогах за период расчета,  отчет делится на итерации, и на каждой итерации первый отчет проходит 50 диалогов и сразу накапливают суммарную информацию по диалогам оператора, после итерации данные о диалогах удаляются из памяти, остаются только по операторам. Т.е. в теории алгоритм должен нормально обрабатывать большое количество диалогов.

          (а при отображении же первого отчета отображается только одна из страницы итерации в 50 диалогов)


          12. Слетание сессии

          Было запрошено в задаче. Причина почему вылетает сессия не понятна, эксперементировал даже с уменьшением ограничения времени жизни сессии до 1 минуты, но не могу повторить. Причем КЦ выполняет кучу аяксом каждые неск. секунд, каждый из которых продлевает время жизни сессии, в таком случае получается что у оператора мог вылететь интернет на очень долгое время, после чего произошел логаут, тк не было обращений к сайту (что тоже нереалистично). Также возможно при авторизации на сайте не установили галку Запомнить меня (но тестировал также и без этой галки, слетов сессии не наблюдал).

          image.png


          Решено косвенно - выводом информационного сообщения.

          Для тестирования нужно открыть КЦ и страницу с сайтом, на второй странице сделать logout

          image.png


          13. Звуковые уведомления

          Звук, проигрываемый при старте КЦ

          https://stage.metabot.dev/media/welcome.mp3

          заменен на mp3 в котором заглушена звуковая дорожка

          https://stage.metabot.dev/media/empty.mp3

          Проигрывание звука необходимо для того чтобы на старте КЦ понять разрешены ли звук уведомления в браузере или нет и вывести инф. окно. 

          В документации это отражать не нужно, но нужно убрать из доки пункт, если там сказано о стартовом звуковом уведомлении, тк теперь его не слышно.


          14. Убран зеленый кружочек, чтобы не возникало мыслей, что клиент онлайн

          image.png 

          image.png

          15. Добавлена подсветка ссылок в сообщениях

          Ссылки теперь подсвечиваются и кликабельные.

          image.png

          PS: Подстветка выполняется на фронте, при добавлении сообщения в чат, сообщение прогоняется через регулярки и для всех ссылок добавляется html тэг <a href ....   

          PS: Другим ключевым моментом необходимым для полноценной работы с КЦ остается добавление поддержки изображений.

          Todo (это на будущее): 

          кц отображение картинок и ссылок
          + emoji
          + ссылок на прикрепленные файлы, документы, картинки и т.д. (хотя бы для telegram и widget)

          также отправка оператором, ссылок, файлов, изображений и emoji

          !!! todo
          в инфо панели выводить ссылку на sys_current_ticket_id

          !!! Автовысота поля отправляемого текста (поле для ввода текста оператором)


          16. Поддержка Enter и Escape в Popup

          Enter и Esc работают на 2х Popup

          1. Стартовое окно где выводится уведомлялка о Выключенном звуке
          2. Форма Расш. поиска - Enter - применить фильтр. Esc - отмена (скрыть попап)


          17. Смена бота / бизнеса при просмотре переписки по лиду

          Добавлена поддержка возможности быстрой смены бота при просмотре переписки по лиду, чтобы можно быстро находить бизнес и бот по лиду. А также передавать ссылки на лид, напримерр при описании бага на платоформе, без указания к какому бизнесу и боту он относится.

          image.png


          18. Имена каналов в списке лидов и в шапке лида

          В списке лидов слева и в шапке лида выводится имя канала и мессендежр, если это не нативный канал, т.е. только для 'jivo','webim','umnico','bitrix'