PHPackages                             batinduz/ami-react - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Queues &amp; Workers](/categories/queues)
4. /
5. batinduz/ami-react

ActiveLibrary[Queues &amp; Workers](/categories/queues)

batinduz/ami-react
==================

Async, event-driven access to the Asterisk Manager Interface (AMI)

v0.3.0(11y ago)0103MITPHPPHP &gt;=5.3

Since Jul 18Pushed 10y ago1 watchersCompare

[ Source](https://github.com/batinduz/php-ami-react)[ Packagist](https://packagist.org/packages/batinduz/ami-react)[ Docs](https://github.com/clue/php-ami-react)[ RSS](/packages/batinduz-ami-react/feed)WikiDiscussions master Synced 4w ago

READMEChangelogDependencies (4)Versions (5)Used By (0)

clue/ami-react [![Build Status](https://camo.githubusercontent.com/8f0696b57ac0e32c9701072d3497ab09f754a59a9e840939d2fe4f4e4d7634ff/68747470733a2f2f7472617669732d63692e6f72672f636c75652f7068702d616d692d72656163742e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/clue/php-ami-react)
====================================================================================================================================================================================================================================================================================================

[](#clueami-react-)

Simple async, event-driven access to the Asterisk Manager Interface (AMI)

The [Asterisk PBX](http://asterisk.org/) is a popular open source telephony solution that offers a wide range of telephony features. The [Asterisk Manager Interface (AMI)](https://wiki.asterisk.org/wiki/display/AST/The+Asterisk+Manager+TCP+IP+API)allows you to control and monitor the PBX. Among others, it can be used to originate a new call, execute Asterisk commands or monitor the status of subscribers, channels or queues.

- **Async execution of Actions** - Send any number of actions (commands) to the asterisk in parallel and process their responses as soon as results come in. The Promise-based design provides a *sane* interface to working with out of bound responses.
- **Event-driven core** - Register your event handler callbacks to react to incoming events, such as an incoming call or a change in a subscriber state.
- **Lightweight, SOLID design** - Provides a thin abstraction that is [*just good enough*](http://en.wikipedia.org/wiki/Principle_of_good_enough)and does not get in your way. Future or custom actions and events require no changes to be supported.
- **Good test coverage** - Comes with an automated tests suite and is regularly tested against versions as old as Asterisk 1.8+

Quickstart example
------------------

[](#quickstart-example)

Once [installed](#install), you can use the following code to access your local Asterisk Telephony instance and issue some simple commands via AMI:

```
$loop = React\EventLoop\Factory::create();
$factory = new Factory($loop);

$factory->createClient('user:secret@localhost')->then(function (Client $client) {
    echo 'Client connected' . PHP_EOL;

    $sender = new ActionSender($client);
    $sender->listCommands()->then(function (Response $response) {
        echo 'Available commands:' . PHP_EOL;
        var_dump($response);
    });
});

$loop->run();
```

See also the [examples](examples).

Usage
-----

[](#usage)

### Factory

[](#factory)

The `Factory` is responsible for creating your [`Client`](#client) instance. It also registers everything with the main [`EventLoop`](https://github.com/reactphp/event-loop#usage).

```
$loop = \React\EventLoop\Factory::create();
$factory = new Factory($loop);
```

If you need custom DNS or proxy settings, you can explicitly pass a custom instance of the [`ConnectorInterface`](https://github.com/reactphp/socket-client#connectorinterface):

```
$factory = new Factory($loop, $connector);
```

#### createClient()

[](#createclient)

The `createClient($amiUrl)` method can be used to create a new [`Client`](#client). It helps with establishing a plain TCP/IP or secure SSL/TLS connection to the AMI and issuing an initial `login` action.

```
$factory->createClient('user:secret@localhost')->then(
    function (Client $client) {
        // client connected and authenticated
    },
    function (Exception $e) {
        // an error occured while trying to connect or authorize client
    }
);
```

> Note: The given $amiUrl *must* include a host, it *should* include a username and secret and it *can* include a scheme (tcp/ssl) and port definition.

### Client

[](#client)

The `Client` is responsible for exchanging messages with the Asterisk Manager Interface and keeps track of pending actions.

If you want to send outgoing actions, see below for the [`ActionSender`](#actionsender) class.

#### on()

[](#on)

The `on($eventName, $eventHandler)` method can be used to register a new event handler. Incoming events and errors will be forwarded to registered event handler callbacks:

```
$client->on('event', function (Event $event) {
    // process an incoming AMI event (see below)
});
$client->on('close', function () {
    // the connection to the AMI just closed
});
$client->on('error', function (Exception $e) {
    // and error has just been detected, the connection will terminate...
});
```

#### close()

[](#close)

The `close()` method can be used to force-close the AMI connection and reject all pending actions.

#### end()

[](#end)

The `end()` method can be used to soft-close the AMI connection once all pending actions are completed.

#### Advanced

[](#advanced)

Creating [`Action`](#action) objects, sending them via AMI and waiting for incoming [`Response`](#response) objects is usually hidden behind the [`ActionSender`](#actionsender) interface.

If you happen to need a custom or otherwise unsupported action, you can also do so manually as follows. Consider filing a PR though :)

##### createAction()

[](#createaction)

The `createAction($name, $fields)` method can be used to construct a custom AMI action. A unique value will be added to "ActionID" field automatically (needed to match incoming responses).

##### request()

[](#request)

The `request(Action $action)` method can be used to queue the given messages to be sent via AMI and wait for a [`Response`](#response) object that matches the value of its "ActionID" field.

### ActionSender

[](#actionsender)

The `ActionSender` wraps a given [`Client`](#client) instance to provide a simple way to execute common actions. This class represents the main interface to execute actions and wait for the corresponding responses.

```
$sender = new ActionSender($client);
```

#### Actions

[](#actions)

All public methods resemble their respective AMI actions.

```
$sender->ping()->then(function (Response $response) {
    // response received for ping action
});
```

Listing all available actions is out of scope here, please refer to the [class outline](src/ActionSender.php).

#### Processing

[](#processing)

Sending actions is async (non-blocking), so you can actually send multiple action requests in parallel. The AMI will respond to each action with a [`Response`](#response) object. The order is not guaranteed. Sending actions uses a [Promise](https://github.com/reactphp/promise)-based interface that makes it easy to react to when an action is *fulfilled*(i.e. either successfully resolved or rejected with an error):

```
$sender->ping()->then(
    function (Response $response) {
        // response received for ping action
    },
    function (Exception $e) {
        // an error occured while executing the action

        if ($e instanceof ErrorException) {
            // we received a valid error response (such as authorization error)
            $response = $e->getResponse();
        } else {
            // we did not receive a valid response (likely a transport issue)
        }
    }
});
```

#### Custom actions

[](#custom-actions)

Using the `ActionSender` is not strictly necessary, but is the recommended way to execute common actions.

If you happen to need a new or otherwise unsupported action, or additional arguments, you can also do so manually. See the advanced [`Client`](#client) usage above for details. A PR that updates the `ActionSender` is very much appreciated :)

### Message

[](#message)

The `Message` is an abstract base class for the [`Response`](#response), [`Action`](#action) and [`Event`](#event) value objects. It provides a common interface for these three message types.

Each `Message` consists of any number of fields with each having a name and one or multiple values. Field names are matched case-insensitive. The interpretation of values is application specific.

#### getFieldValue()

[](#getfieldvalue)

The `getFieldValue($key)` method can be used to get the first value for the given field key. If no value was found, `null` is returned.

#### getFieldValues()

[](#getfieldvalues)

The `getFieldValues($key)` method can be used to get a list of all values for the given field key. If no value was found, an empty `array()` is returned.

#### getFields()

[](#getfields)

The `getFields()` method can be used to get an array of all fields.

#### getActionId()

[](#getactionid)

The `getActionId()` method can be used to get the unique action ID of this message. This is a shortcut to get the value of the "ActionID" field.

#### Response

[](#response)

The `Response` value object represents the incoming response received from the AMI. It shares all properties of the [`Message`](#message) parent class.

##### getCommandOutput()

[](#getcommandoutput)

The `getCommandOutput()` method can be used to get the resulting output of a "command" [`Action`](#action). This value is only available if this is actually a response to a "command" action, otherwise it defaults to `null`.

```
$sender->command('help')->then(function (Response $response) {
    echo $response->getCommandOutput();
});
```

#### Action

[](#action)

The `Action` value object represents an outgoing action message to be sent to the AMI. It shares all properties of the [`Message`](#message) parent class.

#### Event

[](#event)

The `Event` value object represents the incoming event received from the AMI. It shares all properties of the [`Message`](#message) parent class.

##### getName()

[](#getname)

The `getName()` method can be used to get the name of the event. This is a shortcut to get the value of the "Event" field.

Install
-------

[](#install)

The recommended way to install this library is [through composer](http://getcomposer.org). [New to composer?](http://getcomposer.org/doc/00-intro.md)

```
{
    "require": {
        "clue/ami-react": "~0.3.0"
    }
}
```

Tests
-----

[](#tests)

In order to run the tests, you need PHPUnit:

```
$ phpunit
```

The test suite contains both unit tests and functional integration tests. The functional tests require access to a running Asterisk server instance and will be skipped by default. If you want to also run the functional tests, you need to supply *your* AMI login details in an environment variable like this:

```
$ LOGIN=username:password@localhost phpunit
```

License
-------

[](#license)

MIT

###  Health Score

24

—

LowBetter than 31% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity9

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 98.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~128 days

Total

3

Last Release

4109d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/2089790?v=4)[Batin](/maintainers/batinduz)[@batinduz](https://github.com/batinduz)

---

Top Contributors

[![clue](https://avatars.githubusercontent.com/u/776829?v=4)](https://github.com/clue "clue (69 commits)")[![batinduz](https://avatars.githubusercontent.com/u/2089790?v=4)](https://github.com/batinduz "batinduz (1 commits)")

---

Tags

asyncreactamiAsterisk Manager Interface

### Embed Badge

![Health badge](/badges/batinduz-ami-react/health.svg)

```
[![Health](https://phpackages.com/badges/batinduz-ami-react/health.svg)](https://phpackages.com/packages/batinduz-ami-react)
```

###  Alternatives

[ccxt/ccxt

A cryptocurrency trading API with more than 100 exchanges in JavaScript / TypeScript / Python / C# / PHP / Go

43.2k341.0k1](/packages/ccxt-ccxt)[react/socket

Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP

1.3k129.1M445](/packages/react-socket)[league/geotools

Geo-related tools PHP 7.3+ library

1.4k5.6M30](/packages/league-geotools)[clue/ami-react

Streaming, event-driven access to the Asterisk Manager Interface (AMI), built on top of ReactPHP.

85113.9k10](/packages/clue-ami-react)[rector/rector-src

Instant Upgrade and Automated Refactoring of any PHP code

136406.3k14](/packages/rector-rector-src)[clue/reactphp-eventsource

Instant real-time updates. Lightweight EventSource client receiving live messages via HTML5 Server-Sent Events (SSE). Fast stream processing built on top of ReactPHP's event-driven architecture.

5819.5k3](/packages/clue-reactphp-eventsource)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
