29.12.2024 (aktualisiert am 1.1.2025)
Wenn du dich bereits mit der Telefonsoftware Asterisk auskennst und etwas Erfahrung mit Python mitbringst, hast du den perfekten Startpunkt, um AGI (Asterisk Gateway Interface) zu erkunden. In diesem Beitrag stelle ich dir mein Python-Modul `asterisk_agi.py` vor. Es ist das Herzstück für die einfache und effektive Entwicklung von AGI-Skripten und ermöglicht dir, dynamische und interaktive Funktionen in Asterisk zu integrieren.
Mit Python kannst du zum Beispiel Auswahlmenüs und Servicenummern für Asterisk erstellen. Dabei wird der Anrufer aufgefordert über das Tastenfeld seines Telefons während des Gesprächs Interaktionen auszuführen. Getestet habe ich die hier vorgestellten Scripte mit Python 3.10.12 und Asterisk 18.10.0 auf Ubuntu Mate. Weitere AGI-Skripte in Python, die zuverlässig auf meinem Raspberry Pi laufen, findest du am Ende dieses Artikels.
Alternativ zu meinem Asterisk-AGI-Python-Modul gibt es noch pyst2. Es ist eine Bibliothek, die AGI-Funktionen für Python bereitstellt. Allerdings wird pyst2 seit vielen Jahren nicht mehr gepflegt und die Dokumentation ist spärlich. Deshalb habe ich mich entschlossen mein eigenes Modul zu verwenden. Es ist transparent und ich weiß, was ich mache. Unter
https://www.asterisk.name/asterisk/0596009623/asterisk-chp-9-sect-4.html
ist am Beispiel eines Spiels beschrieben, wie man AGIs in Python schreibt. Von dieser Seite habe ich mich inspirieren lassen und eine weitere Funktion hinzugefügt, die Zahlen in Ziffern aufsagen lässt.
Meine Arbeitsumgebung für Tests und für die Programmierung von Asterisk und Python: Da ich meinen Laptop als Arbeitsrechner von Windows auf Ubuntu Mate umgestellt hatte, ergriff ich die Gelegenheit und installierte auf diesem Laptop Asterisk, um einen Test-Server zu betreiben, der über IAX2 mit dem Asterisk-Server auf meinem permanent erreichbaren Raspberry Pi 3B läuft. Auf diese Weise kann ich bequem Asterisk- und Python-Experimente auf meinem Laptop vornehmen, was die Entwicklungszeit sehr beschleunigt. Außerdem kann ich durch Copy & Paste viel leichter Fehlermeldungen nach ChatGPT kopieren und Vorschläge von ChatGPT umsetzen.
Was ist AGI? Das Asterisk Gateway Interface (AGI) ist eine Schnittstelle, mit der du externe Programme oder Skripte aus Asterisk heraus aufrufen kannst. Diese Programme können in nahezu jeder Programmiersprache geschrieben sein und bieten die Möglichkeit, komplexe Logik, Datenbankabfragen oder andere externe Prozesse in deine Asterisk-Dialplans zu integrieren.
AGI funktioniert ähnlich wie CGI (Common Gateway Interface) bei Webservern. Sobald ein AGI-Skript von Asterisk aufgerufen wird, erfolgt die Kommunikation über Standard-Ein- und Ausgabe (STDIN/STDOUT). Das bedeutet, dein Skript erhält Eingaben von Asterisk und antwortet mit Kommandos oder Daten.
Warum Python und das Modul `asterisk_agi.py`? Python ist durch seine Einfachheit und Vielseitigkeit ideal für die Erstellung von AGI-Skripten. Mit dem Modul `asterisk_agi.py` wird dieser Prozess noch intuitiver. Das Modul stellt dir eine Sammlung nützlicher Funktionen bereit, um schnell und effektiv mit Asterisk zu kommunizieren. Dazu gehören unter anderem:
Abspielen von Ansagen: Du kannst Sprachdateien direkt streamen.
Eingabeaufforderungen: Sie erfolgen während des Telefonats über den Ziffernblock.
Variablen setzen: Definiere oder manipuliere Variablen für die Weiterverarbeitung.
Fehlerbehandlung: Integrierte Mechanismen helfen dir, unerwartete Ergebnisse zu verarbeiten.
Das Muster-Projekt zum Testen besteht aus drei Dateien: Einem Auszug aus dem Wählplan, der extensions.conf, dem in Python programmierten AGI-Skript test_agi.py und das dafür notwendige Python-Modul asterisk_agi.py.
Die AGI-Dateien und somit auch die Python-Dateien mit der der Endung py sind unter Linux Debian im Ordner
/usr/share/asterisk/agi-bin/
unterzubringen. Jedenfalls gilt das für Asterisk 16 und Asterisk 18 und den meisten anderen Versionen. Definiert ist der Pfad bzw. Ordner für die AGI-Files in der /etc/asterisk/asterisk.conf. Hier ein Auszug aus der asterisk.conf. Man suche nach der Zeile, die mit astagidir beginnt:
; Auszug aus der /etc/asterisk/asterisk.conf [directories](!) astcachedir => /tmp astetcdir => /etc/asterisk astmoddir => /usr/lib/x86_64-linux-gnu/asterisk/modules astvarlibdir => /var/lib/asterisk astdbdir => /var/lib/asterisk astkeydir => /var/lib/asterisk astdatadir => /usr/share/asterisk astagidir => /usr/share/asterisk/agi-bin ; Hier ist der Pfad für die AGI-Dateien festgelegt. astspooldir => /var/spool/asterisk astrundir => /var/run/asterisk astlogdir => /var/log/asterisk astsbindir => /usr/sbin
Bitte beachte auch, dass die Python-Dateien mit UTF-8 kodiert sein müssen: Unter Windows erstellte Python-Dateien sind dies in der Regel nicht. Installiere dos2unix auf Linux:
sudo apt-get update
sudo apt install dos2unix
Und führe dann den Befehl wie folgt aus, um die die Dateien in UTF-8 zu kodieren:
sudo dos2unix /usr/share/asterisk/agi-bin/beispiel.py
Außerdem müssen sie unter Linux ausführbar sein. So machst du sie ausführbar:
sudo chmod +x /usr/share/asterisk/agi-bin/beispiel.py
Die extensions.conf findest du wie alle Konfigurationsdateien für Asterisk in den meisten Fällen unter /etc/asterisk/ und du kannst sie dort anpassen und editieren.
1. Dialplan-Eintrag in der extensions.conf: Der Dialplan ist das Herzstück jeder Asterisk-Konfiguration. Hier definierst du, wann und wie dein AGI-Skript ausgeführt wird. Ein Beispiel:
; Auszug aus einer extensions.conf ; im ordner /etc/asterisk/ [general] autofallthrough=no static=yes writeprotect=no [telefone] ; Aufruf der test_agi.py durch das Wählen der 504 ; Die test_agi.py braucht das Modul asterisk_agi.py. Beide Scripte im selben Ordner ; /usr/share/asterisk/agi-bin exten => 504,1,Noop(Anruf erfolgt von: "${CALLERID(name)}" <${CALLERID(num)}>) same => n,Noop(AGI- Test mit Modul asterisk_agi.py) same => n,Answer() same => n,AGI(test_agi.py) same => n,NoOP(from script test_agi.py dialing ${EXTNEW}) ; das Python-Skript erzeugt die Variable EXTNEW. ; Diese Nummer (extension) in [telefone] wird durch die nachfolgende Zeile angewählt. same => n,Goto(telefone,${EXTNEW},1) same => n,Hangup() ; Weiteres Beispiel: ; Aufruf der subtraction_game.py durch das Wählen der 505 exten => 505,1,Noop(Anruf erfolgt von: "${CALLERID(name)}" <${CALLERID(num)}>) same => n,Answer() same => n,AGI(subtraction_game.py) same => n,Hangup()
In der extensions.conf wird durch Wählen der Nummer 504 das Skript `test_agi.py` ausgeführt, das wir später genauer betrachten.
2. Das AGI-Skript test_agi.py: Dieses Skript ist das Bindeglied zwischen deinem Asterisk-Dialplan und der Logik, die du mit Python umsetzen möchtest. Es nutzt das Modul `asterisk_agi.py`, um mit Asterisk zu kommunizieren. Aber dazu später noch.
Beispielsweise fordert das Skript test_agi.py mit Sprachdateien den Anrufer auf eine Telefonnummer einzutippen. Die Nummer wird als Zahl und Ziffernfolge aufgesagt und dann gewählt:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Die test_agi.py # Die test_agi.py braucht das Modul asterisk_agi.py. # Beide Scripte im selben Ordner /usr/share/asterisk/agi-bin # Es kommen zum Testen nur die in Asterisk mitgelieferten Sounddateien zum Einsatz import asterisk_agi as agi # Importieren der asterisk_agi.py # Das Skript befindet sich immer in der def main() def main(): # Initialisiert die AGI-Umgebung env = agi.init_env() # Ab hier gehts mit deinem Skript los: # Begrüßungstext mit sayit abspielen agi.sayit("hello") # Sagt Hallo auf agi.sayit("vm-enter-num-to-call") # Ansage fordert auf eine Nummer einzutippen # Benutzer mit getnumber auffordern, eine Nummer einzugeben. # vm-then-pound ist eine Ansage, # die Eingabe mit # abzuschließen. number = agi.getnumber("vm-then-pound", 20000, 50) # Maximal 50 Ziffern, 20 Sekunden Zeit # Überprüfen, ob eine gültige Eingabe vorliegt if number == -1: agi.sayit("invalid") # Falls keine Eingabe erfolgt ist return agi.sayit("you-entered") # Abspielen einer Sound-Datei # Die eingegebene Nummer in der Variablen number mit saynumber als Ganzes aufsagen agi.saynumber(number) # Jede Ziffer der Nummer mit say_digits einzeln aufsagen agi.say_digits(number) # Variabel ETXNEW enthält number als string und wird # der extensions.conf übergeben print("SET VARIABLE EXTNEW " + str(number)) # Hier hört dein Skript auf # Abschließen der def(main) if __name__ == "__main__": main()
3. Das Modul asterisk_agi.py: Dieses Modul stellt Funktionen bereit, um Befehle an Asterisk zu senden und Ergebnisse auszuwerten. Beispiele sind das Abspielen von Ansagen, das Erfassen von Benutzereingaben oder das Setzen von Variablen.
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Das Modul asterisk_agi.py für AGI mit Asterisk und Python """ Asterisk AGI Python Module Place this file in the same directory as your main script. Ensure the file has execution permissions using: chmod +x asterisk_agi.py """ import sys import re def init_env(): """ Initializes the AGI environment and returns it as a dictionary. """ env = {} tests = 0; while 1: line = sys.stdin.readline().strip() if line == '': break key,data = line.split(':') if key[:4] != 'agi_': #skip input that doesn't begin with agi_ sys.stderr.write("Did not work!\n"); sys.stderr.flush() continue key = key.strip() data = data.strip() if key != '': env[key] = data sys.stderr.write("AGI Environment Dump:\n"); sys.stderr.flush() for key in env.keys(): sys.stderr.write(" -- %s = %s\n" % (key, env[key])) sys.stderr.flush() def checkresult (params): params = params.rstrip() if re.search('^200',params): result = re.search('result=(\d+)',params) if (not result): sys.stderr.write("FAIL ('%s')\n" % params) sys.stderr.flush() return -1 else: result = result.group(1) #debug("Result:%s Params:%s" % (result, params)) sys.stderr.write("PASS (%s)\n" % result) sys.stderr.flush() return int(result) else: error_code = re.search('result=(-?\d+)',params) if error_code: error_code = int(error_code.group(1)) sys.stderr.write("FAIL (unexpected result '%s', error code %d)\n" % (params, error_code)) sys.stderr.flush() return error_code else: sys.stderr.write("FAIL (unexpected result '%s')\n" % params) sys.stderr.flush() return -2 def saynumber (params): sys.stderr.write("SAY NUMBER %s \"\"\n" % params) sys.stderr.flush() sys.stdout.write("SAY NUMBER %s \"\"\n" % params) sys.stdout.flush() result = sys.stdin.readline().strip() return checkresult(result) def sayit (params): sys.stderr.write("STREAM FILE %s \"\"\n" % str(params)) sys.stderr.flush() sys.stdout.write("STREAM FILE %s \"\"\n" % str(params)) sys.stdout.flush() result = sys.stdin.readline().strip() checkresult(result) def getnumber(prompt, timelimit, digcount): sys.stderr.write(f"GET DATA {prompt} {timelimit} {digcount}\n") sys.stderr.flush() sys.stdout.write(f"GET DATA {prompt} {timelimit} {digcount}\n") sys.stdout.flush() result = sys.stdin.readline().strip() return checkresult(result) def say_digits(number): """ Says each digit of a number separately. """ for digit in str(number): saynumber(digit)
Wie das Script funktioniert, ist unter
https://www.oreilly.com/library/view/asterisk-the-future/9780596510480/ch09s04.html
beschrieben. Die gesamte Kommunikation erfolgt über `STDIN` und `STDOUT`, wobei das Modul auch eine rudimentäre Fehlerprüfung über `checkresult` bereitstellt.
Das Modul `asterisk_agi.py` umfasst weiterhin:
sayit(params): Spielt eine Audiodatei ab.
getnumber(prompt, timelimit, digcount): Fordert den Benutzer zur Eingabe auf.
say_digits(number): Gibt die einzelnen Ziffern einer Zahl aus.
init_env(): Initialisiert die AGI-Umgebung und gibt eine Umgebungsübersicht zurück.
Zusammenspiel der Komponenten:
1. Der Anruf wird über den Dialplan (z. B. die Durchwahl 504) an das AGI-Skript `test_agi.py` weitergeleitet.
2. Das Skript interagiert mit dem Anrufer, fragt beispielsweise eine Telefonnummer ab und gibt diese zurück.
3. Mithilfe von `asterisk_agi.py` kommuniziert das Skript mit Asterisk und steuert die weitere Verarbeitung.
Anwendungsbeispiele:
Interaktive Anrufsteuerung: Lass Anrufer eine Nummer eingeben, um dynamisch eine Weiterleitung zu steuern.
Datenbankintegration: Erweitere das Skript, um Informationen aus einer Datenbank oder Webseite abzurufen und diese ansagen zu lassen.
Statistiken und Reporting: Erfasse Eingaben und Aktionen für spätere Analysen.
Was zeigt die Asterisk-Konsole? „agi set debug on“ ist gesetzt, damit man das Ausführen der test_agi.py in der Konsole verfolgen kann. Der Teilnehmer wählte die 504 (genauer gesagt über eine Vorwahl von einem anderen Asterisk-Server via IAX2) und tippte dann die 222 ein, um den Echotest unter 222 zu hören.
-- Accepting AUTHENTICATED call from 192.168.1.111:4569: -- > requested format = alaw, -- > requested prefs = (alaw|g722|ulaw|gsm), -- > actual format = alaw, -- > host prefs = (alaw|ulaw|gsm|g722), -- > priority = mine -- Executing [504@telefone:1] NoOp("IAX2/incoming-test77-9043", "Anruf erfolgt von: "Volker Lange-Janson" <1088>") in new stack -- Executing [504@telefone:2] NoOp("IAX2/incoming-test77-9043", "AGI Testen - Test mit asterisk_agi.py") in new stack -- Executing [504@telefone:3] Answer("IAX2/incoming-test77-9043", "") in new stack -- Executing [504@telefone:4] AGI("IAX2/incoming-test77-9043", "test_agi.py") in new stack -- Launched AGI Script /usr/share/asterisk/agi-bin/test_agi.py <IAX2/incoming-test77-9043>AGI Tx >> agi_request: test_agi.py <IAX2/incoming-test77-9043>AGI Tx >> agi_channel: IAX2/incoming-test77-9043 <IAX2/incoming-test77-9043>AGI Tx >> agi_language: en <IAX2/incoming-test77-9043>AGI Tx >> agi_type: IAX2 <IAX2/incoming-test77-9043>AGI Tx >> agi_uniqueid: 1735491853.114 <IAX2/incoming-test77-9043>AGI Tx >> agi_version: 18.10.0~dfsg+~cs6.10.40431411-2 <IAX2/incoming-test77-9043>AGI Tx >> agi_callerid: 1088 <IAX2/incoming-test77-9043>AGI Tx >> agi_calleridname: Volker Lange-Janson <IAX2/incoming-test77-9043>AGI Tx >> agi_callingpres: 0 <IAX2/incoming-test77-9043>AGI Tx >> agi_callingani2: 0 <IAX2/incoming-test77-9043>AGI Tx >> agi_callington: 0 <IAX2/incoming-test77-9043>AGI Tx >> agi_callingtns: 0 <IAX2/incoming-test77-9043>AGI Tx >> agi_dnid: unknown <IAX2/incoming-test77-9043>AGI Tx >> agi_rdnis: unknown <IAX2/incoming-test77-9043>AGI Tx >> agi_context: telefone <IAX2/incoming-test77-9043>AGI Tx >> agi_extension: 504 <IAX2/incoming-test77-9043>AGI Tx >> agi_priority: 4 <IAX2/incoming-test77-9043>AGI Tx >> agi_enhanced: 0.0 <IAX2/incoming-test77-9043>AGI Tx >> agi_accountcode: <IAX2/incoming-test77-9043>AGI Tx >> agi_threadid: 139254387607104 <IAX2/incoming-test77-9043>AGI Tx >> <IAX2/incoming-test77-9043>AGI Rx << STREAM FILE hello "" -- <IAX2/incoming-test77-9043> Playing 'hello.gsm' (escape_digits=) (sample_offset 0) (language 'en') <IAX2/incoming-test77-9043>AGI Tx >> 200 result=0 endpos=6400 <IAX2/incoming-test77-9043>AGI Rx << STREAM FILE vm-enter-num-to-call "" -- <IAX2/incoming-test77-9043> Playing 'vm-enter-num-to-call.gsm' (escape_digits=) (sample_offset 0) (language 'en') <IAX2/incoming-test77-9043>AGI Tx >> 200 result=0 endpos=16320 <IAX2/incoming-test77-9043>AGI Rx << GET DATA vm-then-pound 20000 50 -- <IAX2/incoming-test77-9043> Playing 'vm-then-pound.gsm' (language 'en') <IAX2/incoming-test77-9043>AGI Tx >> 200 result=222 <IAX2/incoming-test77-9043>AGI Rx << STREAM FILE you-entered "" -- <IAX2/incoming-test77-9043> Playing 'you-entered.gsm' (escape_digits=) (sample_offset 0) (language 'en') <IAX2/incoming-test77-9043>AGI Tx >> 200 result=0 endpos=7840 <IAX2/incoming-test77-9043>AGI Rx << SAY NUMBER 222 "" -- <IAX2/incoming-test77-9043> Playing 'digits/2.gsm' (language 'en') -- <IAX2/incoming-test77-9043> Playing 'digits/hundred.gsm' (language 'en') -- <IAX2/incoming-test77-9043> Playing 'digits/20.gsm' (language 'en') -- <IAX2/incoming-test77-9043> Playing 'digits/2.gsm' (language 'en') <IAX2/incoming-test77-9043>AGI Tx >> 200 result=0 <IAX2/incoming-test77-9043>AGI Rx << SAY NUMBER 2 "" -- <IAX2/incoming-test77-9043> Playing 'digits/2.gsm' (language 'en') <IAX2/incoming-test77-9043>AGI Tx >> 200 result=0 <IAX2/incoming-test77-9043>AGI Rx << SAY NUMBER 2 "" -- <IAX2/incoming-test77-9043> Playing 'digits/2.gsm' (language 'en') <IAX2/incoming-test77-9043>AGI Tx >> 200 result=0 <IAX2/incoming-test77-9043>AGI Rx << SAY NUMBER 2 "" -- <IAX2/incoming-test77-9043> Playing 'digits/2.gsm' (language 'en') <IAX2/incoming-test77-9043>AGI Tx >> 200 result=0 <IAX2/incoming-test77-9043>AGI Rx << SET VARIABLE EXTNEW 222 <IAX2/incoming-test77-9043>AGI Tx >> 200 result=1 -- <IAX2/incoming-test77-9043>AGI Script test_agi.py completed, returning 0 -- Executing [504@telefone:5] NoOp("IAX2/incoming-test77-9043", "from script test_agi.py dialing 222") in new stack -- Executing [504@telefone:6] Goto("IAX2/incoming-test77-9043", "telefone,222,1") in new stack -- Goto (telefone,222,1) -- Executing [222@telefone:1] NoOp("IAX2/incoming-test77-9043", "") in new stack -- Executing [222@telefone:2] Answer("IAX2/incoming-test77-9043", "") in new stack -- Executing [222@telefone:3] Playback("IAX2/incoming-test77-9043", "demo-echotest") in new stack -- <IAX2/incoming-test77-9043> Playing 'demo-echotest.gsm' (language 'en') -- Executing [222@telefone:4] Echo("IAX2/incoming-test77-9043", "") in new stack == Spawn extension (telefone, 222, 4) exited non-zero on 'IAX2/incoming-test77-9043' -- Hungup 'IAX2/incoming-test77-9043'
Erweiterung der test_agi.py um ein Auswahlmenü zum Anwählen von Nummern: Gibt der Anrufer Nummern zwischen 1 und 6 ein und schließt die Eingabe mit der Raute-Taste ab, werden die entsprechenden Telefonnnumern angewählt. Bei 1 die 7001, bei 2 die 301 und so weiter. Andernfalls wählt das Skript die Nummer, die eingetippt wurde. Wichtig ist, dass die if-elif-else-Anweisung korrekt eingerückt ist.
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import asterisk_agi as agi def main(): # Initialisiert die AGI-Umgebung env = agi.init_env() # Begrüßungstext abspielen agi.sayit("hello") # Sagt Hallo auf agi.sayit("vm-enter-num-to-call") # # Benutzer auffordern, eine Nummer einzugeben number = agi.getnumber("vm-then-pound", 20000, 50) # Maximal 50 Ziffern, 20 Sekunden Zeit # Überprüfen, ob eine gültige Eingabe vorliegt if number == -1: agi.sayit("invalid") # Falls keine Eingabe erfolgt ist return agi.sayit("you-entered") # Die eingegebene Nummer als Ganzes ansagen agi.saynumber(number) agi.sayit("/usr/share/asterisk/sounds/en_US_f_Allison/beep") # Jede Ziffer der Nummer einzeln ausgeben agi.say_digits(number) # Das Auswalmenue # Gibt der Anrufer Nummern zwischen 1 und 6 ein und schließt die Eingabe # mit der Raute-Taste ab, werden die entsprechenden # Telefonnnumern angewählt. Bei 1 die 7001, bei 2 die 301 und so weiter # Andernfalls wählt das Skript die Nummer, die eingetippt wurde. # Wichtig ist, dass die if-elif-else-Anweisung korrekt eingerückt ist. if int(number) == 1: print("SET VARIABLE EXTNEW " + "7001") elif int(number) == 2: print("SET VARIABLE EXTNEW " + "301") elif int(number) == 3: print("SET VARIABLE EXTNEW " + "305") elif int(number) == 4: print("SET VARIABLE EXTNEW " + "502") elif int(number) == 5: print("SET VARIABLE EXTNEW " + "501") elif int(number) == 6: print("SET VARIABLE EXTNEW " + "503") else: agi.sayit("/usr/share/asterisk/sounds/en_US_f_Allison/beep") print("SET VARIABLE EXTNEW " + str(number)) # Ende des Auswahlmenues if __name__ == "__main__": main()
Damit das Auswahlmenü funktioniert und AGI auch Nummern wählen kann, ist dies in der extensions.conf anzupassen, wenn jemand wie hier im Beispiel die 504 wählt:
exten => 504,1,Noop(Anruf erfolgt von: "${CALLERID(name)}" <${CALLERID(num)}>) same => n,Noop(AGI- Test mit Modul asterisk_agi.py) same => n,Answer() same => n,AGI(test_agi.py) same => n,NoOP(from script test_agi.py dialing ${EXTNEW}) same => n,Goto(telefone,${EXTNEW},1) same => n,Hangup()
Die zweite Zeile in der auszugsweisen Darstellung
same => n,NoOP(from script test_agi.py dialing ${EXTNEW}) same => n,Goto(telefone,${EXTNEW},1)
sorgt dafür, dass die Variable EXTNEW zum Wählen der Telefonnummer übernommen wird und der Wählvorgang ausgeführt wird. NoOP oder Noop leitet nur einen Kommentar ein, der in der Asterisk-Konsole erscheint
Damit wären alle Funktionen getestet, die man für ein Auswahlmenü benötigt. Die Ebenen eines mehrstufigen Auswahlmenüs lassen sich auf verschiedene Skripte verteilen, die über Nummern oder Extensions aufgerufen werden. Der Anrufer merkt davon nichts.
ChatGPT gibt übrigens jede Menge Hilfestellungen und Anregungen. Ich zeige ChatGPT den Code und die Fehlermeldungen in der Asterisk-Konsole und meistens findet er den Fehler. Manchmal macht ChatGPT auch Fehler. Dadurch lernt man selbst und ChatGPT übrigens auch.
Fazit: Das Modul `asterisk_agi.py` ist das zentrale Werkzeug, um die Möglichkeiten von Asterisk durch Python zu erweitern. Es macht deine Telefonie-Lösungen flexibler und intelligenter. Mit den vorgestellten Skripten und Funktionen hast du eine Grundlage, auf der du aufbauen kannst. Jetzt liegt es an dir, das volle Potenzial von AGI und `asterisk_agi.py` auszuschöpfen!
Weiterführend: Nachfolgend gibt es jede Menge AGI-Skripte zur Anregung.
Asterisk-Telefonserver auf einem Raspberry Pi – Installation, Konfiguration, Programmierung, SIP, IAX2, AGI-Skripte, Sicherheit und Tipps zum praktischen Betrieb – 2.11.2022: Diese Seite richtet sich an jene, welche einen Asterisk-Telefon-Server auf einem Raspberry Pi betreiben möchten und später ein kleines Netzwerk aus Asterisk-Servern planen, um ein eigenständiges Telefonnetz aufzubauen. Los geht es mit der Installation von Raspbian und Asterisk auf einem Raspberry Pi und dann nach Lust und Laune immer tiefer in die Programmierung von Asterisk. Die Themen werden laufend erweitert.
Selbstverständlich muss es nicht unbedingt ein Raspberry Pi sein. Andere Linux-Rechner gehen auch. – weiter – |
AGI-Skripte für Asterisk unter Windows editieren – Was ist zu beachten? – 9. März 2023: Windows ist weit verbreitet. Deshalb schreiben nicht wenige ihre AGI-Skripte auf Windows, um sie dann in ihren Raspberry Pi zu kopieren. Wer einige Dinge nicht beachtet, wird die Skripte nicht zum Laufen bekommen. Hier sind die Fallstricke beschrieben, die mich viel Zeit gekostet haben. Die Beispiele beziehen sich auf Python. Sie haben für andere Programmiersprachen die entsprechende Gültigkeit. – weiter – |