Connessione all'Asterisk Manager con Python

-

15 Novembre 2018

Connettersi a un sistema Asterisk operativo, ascoltandone gli eventi, permette di realizzare funzionalità basate sullo stato delle chiamate in corso. Ad esempio, possiamo aprire in automatico una finestra all'operatore che risponde al telefono, con tutte le informazioni sull'utente che sta chiamando.

Come funzionano i canali e i bridge di Asterisk

L'ascolto degli eventi può risultare complicato, perché non esistono eventi semplici come "interno X ha chiamato Y".

Al contrario, l'ascolto avviene più a basso livello (verso l'hardware), nel caso di "interno X ha chiamato Y", ecco quello che succede:

# I nomi dei canali e dei bridge sono inventati, per favorire la comprensibilità.

# Utente X crea un canale
Evento Newchannel, nome canale -> CanaleUtente

# Viene creato un canale anche per Y (utente chiamato, corrisponde al canale della linea)
Evento Newchannel, nome canale -> CanaleLinea

# L'utente risponde, avvengono 3 eventi:
Evento BridgeCreate, nome bridge -> Bridge1
Evento BridgeEnter, CanaleUtente entra nel Bridge1
Evento BridgeEnter, CanaleLinea entra nel Bridge1

# Le due persone si parlano per un po'
# Al momento del riaggancio avventono nuovamente 3 eventi

Evento BridgeLeave, CanaleUtente esce dal Bridge1
Evento BridgeLeave, CanaleLinea esce dal Bridge1
Evento BridgeDestroy, rimosso il bridge

# Nel caso di un trasferimento di chiamata le cose 
# si complicano, con gli eventi BridgeMerge

L'elenco di tutti gli eventi AMI disponibili è disponibile a questa pagina.

Attenzione alla versione di Asterisk consultata, gli eventi elencati possono variare in modo importante, così come le loro proprietà.

Esempio di connessione agli eventi AMI con Python

La prima cosa da fare è configurare una nuova utenza per l'Asterisk Manager, nel file /etc/asterisk/manager.conf

Di seguito un esempio di connessione ad Asterisk, utilizzando la libreria Panoramisk:

import asyncio
from panoramisk import Manager

manager = Manager(loop=asyncio.get_event_loop(),
                  host='127.0.0.1',
                  username='nome_utente',
                  secret='password')


@manager.register_event('*')
def callback(manager, message):
    if "FullyBooted" not in message.event:
        """
        Questo callback stamperà tutti gli eventi AMI, escluso il "FullyBooted" che altrimenti
        spammerebbe in continuazione.
        """
        print(message)


"""
# Questo stamperà gli eventi NewChannel
@manager.register_event('NewChannel')
def callback(manager, message):
    print(message)
    
# Questo stamperà gli eventi BridgeCreate
@manager.register_event('BridgeCreate')
def callback(manager, message):
    print(message)
"""


def main():
    manager.connect()
    try:
        manager.loop.run_forever()
    except KeyboardInterrupt:
        manager.loop.close()


if __name__ == '__main__':
    main()

Alternativa migliore (ma più complessa) a Panoramisk

Volendo, è possibile utilizzare la libreria telnetlib standard di Python.

Dopo aver usato per diverso tempo Panoramisk e aver notato dei problemi sugli ambienti di produzione ad alto traffico, credo che usare direttamente telnetlib sia un approcio più valido.

Utilizzare telnetlib richiede un po' di lavoro in più rispetto a Panoramisk ma non è un lavoro complicato in senso assoluto.

Dopo che avrai fatto un po' di pratica con gli AMI events e le AMI actions direttamente da terminale e averci preso la mano posso assicurarti che è semplice. 

Per iniziare, dai un occhiata alle lezioni da 55 a 58 di questa playlist.


Return to wiki index