Campañas v4
SALIENTES
Desde Agente con Hardphone
${OUTGUID}: Guid de la llamada generada
${OUTAGENT}: Nombre del agente que realiza la llamada
${OUTQUEUE}: Nombre de la cola por la que sale la llamada
${OUTDID}: DID numero callerid para usar al salir corresponde al de la cola
${OUDIDALED}: Numero marcado
Con Telefono Java
La llamada no se hace en 2 paso sino directo y el nombre de la cola, guid y did pueden obtenerse de un SIP Header El resto de las variables son obtenidas directamente de donde corresponden:
${SIP_HEADER(OUTGUID)}: Guid de la llamada generada
${CDR(accountcode)}: Nombre del agente que realiza la llamada
${SIP_HEADER(OUTQUEUE)}: Nombre Cola
${SIP_HEADER(OUTDID)}: DID numero callerid para usar al salir corresponde al de la cola
${EXTEN}: Numero marcado
Ejemplo Completo para ambos casos
Podemos ver las variables que se ejecutan y como se toman en cuenta las que llegan dependiendo del modo que se ejecute el agente.
Es importante usar __Ani para poder buscar en Logs.
El QueueUpdate en el Hangup es fundamenta por temas de estadísticas de campañas salientes.
En Hangup tambien agregar Set(CDR(userfield)=${userfield}) para Marcar la Grabación
Es posible ejecutar en el Dial un Macro para enviar datos al cliente una vez la llamada es atendida.
exten=> _9XXXXXXXX,1,Set(VOLUME(TX)=2)
exten=> _9XXXXXXXX,2,Set(VOLUME(RX)=2)
exten=> _9XXXXXXXX,3,GotoIf($["${OUTQUEUE}"= ""]?48:4)
exten=> _9XXXXXXXX,4,Set(__OUTQUEUE=${OUTQUEUE})
exten=> _9XXXXXXXX,5,Set(__DIALED=${OUTDIALED})
exten=> _9XXXXXXXX,6,Set(__AGENT=${OUTAGENT})
exten=> _9XXXXXXXX,7,Set(CALLERID(num)=${OUTDID})
exten=> _9XXXXXXXX,8,Set(CALLERID(name-pres)=allowed_passed_screen)
exten=> _9XXXXXXXX,9,Set(event=${ODBC_Data(select event from queue_log where agent = '${OUTAGENT}' and queuename= '${OUTQUEUE}' and event in ('PAUSE', 'UNPAUSE') ORDER BY id DESC LIMIT 1)})
exten=> _9XXXXXXXX,10,GotoIf($["${event}" = "PAUSE"]?46:11)
exten=> _9XXXXXXXX,11,GotoIf($["${OUTGUID}" = ""]?41:12)
exten=> _9XXXXXXXX,12,Set(__guid=${OUTGUID})
exten=> _9XXXXXXXX,13,Set(CDR(guid)=${guid})
exten=> _9XXXXXXXX,14,Set(CDR(type)=record)
exten=> _9XXXXXXXX,15,MixMonitor(${guid}.gsm,b,)
exten=> _9XXXXXXXX,16,Set(CDR(campaign)=${OUTQUEUE})
exten=> _9XXXXXXXX,17,Set(CDR(accountcode)=${AGENT})
exten=> _9XXXXXXXX,18,Set(__idLlamada=${guid})
exten=> _9XXXXXXXX,19,Set(__REALDIALED=${EXTEN:1})
exten=> _9XXXXXXXX,20,Set(existeNum=${ODBC_Data(SELECT COUNT(*) FROM black_list WHERE (campaign like '${OUTQUEUE}%' || campaign like '*%') AND phone ='${EXTEN}')})
exten=> _9XXXXXXXX,21,GotoIf($["${existeNum}"!= "0"]?38:22)
exten=> _9XXXXXXXX,22,Dial(SIP/DINSTAR/${EXTEN:1},180,TKkc,)
exten=> _9XXXXXXXX,23,Set(CDR(causecode)=${HANGUPCAUSE})
exten=> _9XXXXXXXX,24,NoOp(${DIALSTATUS})
exten=> _9XXXXXXXX,25,NoOp(${HASH(SIP_CAUSE,${CDR(dstchannel)})})
exten=> _9XXXXXXXX,26,NoOp(${HANGUPCAUSE})
exten=> _9XXXXXXXX,27,GotoIf($["${DIALSTATUS}" = "BUSY"]?36:28)
exten=> _9XXXXXXXX,28,GotoIf($["${DIALSTATUS}" = "CONGESTION"]?36:29)
exten=> _9XXXXXXXX,29,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL"]?34:30)
exten=> _9XXXXXXXX,30,GotoIf($["${DIALSTATUS}" = "CANCEL"]?32:31)
exten=> _9XXXXXXXX,31,Hangup()
exten=> _9XXXXXXXX,32,Playback(outofservice,)
exten=> _9XXXXXXXX,33,Goto(agentes,${EXTEN},31)
exten=> _9XXXXXXXX,34,Playback(outofservice,)
exten=> _9XXXXXXXX,35,Goto(agentes,${EXTEN},31)
exten=> _9XXXXXXXX,36,Playback(busy,)
exten=> _9XXXXXXXX,37,Goto(agentes,${EXTEN},31)
exten=> _9XXXXXXXX,38,Set(dummy=${ODBC_Repo(INSERT INTO black_list_history(calldate\,src\,dst) VALUES (now()\,'${AGENT}'\,'${EXTEN}'))})
exten=> _9XXXXXXXX,39,Playback(DNCRaudio,)
exten=> _9XXXXXXXX,40,Goto(agentes,${EXTEN},31)
exten=> _9XXXXXXXX,41,GotoIf($["${SIP_HEADER(OUTGUID)}" = ""]?44:42)
exten=> _9XXXXXXXX,42,Set(__guid=${SIP_HEADER(OUTGUID)})
exten=> _9XXXXXXXX,43,Goto(agentes,${EXTEN},13)
exten=> _9XXXXXXXX,44,GUID(__guid)
exten=> _9XXXXXXXX,45,Goto(agentes,${EXTEN},13)
exten=> _9XXXXXXXX,46,Playback(pausaerror,)
exten=> _9XXXXXXXX,47,Hangup()
exten=> _9XXXXXXXX,48,GotoIf($[$["${SIP_HEADER(OUTQUEUE)}"= ""]|$["${SIP_HEADER(OUTQUEUE)}"= "null"]]?54:49)
exten=> _9XXXXXXXX,49,Set(__AGENT=${CDR(accountcode)})
exten=> _9XXXXXXXX,50,Set(__DIALED=${EXTEN})
exten=> _9XXXXXXXX,51,Set(__OUTQUEUE=${SIP_HEADER(OUTQUEUE)})
exten=> _9XXXXXXXX,52,Set(CALLERID(num)=${SIP_HEADER(OUTDID)})
exten=> _9XXXXXXXX,53,Goto(agentes,${EXTEN},8)
exten=> _9XXXXXXXX,54,Set(HASH(Result)=${ODBC_Data(select did\,name from queues where name in (select queue_name from queue_members where membername = '${CDR(accountcode)}') and direction = 'Outbound')})
exten=> _9XXXXXXXX,55,GotoIf($["${HASH(Result,name)}"= ""]?61:56)
exten=> _9XXXXXXXX,56,Set(__AGENT=${CDR(accountcode)})
exten=> _9XXXXXXXX,57,Set(__DIALED=${EXTEN})
exten=> _9XXXXXXXX,58,Set(__OUTQUEUE=${HASH(Result,name)})
exten=> _9XXXXXXXX,59,Set(CALLERID(num)=${HASH(Result,did)})
exten=> _9XXXXXXXX,60,Goto(agentes,${EXTEN},8)
exten=> _9XXXXXXXX,61,Background(llamadasincola,,,)
exten=> _9XXXXXXXX,62,Hangup()
exten=> h,1,Set(CDR(userfield)=${userfield})
exten=> h,2,QueueUpdate(${OUTQUEUE},${UNIQUEID},${AGENT},${DIALSTATUS},${ANSWEREDTIME},${DIALEDTIME}|${DIALED}|${IdLlamada}|)
En la creación de campañas se define el Form o la URL que hay que desplegar al hacer click en el botón de formularios para determinada campaña.
Opción 1: uContact Form: Solo nombre del Form, Nombre del Form y | true (esto para desplegar la cruz del form y poder cerrarlo)
Ejemplos: Codigos | true
Codigos
Opcion 2: uContact URL: URL bien formada y | nombre a mostrar en Tab o URL bien formada | nombre del tab | true (esto para desplegar la cruz del form y poder cerrarlo)
Ejemplos: http://www.observador.com.uy | Observa
http://www.observador.com.uy | Observa | true
ENTRANTES
Podemos ver el workflow de ejecución.
Es importante usar __Ani para poder buscar en Logs.
Ya no usamos mas MACRO para pasar datos de CTI sino SIP HEADER, esta se persiste durante toda la llamada lo cual deberia si es una transferencia tambien pasar los datos, tambien es posible eliminar el HEADER.
Ejemplo Completo
exten=> _XXXXXXXX,1,Set(CHANNEL(Language)=es)
exten=> _XXXXXXXX,2,Set(__Ani=${CALLERID(num)})
exten=> _XXXXXXXX,3,Set(CDR(campaign)=Unicef<-)
exten=> _XXXXXXXX,4,Answer(0)
exten=> _XXXXXXXX,5,Set(sound=${ODBC_Data(select sound from holidays WHERE day = '${STRFTIME(${EPOCH},,%d)}' AND month = '${STRFTIME(${EPOCH},,%m)}' AND (year = '${STRFTIME(${EPOCH},,%Y)}' OR year = '*') AND substring(timerange,1,5) <= '${STRFTIME(${EPOCH},,%R)}' AND substring(timerange,7) >= '${STRFTIME(${EPOCH},,%R)}' AND (campaign ='*' OR campaign ='${CDR(campaign)}'))})
exten=> _XXXXXXXX,6,GotoIf($["${sound}"=""]?10:7)
exten=> _XXXXXXXX,7,Playback(${sound},)
exten=> _XXXXXXXX,8,VoiceMail(1000@voicemail,)
exten=> _XXXXXXXX,9,Hangup()
exten=> _XXXXXXXX,10,Set(AUDIOHOOK_INHERIT(MixMonitor)=yes)
exten=> _XXXXXXXX,11,Set(HASH(queue)=${ODBC_Data(SELECT welcome\, schedule FROM queues WHERE name = '${CDR(campaign)}')})
exten=> _XXXXXXXX,12,Set(welcome=${HASH(queue,welcome)})
exten=> _XXXXXXXX,13,Set(Bienvenida=${CUT(welcome,\;,1)})
exten=> _XXXXXXXX,14,Set(FueraDeHora=${CUT(welcome,\;,2)})
exten=> _XXXXXXXX,15,Set(schedule=${HASH(queue,schedule)})
exten=> _XXXXXXXX,16,Set(cantidad=${FIELDQTY(schedule,&)})
exten=> _XXXXXXXX,17,Set(dentroDeHora=0)
exten=> _XXXXXXXX,18,While($[${cantidad} >0 && ${dentroDeHora} = 0])
exten=> _XXXXXXXX,19,Set(date=${CUT(schedule,\&,${cantidad})})
exten=> _XXXXXXXX,20,Set(hourrange=${CUT(date,\;,2)})
exten=> _XXXXXXXX,21,Set(dayrange=${CUT(date,\;,1)})
exten=> _XXXXXXXX,22,Set(cantidad=${MATH(${cantidad} - 1,i)})
exten=> _XXXXXXXX,23,GotoIfTime(${hourrange},${dayrange},,?,${EXTEN},37)
exten=> _XXXXXXXX,24,EndWhile()
exten=> _XXXXXXXX,25,GotoIf($[${dentroDeHora}=1]?28:26)
exten=> _XXXXXXXX,26,Playback(${FueraDeHora},)
exten=> _XXXXXXXX,27,Goto(entrantes,${EXTEN},8)
exten=> _XXXXXXXX,28,Playback(${Bienvenida},)
exten=> _XXXXXXXX,29,GUID(__guid)
exten=> _XXXXXXXX,30,Set(CDR(guid)=${guid})
exten=> _XXXXXXXX,31,Set(CDR(type)=record)
exten=> _XXXXXXXX,32,Set(MONITOR_FILENAME=${guid})
exten=> _XXXXXXXX,33,Set(CALLERID(name)=Integra)
exten=> _XXXXXXXX,34,SipAddHeader(CTI: {"Guid": "${guid}" , "Screen": "FALSE" , "Form": "MalCod" , "Campaign" : "Entrada" , "Callerid" : "${CALLERID(num)}" , "ParAndValues" : "par1=val1-par2=val2-par3=val3" , "Beep" : "TRUE" , "Answer" : "FALSE"})
exten=> _XXXXXXXX,35,Queue(CallCenter<-,tTkK,,,400,,CTI,,,)
exten=> _XXXXXXXX,36,Hangup()
exten=> _XXXXXXXX,37,Set(dentroDeHora=1)
exten=> _XXXXXXXX,38,Goto(entrantes,${EXTEN},24)
exten=> h,1,Set(CDR(userfield)=${userfield})
Para Hardphones si se quiere autoanswer setera el SIP Header: P-Auto-Answer: normal
En El SIPAddHeader setear que Form o la URL que hay que desplegar al entrar una llamada .
Opción 1: uContact Form: Solo nombre del Form, Nombre del Form y | true (esto para desplegar la cruz del form y poder cerrarlo)
Ejemplos: Codigos | true
Codigos
exten=> _XXXXXXXX,34,SipAddHeader(CTI: {"Guid": "${guid}" , "Screen": "FALSE" , "Form": "Codigos" , "Campaign" : "Entrada" , "Callerid" : "${CALLERID(num)}" , "ParAndValues" : "par1=val1-par2=val2-par3=val3" , "Beep" : "TRUE" , "Answer" : "FALSE"})
exten=> _XXXXXXXX,34,SipAddHeader(CTI: {"Guid": "${guid}" , "Screen": "FALSE" , "Form": "Codigos | true" , "Campaign" : "Entrada" , "Callerid" : "${CALLERID(num)}" , "ParAndValues" : "par1=val1-par2=val2-par3=val3" , "Beep" : "TRUE" , "Answer" : "FALSE"})
Opcion 2: uContact URL: URL bien formada y | nombre a mostrar en Tab o URL bien formada | nombre del tab | true (esto para desplegar la cruz del form y poder cerrarlo)
Ejemplos: http://www.observador.com.uy | Observa
http://www.observador.com.uy | Observa | true
exten=> _XXXXXXXX,34,SipAddHeader(CTI: {"Guid": "${guid}" , "Screen": "FALSE" , "Form": " http://www.observador.com.uy | Observa" , "Campaign" : "Entrada" , "Callerid" : "${CALLERID(num)}" , "ParAndValues" : "par1=val1-par2=val2-par3=val3" , "Beep" : "TRUE" , "Answer" : "FALSE"})
exten=> _XXXXXXXX,34,SipAddHeader(CTI: {"Guid": "${guid}" , "Screen": "FALSE" , "Form": " http://www.observador.com.uy | Observa | true" , "Campaign" : "Entrada" , "Callerid" : "${CALLERID(num)}" , "ParAndValues" : "par1=val1-par2=val2-par3=val3" , "Beep" : "TRUE" , "Answer" : "FALSE"})
AVANZADAS
Ir primero a un agente
Setear en los agentes diferentes números de penalización
Setear en la campaña la estrategia wrandom
En el Workflow setear las variables con el mismo numero (el de la penalización del agente por el que se quiere comenzar), y en el wrokflow en la actividad de Queue setear la rule que se quiera o sea la que esta entre [] en el archivo queuerules.conf
QUEUE_MIN_PENALTY y QUEUE_MAX_PENALTY
En /etc/asterisk/queuerules.conf agregar una regla que después de X tiempo si no lo pudo contactar comience a saltar por los agentes disponibles.
[regla]
penaltychange => 30,+1000,-1000
Significa:
Después de 30 segundos, ajustar las variables QUEUE_MAX_PENALTY en +1000 y ajustar QUEUE_MIN_PENALTY en - 1000
esto hace que luego de este tiempo ya salte entre otros agentes.
ejemplo
exten=> _XXXXXX,1,Set(VOLUME(TX)=2)
exten=> _XXXXXX,2,Set(VOLUME(RX)=2)
exten=> _XXXXXX,3,Set(CHANNEL(Language)=es)
exten=> _XXXXXX,4,Set(__Ani=${CALLERID(num)})
exten=> _XXXXXX,5,Set(CDR(campaign)=CobrosG10->)
exten=> _XXXXXX,6,Answer(0)
exten=> _XXXXXX,7,Read(extension,MenuOpciones,4,,2,5)
exten=> _XXXXXX,8,Set(QUEUE_MAX_PENALTY=${extension:0:4})
exten=> _XXXXXX,9,Set(QUEUE_MIN_PENALTY=${extension:0:4})
exten=> _XXXXXX,10,Set(AUDIOHOOK_INHERIT(MixMonitor)=yes)
exten=> _XXXXXX,11,GotoIfTime(08:00-23:00,mon-fri,,?,${EXTEN},19)
exten=> _XXXXXX,12,GotoIfTime(08:00-12:00,sat-sat,,?,${EXTEN},16)
exten=> _XXXXXX,13,Playback(exceltecFuerahorario,)
exten=> _XXXXXX,14,VoiceMail(1000@voicemail,)
exten=> _XXXXXX,15,Hangup()
exten=> _XXXXXX,16,Set(CALLERID(num)=40322386)
exten=> _XXXXXX,17,Dial(SIP/tigo/25872587,60,tT,)
exten=> _XXXXXX,18,Hangup()
exten=> _XXXXXX,19,GUID(__guid)
exten=> _XXXXXX,20,Set(__idLlamada=${guid})
exten=> _XXXXXX,21,Set(CDR(guid)=${guid})
exten=> _XXXXXX,22,Set(CDR(type)=record)
exten=> _XXXXXX,23,Set(MONITOR_FILENAME=${guid})
exten=> _XXXXXX,24,Set(CALLERID(name)=Ventas_Inbbd_2)
exten=> _XXXXXX,25,Queue(Ventas_Inbbd_2<-,tTkK,,,400,,CTI,,regla,)
exten=> _XXXXXX,26,Hangup()