Cómo usar nombres de usuario con agentes dinámicos en colas de Asterisk

Asignar nombres de usuario a miembros de colas de Asterisk

En este artículo veremos una manera de asignar a los agentes, también llamados miembros, de las colas de Asterisk, un nombre de usuario, para hacer más sencillo su uso y su seguimiento.

Para hacer esto supondremos una instalación sencilla de Asterisk sobre una distribución Debian. En esa instalación tendremos incluido FOP2 y Asternic para ver un ejemplo de aplicación.

Obviamente, se necesitan conocimientos previos de Asterisk.

xustificación

Cuando se utilizan miembros dinámicos para las colas de llamadas en Asterisk, nos encontramos con el problema de que los usuarios que toman las llamadas quedan identificados por el número de extensión en la que trabajan. En muchos entornos de trabajo las extensiones pueden estar siendo utilizadas por diferentes usuarios; es necesario entonces encontrar la manera de identificarlos no por su extensión (el número SIP por ejemplo) sino por un nombre de usuario normal.

Colas de Asterisk en FOP2 sin nombres de usuario
Una imagen del FOP2, con agentes normales, se reconocen por su número de extensión.

Al utilizar nombres de usuario, el seguimiento a través de registros (logs) o la construcción de estadísticas será más intuitiva y eficaz.

Colas de Asterisk en FOP2 con nombres de usuario
Aquí ya se comprueba cómo podemos ver en el FOP a los diferentes usuarios.
Colas de Asterisk en FOP2 con usuarios dinámicos en funcionamiento
Vemos quién está ocupado y quién está disponible para otras llamadas, etc.

Desarrollo

Para desarrollar esto utilizamos canales locales; se llaman así porque se utilizan para hacer llamadas dentro del propio sistema de Asterisk, sin salir al exterior.

Podéis encontrar más información sobre esto en:
Canales locales (en inglés)

En nuestro caso los operarios realizarán una de estas llamadas para convertirse en miembros de la cola o colas correspondientes. Cada operario utilizará un código de llamada para hacer esto, dicho código lo utilizaremos como nombre de usuario para identificarlo.

No importa desde qué extensión se realice la llamada, ya no se reconocerá al miembro de la cola por su canal SIP, si no por el canal local.

Vamos a crear un ejemplo que sirva para comprender todo.

En este ejemplo, los operarios se conectarán a la cola clientes tecleando sus códigos (sus nombres de usuario) con un asterisco por delante, para registrarse desde un terminal cualquiera.

Se les crea un canal local con ese registro, y se les introduce en el contexto atencion_clientes que debe aparecer a continuación en el plan de llamadas. Se guarda ese registro en la base de datos de Asterisk haciendo la correlación terminal_SIP-usuario, para así poder quedar reflejado el usuario en los logs (sino, solo se registra el terminal SIP)

Cuando el usuario abandona su puesto, tecleará su nombre de usuario precedido de un cero.

Ejemplo de uso en un softphone
Ejemplo de ejecución desde un softphone Zoiper

Toda esta configuración la hacemos en el archivo /etc/asterisk/extensions.conf, os lo dejo comentado para que se entienda mejor:

[salientes]
exten => _*[a-z].,1,NoOp(-- Petición de login de miembros --)
same => n,Set(VAR=${SHELL(grep ${EXTEN:1} /etc/asterisk/archivos/usuarios.txt -w)}) ; en un archivo guardamos los nombres válidos.
same => n,GotoIf($["${VAR}" = ""]?cuelga) ; si en el archivo no aparece el nombre tecleado por el operario, lo expulsa.
same => n,AddQueueMember(clientes,Local/${EXTEN:1}@atencion_clientes)
same => n,Set(DB(atencion_clientes/${EXTEN:1})=${CALLERID(num)}) ;almacenamos esa correlación en la base de datos interna de Asterisk
same => n,Playback(agent-loginok)
same => n(cuelga),Hangup()
 ; para desregistrarse usamos el carácter 0 en vez de * con el mismo código.
exten => _0[a-z].,1,NoOp(-- Petición de deslogueo de miembros--)
same => n,RemoveQueueMember(clientes,Local/${EXTEN:1}@atencion_clientes)
same => n,Set(borrar=${DB_DELETE(atencion_clientes/${EXTEN:1})}) ; aquí se elimina la correlación, usamos una variable (borrar en este caso)
same => n,Playback(agent-loggedoff)
same => n,Playback(goodbye)
same => n,Hangup()

[atencion_clientes] ; este es el contexto que determina la llamada al miembro desde la cola, si está ocupado no hace nada, manda un mensaje por consola.
exten => _[a-z].,1,NoOp(-Llamada al  miembro -)
same => n,Set(MIEMBRO=${DB(atencion_clientes/${EXTEN})})
same => n,GotoIf($[${SIPPEER(${MIEMBRO},curcalls)} = 1]?ocupado)
same => n,Dial(SIP/${MIEMBRO})
same => n(ocupado),NoOP(Miembro ocupado, llamada en cola) ; aquí acabamos.

Como véis, utilizamos un archivo, usuarios.txt en este caso, para almacenar los nombres de los usuarios. Podría plantearse lo mismo con una base de datos.

Asternic con nombres de usuario
Aquí tenemos un detalle del Asternic, para construir estadísticas.

No dudéis en opinar y aportar vuestras posibles soluciones alternativas, grazas.


Sobre Anxo Calvo

Apaixonado sobre ciencia e tecnoloxía. Profesor, autor de manuais e sistemas e director de comunicacións.

Deixar unha resposta