Asterisk IP Telephony Integration

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:
Development stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    847
  • image_website-sbh_0.png
    Website development for SBH Partners
    999
  • image_website-_0.png
    Website development for Red Pear
    451

Asterisk IP Telephony Integration on Website

Asterisk is an open-source IP PBX platform, the de-facto standard for corporate telephony. Unlike cloud providers (Mango, Zadarma), Asterisk is deployed on your own server — full control over data, routing, and call costs.

Integration Architecture

Browser (WebRTC/SIP.js) ←→ Asterisk (Kamailio/nginx + WebSocket)
                                    ↓
                              AMI (Asterisk Manager Interface)
                                    ↓
                              Backend API (PHP/Go/Node)
                                    ↓
                              Database + Redis (events)

Asterisk Manager Interface (AMI) — TCP connection to port 5038, through which backend receives real-time events (incoming call, answer, completion) and sends commands (originate, hangup).

Connecting to AMI

// Low-level TCP connection to 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");

// Receiving events (polling in background process)
while (!feof($socket)) {
    $line = fgets($socket);
    // Parse events: Event: Newchannel, Event: Hangup, etc.
}

In practice, it's more convenient to use a library: optika-si/phpagi or pami/pami (PAMI — PHP Asterisk Manager Interface).

PAMI — Working with Events

// 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();

// Listen for incoming calls
$client->registerEventListener(function(\PAMI\Message\Event\EventMessage $event) {
    if ($event->getName() === 'Newchannel') {
        $callerNum = $event->getKey('CallerIDNum');
        $channel   = $event->getKey('Channel');
        // Find customer, notify manager via Redis pub/sub
        Redis::publish('incoming_call', json_encode([
            'caller' => $callerNum,
            'channel' => $channel,
            'timestamp' => now()->toIso8601String()
        ]));
    }
    if ($event->getName() === 'Hangup') {
        $duration = $event->getKey('Duration');
        // Save call to database
    }
});

while (true) {
    $client->process();
    usleep(100000); // 100ms
}

This process runs as a supervisor daemon, always maintaining connection with AMI.

Click-to-Call via Originate

// Initiate call: connect agent with customer
$client->send(new \PAMI\Message\Action\OriginateAction(
    "SIP/{$agentExtension}",  // agent's channel
    "exten,{$customerPhone},default",  // where to call after agent answers
    [
        'Timeout'    => 30000,
        'CallerID'   => '"My Store" <80001234567>',
        'Variable'   => "ORDER_ID={$orderId}",
        'Async'      => true
    ]
));

Asterisk first calls the agent, then after answer connects them to the customer — this is more convenient for the agent than dialing the number themselves.

ARI (Asterisk REST Interface)

Modern approach — ARI (Asterisk REST Interface) via WebSocket. Allows building complex call handling scenarios as code:

// 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;
        // Find customer, play personalized greeting
        channel.play({media: `sound:welcome-${customerId}`});
    });
    client.start('my-stasis-app');
});

WebRTC via Asterisk + Nginx

For browser calls Asterisk must work with WebSocket TLS. Configuration:

; /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

Call Recording

Asterisk records calls with MixMonitor. Files are stored in /var/spool/asterisk/monitor/. A script moves them to S3 and updates call_records.recording_url.

Development timeline: 3–5 weeks for full integration: deploying Asterisk, AMI daemon, click-to-call, WebRTC in browser and call history.