Abfrage Anrufername aus CRM / MSSQL-Datenbank

german
desktop-client
script

#1

Wir möchten in der Benachrichtigung im Desktop Client bei eingehenden Anrufen anzeigen, welcher Kunde da eigentlich anruft. Dazu würde ich am liebsten unsere CRM-Datenbank anzapfen. Es handelt sich dabei um eine MSSQL-Datenbank.

Soeine Abfrage scheint man ja mit einem Skript lösen zu können, wie es in diesem Thread getan wurde. Jetzt ist nur die Frage ob ich auch die Möglichkeit habe da ODBC oder ähnliches zu verwenden um auf die MSSQL-Datenbank zugreifen zu können.

Wenn ich php -r 'print_r(PDO::getAvailableDrivers());' eingebe dann scheine ich da nur die Möglichkeit zu haben pgsql und sqlite verwenden zu können :frowning:


#2

Hi,

vielleicht hilft dir das weiter.
Du kannst mittels AGI bzw. CURL auch remote auf einen anderen Rechner zu greifen.
Siehe hierzu https://wiki.asterisk.org/wiki/display/AST/Asterisk+11+Application_AGI und https://wiki.asterisk.org/wiki/display/AST/Asterisk+11+Function_CURL

Grüße
Markus


#3

Hallo @Markus,

das hat mir sehr weitergeholfen! Ich habe jetzt auf einem externen Server ein PHP Skript eingerichtet, was die Abfrage an die Datenbank durchführt. Das scheint auch so weit zu funktionieren, wenn ich der Ausgabe der Konsole glauben schenken darf:

– Executing [ext@sub_prefix-34:1] Gosub(“SIP/mdc_trunk_conf-7-00000146”, “phonebook_w4a,s,1”) in new stack
– Executing [s@phonebook_w4a:1] Set(“SIP/mdc_trunk_conf-7-00000146”, “CURL_CALLER_ID=Test W4A”) in new stack
– Executing [s@phonebook_w4a:2] ExecIf(“SIP/mdc_trunk_conf-7-00000146”, “$ “Test W4A” != “” ]?Verbose(1,“Test W4A””) in new stack
“Test W4A”
– Executing [s@phonebook_w4a:3] ExecIf(“SIP/mdc_trunk_conf-7-00000146”, “$ “Test W4A” != “” ]?Set(CALLERID(name)=Test W4A)”) in new stack

Als Inspiration habe ich das Skript verwendet und entsprechend angepasst:

exten => s,1,Set(CURL_CALLER_ID=${CURL(http://srvmssql01/pascom_w4a.php?callnum=${MDC_CALLER_NUM_INTERNAT})})
same => n,ExecIf($ “${CURL_CALLER_ID}” != “” ]?Verbose(1,"${CURL_CALLER_ID}")
same => n,ExecIf($ “${CURL_CALLER_ID}” != “” ]?Set(CALLERID(name)=${CURL_CALLER_ID}))
same => n,Return()

Leider wird im Client aber nur die Rufnummern und nicht der Name angezeigt. Muss ich eventuell eine andere Variable überschreiben?


Des Weiteren würde ich das Skript gerne nur ausführen, wenn kein Name im Telefonbuch dazu gefunden wurde. Dafür wurde im verlinkten Skript folgender Befehl genutzt:

# perform search only if name is not set
exten => s,1,GotoIf($ “${CALLERID(name)}” != “” ] ?skip)

CALLERID(name) ist allerdings nie leer, da wenn CALLERID(name) leer ist es automatisch mit dem Wert von CALLERID(num) gefüllt wird. Kann man das eventuell irgendwie deaktivieren?

Vielen Dank im Voraus :slight_smile:

Mit freundlichen Grüßen
Stefan


#4

Re,

schön, wenn es soweit schon klappt.
Du könntest vorab prüfen, ob CALLERID(name) != CALLERID(num) ist, anstatt CALLERID(name) auf leer und dann das Skript ausführen.

Mit der Anzeige des Namens im Client könnte klappen, wenn der unmittelbar nach der Telefonbuchsuche gesetzt wird und die Variable “MDC_RESOLVENAME_HITS” auf 1 gesetzt wird. Wäre auszuprobieren, Ist eine Zeit abhängige Geschichte!

Gruß
Markus


#5

Hallo @Markus,

Das ist natürlich eine super Idee! Da hätte ich auch selber drauf kommen können :sweat_smile: Leider hat CALLERID(num) im Gegensatz zu CALLERID(name) noch eine führende Null… Aber die Idee werde ich weiterverfolgen. Das ist auch erstmal nur zweitrangig.

Ich habe zur Vereinfachung einfach mal direkt einen Wert in die Variable “CURL_CALLER_ID” geschrieben. Zusätzlich setze ich noch “MDC_RESOLVENAME_HITS” auf 1. Leider wird weiterhin nur die Nummer beim Client angezeigt.

exten => s,1,Set(CURL_CALLER_ID=Test)
same => n,ExecIf($ “${CURL_CALLER_ID}” != “” ]?Verbose(1,"${CURL_CALLER_ID}")
same => n,ExecIf($ “${CURL_CALLER_ID}” != “” ]?Set(CALLERID(name)=${CURL_CALLER_ID}))
same => n,ExecIf($ “${CURL_CALLER_ID}” != “” ]?Set(MDC_RESOLVENAME_HITS=1))
same => n,Return()

