Integrating AMI (Asterisk Manager Interface) for Real-Time Call Control
Integrating AMI (Asterisk Manager Interface) for Real-Time Call Control
The Asterisk Manager Interface (AMI) provides powerful real-time control over PBX operations. I've built several systems that use AMI for live call monitoring, dynamic routing, and automated call handling.
🎯 What is AMI?
AMI is a TCP/IP interface that allows external applications to:
- Monitor calls in real-time
- Control calls (answer, hangup, transfer)
- Execute dialplan applications
- Receive events (call start, end, status changes)
🏗 Architecture
``` Laravel Application → AMI Client (PHP) → Asterisk AMI → Real-time Events ```
Components
1. AMI Client: PHP library to connect to Asterisk 2. Event Listener: Receives real-time events 3. Action Sender: Sends commands to Asterisk 4. Database: Stores call data and statistics
💻 Implementation
1. Install AMI Client Library
```bash composer require pami/pami ```
2. Connect to AMI
```php // app/Services/AsteriskAMI.php use PAMI\Client\Impl\ClientImpl as PamiClient;
class AsteriskAMI { private $client;
public function __construct() { $this->client = new PamiClient([ 'host' => config('asterisk.ami_host'), 'port' => config('asterisk.ami_port'), 'username' => config('asterisk.ami_username'), 'secret' => config('asterisk.ami_secret'), 'connect_timeout' => 10000, 'read_timeout' => 10000, ]);
$this->client->open(); }
public function disconnect() { $this->client->close(); } } ```
3. Listen for Events
```php public function listenForEvents() { while (true) { $event = $this->client->waitEvent();
if ($event instanceof \PAMI\Message\Event\NewchannelEvent) { $this->handleNewCall($event); }
if ($event instanceof \PAMI\Message\Event\HangupEvent) { $this->handleCallEnd($event); }
if ($event instanceof \PAMI\Message\Event\BridgeEvent) { $this->handleCallBridge($event); } } }
private function handleNewCall($event) { Call::create([ 'channel' => $event->getChannel(), 'caller_id' => $event->getCallerIDNum(), 'started_at' => now(), 'status' => 'ringing', ]);
// Broadcast to dashboard broadcast(new CallStarted($event))->toOthers(); } ```
4. Send Actions
```php public function answerCall($channel) { $action = new \PAMI\Message\Action\OriginateAction($channel); $action->setContext('default'); $action->setExtension('s'); $action->setPriority(1);
$response = $this->client->send($action); return $response->isSuccess(); }
public function hangupCall($channel) { $action = new \PAMI\Message\Action\HangupAction($channel); $response = $this->client->send($action); return $response->isSuccess(); }
public function transferCall($channel, $extension) { $action = new \PAMI\Message\Action\RedirectAction($channel); $action->setContext('internal'); $action->setExtension($extension); $action->setPriority(1);
$response = $this->client->send($action); return $response->isSuccess(); } ```
📊 Real-Time Dashboard Integration
Backend: Broadcast Events
```php // app/Events/CallStatusChanged.php class CallStatusChanged implements ShouldBroadcast { public $call;
public function broadcastOn() { return new Channel('calls'); }
public function broadcastAs() { return 'call.status.changed'; } }
// In AMI listener broadcast(new CallStatusChanged($call))->toOthers(); ```
Frontend: Display Live Calls
```javascript Echo.channel('calls') .listen('.call.status.changed', (e) => { updateCallStatus(e.call); }); ```
🔍 Common AMI Events
Call Events
- NewchannelEvent: New call initiated
- NewstateEvent: Call state changed (ringing, answered)
- BridgeEvent: Calls bridged (connected)
- HangupEvent: Call ended
- DialEvent: Dial attempt started
Channel Events
- PeerStatusEvent: SIP peer status changed
- RegistryEvent: SIP registration event
- VarSetEvent: Channel variable set
🚀 Advanced Use Cases
1. Call Queue Monitoring
```php public function monitorQueue($queueName) { $action = new \PAMI\Message\Action\QueueStatusAction($queueName); $response = $this->client->send($action);
return [ 'waiting' => $response->getKey('Waiting'), 'agents' => $response->getKey('Members'), ]; } ```
2. Dynamic Call Routing
```php public function routeCall($callerId, $destination) { // Check business rules if ($this->isBusinessHours()) { $extension = $this->getAvailableAgent(); } else { $extension = 'voicemail'; }
$this->transferCall($destination, $extension); } ```
3. Call Recording Control
```php public function startRecording($channel) { $action = new \PAMI\Message\Action\MonitorAction($channel); $action->setFile('recording-' . time()); $action->setFormat('wav');
$this->client->send($action); } ```
⚡ Performance Optimization
1. Connection Pooling
Reuse AMI connections:
```php class AMIConnectionPool { private $connections = [];
public function getConnection() { if (empty($this->connections)) { $this->connections[] = new AsteriskAMI(); } return array_pop($this->connections); }
public function releaseConnection($connection) { $this->connections[] = $connection; } } ```
2. Event Filtering
Only process relevant events:
```php if ($event->getEventType() === 'Newchannel' && $event->getChannelState() === '6') { // Ringing // Process only ringing calls } ```
3. Async Processing
Process events in background:
```php // Queue event processing ProcessAMIEvent::dispatch($event); ```
🔒 Security Considerations
1. AMI Authentication
```ini
/etc/asterisk/manager.conf
[admin] secret = strong_password_here deny = 0.0.0.0/0.0.0.0 permit = 127.0.0.1/255.255.255.255 read = system,call,log,verbose,command,agent,user write = system,call,log,verbose,command,agent,user ```
2. Rate Limiting
Limit AMI actions per second:
```php if (Cache::get("ami_rate_limit") > 100) { throw new Exception("Rate limit exceeded"); } Cache::increment("ami_rate_limit", 1, now()->addSecond()); ```
💡 Real-World Example
I built a call monitoring dashboard:
1. AMI Listener: Receives all call events 2. Database: Stores call records in real-time 3. WebSocket: Broadcasts updates to dashboard 4. Dashboard: Shows live calls, queue status, agent availability 5. Alerts: Notifies on call failures or long wait times
Result: Real-time visibility into all PBX operations, instant alerts, and comprehensive call analytics.
🎓 Key Takeaways
- AMI provides powerful real-time control
- Event-driven architecture scales well
- Filter events to reduce processing load
- Queue processing for heavy operations
- Secure AMI access with proper authentication
Conclusion
AMI integration enables powerful real-time call control and monitoring. Combined with Laravel broadcasting, you can build sophisticated call center dashboards and automated systems that respond instantly to call events.