Unangekündigter Breaking Change im LUA Dialplan und Workaround

Problem

Mit dem Pascom Cloud Update vom 01.12.2022 wurde das Verhalten unangekündigt und undokumentiert in LUA Skripten in Gänze verändert. So erfolgte der Abwurf an eine Durchwahl bis zu diesem Update in LUA über folgenden Befehl:

app["goto"]("main", {{extension}}, 1)

Das Problem ist, dass der Abwurf zwar weiterhin ausgeführt, jedoch nicht mehr im CDR erfasst wird. Dadurch fehlen zum einen wichtige Elemente in der Anrufkette, zum anderen erfolgt beim Wechsel der Chain-ID, z.B. durch Abwurf per Kurzdurchwahl an eine externe Rufnummer, zwangsläufig auch der Wechsel des Rufstatus auf nicht verbunden. Die CDR, die durch diese Abwürfe entsteht, ist zum Teil so kaputt, dass es nicht mehr möglich ist einen sinnvollen Anruf daraus zusammenzusetzen.

Lösung

Da der Abwurf technisch weiterhin ausgeführt wird, kann man über eine kleine Erweiterung im Skript, einen Anrufverteiler, eine Aktionsbedingung und ein Label, in dem die Zieldurchwahl festgehalten wird, das vorherige Verhalten wiederherstellen.

1.) LUA-Skript Modifikation

Der bisherige LUA Abwurf wird wie folgt verändert:

channel["MDC_LABEL-{{ID}}"] = {{target_extension}}
app.UserEvent("ForwardAction", "target:main,{{distributor_extension}},1")    
app["goto"]("main", {{distributor_extension}}, 1)

Hier noch eine kurze Erläuterung zu den Platzhaltern (dargestellt durch {{NAME}}):

  • MDC_LABEL-{{ID}} = Das Label, welches die tatsächliche Zieldurchwahl beinhaltet.
  • {{target_extension}} = Die Durchwahl, an die eigentlich abgeworfen werden soll (Zieldurchwahl).
  • {{distributor_extension}} = Der Anrufverteiler, der den Abwurf dann mit Pascom Boardmitteln ausführen soll.

Ich möchte an dieser Stelle darauf hinweisen, dass der Code grundsätzlich funktional, aber vereinfacht ist und man in der Praxis Funktionen und Variablen zur Realisierung nutzen sollte. Für die technische Demonstration sollte diese Darstellungsform jedoch ausreichend sein.

2) Aktionsbedingung

Als nächstes folgt die Aktionsbedingung, mit der sichergestellt werden soll, dass das Label wirklich gesetzt ist, bevor der Abwurf im Verteiler ausgeführt wird. Dafür erstellen wir eine Aktionsbedingung des Typs “Asterisk Expression” mit folgendem Inhalt:

$[ "${MDC_LABEL-{{ID}}}" != "" ]

Ich verzichte an dieser Stelle darauf das Konzept von Labeln und die Erstellung dieser zu erklären. Das setze ich zum Verständnis dieser Lösung voraus.

3) Anrufverteiler

Zu guter Letzt noch der Anrufverteiler, der letztendlich für die Behebung des Problems verantwortlich ist. Denn hier setzen wir wieder auf grafische Pascom-Boardmittel. Der Anrufverteiler besteht aus 2 Bedingungen und sieht wie folgt aus:

Die Bedingung SBR_TARGET_EXISTS beinhaltet die in 2) erstellte Aktionsbedingung. Sollte keine Durchwahl im Label festgehalten worden sein, handelt es sich normalerweise um einen strukturellen Fehler, dennoch sollte eine Ausnahmebehandlung existieren, hier in Form von Auflegen. Wie gesagt, dieser Teil wird bei korrekter Funktionsweise niemals erreicht.

Warum überhaupt LUA-Skript?

In dem Großteil der Konfigurationen werden LUA-Skripte als Dialplan überhaupt nicht benötigt. Man könnte den Abwurf z.B. auch per Bedingung Vorher/Nachher in Teams oder Verteilern ausführen. In meinem Fall jedoch steck ein Routing dahinter, in dem Teilnehmer sich über mein ERP Systems in ein Team einloggen und dabei bestimmen können, mit welcher Priorität bei Ihnen das Telefon klingelt. Hier existiert ein System von A bis D, in dem A bedeutet, es klingelt zuerst und D bedeutet, es klingelt, wenn keiner aus A, B, C erreichbar ist.

