19.4. Der Asynchronous Javascript Asterisk Manager (AJAM)

Seit Version 1.4 bringt Asterisk einen kleinen Webserver mit, AJAM genannt, über den man per HTTP auf das Asterisk Manager Interface (AMI) zugreifen kann. Die Bezeichnung AJAM ist eindeutig von AJAX[107] (Asynchronous JavaScript and XML) abgeleitet.
Zur Einrichtung sind die Schritte wie in Abschnitt 19.3, „Das Manager-Interface (AMI)“ Voraussetzung. Zusätzlich stellt man in der manager.conf im Abschnitt [general] den Parameter webenabled auf yes ein. Beachten Sie auch den Parameter httptimeout, der festlegt, nach welcher Inaktivität (in Sekunden) man im Web-Interface automatisch ausgeloggt wird. Um dann den Webserver zu aktivieren, setzt man in der http.conf folgende Einstellungen:
[general]
enabled=yes
enablestatic=yes
bindaddr=127.0.0.1
bindport=8088
prefix=asterisk
enablestatic muss man nur dann aktivieren, wenn der AJAM auch als Webserver für statische Dateien im Verzeichnis /var/lib/asterisk/static-http/ fungieren soll. Normalerweise stellt man das auf no, es ist aber Voraussetzung für die Asterisk-AJAM-Demo („AJAM Demo“).
Vergessen Sie nicht, Asterisk neu zu starten!

Achtung

Nach meiner Einschätzung ist es in den seltensten Fällen empfehlenswert, andere Webapplikationen, also solche, die ausschließlich für den Administrator zugänglich sind, direkt auf die AJAM-Schnittstelle zugreifen zu lassen, und das ist wohl auch nicht so gedacht, denn dazu lassen sich die Rechte mit read und write (siehe Abschnitt 19.3, „Das Manager-Interface (AMI)“) einfach nicht granular genug einstellen. Denken Sie daran, dass ein User absichtlich oder unabsichtlich auch andere Aktionen ausführen kann, als Sie ihm in der GUI zur Verfügung stellen. Besser wäre es, Ihre Applikation auf z. B. ein PHP-Skript zugreifen zu lassen, das nur vordefinierte erlaubte Befehle auf dem AMI ausführt; und zur Sicherheit muss noch nicht mal dieses Skript alle AMI-Rechte haben.

Beispiel: Anzahl der Mailbox-Nachrichten per AJAM abfragen

Wir betrachten wieder die aus „Beispiel: Anzahl der Mailbox-Nachrichten mit Expect abfragen“ und „Beispiel: Anzahl der Mailbox-Nachrichten mit PHP abfragen“ bekannte einfache Aufgabe, die Anzahl der Nachrichten auf einer Mailbox abzufragen. Der AJAM bietet hier folgende Möglichkeiten:

HTML

Unter der URL
http://localhost:8088/asterisk/manager
wartet das Manager-Interface auf unsere Anfragen. Dabei werden die Felder eines Pakets als Parameter an die URL gehängt. Probieren Sie die folgenden beiden Adressen im Webbrowser aus:
http://localhost:8088/asterisk/manager?action=Login&username=admin&secret=geheim
http://localhost:8088/asterisk/manager?action=MailboxCount&mailbox=123
Die Antwort erfolgt jeweils als HTML-Seite, ist also für den Zugriff durch Skripte denkbar ungeeignet.

Plain-Text

Man kann in der URL manager durch rawman ersetzen, dann erfolgt die Antwort als Plain-Text. Zum Einloggen und Abfragen der Mailbox-Nachrichten schreiben Sie also:
http://localhost:8088/asterisk/rawman?action=Login&username=admin&secret=geheim
Response: Success
Message: Authentication accepted
http://localhost:8088/asterisk/rawman?action=MailboxCount&mailbox=123
Response: Success
Message: Mailbox Message Count
Mailbox: 123
NewMessages: 0
OldMessages: 0
http://localhost:8088/asterisk/rawman?action=Logoff
Response: Goodbye
Message: Thanks for all the fish.
Diese Text-Ausgabe kann man also gut in automatisierten Skripten verwenden.

XML