Vielleicht kann auch @Stefan weiterhelfen?


#6

Hi @HExSM

I see a typo in your dialplan. It should be:

exten => s,1,Set(CURL_CALLER_ID=Test)
same => n,ExecIf($[ “${CURL_CALLER_ID}” != “” ]?Verbose(1,"${CURL_CALLER_ID}"))
same => n,ExecIf($[ “${CURL_CALLER_ID}” != “” ]?Set(CALLERID(name)=${CURL_CALLER_ID}))
same => n,ExecIf($[ “${CURL_CALLER_ID}” != “” ]?Set(MDC_RESOLVENAME_HITS=1))
same => n,Return()

It’s very important when do you invoke the script (which context). It should be as early as possible (maybe premain)

Kind regards,
Stefan


#7

Hi @Stefan,

I fixed the typo. Thank you for that :slight_smile:
Unfortunately, it still doesn’t work.

Ah, that’s what “context” is good for. Good to know!
I changed the context of the script to “pre-main”. However, only the telephone number and no name is displayed.


#8

Hi @HExSM

Could you provide an asterisk CLI output?

Kind regards,
Stefan


#9

Hi @Stefan

here is the output:
asterisk_cli.txt (22,4 KB)

Best regards,
Stefan


#10

Hi @HExSM

Maybe you can give a try to the following context

exten => s,1,Set(CURL_CALLER_ID=Test)
same => n,ExecIf($[ “${CURL_CALLER_ID}” != “” ]?Verbose(1,"${CURL_CALLER_ID}"))
same => n,ExecIf($[ “${CURL_CALLER_ID}” != “” ]?Set(MDC_RESOLVENAME_HITS=1))
same => n,ExecIf($[ “${CURL_CALLER_ID}” != “” ]?Set(__MDC_DIALCALLERNAME=${CURL_CALLER_ID}))
same => n,ExecIf($[ “${CURL_CALLER_ID}” != “” ]?Set(CALLERID(name)=${CURL_CALLER_ID}))
same => n,Return()

Kind regards,
Stefan


#11

Hello @Stefan,

yes, that works great! :+1:
Thank you very very much!!

Can this also be used for outgoing calls anyhow?

Best regards,
Stefan


#12

Hi @HExSM,

That’s good.

For outgoing call you can try with another variable

exten => s,1,Set(CURL_CALLEE_ID=Test)
same => n,ExecIf($[ “${CURL_CALLEE_ID}” != “” ]?Verbose(1,"${CURL_CALLEE_ID}"))
same => n,ExecIf($[ “${CURL_CALLEE_ID}” != “” ]?Set(MDC_RESOLVENAME_HITS=1))
same => n,ExecIf($[ “${CURL_CALLEE_ID}” != “” ]?Set(__MDC_DIALCALLEENAME=${CURL_CALLEE_ID}))
same => n,Return()

Kind regards,
Stefan


#13

Hello @Stefan,

do I also have to choose the context “pre-main” and put it into “External/Before” to execute the script?
I’m just asking, because in the asterisk CLI output I can’t find the execution of the script.

EDIT: It seems like it’s working now. :slight_smile:
@Stefan you are the man!!

But you have to change __MDC_DIALCALLEENAME into MDC_DIALCALLEENAME.

Best regards,
Stefan


#14

Hier nochmal eine Zusammenfassung, was ich eingestellt habe damit eingehende und ausgehende Anrufe mit meiner CRM-Datenbank abgeglichen werden:

Als erstes habe ich folgende 2 Skripte in der pascom unter Erweitert > Skripte erstellt:

Skript 1

Bezeichnung: phonebook_in
Kontext: phonebook_in
Einbinden: NEIN
Skriptinhalt:

