Інтеграція IP-телефонії Asterisk на сайт
Asterisk — відкритаплатформа IP-АТС, де-факто стандарт для корпоративної телефонії. На відміну від хмарних провайдерів (Mango, Zadarma), Asterisk розгортається на вашому власному сервері — повний контроль над даними, маршрутизацією та вартістю дзвінків.
Архітектура інтеграції
Браузер (WebRTC/SIP.js) ←→ Asterisk (Kamailio/nginx + WebSocket)
↓
AMI (Asterisk Manager Interface)
↓
Backend API (PHP/Go/Node)
↓
База даних + Redis (eventos)
Asterisk Manager Interface (AMI) — TCP-зв'язок до порту 5038, через який backend отримує события в реальному часі (вхідний дзвінок, відповідь, завершення) та відправляє команди (originate, hangup).
Підключення до AMI
// Низькорівневий TCP-зв'язок до AMI
$socket = fsockopen(env('ASTERISK_HOST'), 5038, $errno, $errstr, 5);
fwrite($socket, "Action: Login\r\nUsername: api_user\r\nSecret: api_secret\r\n\r\n");
// Отримання событiй (polling у фоновому процесі)
while (!feof($socket)) {
$line = fgets($socket);
// Парсити события: Event: Newchannel, Event: Hangup, etc.
}
На практиці зручніше користуватися бібліотекою: optika-si/phpagi або pami/pami (PAMI — PHP Asterisk Manager Interface).
PAMI — робота з событіями
// composer require marcelog/pami
$client = new \PAMI\Client\Impl\ClientImpl([
'host' => env('ASTERISK_HOST'),
'port' => 5038,
'username' => 'api_user',
'secret' => 'api_secret',
'connect_timeout' => 10
]);
$client->open();
// Слухати вхідні дзвінки
$client->registerEventListener(function(\PAMI\Message\Event\EventMessage $event) {
if ($event->getName() === 'Newchannel') {
$callerNum = $event->getKey('CallerIDNum');
$channel = $event->getKey('Channel');
// Знайти клієнта, сповістити менеджера через Redis pub/sub
Redis::publish('incoming_call', json_encode([
'caller' => $callerNum,
'channel' => $channel,
'timestamp' => now()->toIso8601String()
]));
}
if ($event->getName() === 'Hangup') {
$duration = $event->getKey('Duration');
// Зберегти дзвінок у БД
}
});
while (true) {
$client->process();
usleep(100000); // 100ms
}
Цей процес запускається як supervisor-демон, завжди підтримує зв'язок з AMI.
Click-to-Call через Originate
// Ініціювати дзвінок: з'єднати менеджера з клієнтом
$client->send(new \PAMI\Message\Action\OriginateAction(
"SIP/{$agentExtension}", // канал менеджера
"exten,{$customerPhone},default", // куди дзвонити після відповіді менеджера
[
'Timeout' => 30000,
'CallerID' => '"Мій магазин" <80001234567>',
'Variable' => "ORDER_ID={$orderId}",
'Async' => true
]
));
Asterisk спочатку дзвонить менеджеру, після відповіді з'єднує його з клієнтом — це зручніше для менеджера, ніж самостійно набирати номер.
ARI (Asterisk REST Interface)
Сучасний підхід — ARI (Asterisk REST Interface) через WebSocket. Дозволяє будувати складні сценарії обробки дзвінків як код:
// Node.js + ari-client
const ari = require('ari-client');
ari.connect('http://asterisk:8088', 'user', 'secret', function(err, client) {
client.on('StasisStart', function(event, channel) {
const callerNum = channel.caller.number;
// Знайти клієнта, відтворити персоналізоване привітання
channel.play({media: `sound:welcome-${customerId}`});
});
client.start('my-stasis-app');
});
WebRTC через Asterisk + Nginx
Для дзвінків з браузера Asterisk має працювати з WebSocket TLS. Конфігурація:
; /etc/asterisk/http.conf
[general]
enabled=yes
tlsenable=yes
tlsbindaddr=0.0.0.0:8089
tlscertfile=/etc/ssl/asterisk/asterisk.crt
tlsprivatekey=/etc/ssl/asterisk/asterisk.key
; /etc/asterisk/pjsip.conf
[transport-wss]
type=transport
protocol=wss
bind=0.0.0.0:8089
Запис розмов
Asterisk записує розмови через MixMonitor. Файли зберігаються в /var/spool/asterisk/monitor/. Скрипт перекладає їх на S3 та оновлює call_records.recording_url.
Строк розробки: 3–5 тижнів для повної інтеграції: розгортання Asterisk, AMI-демону, click-to-call, WebRTC у браузері та історія дзвінків.