Will man stattdessen lieber XML verwenden, dann ruft man mxml auf. Die XML-Ausgabe ist hier zur leichteren Lesbarkeit formatiert dargestellt; der AJAM macht keine Zeilenumbrüche innerhalb der Tags. Einen korrekten XML-Parser würde das aber auch so, wie es hier dargestellt ist, nicht stören.
http://localhost:8088/asterisk/mxml?action=Login&username=admin&secret=geheim
<ajax-response>
    <response type='object' id='unknown'>
        <generic
            response='Success'
            message='Authentication accepted' />
    </response>
</ajax-response>
http://localhost:8088/asterisk/mxml?action=MailboxCount&mailbox=123
<ajax-response>
    <response type='object' id='unknown'>
        <generic
            response='Success'
            message='Mailbox Message Count'
            mailbox='123'
            newmessages='0'
            oldmessages='0' />
    </response>
</ajax-response>
http://localhost:8088/asterisk/mxml?action=Logoff
<ajax-response>
    <response type='object' id='unknown'>
        <generic
            response='Goodbye'
            message='Thanks for all the fish.' />
    </response>
</ajax-response>

Hinweise zu AJAX und AJAM

JSON

Bei AJAX-Anwendungen – das erkennt man leicht am Namen Asynchronous JavaScript and XML – ist XML das übliche Format, obwohl es wegen seiner aufgeblähten Struktur vielfach kritisiert wird. Für AJAX können aber auch andere Formate wie JSON[108] zum Einsatz kommen. JSON (JavaScript Object Notation) ist – der Name verrät es – besonders gut für JavaScript-Anwendungen geeignet, da die Datenstruktur hier nativ mit eval() in ein Objekt umgewandelt werden kann und wenig Overhead hat. Es existieren aber auch zahlreiche Implementierungen für PHP, Perl etc. Eine Ausgabe in JSON fehlt dem AJAM bisher jedoch leider. Sie könnten aber beispielsweise die Plain-Text-Ausgabe clientseitig in JSON umwandeln, wenn Ihnen das leichter fällt oder wenn es sich besser in vorhandene JS-Libs integrieren lässt. Hier der Ansatz als Idee:
// angenommen, in responseText ist der empfangene Antwort-Text
// gespeichert, was wir hier nur simulieren:
var responseText = 'Response: Success\n'
+'Message: Mailbox Message Count\n'
+'Mailbox: 123\n'
+'NewMessages: 0\n'
+'OldMessages: 0\n';

// einfache Anführungszeichen escapen:
responseText = responseText.replace( /\'/g, "\\'" );
// Felder quoten:
responseText = responseText.replace( /^([a-z\d]*):\s*(.*)/gmi, "'$1':'$2'," );
// in Objekt umwandeln:
eval('var packet = {'+ responseText +'}');

// jetzt kann man wie bei jedem Objekt so auf die Felder zugreifen:
alert( packet['NewMessages'] );   // gibt "0" aus

Ping

Für Zugriffe von AJAX-Anwendungen auf den AJAM ist der Ping-Befehl besonders hilfreich, der dazu dient, die Verbindung und Authentifizierung offen zu halten:
http://localhost:8088/asterisk/rawman?action=Ping
Response: Pong

AJAM Demo

Unter der URL
http://localhost:8088/asterisk/static/ajamdemo.html
ist eine kleine Beispielanwendung mitgeliefert, die den Zugriff per AJAX demonstriert. Sie verwendet die äußerst praktische JavaScript-Library Prototype[109] für die AJAX-Zugriffe und zeigt mit der Action Status die momentan aktiven Kanäle an. Sie können die AJAM-Demo als Basis für eigene AJAX-Anwendungen heranziehen.

Apache

Der Webserver von Asterisk ist sehr minimalistisch und ersetzt keinesfalls einen richtigen Server wie den Apache, der auch PHP-Skripte ausführt etc. Um beides zu vereinen, könnten Sie z. B. in der httpd.conf des Apache an der entsprechenden Stelle den Eintrag
ProxyPass /ajam http://localhost:8088/asterisk
verwenden, um für alle Zugriffe auf den URL-Pfad /ajam nur als Proxy zu fungieren und die Anfragen zum AJAM durchzuschleusen.