exten => s,1,Verbose(phonebook_in)
# perform search only if name is not set
same => n,GotoIf($[ "${CALLERID(name)}" != "${CALLERID(num):1}" ]?skip)
# invoke CURL
same => n,Set(CURL_CALLER_ID=${CURL(http://server/pascom_crm.php?callnum=${MDC_CALLER_NUM_INTERNAT})})
# set variable CURL_CALLER_ID if matching result is found
same => n,ExecIf($[ "${CURL_CALLER_ID}" != "" ]?Verbose(1,"${CURL_CALLER_ID}")
same => n,ExecIf($[ "${CURL_CALLER_ID}" != "" ]?Set(MDC_RESOLVENAME_HITS=1))
same => n,ExecIf($[ "${CURL_CALLER_ID}" != "" ]?Set(__MDC_DIALCALLERNAME=${CURL_CALLER_ID}))
same => n,ExecIf($[ "${CURL_CALLER_ID}" != "" ]?Set(CALLERID(name)=${CURL_CALLER_ID}))
same => n,Return()
same => n(skip),Return()

Skript 2

Bezeichnung: phonebook_out
Kontext: sub_pre-main
Einbinden: AUSGEHEND
Skriptinhalt:

exten => s,1,Verbose(phonebook_out)
# invoke CURL
same => n,Set(CURL_CALLEE_ID=${CURL(http://server/pascom_crm.php?callnum=${MDC_CALLEE_NUM:1})})
# set variable CURL_CALLEE_ID if matching result is found
same => n,ExecIf($[ "${CURL_CALLEE_ID}" != "" ]?Verbose(1,"${CURL_CALLEE_ID}")
same => n,ExecIf($[ "${CURL_CALLEE_ID}" != "" ]?Set(MDC_RESOLVENAME_HITS=1))
same => n,ExecIf($[ "${CURL_CALLEE_ID}" != "" ]?Set(MDC_DIALCALLEENAME=${CURL_CALLEE_ID}))
same => n,Return()

Skript 1 habe ich dann jedem Benutzer unter Extern/Vorher zugeordnet.

Hier noch ein Beispiel für ein PHP-Skript um eine MSSQL-Datenbank abzufragen:
pascom_crm.php (966 Bytes)

Das Skript führe ich auf einem Ubuntu 16.04 Server aus.
Für den Zugriff auf die MSSQL-Datenbank unter PHP muss noch das Paket php-sybase installiert werden.

Abschließend muss noch in der /etc/freetds/freetds.conf ein Eintrag für den MSSQL-Server hinterlegt werden.
Folgende Einstellungen habe ich benutzt:

[mssqlLocal]
host = localhost
port = 1433
tds version = 7.2
client charset = UTF-8

@Stefan would you keep that configuration or is there a better solution?
If I put both scripts in sub_pre-main then script 2 isn’t working anymore. I thought it would work if I change the field integrate for script 1 to BEFORE and for script 2 to OUTGOING but it doesn’t matter. It would be nice if I didn’t have to assign the script phonebook_in to every user and it would be executed automatically when an incoming call is received.

Edit 19.01.2018 15:58: pascom_crm.php aktualisiert
Edit 01.03.2018 11:27: Formatierung angepasst


API Nummernabfrage
#15

Hallo zusammen,

nun habe ich auch endlich Zeit hierfür gefunden.

Ich habe das Script von @HExSM testweise bei einem User extern/vorher eingebunden.
Bei einem externen Anruf wird das Script auch durchlaufen. Allerdings meldet die CLI folgenden Fehler:

[Feb 27 10:24:03] WARNING[24582][C-000011e1]: ast_expr2.fl:470 ast_yyerror: ast_yyerror(): syntax error: syntax error, unexpected ‘’, expecting $end; Input:
“Maik H*****” != “016090******”
^
[Feb 27 10:24:03] WARNING[24582][C-000011e1]: ast_expr2.fl:474 ast_yyerror: If you have questions, please refer to https://wiki.asterisk.org/wiki/display/AST/Channel+Variables

Ich vermute hier liegt der Fehler: Ich sehe diesen nur leider nicht.

Hat einer eine Idee ?

Grüße

Maik


#16

Hallo @maik,

die Anführungszeichen sind nicht korrekt. Wenn man die Zitatfunktion hier im Forum nutzt, dann scheint er das Standard-Anführungszeichen in ein typografisches Anführungszeichen zu ändern und wenn man das kopiert, dann gibt es einen Syntaxerror. Daher müsstest du die ganzen “falschen” Anführungszeichen ersetzen.

Zumindest ist das meine Theorie :smiley:

Falsch:

same => n,GotoIf($[ “${CALLERID(name)}” != “${CALLERID(num):1}” ]?skip)

Korrekt:
same => n,GotoIf($[ "${CALLERID(name)}" != "${CALLERID(num):1}" ]?skip)

Gruß
Stefan


#17

Hallo @HExSM

danke das war es. Darauf muss man erstmal kommen… @Mathias könnte dies im Forum angepasst werden.

Grüße

Maik


#18

Hallo @maik,

wenn man den entsprechenden Abschnitt als “Code” formattiert (Entweder: Leerzeile vor dem Abschnitt + 4 Leerzeichen am Anfang oder Backticks rundherum: `var y = "Beispiel";`. Dann formattiert das Forum das standardmäßig richtig.

var x = "Dies ist ein Beispiel";

Vielleicht ist es hier am Anfang vergessen worden oder es kommt noch von der Konvertierung von der alten Forum-Engine.

Grüße,
Jan


#19

Es ist wie @HExSM sagt: Sobald ich code zitiere lässt er die code Markierung weg und dann schaut es so aus:

man kann aber einfach beim Zitieren im Zitat markieren das es code ist, dann passt alles wieder:

Quellcode

[quote="jlorenz, post:18, topic:3167"]
`var x = "Dies ist ein Beispiel";`
[/quote]

Umstellen kann ich da leider nix.


#20

FYI: Ich habe meinen Beitrag oben bearbeitet und alles als Code formatiert. Damit sollte das jetzt für die Zukunft passen.