Pascom Zammad Helpdesk Integration

Hallo zusammen,

habe gerade dazu ein Support-Ticket erstellt. Leider haben wir eine Kundenvorgabe, dass wir ein Ticketsystem einbinden MÜSSEN. Also brauchen wir unbedingt eine Lösung.
Wie schauts denn mittlerweile aus?

Hallo zusammen,

ich habe eine Integration mit Scripts per REST gelöst.

Pascom Calls -> Zammad

Skript vorher -> Erstellt eingehenden Anruf

exten => s,1,Set(CURLOPT(httptimeout)=3)
exten => s,2,Set(CURLOPT(conntimeout)=3)
exten => s,3,Set(NAME=${CURL(https://subdomain.zammad.com/api/v1/cti/token/,event=newCall&from=${CALLERID(num)}&to=${CALLERID(dnid)}&direction=in&callId=${CHANNEL(LINKEDID)})})
exten => s,4,Return()

def_outbound -> Erstellt ausgehenden Anruf

same => n,Set(CURLOPT(httptimeout)=3)
same => n,Set(CURLOPT(conntimeout)=3)
same => n,Set(OUT=${CURL(https://subdomain.zammad.com/api/v1/cti/token/,event=newCall&direction=out&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${MDC_DIALCALLERNAME})})

def_hangup -> Status Anruf beendet

Ab Zeile 2:
same => n,GoToIf($[ "${MDC_DIALDESCENT}" = "int" ]?10,1:11,1)

; extension 10 in -> ext
exten => 10,1,Set(OUT=${CURL(https://subdomain.zammad.com/api/v1/cti/token/,event=hangup&direction=out&cause=normalClearing&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${MDC_DIALCALLERNAME})})
same => n,Return()

; extension 11: ext -> in
exten => 11,1,Set(OUT=${CURL(https://subdomain.zammad.com/api/v1/cti/token/,event=hangup&direction=in&cause=normalClearing&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${MDC_DIALCALLERNAME})})
same => n,Return()

Was mir noch fehlt ist ein Auslöser für Answer
Da habe ich keine Ahnung wie ich das per Skript machen kann.
Vielleicht hat jemand eine Idee.
Wir haben ein Team mit Ansage und IVR, wenn nun ein Agent den Anruf annimmt sollte ein Skript ausgeführt werden.

exten => s,1,Set(CURLOPT(httptimeout)=3)
exten => s,2,Set(CURLOPT(conntimeout)=3)
exten => s,3,Set(NAME=${CURL(https://subdomain.zammad.com/api/v1/cti/token/,event=answer&from=${CALLERID(num)}&to=${CALLERID(dnid)}&direction=in&callId=${CHANNEL(LINKEDID)})})
exten => s,4,Return()
1 Like

@moderators habt ihr hier einen Tipp wie ich ein Skript bei rufannahme ausführen kann?

1 Like

Hi, gibts zu dem Thema inzwischen News ?

Hy,
hast du zum answer Event schon eine Lösung?

Moin @colesnicov,

Nein leider nicht

hallo @rouven.matthies.hds,

wie habt ihr dann das Answer-Event gelöst? oder gar nicht mehr?

moin @colesnicov,

ich habe leider keine Lösung dazu gefunden :frowning:

Das Problem ist, dass Pascom nach wie vor keine Webhoocks kennt. Per API geht das nicht. Ich hatte mal versucht einen Python-XMPP-Client zu schreien bin aber bei der Authentisierung gescheitert, da Pascom hier etwas verwendet was sich nicht einfach so mit bestehenden XMPP-Modulen abbilden lässt bzw. ich habe das nicht hin bekommen. Wenn jemand herausfindet wie das geht lässt sich der Rest relative leicht machen.

+1 dafür. Das ist das wahre Manko, so toll der Rest ja funktioniert. 2022 wäre es ja echt mal an der Zeit :wink: GIbt so viele Dinge, die sich damit super einfach umsetzen lassen würden, weit über Zammad hinaus.

Da aber auch Pascom vermutlich keine ungenutzten Entwickler-Kapaziäten irgenwo rumfliegen hat, wird das wohl noch warten müssen, bis der Druck groß genug geworden ist.

Hat sich hier mitlerweile nochmal was getan?

Schön wäre es, aber leider nicht. Wird für mich persönlich zunehmend zu einem echten Problem. Je mehr Kunden, umso mehr sinnfreien, weil manuellen Aufwand.

+1 für eine Zammad Integration bzw. noch besser die Webhooks, da flexibler

2 Likes

Da warte ich auch schon soooooo lange drauf, gibt aber anscheinend wichtigere Themen.

1 Like

+1 für Webhooks und native Zammad-Integration (letzere wäre mir persönlich wichtiger)

2 Likes

Nochmals viele Dank für den hier geteilten Ansatz: Da ich persönlich noch neu beim Thema Asterisk unterwegs bin (und die fähigen Kollegen nicht nerven wollte + irgendwann muss man es ja lernen) kam ich damit schon erheblich weiter. Ich will meine Ergebnisse hier einmal teilen, jedoch :warning: bitte bedenken, dass dies meine absolut ersten Astersik-Dialplan- und Astersik-Scripting-Schritte sind :warning: und das bisher noch keiner bei uns qualitätsgesichert hat (Wochenende :-D), der davon mehr Ahnung hat, als ich.

Hier mal, was ich bisher zusammengebaut habe (gänzlich auf den freundlicherweise geteilten Snippets von @rouven.matthies.hds basierend (nur etwas ausführlicher beschrieben, sofern sich jemand ähnlich einarbeiten muss/will wie ich gerade)).

Schritt 1: Zunächst ein Script namens fd_zammad_cti unter Einstellungen-> Skripte angelegt, dass man dann unter Extern/Vorher und Extern/Nacher für ein Team oder User und die passenden Zammad-Calls über die jeweilige s,Extension (z.B. s,920110 für Zammad, New Call (Incoming) unter Ausdruck eintragen kann; Zudem sind unter ;;;;; Generic ein paar Aufrufe vorbereitet, die ich noch nicht sinnvoll an ein passendes pascom-Event packen konnte. Davon nicht irritieren lassen…).


Damit weden eingehende Anrufe von Extern, die nicht einfach durch auflegen beendet werden, an Zamad kommuniziert (Extensions wi s,920110 kann man natürlich ebenfalls noch nach eigenem Bedarf anpassen … ergibt hier in der Testanlage wegen eines dokumentierten Numemrnschemas aber Sinn :-D) .

Skript-Inhalt:

; Different actions to interact with the Zammad CTI. Simply add them to your
; workflow as needed and use the appropriate extension/expression (e.g., "s,920110"
; for a new incoming call for the office queue).
;
; Adapt all occurrences to your needs:
; - same => n,Set(ZammadEndpointURL=[...])
; - same => n,Set(ZammadQueue=[..., empty value is possible])
; - same => n,Set(ZammadQueue=[... if there are special target Queues in Zammad])


;;;;; Office

; Zammad, New Call (Incoming)
exten => s,920110,NoOp(Zammad CTI: New Call (Incoming): From=${CALLERID(num)}, To=${CALLERID(dnid)}, CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadQueue=office)
  same => n,Set(ZammadData=event=newCall&direction=in&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&queue=${ZammadQueue})
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(NAME=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

; Zammad, New Call (Outgoing)
exten => s,920120,NoOp(Zammad CTI: New Call (Outgoing): From=${CALLERID(num)}, To=${CALLERID(dnid)}, CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadQueue=office)
  same => n,Set(ZammadData=event=newCall&direction=out&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&queue=${ZammadQueue})
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()


;;;;; IT-Support

; Zammad, New Call (Incoming)
exten => s,920210,NoOp(Zammad CTI: New Call (Incoming): From=${CALLERID(num)}, To=${CALLERID(dnid)}, CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadQueue=it-support)
  same => n,Set(ZammadData=event=newCall&direction=in&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&queue=${ZammadQueue})
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(NAME=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

; Zammad, New Call (Outgoing)
exten => s,920220,NoOp(Zammad CTI: New Call (Outgoing): From=${CALLERID(num)}, To=${CALLERID(dnid)}, CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadQueue=it-support)
  same => n,Set(ZammadData=event=newCall&direction=out&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&queue=${ZammadQueue})
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()


;;;;; Sales

; Zammad, New Call (Incoming)
exten => s,920310,NoOp(Zammad CTI: New Call (Incoming): From=${CALLERID(num)}, To=${CALLERID(dnid)}, CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadQueue=it-support)
  same => n,Set(ZammadData=event=newCall&direction=in&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&queue=${ZammadQueue})
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(NAME=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

; Zammad, New Call (Outgoing)
exten => s,920320,NoOp(Zammad CTI: New Call (Outgoing): From=${CALLERID(num)}, To=${CALLERID(dnid)}, CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadQueue=it-support)
  same => n,Set(ZammadData=event=newCall&direction=out&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&queue=${ZammadQueue})
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()


;;;;; Generic

; Zammad, Call Answered (Incoming)
exten => s,100,NoOp(Zammad CTI: Answered (Incoming): CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadData=event=answer&direction=in&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&answeringNumber=${CHANNEL})
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(NAME=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

; Zammad, Call Answered (Outgoing)
exten => s,110,NoOp(Zammad CTI: Answered (Outgoing): CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadData=event=answer&direction=out&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&answeringNumber=${CHANNEL})
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(NAME=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

; Zammad, Call Hang Up (Incoming): normalClearing (One of the parties hung up after the call was established)
exten => s,130,NoOp(Zammad CTI: Hang Up (Incoming): normalClearing: CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadData=event=hangup&direction=in&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&answeringNumber=${CHANNEL}&cause=normalClearing)
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

; Zammad, Call Hang Up (Outgoing): normalClearing (One of the parties hung up after the call was established)
exten => s,140,NoOp(Zammad CTI: Hang Up (Outgoing): normalClearing: CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadData=event=hangup&direction=out&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&answeringNumber=${CHANNEL}&cause=normalClearing)
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

; Zammad, Call Hang Up (Incoming): busy (The called party was busy)
exten => s,150,NoOp(Zammad CTI: Hang Up (Incoming): busy: CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadData=event=hangup&direction=in&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&answeringNumber=${CHANNEL}&cause=busy)
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

; Zammad, Call Hang Up (Outgoing): busy (The called party was busy)
exten => s,160,NoOp(Zammad CTI: Hang Up (Outgoing): busy: CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadData=event=hangup&direction=out&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&answeringNumber=${CHANNEL}&cause=busy)
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

; Zammad, Call Hang Up (Incoming): cancel (The caller hung up before the called party picked up)
exten => s,170,NoOp(Zammad CTI: Hang Up (Incoming): cancel: CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadData=event=hangup&direction=in&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&answeringNumber=${CHANNEL}&cause=cancel)
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

; Zammad, Call Hang Up (Outgoing): cancel (The caller hung up before the called party picked up)
exten => s,180,NoOp(Zammad CTI: Hang Up (Outgoing): cancel: CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadData=event=hangup&direction=out&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&answeringNumber=${CHANNEL}&cause=cancel)
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

; Zammad, Call Hang Up (Incoming): noAnswer (The called party rejected the call (e.g. through a DND setting))
exten => s,190,NoOp(Zammad CTI: Hang Up (Incoming): noAnswer: CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadData=event=hangup&direction=in&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&answeringNumber=${CHANNEL}&cause=noAnswer)
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

; Zammad, Call Hang Up (Outgoing): noAnswer (The called party rejected the call (e.g. through a DND setting))
exten => s,200,NoOp(Zammad CTI: Hang Up (Outgoing): noAnswer: CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadData=event=hangup&direction=out&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&answeringNumber=${CHANNEL}&cause=noAnswer)
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

Schritt 2: Dann habe ich ein fd_outbound-Script für alle ausgehenden Anrufe angelegt (Kontext: fd_outbound, Einbinden: [Ausgehend]) und selbiges im Trunk unter “Skript ausgehende Regeln: [fd_outbound]” angegeben:


Skript-Inhalt:

; Additional actions for outbound calls
exten => s,1,NoOp(fd_outbound)
  same => n,Progress()
  ; Zammad, New Call (Outgoing)
  ; Adapt all occurrences to your needs:
  ; - same => n,Set(ZammadEndpointURL=[...])
  ; - same => n,Set(ZammadQueue=[..., empty value is possible])
  same => n,NoOp(Zammad CTI: New Call (Outgoing): From=${CALLERID(num)}, To=${CALLERID(dnid)}, CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadQueue=office)
  same => n,Set(ZammadData=event=newCall&direction=out&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${CALLERID(name)}&queue=${ZammadQueue})
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  ; continue with usual flow
  same => n,Progress()
  same => n,Ringing()
  same => n,Return()

Schritt 3: Anschließend habe ich das Skript default009 angepasst, um Aktionen zu triggern, wenn z.B einfach in einer Warteschlange vom Anrufer aufgelegt wird (und daher [Extern/Nacher] nicht greift). Das Script ist von pascom bereitgestellt und wurde daher editiert. Es wurde um folgenden Inhalt ergänzt (also einach direkt danach eingefügt, Stand 2025-02-09 war das Original nur eine Zeile):

;;; BEGIN: Edit for fd
  ; Additional actions for hangup (Zammad)
  same => n,GoToIf($[ "${MDC_DIALDESCENT}" = "int" ]?610:600)

; Zammad, Call Hang Up
; Adapt all occurrences to your needs:
; - same => n,Set(ZammadEndpointURL=[...])

; Zammad, Call Hang Up (Incoming): normalClearing (One of the parties hung up after the call was established)
exten => s,600,NoOp(Zammad CTI: Hang up: CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadData=event=hangup&direction=in&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${MDC_DIALCALLERNAME}&answeringNumber=${CHANNEL}&cause=normalClearing)
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()

; Zammad, Call Hang Up (Outgoing): normalClearing (One of the parties hung up after the call was established)
exten => s,610,NoOp(Zammad CTI: Hang up: CallId=${CHANNEL(LINKEDID)})
  same => n,Set(ZammadEndpointURL=https://zammad.example.com/api/v1/cti/fixme-token/)
  same => n,Set(ZammadData=event=hangup&direction=out&from=${CALLERID(num)}&to=${CALLERID(dnid)}&callId=${CHANNEL(LINKEDID)}&user[]=${MDC_DIALCALLERNAME}&answeringNumber=${CHANNEL}&cause=normalClearing)
  same => n,Verbose(Sending data as HTTP POST request: ${ZammadData})
  same => n,Set(CURLOPT(httptimeout)=3)
  same => n,Set(CURLOPT(conntimeout)=3)
  same => n,Set(OUT=${CURL(${ZammadEndpointURL},${ZammadData})})
  same => n,Return()
;;; END: Edit for fd

Probleme / ToDos / Anmerkungen:

  • Ebenfalls keine Lösung für “Status update in Zammad wenn Gespräch angenommen” gefunden bisher, das Problem mit “CURL gegen Zammad bei answered” habe ich auch also noch. Wenn wir nur Hardware-Telefone im Einsatz hätten, würde ich als Workaround ggf. deren Action-URLs oder Ähnliches bei Annahme nutzen. @moderators @Mathias wirklich keine Idee / Hint? Ggf. irgendwie eine Möglichkeit M(myCustomMacro) einzuschleusen an der richtigen Stelle?
  • default009 wird nicht gefeuert, wenn während einer Ansage aufgelegt wird. Skript-Aufruf also eher nach einer Ansage legen (damit in Zammand nicht alles auf “läutet…” hängt mit den Nachteil, dass Anrufe eben erst nach der Ansage erscheinen) oder noch weitere Skripte analog anpassen (müsste man wahrscheinlich an default005 (def_rcs) sein…)
1 Like

Servus @andreashaerter,

da hast Du Dich ja ganz schön reingefuchst :wink: .

Ich habe jetzt nicht im Detail nachvollzogen, was Du da alles mit Scripting machst.

Aber ich verstehe das so: Du möchtest dem Zammad bei den verschiedenen Call States mitteilen, was gerade Sache ist. Wir machen das z.B. auch für die Tomedo (Arztsoftware) und anderen Integrationen. Allerdings nicht über den Server per Scripting, sondern über unseren Client per Aktionen:

Hier kannst Du Aktionen je nach Rufrichtung, Event oder Anruftyp auslösen. Genügt Dir eine einfache URL nicht, kannst Du es auch per App direkt über CURL oder ein Script machen. Wenn Du zufrieden bist, kannst Du die Aktionen exportieren und bei allen Clients wieder importieren.

Evtl. lassen sich so noch einige Deiner Anforderungen erfüllen.

LG
Mathias

Hallo Mathias,

vielen lieben Dank! In der Tat könnte ich das noch fehlende Event (Annehmen des Calls) so durch die Hintertür wahrscheinlich feuern:

Darauf werde ich sicher zurückgreifen / lindert das Problem an einigen Stellen.

Dennoch: Das schließt die funktionale Lücke nur teilweise, “bei Annehmen” auf das Instanz selber CURL zu feuern wäre schon deutlich geschickter:

  1. URL-Aktionen gibt es in der Mobile App nicht, korrekt? (das ist bei uns ein Problem, da die MA zu 80% nur diesen nutzen und damit ist das kein allgemeingültiger Workaround)
  2. Für HW-Telefone (z.B snom Action URLs) wäre es gangbar, aber eben nochmal etwas zum verstehen
  3. Ungut ist aber vorallem auch, dass der API-Endpunkt-Token von Zammad dann im Client für den User auch einsehbar ist. Das ist nicht unerheblich sicherheitsrelevant.