Отображение информации об очередях Asterisk в личном кабинете Team через JavaScript-виджет

Источником данных в личном кабинете сервиса Softphone.Pro Team являются софтфоны Операторов. Это позволяет Руководителям просматривать различную информацию, например, историю звонков Операторов, их статусы, снимки с веб-камеры, и т.д.

Зачастую для работы Руководителям также может потребоваться дополнительная информация из сторонних систем, например:

  • состояние очередей на АТС Asterisk;
  • статусы Операторов в CRM;
  • список необработанных лидов из CRM;
  • и т.п.

Чтобы расширить возможности личного кабинета Team, добавьте специальный JavaScript-виджет, который позволяет показывать произвольную информацию на вкладке Онлайн личного кабинета Team. Это позволит Руководителям получать нужную информацию прямо в личном кабинете сервиса Softphone.Pro Team, без необходимости переключаться между вкладками.

Далее в статье описан пример виджета, который отображает информацию об очередях на АТС Asterisk, его настройка и использование:

Отображение виджета с очередями

Приведены инструкции по разработке вашего собственного виджета для отображения любой необходимой информации (от погоды до статусов сотрудников в CRM).

1. Пример JavaScript виджета для отображения состояния очередей Asterisk

Приведём пример JavaScript-виджета, который позволяет получить информацию о звонках в очередях на вашей АТС Asterisk. Встройте код виджета в личный кабинет Team, чтобы руководители в реальном времени видели информацию на вкладке Онлайн личного кабинета.

1.1. Системные требования

Для работы примера из этого раздела ваша АТС Asterisk должна соответствовать следующим требованиям:

  • Установлен PHP версии 5.5 и новее с модулями curl и fpm;
  • Установлен веб-сервер (Apache, Nginx) с доступом по HTTPS и запуском PHP файлов через php-fpm;
  • В настройках Asterisk включен и настроен HTTP-сервер;
  • В настройках Asterisk включен и настроен интерфейс AMI, и настроен доступ к AMI через HTTP;

Внимание! Работа пользователей с личным кабинетом Team ведётся по протоколу HTTPS, поэтому доступ по данному протоколу должен быть настроен на веб-сервере. Допускается использование самоподписанных SSL сертификатов, если браузеры пользователей предварительно настроены и доверяют данному сертификату.

Для настройки веб-сервера, PHP, Asterisk используйте соответствующие инструкции и документацию.

После настройки АТС переходите к следующему разделу инструкции.

1.2. Скачайте архив с примером виджета

Скачайте архив с примером виджета по ссылке: AsteriskQueuesWidget.zip. Распакуйте его в удобную вам папку.

Содержимое архива:

  • index.php
    Основной файл PHP, который получает информацию об очередях с АТС Asterisk по AMI. Доступ к этому файлу по сети необходимо открыть с компьютеров, на которых будет открыт личный кабинет Softphone.Pro Team с настроенным виджетом;
  • config.php
    Файл PHP, в котором указываются настройки подключения к Asterisk. Параметры, доступные для настройки, описаны далее в статье;
  • queue_widget.js
    Файл с кодом виджета. Этот код задаётся в настройках личного кабинета Softphone.Pro Team и отображается на вкладке Онлайн;
  • widget.html
    HTML файл, используйте его для тестирования виджета без его добавления в личный кабинет.

Как правильно настроить файлы и разместить их на сервере вашей АТС описано в следующем разделе.

1.3. Установка и настройка виджета

Проверьте, что ваша АТС удовлетворяет требованиям для работы виджета. Разместите файлы виджета на вашей АТС, настройте доступ к ним и проверьте работу виджета с помощью HTML файла из примера. После этого настройте личный кабинет Softphone.Pro Team для работы с вашим виджетом.

1.3.1. Проверьте перед установкой виджета

Для отображения информации об очередях АТС Asterisk нужно разместить PHP скрипт из примера на сервере, к которому есть доступ с рабочих мест Руководителей. Если работа с АТС ведётся по локальной сети, достаточно локального подключения. Далее в инструкции для упрощения будем считать, что скрипт размещается непосредственно на сервере с АТС Asterisk.

