Ejemplo practico para el uso de Asterisk con sonsulta a DDBB mediante ODBC.
El entorno,
Se pide que se identifique a los clientes que llaman, por Nº de cliente y después por un PIN de cliente, para su posterior enrutado de la llamada al comercial personal del cliente.
La opción de identificar al cliente por el Nº de Teléfono, es muy "dificil" puesto que estaríamos impidiendo que llamara desde cualquier número. Está orientado a llamadas de empresas, no particulares, una empresa puede tener multitud de números, tanto fijos, como móviles.
Para un particular seria mas acertado , o quizás no, el uso del Tlf fijo o movil, como identificador de Cliente.
La DDBB.
Tendremos una sola tabla, con tres columnas, Numero de cliente, Pin y Extensión.
La tabla se llamara ccliente, y las columnas NCliente, Pin y NExt
Y la tabla ccliente tendrá estos datos.
Pin NCliente NExt
1234 987654 222
El orden de las columnas en indiferente, a esta tabla solo hay que poblarla, como ejemplo es perfecta, no voy a entrar en el detalle que que tipo de campos, o quien es el indice, o llave primaria, ni nada por el estilo, esto es un EJEMPLO.
Por otro lado tendremos una serie de grabaciones que preguntaran, Por el Nº de cliente (ncliente.wav), otra para cuando no se acierta o no exixte el cliente o el Pin (clienteinexis.wav), y otra con la bienvenida una vez pasado el Nº del cliente y PIN, (bienvenida.wav).
Como Ejemplo, el numero sera el 1111. Llamando a este nº, se inicia todo el proceso.
El Uso de NoOp, para descubrir mas fácilmente las variables, que se van creando.
Y usaremos 3 funciones en el Fichero func_odbc.conf
NCli ,ValCli y NExt.
Referencias de ayuda:
https://wiki.asterisk.org/wiki/display/AST/Getting+Asterisk+Connected+to+MySQL+via+ODBC
El Dialplan.
exten = 1111,1,NoOp(llamada entrante de numero Clientes para ${EXTEN} desde,${CALLERID(number)})
same => n,Read(NCliente,es/test/ncliente,6)
same => n,NoOp(${NCliente})
same => n,GotoIf($[${ODBC_NCli(${NCliente})}]?ncliente)
same => n,Playback(es/test/clienteinexis)
same => n,Hangup()
same => n(ncliente),Read(Pin,es/test/clienteexis-Pin,4)
same => n,NoOp(${NCliente},${Pin})
same => n,GotoIf($[${ODBC_ValCli(${NCliente},${Pin})}]?valido)
same => n,Playback(es/test/accesdeny)
same => n,Hangup()
same => n(valido),Playback(es/test/bienvenida)
same => n,Set(Comercial=${ODBC_NExt(NExt,${NCliente})})
same => n,NoOp(${Comercial},${NCliente})
same => n,Dial(SIP/${Comercial},20)
same => n,Hangup()
La secuencia. (Para los detalles de que pasa en las consultas SQL, un poco mas abajo en El Fichero func_odbc.conf.)
Se marca 1111, con Read, se inicia el proceso de reproducir el fichero "ncliente" un fichero de audio donde pide que introduzca el numero de cliente, que tendrá que ser de 6 digitos. Ademas este valor se guardara en NCliente. (${NCliente})
Primera consulta
¿Está este numero de cliente en la tabla que se define por ODBC_NCli,?? si esta, SALTA a la etiqueta (ncliente)
GotoIf($[${ODBC_NCli(${NCliente})}]?ncliente)
De lo contrario se reproduce el fichero "clienteinexis" y se le cuelga.
Vale, SI está, salta a la etiqueta (ncliente) y preguntamos por el PIN, igual que antes reproducimos el fichero clienteexis-Pin que dira algo como vale el cliente está pero dame tu pin, (con esto se pueden hacer muchas cosas como tirar de otra columna con los nombres de las empresas e integrar lecturas personalizadas de "bienvenida empresa Logaisa proporcionenos su pin"). Tomamos el valor leído con Pin y lo pasamos a la variable ${Pin} para trabajar con ella como antes, y claro tenemos que saber que el Pin coincide.
GotoIf($[${ODBC_ValCli(${NCliente},${Pin})}]?valido)
A qui pasamos los dos argumentos y con la función ValCli, sabremos si coincide. Obtendremos un 0 Si el PIN dado no coincide al Cliente previamente consultado. En este punto se pueden hacer muchas cosas, que se repita otra vez, o que Ud tiene solo 3 intentos, en fin muchas cosas, pero como no paro de repetir, esto es un EJEMPLO, y nos vale. Con lo que si el pin no es valido, se le dice hasta luego y se cuelga.Pero si es valido, SALTA a la etiqueta (valido).
En esta ocasión es cosa toda nuestra, se le da la bienvenida, y se le asigna la extensión personalizada, en la que estará, el comercial asignado a esa cuenta-cliente.
Set(Comercial=${ODBC_NExt(NExt,${NCliente})})
Asignamos a la variable Comercial, lo que nos diga la función ODBC_NExt nosotros pasamos lo que queremos NExt (que coincide con la función, pero que no es lo mismo esto es el valor almacenado en la columna NExt) y como datos (Argumento2 de la consulta) el numero de cliente almacenado en la Variable ${NCliente} (que también coincide con la columna, PERO no es lo mismo, yo paso un numero, no el nombre de la columna como pasa con el argumento1)
Se asigna a "Comercial" el valor de la columna NExt, que coincida con el valor de la variable ${NCliente}
Quizás para estas cosas las reglas nemotecnias, no son las mas adecuadas.
Pues con esto ya tenemos el dato, la Variable ${Comercial} almacenara ese valor, de la consulta, ya solo tenemos que hacer el Dial, y listo.
Dial(SIP/${Comercial},20)
El Fichero func_odbc.conf.
[NCli]
dsn=asterisk
readsql=SELECT COUNT(*) FROM ccliente WHERE NCliente='${SQL_ESC(${ARG1})}'
Como estamos usando un GotoIf en el Dialplan nos vale si esta o NO, el NCliente pasado como ARG1 (Argumento) por el dialplan.
ha de entragar un valor o 0, no aparece este numero de cliente, o si aparece, (solo ha de aparecer 1 vez)
[ValCli]
dsn=asterisk
readsql=SELECT COUNT(*) FROM ccliente WHERE NCliente='${SQL_ESC(${ARG1})}' AND Pin='${SQL_ESC(${ARG2})}'
En esta nos aseguramos que el PIN , coincide con el Numero de cliente, (AND) no sea que ese cliente que SI aparece, tenga otro PIN, y la liemos.
[NExt]
dsn=asterisk
readsql=SELECT ${ARG1} FROM ccliente WHERE NCliente='${SQL_ESC(${ARG2})}'
Con esta tomamos el valor de la columna dada como ARG1 argumento del dialplan NExt para la coincidencia del NCliente (el numero de cliente que pasamos como variable)
Con esta función por un lado pedimos un dato, que pasaremos a variable (ARG1) mediante el dialplan, y por otro, pasamos un dato como variable (ARG2).
Como es mas factible que se tenga mas PINs iguales (4 digitos) que clientes (6 digitos), mejor cogemos esta.
Estoy segurisimo que esto es mejorable, o incluso, poco ortodoxo, pero es la mejor manera de ver, como funciona "despacito".
Esto que sea mas entendible, y que me ayude en un futuro por si me lio.