Skip to content


Shift8 PHP Asterisk Manager Library

Shift8 provides a simple mechanism over the AJAM asterisk interface. Apart from the obvious reason of providing an easy way to talk with a remote asterisk server, the main benefit of having an intermediate library between a software and an Asterisk server, is mostly that you can isolate the remote Asterisk, protecting the credentials and the entire PBX

Features

  • Shift8 supports pretty much all asterisk manager commands
  • Provides a Event listener mechanism, so that when an event occurs to notify a part of a system. The Event listener can also contain a filter to notify the listener for specific events only
  • Provides a Debug listener to assist in the debugging of the application your are creating. (Currently containing a Dummy (stdout) and a syslog debug listener)
  • Provides a Queue manager interface. Using Shift8 one could create a two part application that instead of executing a command directly to the remote asterisk, would queue the command via a Queue Processor, and another application would run, execute the commands in Queue for a specific interval, and store the results into the same Queue for the ‘frontend’ application to retrieve
  • Supports a common (as much as possible) infrastructure for all results coming from the remote asterisk via Shift8_Event
  • Shift8 library is properly documented and all the return values from the internal functions are created in a way to make the library SOAP discoverable.

Prerequisites

  • Asterisk (with AJAM interface) Shift8 has been developed under Asterisk 1.6 but I don’t think there will be any problems with version 1.4
  • PHP5
  • PHP5 Curl extension (apt-get install php5-curl under debian/ubuntu)
  • Optional: PHP5 Mysql extension (used by the Shift8 Queue Mysql Processor)

Installation

You must initially enable the manager interface in the asterisk by editing asterisk/manager.conf. You need to set:

enabled = yes
webenabled = yes

You also need to create a manager for Shift8 to connect with:

[manager]
secret=secret
deny=0.0.0.0/0.0.0.0
permit=127.0.0.1/255.255.255.0
read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan
write = system,call,agent,user,config,command,reporting,originate

Finally you must edit http.conf and enable it by setting ‘enable’ attibute to yes.

One could also setup bindaddr to explicitly define where the manager interface should bind to.

Todo

  • This version of Shift8 is considered an early version where many events returned by the remote asterisk might not be trapped properly. I have decided to make it public to get some assistance in
  • I need to populate the examples that come with Shift8
  • I have started building a GUI (web frontend) based on AJAX and Shift8, but since I am lousy on graphical design, If anyone is willing to assist please drop me a line
  • Expand the documentation

Changelog

  • 0.1.3
    1. Fixed bug with proxy() not returning correct error when no asterisk could be reached
      Fixed a warning with an non existing variable
  • 0.1.2
    1. Fixed wrong parameter Date on Originate Action
      Added urlencode() in all variables passed to AJAM
      Removed a debug syslog message
  • 0.1.1
    1. Corrected a bug on proxy function that would cause the request to be sent twice on the remote asterisk server
      Added support for saving and retrieving the last error message that has occurred in the communication with the remote asterisk (via setLastError()/getLastError())
      Changed queueAddInterface to support member, penalty, and paused status
  • 0.1
    1. Initial release

Examples

Shift8 Downloads & API

Posted in PHP, Telephony.

Tagged with , , , , .