Убедитесь, что сервер АТС соответствует системным требованиям, описанным в пункте 1.1 данной инструкции, и что у вас есть данные учётной записи для подключения по AMI (логин/пароль), которые настраиваются в файле /etc/asterisk/manager.conf на сервере АТС Asterisk.

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

1.3.2. Установка скрипта на АТС и проверка его работы

Разместите файлы index.php и config.php, полученные на шаге 1.2 инструкции, в папке на вашей АТС Asterisk, к которой открыт доступ через веб-сервер.

Для примера, предположим что вы разместили файлы index.php и config.php в папке /opt/widget/, и настроили веб-сервер так, что файл index.php доступен с рабочих мест Руководителей по ссылке https://pbxasterisk.example.com/widget/index.php в браузере.

Внимание! Работа пользователей с личным кабинетом Team ведётся по протоколу HTTPS, поэтому доступ по данному протоколу должен быть настроен на веб-сервере. Допускается использование самоподписанных SSL сертификатов, если браузеры пользователей предварительно настроены и доверяют данному сертификату.

Отредактируйте файл настроек config.php для того, чтобы скрипт мог подключиться к вашей АТС и получить данные об очередях. По умолчанию он имеет следующий вид:

<?php
...
$config = [
    'url' => 'http://127.0.0.1:8088',
    'username' => 'user',
    'password' => 'password',
    'cache_file' => 'asterisk_cache.tmp',
    'cookie_file' =>  'asterisk_cookie.tmp',
    'throttling_timeout' => 10,
    'queues' => ['Queue1', 'Queue2']
];

Описание параметров скрипта:

  • url
    Адрес и порт, по которому доступен HTTP сервер Asterisk, через который скрипт будет подключаться к АТС по AMI.
    Значение по умолчанию: http://127.0.0.1:8088
  • username
    Имя пользователя AMI, заданного в настройках Asterisk в файле /etc/asterisk/manager.conf
    Значение по умолчанию: user
  • password
    Пароль пользователя AMI, заданного в настройках Asterisk в файле /etc/asterisk/manager.conf
    Значение по умолчанию: password
  • cache_file
    Файл, в котором хранятся кэшированные данные об очередях, полученные с АТС.
    Значение по умолчанию: asterisk_cache.tmp
  • cookie_file
    Файл, в котором хранятся куки авторизации пользователя AMI на АТС.
    Значение по умолчанию: asterisk_cookie.tmp
  • throttling_timeout
    Промежуток времени в секундах, через который скрипт обновляет данные в файле. Увеличьте параметр, чтобы скрипт реже обращался к АТС по AMI, или уменьшите его, чтобы получать более актуальные данные об очередях за счёт увеличения частоты обращений к АТС.
    Значение по умолчанию: 10
  • queues
    Названия очередей, данные о которых будут отображаться в виджете, задаются в виде массива названий в кавычках. Для указания нескольких очередей разделите названия запятой.
    Значение по умолчанию: ['Queue1', 'Queue2']

Для проверки корректности работы скрипта откройте ранее настроенную ссылку https://pbxasterisk.example.com/widget/index.php в браузере (например Google Chrome).

Если все параметры скрипта в файле config.php заданы корректно, вы увидите в браузере страницу с текстом следующего вида:

[
    {
        "queue_name": "Queue1",
        "call_count": 0,
        "call_holdtime": 2,
        "call_talktime": 2,
        "callers": [

        ]
    },
    {
        "queue_name": "Queue2",
        "call_count": 0,
        "call_holdtime": 0,
        "call_talktime": 0,
        "callers": [

        ]
    }
]

PHP скрипт для получения информации об очередях с АТС настроен и работает. Переходите к настройке и тестированию JavaScript-виджета по инструкции в следующем разделе.

1.3.3 Настройка и проверка JavaScript-виджета