Mit LUA lässt sich z.B. auch die Anzahl der verfügbaren Teilnehmer ermitteln, die angemeldet sind und nicht telefonieren. Dies ist mit folgendem Befehl möglich:

function get_ready_member_count(queue_name)
    return tonumber(channel["QUEUE_MEMBER(" .. queue_name .. ",ready)"]:get())
end

Daraus ergeben sich Möglichkeiten, die mit anderen Pascom-Boardmitteln schlicht und ergreifend nicht realisierbar sind. So kann ich in meinem Fall das Login per REST-API ausführen und hier passiert folgendes:

Teilnehmer haben im entsprechend ERP Modul ein Formular, in dem sie zwischen Offline, Prio A, Prio B, Prio C und Prio D wählen können. Jede Prio darunter wird automatisch mit eingeloggt bzw. ausgeloggt, sodass Prio A bedeutet, dass bei diesem Teilnehmer auch das Telefon für Anrufe in Prio B, C und D klingelt, z.B. dann hilfreich, wenn man gerade frei wird und als “Person an der Front” wieder ans Telefon gehen kann, obwohl bereits in die Ebene darunter abgeworfen wurde.

Per Skript wird immer geprüft, wie die Verteilung der Teilnehmer nach Prio ist und ob es überhaupt verfügbare Teilnehmer gibt. Wenn die Art und Anzahl der Teilnehmer in allen Prios gleich ist, z.B., weil alle Teilnehmer in A eingeloggt sind, würde ein eingehender Anruf direkt nach Prio D abgeworfen werfen. Es würde dennoch bei allen Teilnehmern klingeln und vor allem würde verhindert werden, dass der Anrufer unnötig Prio A bis D durchlaufen muss, ehe das finale Timeout erreicht wird. Ist jemand in A eingeloggt und ein anderer Teilnehmer in B, so würde zuerst A klingeln und danach D. Würde der Teilnehmer in A telefonieren, könnte ich dies per LUA erkennen und direkt auf D abwerfen.

Mit diesem Routing können sich z.B. Vertriebsmitarbeiter zurücknehmen und verhindern, dass Ihr Telefon klingelt, wenn jemand anderes übernehmen könnte, z.B. dann, wenn man gerade an einem Angebot arbeitet und Ruhe braucht. Dann ändert man seine Prio auf D und so lange Teilnehmer von A bis C erreichbar sind, klingelt das Telefon nicht. Klingelt es doch, weiß der Teilnehmer, dass er rangehen muss, weil sonst niemand verfügbar ist.

Bei uns gibt es auf Grund der Vielzahl unterschiedlicher Vertriebsteams eben den Sonderfall, dass die reine Abwurf-Steuerung im Nachher-Kontext viel zu aufwendig wäre und man den Teilnehmer-Status dort nicht berücksichtigen kann. Statt viele unterschiedliche Bedingungen und Aktionen hinzuzufügen, reicht ein einziges Skript in jedem Team und eine Änderung in eben jenem Team aktualisiert sofort alle anderen Teams.

Schlusswort

Dieser Beitrag richtet sich ganz klar an fortgeschrittener Anwender mit komplexen Routings, wodurch ein Groß der Leute hier sicher wenig mit anfangen können wird. Dennoch denke ich, dass die hier genannten technischen Ansätze dem ein oder anderen helfen können Rufpläne zu realisieren oder bestehende Probleme zu lösen.

Ich möchte an dieser Stelle noch darauf hinweisen, dass Pascom bisher ausdrücklich nicht bereit ist zu garantieren, dass erstellte LUA-Skripte mit kommenden Updates auch weiterhin funktionieren werden. Es gibt zwar die Möglichkeit LUA-Skripte für Rufpläne zu erstellen, allerdings gibt es hierfür keinen Support und es muss immer damit gerechnet werden, dass eine bestehende Funktion sich in Ihrem Verhalten unangekündigt verändert oder ganz verschwindet.

Deswegen versuche ich immer häufiger LUA-Skripte per Channel-Variabeln über Label mit Bedingungen im Vorher/Nachher-Kontext zu kombinieren, um so eine höhere Sicherheit zu erreichen, dass meine Skripte auch nach Updates noch funktionieren.