A comprehensive Laravel package for Asterisk PBX management via the Asterisk Manager Interface (AMI). This package provides a modern, Laravel-native interface for integrating telephony functionality into your Laravel applications.
- 🔌 AMI Connection Management: Robust connection handling with automatic reconnection
- 📡 Real-time Event Processing: Laravel event system integration for Asterisk events
- 📞 Complete Action Support: Originate calls, manage queues, control channels
- 🚀 Laravel Integration: Native service providers, facades, and configuration
- 📺 Event Broadcasting: Real-time updates via Laravel Broadcasting
- đź’ľ Database Logging: Optional call logging and metrics storage
- đź”§ Artisan Commands: CLI tools for AMI management and monitoring
- 🛡️ Type Safety: Full PHP 8.4+ type hints and return types
- đź§Ş Comprehensive Testing: Unit and integration tests included
- PHP 8.4 or higher
- Laravel 12.0 or higher
- Asterisk PBX server with AMI enabled
You can install the package via composer:
composer require apn-ra/asterisk-pbx-manager
Publish the configuration file:
php artisan vendor:publish --provider="AsteriskPbxManager\AsteriskPbxManagerServiceProvider" --tag="config"
Publish and run the migrations (optional, for database logging):
php artisan vendor:publish --provider="AsteriskPbxManager\AsteriskPbxManagerServiceProvider" --tag="migrations"
php artisan migrate
Add the following environment variables to your .env
file:
# Asterisk AMI Configuration
ASTERISK_AMI_HOST=127.0.0.1
ASTERISK_AMI_PORT=5038
ASTERISK_AMI_USERNAME=admin
ASTERISK_AMI_SECRET=your_ami_secret
ASTERISK_AMI_CONNECT_TIMEOUT=10
ASTERISK_AMI_READ_TIMEOUT=10
ASTERISK_AMI_SCHEME=tcp://
# Event Configuration
ASTERISK_EVENTS_ENABLED=true
ASTERISK_EVENTS_BROADCAST=true
ASTERISK_LOG_TO_DATABASE=true
The package configuration file (config/asterisk-pbx-manager.php
) provides comprehensive options:
return [
'connection' => [
'host' => env('ASTERISK_AMI_HOST', '127.0.0.1'),
'port' => env('ASTERISK_AMI_PORT', 5038),
'username' => env('ASTERISK_AMI_USERNAME', 'admin'),
'secret' => env('ASTERISK_AMI_SECRET'),
'connect_timeout' => env('ASTERISK_AMI_CONNECT_TIMEOUT', 10),
'read_timeout' => env('ASTERISK_AMI_READ_TIMEOUT', 10),
'scheme' => env('ASTERISK_AMI_SCHEME', 'tcp://'),
],
'events' => [
'enabled' => env('ASTERISK_EVENTS_ENABLED', true),
'broadcast' => env('ASTERISK_EVENTS_BROADCAST', true),
'log_to_database' => env('ASTERISK_LOG_TO_DATABASE', true),
],
'logging' => [
'enabled' => env('ASTERISK_LOGGING_ENABLED', true),
'channel' => env('ASTERISK_LOG_CHANNEL', 'single'),
'level' => env('ASTERISK_LOG_LEVEL', 'info'),
],
];
use AsteriskPbxManager\Facades\AsteriskManager;
// Check connection status
if (AsteriskManager::isConnected()) {
echo "Connected to Asterisk";
}
// Originate a call
$result = AsteriskManager::originateCall('SIP/1001', '2002');
if ($result) {
echo "Call originated successfully";
}
// Get system status
$status = AsteriskManager::getStatus();
use AsteriskPbxManager\Services\AsteriskManagerService;
class CallController extends Controller
{
public function __construct(
private AsteriskManagerService $asteriskManager
) {}
public function makeCall(Request $request)
{
$channel = $request->input('channel');
$extension = $request->input('extension');
try {
$result = $this->asteriskManager->originateCall($channel, $extension);
return response()->json([
'success' => $result,
'message' => $result ? 'Call initiated' : 'Call failed'
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => $e->getMessage()
], 500);
}
}
}
use AsteriskPbxManager\Services\QueueManagerService;
class QueueController extends Controller
{
public function __construct(
private QueueManagerService $queueManager
) {}
public function addAgent(Request $request)
{
$queue = $request->input('queue');
$member = $request->input('member');
$result = $this->queueManager->addMember($queue, $member);
return response()->json(['success' => $result]);
}
public function getQueueStatus(string $queue)
{
$status = $this->queueManager->getQueueStatus($queue);
return response()->json($status);
}
}
The package automatically fires Laravel events for Asterisk events:
// Listen for call events
Event::listen(\AsteriskPbxManager\Events\CallConnected::class, function ($event) {
Log::info('Call connected', [
'unique_id' => $event->uniqueId,
'channel' => $event->channel,
'caller_id' => $event->callerId,
]);
});
Event::listen(\AsteriskPbxManager\Events\CallEnded::class, function ($event) {
Log::info('Call ended', [
'unique_id' => $event->uniqueId,
'duration' => $event->duration,
'cause' => $event->cause,
]);
});
Create custom event listeners:
use AsteriskPbxManager\Events\CallConnected;
class LogCallActivity
{
public function handle(CallConnected $event)
{
// Custom logging logic
CallLog::create([
'unique_id' => $event->uniqueId,
'channel' => $event->channel,
'caller_id' => $event->callerId,
'connected_at' => now(),
]);
}
}
Register in your EventServiceProvider
:
protected $listen = [
\AsteriskPbxManager\Events\CallConnected::class => [
\App\Listeners\LogCallActivity::class,
],
];
Enable real-time updates by configuring broadcasting:
// In your broadcasting configuration
'channels' => [
'asterisk' => [
'driver' => 'pusher', // or your preferred driver
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true,
],
],
],
Listen for events in JavaScript:
Echo.channel('asterisk.calls')
.listen('CallConnected', (e) => {
console.log('Call connected:', e);
})
.listen('CallEnded', (e) => {
console.log('Call ended:', e);
});
php artisan asterisk:status
php artisan asterisk:monitor-events
# Add queue member
php artisan asterisk:queue:add support SIP/1001
# Remove queue member
php artisan asterisk:queue:remove support SIP/1001
# Pause queue member
php artisan asterisk:queue:pause support SIP/1001
# Get queue status
php artisan asterisk:queue:status support
php artisan asterisk:health-check
Track call history and analytics:
use AsteriskPbxManager\Models\CallLog;
// Get recent calls
$recentCalls = CallLog::recent()->get();
// Get calls by date range
$calls = CallLog::whereBetween('created_at', [$startDate, $endDate])->get();
// Get calls by caller ID
$calls = CallLog::whereCallerId('1001')->get();
Store and query Asterisk events:
use AsteriskPbxManager\Models\AsteriskEvent;
// Get recent events
$events = AsteriskEvent::recent()->get();
// Get events by type
$dialEvents = AsteriskEvent::whereEventName('Dial')->get();
// Get events by unique ID
$callEvents = AsteriskEvent::whereUniqueId($uniqueId)->get();
The package provides custom exceptions for different error scenarios:
use AsteriskPbxManager\Exceptions\AsteriskConnectionException;
use AsteriskPbxManager\Exceptions\ActionExecutionException;
try {
$result = AsteriskManager::originateCall('SIP/1001', '2002');
} catch (AsteriskConnectionException $e) {
Log::error('AMI connection failed: ' . $e->getMessage());
} catch (ActionExecutionException $e) {
Log::error('Action execution failed: ' . $e->getMessage());
} catch (\Exception $e) {
Log::error('Unexpected error: ' . $e->getMessage());
}
The package includes comprehensive tests. Run the test suite:
composer test
Run specific test suites:
# Unit tests only
./vendor/bin/phpunit --testsuite=Unit
# Integration tests only
./vendor/bin/phpunit --testsuite=Integration
# Performance tests only
./vendor/bin/phpunit --testsuite=Performance
Generate code coverage:
./vendor/bin/phpunit --coverage-html coverage
- Always use environment variables for sensitive configuration
- Never commit AMI credentials to version control
- Use strong, unique AMI passwords
- Restrict AMI access to specific IP addresses when possible
The package automatically validates all inputs to AMI commands to prevent injection attacks.
Errors are logged without exposing sensitive information in responses.
- The package uses connection pooling for optimal performance
- Connections are automatically reestablished if lost
- Configure appropriate timeouts for your environment
- Use Laravel queues for heavy event processing
- Configure event filtering to reduce processing overhead
- Consider using Redis for event caching in high-load scenarios
- Use database indexes for frequently queried fields
- Consider partitioning large event tables
- Regularly archive old call logs to maintain performance
AsteriskConnectionException: Failed to connect to AMI
Solutions:
- Verify Asterisk is running and AMI is enabled
- Check AMI configuration in
/etc/asterisk/manager.conf
- Verify network connectivity and firewall rules
- Confirm AMI credentials are correct
ActionExecutionException: Action not permitted
Solutions:
- Check AMI user permissions in
manager.conf
- Verify the user has necessary action permissions
- Confirm authentication is successful
Solutions:
- Verify event logging is enabled in Asterisk
- Check Laravel event listeners are registered
- Confirm broadcasting configuration if using real-time updates
Enable debug logging for detailed troubleshooting:
ASTERISK_LOG_LEVEL=debug
Use the health check command to verify system status:
php artisan asterisk:health-check --verbose
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details on how to contribute to this project.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.
If you discover any issues or have questions, please:
- Check the troubleshooting section
- Search existing issues
- Create a new issue with detailed information
For commercial support and consulting, please contact [email protected].