Разместите файлы queue_widget.js и widget.html, полученные на шаге 1.2 инструкции, в любой папке на вашем компьютере.

Откройте файл queue_widget.js в текстовом редакторе. Измените значения параметров запуска виджета в строках:

  • this.url = options.url || 'https://pbxasterisk.example.com/widget/index.php';
    Укажите в кавычках после знака || адрес, по которому доступен PHP-скрипт index.php на вашей АТС. Этот адрес вы получили в результате выполнения пункта 1.3.2 инструкции и проверили его корректность.
    Значение по умолчанию: 'https://pbxasterisk.example.com/widget/index.php'
  • this.interval = options.interval || 5000;
    Укажите после знака || интервал (в миллисекундах), по истечении которого виджет будет запрашивать данные об очередях из PHP-скрипта на АТС.
    Значение по умолчанию: 5000 (5 секунд).
  • this.maxErrors = options.maxErrors || 5;
    Укажите после знака || количество ошибок, после получения которого виджет перестанет пытаться получить данные из PHP-скрипта на АТС.
    Значение по умолчанию: 5

Сохраните изменения в файле queue_widget.js и откройте файл widget.html в браузере (например Google Chrome). Если настройки виджета указаны корректно, вы увидите страницу вида:

Проверка виджета в HTML файле

Настройка виджета закончена. Отправьте файл с кодом виджета (файл queue_widget.js) в службу технической поддержки Softphone.Pro Team, и укажите ID компании, для которой вы хотите настроить виджет. Работа конечных пользователей с виджетом описана в следующем разделе инструкции.

1.4. Как пользоваться виджетом

После подключения поддержкой Softphone.Pro Team виджета к вашему личному кабинету откройте вкладку Онлайн. Добавленный виджет отображается на странице справа от графика звонков с фильтрами:

Отображение виджета с очередями

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

Отображение очередей на Asterisk это только один пример доступных возможностей. Используйте данную возможность, чтобы отображать в личном кабинете Softphone.Pro Team, например:

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

Для этого разработайте свой JavaScript-виджет, используя инструкции из следующего раздела.

2. Разработка своего JavaScript виджета для страницы Онлайн личного кабинета Team

Инструкции в данном разделе предназначены для специалистов с опытом разработки вёрстки и разработки веб-приложений с использованием HTML, CSS и JavaScript. Виджеты представляют собой самостоятельные JavaScript-модули, которые рендерятся в указанный DOM-контейнер.

В документации опишем пример виджета, показывающего состояние очередей на Asterisk. Итоговый виджет будет открываться в браузере на компьютере сотрудников, которые открыли вкладку Онлайн личного кабинета Softphone.Pro Team.

2.1. Общие требования к виджету

Перечислим общие требования к JavaScript-виджету для личного кабинета Softphone.Pro Team. Виджеты, не удовлетворяющие данным требованиям, не будут добавлены в личный кабинет.

  • Формат
    Виджет — это JavaScript-код, представляющий класс виджета. В конце кода возвращается экземпляр класса виджета (return widgetInstance;). Рекомендуем обернуть код в try-catch блок для обработки ошибок.
  • Зависимости
    Код не использует внешние библиотеки. Используйте только vanilla JavaScript (ES6+).
  • Безопасность
    Избегайте манипуляций с глобальным состоянием или опасными операциями (например, eval). Виджет рендерится в изолированном контейнере.
  • Размер и производительность
    Виджет должен быть компактным (max-width ~600px, max-height ~180-300px). Избегайте тяжелых вычислений или бесконечных циклов.
  • Обработка ошибок
    В случае ошибки отображайте простое сообщение в контейнере (как в примерах).
  • Совместимость
    Тестируйте в современных браузерах (Chrome, Firefox, Safari, Edge).

2.2. Структура виджета