24 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Jason Yeh says

    Sir to whom it may concern;

    I realized I couldn’t find your email contact anywhere, nor in the release note. I am very interested in your PHP Framework for Asterisk, its seem to have lot of potential. I am still learning more about this framework and really want to understand how exactly this framework handles the API Response from Asterisk after all the command been injected through its queue messages.

    1) I got off guard confusing when I looked at the “QueueExecute.php”example on that line “$shift8->getQueuedCommandResponse()”, am I supposed to loop through code to see if I ever got response back from Asterisk?

    2) Is it going to be similar to RESTful HTTP requests, where Asterisk will push for result in response?

    3) Also, the document did mentioned about message in queue’s data been stored somewhere in the database, what is it?

    Because I am critically interested in this framework, thus I would really like to understand how its designed and architect for PHP to really handle real-time communications with Asterisk. I shall look forward hearing back from you soon.

    Thanks,
    Jason

  2. mobius says

    Hello Jason,

    Sorry for taking so long to respond. I was away on holiday! I have moved the comment here since it is about the Shift8 library.

    Well the logic behind Queue mechanism of the library is a bit abstract. The concept is rather simple. Shift8 provides a mechanism for adding commands to a queue, a mechanism for executing the commands in Queue and finally one to retrieve the result from an executed command.

    One should implement a Shift8_Queue_Processor (see the abstract class here) that handles the inserts/updates/executes/retrievals from the queue data source. There is a simple MySQL implementation here

    In order to handle a queued command one should handle it via the Shift8_Queue_Item. Each queue item must have a unique queue id (assigned by the Shift8_Queue_Processor) so as it can be retrieved afterwards via the getQueuedCommandResponse

    I am guessing that this can be extended for the Processor to automatically retrieve all the processed non-retrieved commands. And in front you could have a RESTfull client.

    Give me more information on what you would like to achieve, I could see if I can modify Shift8 to better suit you.

    Cheers!

  3. Leo says

    Hello there,

    Can Shift8 be used as an AMI proxy? I’m writing PHP software that requires multiple users to send simultaneous requests to the asterisk manager. Can Shift8 help me with that task? If not, what would you recommend?

    Thanks in advance,

    Leo

  4. mobius says

    Hello Leo,

    You could use Shift8 to create an AMI proxy, but you need to pass the asterisk manager session id back and forth. You could use the getCookie(), setCookie() functions from Shift8 so that the connection will remain open.

    You are also responsible for keeping the connection open with the AMI by ping()ing the asterisk library and then use waitEvent() to retrieve all events generated by the Asterisk

    Remember to close the PHP session after saving/reading the cookie, because Sessions in PHP are locking and when you do a WaitEvent() will lock the session until that terminates. (It took me a while to figure that out. Thankfully there is Xdebug Profiler :) )

  5. Pawel says

    Hi,

    Could you give me examle how to ( if possible ) get uniqueid of call generated with originate.

    Thanks
    Pawel

  6. David says

    Hi

    First,
    I can try to help coding small php tasks in my spare time (hope i’ll have one)

    2nd, I’m using the old PHP AGI API and one of problems i experience is an occasional manger’s logging off. Is it an issue that you familiar with/was fixed? or is it my own bug?

    Tnx! David R.

  7. mobius says

    Hi David,

    Well if you feel like contributing any part you are most welcome to do so!

    As for your question, in any applications I’ve build using Shift8 I’ve never had any problems with the Manager disconnecting. Maybe it is AJAM that does a difference (since Shift8 is using AJAM). Give it a try and we could work any issues out!

  8. Massimiliano says

    Hi,

    Shift8 seem to be a very interesting project but it lack of examples and documentation as you told in TODO list.
    Anyway, I would try it in a faster bit but to do so I should have a minimal GUI (web frontend).
    Thus, can you provide an example of a little web client that monitor the Asterisk channels status in real time?
    I think it will be a good starting point for everyone would try and assist you in the project expansion.
    Every project can be a good project if it has a good community and more effort as possible.

    Thank you.
    Massimiliano

  9. mobius says

    Hi Massimiliano,

    You are right. I will try to come up with something in the next few days and I’ll post it here :)

  10. mobius says

    Masimiliano,

    Well it took me a while but I’ve crafted something up for you to check out. You can find it here: Simple Channel Monitoring via Shift8

  11. Tube says

    I think Asterisk Manager API is not very stable, so far. Your thoughts on this?

  12. mobius says

    @Tube,

    Well I’ve heard this one before. I believe AMI has made a major step forward since it was first added to the asterisk trunk. I believe that it can be considered a rather safe option when you need to send commands to an asterisk server through it. I have created various production applications (Dialers, Queue Monitors/Actions, etc) through the AMI that for the load they are getting they never had any issues.

    However if you were to read events from asterisk, through lets say a web application I would think twice of my implementation. I wouldn’t want for each web connection to have one connection to the AMI, and I would probably implement a proxy in-between so that asterisk will send the events to the proxy and have the proxy distribute the messages to the web clients. (One idea that comes to mind easily is have the proxy receive the messages, send them to a message queue system like RabbitMQ and then via a fanout queue to spread the message to all clients listening)

    What are you thinking of building?

  13. jean-louis says

    I just found your site, it looks great, I wish I could see more examples ( I’m not a programmer )
    to realize something like this: http://code.google.com/p/lynks-ajax-panel/
    do you maintain shift8 library ?
    thanks
    Jean-loui

  14. mobius says

    Yes I do maintain it but there has not been a need for changes recently! I guess you need to spend some time to get familiar with the lib.I will see if I can add some more examples

  15. jl curty says

    it would be great! thanks mobius

  16. leky says

    Hello,

    The “processEvents” for getExtensionState is not working in Asterisk 1.8 – it just returns empty array.

    $stanjestevilke=$shift8->getExtensionState(’100′,’from-internal’);
    print_r($stanjestevilke);

    When I trace it (via wireshark) I can see, that the AJAM sends the data back, but it looks like the process events is not working in this case…

  17. mobius says

    @leky,

    Hey there! Could you try the master branch from github now? I think I’ve got it sorted out. Also please use github for bug reports please, just to make sure that everyone follows.

  18. Paolo says

    Hi Mobius,
    First thanks for this library!
    I’m using it to make a GUI where an extension can add itself on a queue, and from the GUI can operate on the call (monitor, send DTMF ecc).
    With your sample i can see calls arriving i am able to read the events.. but when i send a command with the manager.php like QueueAddInterface or QueueRemoveInterface, playDTMF ecc.. it seems to take long time to execute it and actually i cannot understand why.. For example i send the command QueueAddInterface and wait the event QueueMemberAdded from the poller.php, but it can arrive immediatly or after 1 minutes or never.. is there something i don’t know??

  19. mobius says

    Hi Paolo,

    It’s good to hear that you find it useful! I would like to see what you will have built at the end. :) Regarding your issue, its probably because of PHP sessions being locked.

    I’ve already written in http://www.foriamroot.org/simple-channel-monitoring-via-shift8/, “Please note that there is one more thing not handled by this poller. If you were to do multiple requests using AJAX please remember that PHP Sessions are locking. Thus you can’t have an open connection to the poller waiting for events from the remote asterisk and perform another command on the Asterisk at the same time. (PHP will wait for the poller to return before unlocking the session and giving access to the next request). (This is a common scenario which you will face if you need to terminate or spy an active channel).

    In order to avoid this you must use session_write_close() before calling WaitEvent() so that the session is released before polling the remote server. However if you have closed the session before the WaitEvent() you cannot unset the $_SESSION['acookie'] on null return. (You should have another AJAX request pinging the remote asterisk (See ping()) and if the request fails re-login)”

    So add a session_write_close() in the getEvents() function of the poller before the waitEvent() and see if this solves your problem. You should then using javascript and ping() the remote asterisk server to verify the session. But before that, check if my solution works for you.

  20. Paolo says

    Hi mobius,
    you’re great! i should read twice your article, it answer to my problem..
    I put session_write_close() before the WaitEvent, and with jscript call a ping each second and all is going exactly like i want (maybe 1 sec is too few, i will try other values) .
    Thank you so much for you quick answer, and i will be happy to show you my final application. sys

  21. Paolo says

    Hi mobius.
    My AJAM application need to send DTMF tone and make other actions in a connected call..for example during a call throug a SIP/trunk and a Local/Extension, need to send a DTMF tone to the trunk an then hangup.
    I’m using jquery ajax functions and Shift8 library to connect to AMI.

    es. send a DTMF tone to the trunk line then disconnect the call

    // array with the sequence of actions

    m[0][action_code]=’playDTMF’;
    m[0][parameter]=’5′;
    m[1][action_code]=’hangup’;
    m[1][parameter]=”;

    execMacro(m,’SIP/trunk_on’); //function that run the macro


    function execMacro(macroArray,channel){
    //ricorsive function that run the sequence of actions
    if (macroArray.lengthplayDTMF($dtmf,$channel);
    echo json_encode($response);
    break;
    case “hangup”:
    $channel=$_POST['channel'];
    $response=$shift8->hangup($channel);
    echo json_encode($response);
    break;
    ….
    }
    ————————————–

    the problem is :
    the system exec the actions but the response from server is too quick.. in this case the call is closed before the DTMF sent.

    I try to get the “DTMF” event from manager poller but it starts only if one of the telephone connected press a DTMF tone, it doesnt starts if the manager send the DTMF.. why???
    any ideas?

    i can delay the next request with a No Op delay but it’s not efficient and elegant solution. i’d like to get an event when the action is effectively terminated

  22. mobius says

    Hi Paolo,

    I am not entirely sure I understood your snippet and problem. Could you paste a sample code in github so that I can try and replicate it? In theory to answer your second question asterisk should fire a DTMF event on the SendDTMF manager command.

    You could also try to generate a custom event yourself that the poller would receive by using the sendUserEvent() function. (However please note that this function is untested and may not work exactly as it should. If you do test it please write back with an issue on github so that I can get it fixed)

  23. Bahman says

    Hi and thanks
    Im newbie from asterisk, so
    I want to call mobile number in my users panel. exactly when user click on a number, connect to asterisk and call selected mobile number via specified internal extension.
    is there any solution in shift8?

Continuing the Discussion

  1. setlasterror linked to this post on April 1, 2010

    [...] in a textbox. To achieve this we have to call native keyboard event for tab key whenever enter is…Shift8 PHP Asterisk Manager Library Bow before me…for I …Shift8 provides a simple mechanism over the AJAM asterisk interface. Apart from the obvious reason [...]



Some HTML is OK

or, reply to this post via trackback.