Computer-Telephony Integration и телефоны Grandstream

Все больше и больше современные средства связи интегрируются в окружающий нас мир, и офисная телефония не является исключением. В компании Grandstream решили не отставать и добавили поддержку специального интерфейса CTI (Computer-Telephony Integration) в свои телефоны. Изначально были обновлены аппараты серии GXP21ХХ, а чуть позже обновились устройства младшей линейки GXP16ХХ, такие как GXP1610, GXP1620 и т.д.
На самом деле, «интерфейс CTI» это громко сказано, в реальности – небольшое REST API, позволяющее управлять телефоном с помощью простых HTTP запросов. Казалось бы: инициировать звонок, отследить состояние линий, используемых телефоном, можно и на АТС, но при использовании, к примеру, облачной IP АТС это не всегда представляется возможным. В добавок к этому, CTI позволяет управлять громкой связью, громкостью динамиков, отключением микрофона и т.д., что на уровне АТС не всегда реализуемо.
Итак, что же мы можем сделать с помощью CTI? В общем-то, не очень много, нам доступно всего пять типов запросов:
| Запрос | Описание |
|---|---|
| api-get_line_status | Состояние линий |
| api-get_phone_status | Состояние телефона |
| api-send_key | Нажатие какой-либо клавиши (0-9, #, *, контекстно зависимые и т.д.) |
| api-phone_operation | Простейшие манипуляции с телефоном (принять звонок, сбросить и т.д.) |
| api-sys_operation | Позволяет перезагрузить и сбросить аппарат к заводским настройкам |
Пользоваться этим очень просто, формируем запрос вида:
"http://IP адрес телефона/cgi-bin/api-get_line_status?passcode=Пароль" // (пароль от учётки с правами администратора)
В ответ получим JSON вида:
{
"response": "success",
"body": [
{ "line": 1, "state": "idle", "acct": 1, "active": 0, "remotename": "", "remotenumber": "" },
{ "line": 2, "state": "connected", "acct": 2, "active": 1, "remotename": "Виталик", "remotenumber": "203" },
{ "line": 3, "state": "idle", "acct": 1, "active": 0, "remotename": "", "remotenumber": "" },
...
{ "line": 8, "state": "idle", "acct": 1, "active": 0, "remotename": "", "remotenumber": "" }
] }
Заменив в запросе api-get_line_status на api-get_phone_status мы получим краткую информацию по телефонному аппарату:
{ "response": "success", "body": "busy", "misc": "0" }
Такой способ удобен, когда нам требуется просто опросить состояние аппарата или телефонных линий и очень неудобен в случаях, когда мы хотим отслеживать происходящие изменения. Поступил звонок, нам бы взять входящий номер и показать пользователю уведомление, но как это сделать? Возможности подписаться на какие-либо события у нас нет, два-три раза в секунду долбить телефон запросами о состоянии не кажется хорошим решением. К сожалению, в такой ситуации CTI не помощник.
Смотрим дальше, api-send_key, как понятно из названия, служит этот запрос для отправки нажатий на клавиши телефона, передавать можно как по одной, так и сразу несколько. Фактически, инициируются нажатия на переданные клавиши с интервалом около секунды и прервать этот процесс нельзя. При этом, клавиши на телефоне не блокируются и их можно свободно нажимать, в результате исполняемое телефоном превращается в непонятную «кашу».
"http://192.168.4.118/cgi-bin/api-send_key?passcode=admin&keys=LINE2:2:0:3:SEND"
Как видим, добавился еще один параметр keys, указывающий какие клавиши надо нажать. (Таблица со списком всех клавиш, которые можно виртуально нажать, есть в документации по CTI.)
Первое что приходит в голову: «А не написать ли расширение для браузера, которое позволяло бы инициировать звонок прямо из него?». Простейший вариант не заставил себя долго ждать. Так как у меня основной браузер Google Chrome, то написал для него, потребовалось всего-то создать два файла:
// manifest.json
{
"manifest_version": 2,
"name": "ArtDial",
"version": "0.1",
"permissions": ["contextMenus"],
"background": {
"scripts": ["background.js"]
}
}
// background.js
function dial(selectedText) {
var serviceCall = 'http://192.168.4.118/cgi-bin/api-send_key?passcode=admin&keys='+ selectedText.replace(/[^d]/g, '').split('').join(':') +':SEND';
var xhr = new XMLHttpRequest();
xhr.open("GET", serviceCall, true);
xhr.send();
}
chrome.contextMenus.create({
title: "Набрать: %s",
contexts: ["selection"],
onclick: function(info, tab) {
dial(info.selectionText);
}
});
Кладем их в одну папку, на странице расширений включаем режим разработчика и подключаем наше расширение.


Для управления вызовами предусмотрен запрос api-phone_operation, с его помощью мы можем принять или отклонить входящий вызов (acceptcall/rejectcall), поставить на удержание или завершить текущий разговор (holdcall/endcall). Так же доступна более универсальная команда cancel, позволяющая отклонять и завершать вызовы. Для отправки используем запрос вида:
"http://192.168.4.118/cgi-bin/api-phone_operation?passcode=admin&cmd=cancel"
И самое последнее: api-sys_operation, позволит нам перезагрузить телефон, либо сбросить в заводские настройки (REBOOT и RESET соответственно). Используем запросы вида:
"http://192.168.4.118/cgi-bin/api-sys_operation?passcode=admin&request=REBOOT"
Используя только Computer-Telephony Integration вряд ли удастся создать разухабистое приложение, которое будет всесторонне взаимодействовать с вашим окружением. Но как дополнительный инструмент, используемый совместно с другими API (Action URL в телефонах или AMI в Asterisk), CTI вполне имеет право на существование.
Источник
Microsoft может платить пользователям за обучение ИИ на их простаивающих видеокартах
Colorful выпустила жидкостное охлаждение Star Wind S1 для ноутбука Hidden Star P16 Pro Star Wind Edition 2026 с RTX 5060
Индия планирует разработать собственный GPU за два года и снизить зависимость от зарубежных чипов
Anthropic показала, как ИИ самостоятельно создаёт научные модели
Глава Nvidia признался в романе с возможной китайской шпионкой
До 80 часов автономной работы: Bloody представила три беспроводные игровые гарнитуры
Новогодняя ёлка? Нет, Lily58 с подсветкой и кастомным прозрачным корпусом
Apple сделает Siri ИИ-агентом