Виджет реализуется как класс (например, AsteriskQueueWidget), который принимает два параметра:

  • container
    DOM-элемент (HTMLElement), куда рендерится виджет. Используйте container.innerHTML для вставки HTML.
  • options
    Объект с конфигурацией, например { url: 'http://example.com/index.php, interval: 5000, autoStart: true }

Пример кода виджета:

try {
  console.log('Loading [Название] widget...');
   
  class ExampleWidget {
    constructor(container, options) {
      this.container = container;       // DOM-элемент для рендеринга
      this.options = options || {};     // Настройки виджета
       
      // Инициализация настроек
      this.property = options.property || defaultValue;
       
      this.init();
       
      console.log('Widget initialized');
    }
     
    init() {
      this.injectStyles();
      this.render();
      this.fetchData();  // Если требуется загрузка данных
    }
     
    // ... остальные методы
  }
  
  var widgetInstance = new ExampleWidget(container, options);
} catch (error) {
  console.error('Error creating widget:', error);
  container.innerHTML = `<div style="...">Ошибка: ${error.message}</div>`;
}
 
return widgetInstance;

2.2.1. Описание основных методов класса

На примере виджета, показывающего состояние очередей Asterisk (файл queue_widget.js, полученный на шаге 1.2 инструкции), опишем основные методы класса.

1. constructor(container, options):


  • Инициализируйте свойства (например, this.container, this.options).
  • Определите значения по умолчанию для опций.
  • Вызовите this.init(), который создаст HTML-структуру и применит стили.

Пример:

class AsteriskQueueWidget {
    constructor(container, options) {
      this.container = container;
      this.url = options.url || 'http://example.com/index.php';
      this.interval = options.interval || 5000;
      this.autoStart = options.autoStart !== false;
      this.headers = options.headers || {};
      this.isLoading = false;
      this.lastUpdate = null;
      this.errorCount = 0;
      this.maxErrors = options.maxErrors || 5;
      this.updateTimer = null;
      console.log('Widget initialized with URL:', this.url);
    
      this.init();
  }

}

2. init():


  • Вызовите this.injectStyles() для добавления CSS.
  • Вызовите this.render() для создания HTML-структуры.
  • Инициализируйте данные (например, fetch данных).
  • Настройте таймеры или события (если нужно).

Пример:

init() {
  this.injectStyles();
  this.render();
  if (this.autoStart) {
      this.start();
  }
}

3. injectStyles():


  • Создайте элемент <style> и добавьте CSS-строки.
  • Проверьте, существует ли уже стиль (по ID), чтобы избежать дубликатов.
  • Используйте локальные классы (например, .asterisk-queue-widget-styles), чтобы избежать конфликтов.

Пример:

injectStyles() {
  if (document.getElementById('asterisk-queue-widget-styles')) {
    return;
  }
  
  const style = document.createElement('style');
  style.id = 'asterisk-queue-widget-styles';
  style.textContent = `
    .asterisk-widget {
      font-family: Arial, sans-serif;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 20px;
      margin: 10px;
      background: #f9f9f9;
      max-width: 600px;
    }
    .widget-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 15px;
      border-bottom: 1px solid #eee;
      padding-bottom: 10px;
    }
  `;
  
  document.head.appendChild(style);
}

4. render():


  • Создайте HTML-структуру виджета (используйте шаблонные строки `).
  • Вставьте в this.container.innerHTML.
  • Кэшируйте DOM-элементы (например, this.element = this.container.querySelector('#widgetStatus)).
  • Добавьте event listeners, если требуется (click, change и т.д.).

Пример:

render() {
      const html = `
        <div class="asterisk-widget">
          <div class="widget-header">
            <div class="widget-title">Данные очередей</div>
            <div class="widget-status status-loading" id="widgetStatus">Загрузка...</div>
          </div>
          <div class="widget-content" id="widgetContent">
            <div class="loading">Загрузка данных...</div>
          </div>
          <div class="update-info" id="updateInfo">
            Обновление каждые ${this.interval / 1000} сек
          </div>
        </div>
      `;
 
      this.container.innerHTML = html;
 
      this.statusElement = this.container.querySelector('#widgetStatus');
      this.contentElement = this.container.querySelector('#widgetContent');
      this.updateInfoElement = this.container.querySelector('#updateInfo');
  
      console.log('Widget rendered');
}

5. update(data, options):


  • Обновите виджет при изменении данных или опций.
  • Вызовите перезапуск (например, this.onDataReceived()).

Пример:

update(data, options) {
  if (data) {
    console.log('Updating widget with new data');
    this.onDataReceived(data);
  }
}
     
onDataReceived(data) {
  this.lastUpdate = new Date();
  this.setStatus('connected', 'Подключено');
  this.renderQueues(data);
  this.updateLastUpdateInfo();
}

6. destroy():


  • Очистите контейнер (this.container.innerHTML = '').
  • Удалите стили, если они были добавлены.
  • Остановите таймеры (clearInterval, clearTimeout).
  • Удалите event listeners, если были добавлены.

Пример:

destroy() {
  this.stop();
  this.container.innerHTML = '';
  const styleEl = document.getElementById('asterisk-queue-widget-styles');
  if (styleEl) {
    styleEl.remove();
  }
}
  
stop() {
  if (this.updateTimer) {
  clearInterval(this.updateTimer);
  this.updateTimer = null;
  }
  this.setStatus('loading', 'Остановлено');
}

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

2.2.2. Советы для дальнейшей доработки

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

Обработка данных и API

  • Чтобы реализовать асинхронные операции обработки данных, используйте async/await или Promises.
  • Добавьте индикатор загрузки (spinner) и обработку ошибок, чтобы более явно показать конечному пользователю процесс работы виджета.

Стили и дизайн

  • Чтобы добавить в виджет темы и/или анимации, используйте CSS в injectStyles.
  • Чтобы виджет выглядел корректно в личном кабинете для любого разрешения экрана, реализуйте адаптируемую разметку: max-width 600px, flex/grid.
  • Для добавления иконок используйте emoji или подключаемые шрифты (Font Awesome не поддерживается).

Звуки и анимации

  • Чтобы добавить в виджет звуки, используйте Web Audio API.
  • Для анимаций используйте CSS transitions/animations (spinners, hover).

Обёртка try-catch

  • Для корректной обработки ошибок в ходе работы виджета и упрощения диагностики на компьютере Руководителя оберните весь код в try { ... } catch (error) { ... }.
  • В блоке catch для наглядной диагностики логируйте ошибку в console и отобразите сообщение в контейнере - это предоставит нужную информацию как пользователю, так и разработчику виджета.

Пример:

try {
  // Код виджета
  return widgetInstance;
} catch (error) {
  console.error('Error creating widget:', error);
  container.innerHTML = `
 
    Ошибка создания виджета: ${error.message}
  
`;
}

После доработки кода проверьте его работу перед отправкой его в личный кабинет.

2.3. Как создать свой виджет

Для создания и тестирования своего JavaScript виджета выполните следующие действия:

1. Создайте класс YourWidget с описанной структурой.

2. Добавьте логику (рендер, события, данные).

3. Сохраните получившийся код виджета в файл, например, your_widget.js.

4. Для локального тестирования оберните JavaScript-код в функцию и определите контейнер с id widget-container, например:

(function() {
  const container = document.getElementById('widget-container');
  class YourWidget {
    constructor(container, options) {
      this.container = container;
      ...
    }
    ...
  }
  ...
})()

5. Сохраните получившийся код виджета в файл, например, your_widget_test.js.

6. Создайте HTML-файл с тегом <div id="widget-container"></div>.

7. Подключите скрипт в HTML <script src="your_widget_test.js"></script>

8. Откройте получившийся HTML файл в браузере и проверьте работу виджета.

9. После успешного тестирования виджета передайте полученный на шаге 3 код виджета (файл queue_widget.js) в поддержку Softphone.Pro Team, и укажите ID вашего личного кабинета, чтобы коллеги могли подключить виджет к вашему личному кабинету.

10. Проверьте работу виджета в личном кабинете Softphone.Pro Team, как описано в пункте 1.4 инструкции.