Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

...

...

...

...

...

Table of Contents

...

Salientes

Desde Agente con

...

hardphone

Code Block
languagedelphi
${OUTGUID}:   

...

GUID de la llamada que 

...

se genera.
${OUTAGENT}:  Nombre del agente que realiza la llamada.

...

${OUTQUEUE}:  Nombre de la 

...

campaña por la que sale la llamada.

...

${OUTDID}:    DID 

...

número callerid para usar al salir, corresponde al de la 

...

campaña. 
${OUDIDALED}: 

...

Número marcado.

...

Con

...

teléfono Webrtc

La llamada no se hace en 2 pasos sino directo y el se realiza directamente. El nombre de la colacampaña, guid GUID y did pueden obtenerse de DID se pueden obtener desde un SIP Header, el resto de las variables son obtenidas directamente de desde donde corresponden:.

Code Block
languagedelphi
${SIP_HEADER(OUTGUID)}:   

...

GUID de la llamada

...

 que se genera.
${CDR(accountcode)}:      Nombre del agente que realiza la llamada.
${SIP_HEADER(OUTQUEUE)}:  Nombre

...

 de la campaña.
${SIP_HEADER(OUTDID)}:    DID 

...

número callerid para usar al salir corresponde al de la 

...

campaña.
${EXTEN}:                 

...

Número marcado.

...


Ejemplo

...

completo de 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.

Code Block
languagedelphi

...

...

exten=> _9XXXXXXX.,1,Set(VOLUME(TX)=2)
exten=> _9XXXXXXX.,2,Set(VOLUME(RX)=2)
exten=> _9XXXXXXX.,3,GotoIf($[${EXTEN:0:3}= 900]?62:4)
exten=> _9XXXXXXX.,4,GotoIf($["${OUTQUEUE}"= ""]?47:5)
exten=> _9XXXXXXX.,5,Set(__OUTQUEUE=${OUTQUEUE})
exten=> _9XXXXXXX.,6,Set(__DIALED=${OUTDIALED})
exten=> _9XXXXXXX.,7,Set(__AGENT=${OUTAGENT})
exten=> _9XXXXXXX.,8,Set(CALLERID(num)=${OUTDID})
exten=> _9XXXXXXX.,9,Set(CALLERID(name-pres)=allowed_passed_screen)
exten=> _9XXXXXXX.,10,Set(HASH(Result)=${ODBC_Data(select did\,name\,dialstring from queues where name in (select queue_name from queue_members where membername =  '${CHANNEL(accountcode)}')  and direction = 'Outbound' and name ='${OUTQUEUE}')})
exten=> _9XXXXXXX.,11,Set(CALLERID(name)=${OUTQUEUE})
exten=> _9XXXXXXX.,12,Set(event=${ODBC_Data(select event from queue_log where agent = '${AGENT}' and queuename= '${OUTQUEUE}'  and event in ('PAUSE', 'UNPAUSE') ORDER BY id DESC LIMIT 1)})
exten=> _9XXXXXXX.,13,GotoIf($["${event}" = "PAUSE"]?45:14)
exten=> _9XXXXXXX.,14,GotoIf($["${OUTGUID}" = ""]?40:15)
exten=> _9XXXXXXX.,15,Set(__guid=${OUTGUID})
exten=> _9XXXXXXX.,16,Set(CDR(guid)=${guid})
exten=> _9XXXXXXX.,17,Set(CDR(type)=record)
exten=> _9XXXXXXX.,18,MixMonitor(${guid}.gsm,b,)
exten=> _9XXXXXXX.,19,Set(CDR(campaign)=${OUTQUEUE})
exten=> _9XXXXXXX.,20,Set(CHANNEL(accountcode)=${AGENT})
exten=> _9XXXXXXX.,21,Set(__idLlamada=${guid})
exten=> _9XXXXXXX.,22,Set(__REALDIALED=${EXTEN:1})
exten=> _9XXXXXXX.,23,Set(existeNum=${ODBC_Data(SELECT COUNT(*) FROM black_list WHERE (campaign like '${OUTQUEUE}%' || campaign ='*') AND phone ='${EXTEN}')})
exten=> _9XXXXXXX.,24,GotoIf($["${existeNum}"!= "0"]?37:25)
exten=> _9XXXXXXX.,25,Dial(${HASH(Result,dialstring)}/${EXTEN:1},180,TKkc,)
exten=> _9XXXXXXX.,26,Set(CDR(causecode)=${HANGUPCAUSE})
exten=> _9XXXXXXX.,27,NoOp(${DIALSTATUS} - ${HANGUPCAUSE})
exten=> _9XXXXXXX.,28,GotoIf($["${DIALSTATUS}" = "BUSY"]?35:29)
exten=> _9XXXXXXX.,29,GotoIf($["${DIALSTATUS}" = "CONGESTION"]?35:30)
exten=> _9XXXXXXX.,30,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL"]?33:31)
exten=> _9XXXXXXX.,31,GotoIf($["${DIALSTATUS}" = "CANCEL"]?33:32)
exten=> _9XXXXXXX.,32,Hangup()
exten=> _9XXXXXXX.,33,Playback(outofservice,)
exten=> _9XXXXXXX.,34,Goto(agentes,${EXTEN},32)
exten=> _9XXXXXXX.,35,Playback(busy,)
exten=> _9XXXXXXX.,36,Goto(agentes,${EXTEN},32)
exten=> _9XXXXXXX.,37,Set(dummy=${ODBC_Repo(INSERT INTO black_list_history(calldate\,src\,dst) VALUES (now()\,'${AGENT}'\,'${EXTEN}'))})
exten=> _9XXXXXXX.,38,Playback(DNCRaudio,)
exten=> _9XXXXXXX.,39,Goto(agentes,${EXTEN},32)
exten=> _9XXXXXXX.,40,GotoIf($["${SIP_HEADER(OUTGUID)}" = ""]?43:41)
exten=> _9XXXXXXX.,41,Set(__guid=${SIP_HEADER(OUTGUID)})
exten=> _9XXXXXXX.,42,Goto(agentes,${EXTEN},16)
exten=> _9XXXXXXX.,43,GUID(__guid)
exten=> _9XXXXXXX.,44,Goto(agentes,${EXTEN},16)
exten=> _9XXXXXXX.,45,Playback(pausaerror,)
exten=> _9XXXXXXX.,46,Hangup()
exten=> _9XXXXXXX.,47,GotoIf($[$["${SIP_HEADER(OUTQUEUE)}"= ""]|$["${SIP_HEADER(OUTQUEUE)}"= "null"]]?53:48)
exten=> _9XXXXXXX.,48,Set(__AGENT=${CHANNEL(accountcode)})
exten=> _9XXXXXXX.,49,Set(__DIALED=${EXTEN})
exten=> _9XXXXXXX.,50,Set(__OUTQUEUE=${SIP_HEADER(OUTQUEUE)})
exten=> _9XXXXXXX.,51,Set(CALLERID(num)=${SIP_HEADER(OUTDID)})
exten=> _9XXXXXXX.,52,Goto(agentes,${EXTEN},9)
exten=> _9XXXXXXX.,53,Set(HASH(Result)=${ODBC_Data(select did\,name\,dialstring from queues where name in (select queue_name from queue_members where membername =  '${CHANNEL(accountcode)}')  and direction = 'Outbound')})
exten=> _9XXXXXXX.,54,GotoIf($["${HASH(Result,name)}"= ""]?60:55)
exten=> _9XXXXXXX.,55,Set(__AGENT=${CHANNEL(accountcode)})
exten=> _9XXXXXXX.,56,Set(__DIALED=${EXTEN})
exten=> _9XXXXXXX.,57,Set(__OUTQUEUE=${HASH(Result,name)})
exten=> _9XXXXXXX.,58,Set(CALLERID(num)=${HASH(Result,did)})
exten=> _9XXXXXXX.,59,Goto(agentes,${EXTEN},9)
exten=> _9XXXXXXX.,60,Background(llamadasincola,,,)
exten=> _9XXXXXXX.,61,Hangup()
exten=> _9XXXXXXX.,62,Set(inter-var=${DB(${CALLERID(num)}/INTER)})
exten=> _9XXXXXXX.,63,GotoIf($["${inter-var}" = "TRUE"]?4:64)
exten=> _9XXXXXXX.,64,Playback(disabled-INTER,)
exten=> _9XXXXXXX.,65,Hangup()

exten=> h,1,Set(HASH(rates)=${ODBC_Data(select  rates.gateway\, rates.rate\, rates.cost\, rates.note FROM rates LEFT JOIN provider ON provider.name=rates.gateway WHERE provider.status = 'true' AND substring( '${EXTEN}'\, 1\, length( prefix_regexp ) ) REGEXP prefix_regexp ORDER BY length(prefix_regexp) DESC\,rates.rate ASC)})
exten=> h,2,Set(talkedminutes=${MATH(${CDR(billsec)} / 60,f)})
exten=> h,3,Set(talkedminutes=$[CEIL(${talkedminutes})])
exten=> h,4,Set(chargedbalance=${MATH(${talkedminutes} * ${HASH(rates,rate)},f)})
exten=> h,5,Set(realbalance=${MATH(${talkedminutes} * ${HASH(rates,cost)},f)})
exten=> h,6,Set(CDR(charged_balance)=${chargedbalance})
exten=> h,7,Set(CDR(real_balance)=${realbalance})
exten=> h,8,Set(CDR(note)=${HASH(rates,note)})
exten=> h,9,Set(CDR(carrier)=${HASH(rates,gateway)})
exten=> h,10,Set(CDR(userfield)=${userfield})
exten=> h,11,Set(CDR(direction)=outgoing)
exten=> h,12,Set(CDR(causecode)=${HANGUPCAUSE})
exten=> h,13,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 clic 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.

...

Ya no usamos mas MACRO para pasar datos de CTI sino SIP HEADER, esta se persiste durante toda la llamada lo cual debería si es una transferencia tambien pasar los datos, también es posible eliminar el HEADER.

Ejemplo:

Code Block
languagedelphi

...

...

exten=> _XXXXXXXX,1,Set(HASH(queue)=${ODBC_Data(SELECT welcome\, schedule \, name \, form \, interactions FROM queues WHERE did= '${EXTEN}' AND direction = 'inbound')})
exten=> _XXXXXXXX,2,Set(CHANNEL(Language)=es)
exten=> _XXXXXXXX,3,Set(__Ani=${CALLERID(num)})
exten=> _XXXXXXXX,4,Set(CDR(campaign)=${HASH(queue,name)})
exten=> _XXXXXXXX,5,Answer(0)
exten=> _XXXXXXXX,6,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,7,GotoIf($["${sound}"=""]?11:8)
exten=> _XXXXXXXX,8,Playback(${sound},)
exten=> _XXXXXXXX,9,VoiceMail(1000@voicemail,)
exten=> _XXXXXXXX,10,Hangup()
exten=> _XXXXXXXX,11,Set(__DID=${EXTEN})
exten=> _XXXXXXXX,12,Set(__VirtualHold=${HASH(queue,interactions)})
exten=> _XXXXXXXX,13,Set(welcome=${HASH(queue,welcome)})
exten=> _XXXXXXXX,14,Set(Bienvenida=${CUT(welcome,\;,1)})
exten=> _XXXXXXXX,15,Set(FueraDeHora=${CUT(welcome,\;,2)})
exten=> _XXXXXXXX,16,Set(schedule=${HASH(queue,schedule)})
exten=> _XXXXXXXX,17,Set(cantidad=${FIELDQTY(schedule,&)})
exten=> _XXXXXXXX,18,Set(dentroDeHora=0)
exten=> _XXXXXXXX,19,While($[${cantidad} >0 && ${dentroDeHora} = 0])
exten=> _XXXXXXXX,20,Set(date=${CUT(schedule,\&,${cantidad})})
exten=> _XXXXXXXX,21,Set(hourrange=${CUT(date,\;,2)})
exten=> _XXXXXXXX,22,Set(dayrange=${CUT(date,\;,1)})
exten=> _XXXXXXXX,23,Set(cantidad=${MATH(${cantidad} - 1,i)})
exten=> _XXXXXXXX,24,GotoIfTime(${hourrange},${dayrange},,?,${EXTEN},42)
exten=> _XXXXXXXX,25,EndWhile()
exten=> _XXXXXXXX,26,GotoIf($[${dentroDeHora}=1]?29:27)
exten=> _XXXXXXXX,27,Playback(${FueraDeHora},)
exten=> _XXXXXXXX,28,Goto(entrantes,${EXTEN},9)
exten=> _XXXXXXXX,29,Playback(${Bienvenida},)
exten=> _XXXXXXXX,30,GUID(__guid)
exten=> _XXXXXXXX,31,Set(CDR(guid)=${guid})
exten=> _XXXXXXXX,32,Set(CDR(type)=record)
exten=> _XXXXXXXX,33,Set(MONITOR_FILENAME=${guid})
exten=> _XXXXXXXX,34,Set(CALLERID(name)=${HASH(queue,name)})
exten=> _XXXXXXXX,35,SipAddHeader(CTI: {"Guid": "${guid}" , "Screen": "FALSE" , "Form": "${HASH(queue,form)}" , "Campaign" : "${CDR(campaign)}" , "Callerid" : "${CALLERID(num)}" , "ParAndValues" : "par1=val1:par2=val2:par3=val3" , "Beep" : "FALSE" , "Answer" : "FALSE"})
exten=> _XXXXXXXX,36,SipAddHeader(VIDEO : ${SIP_HEADER(VIDEO)})
exten=> _XXXXXXXX,37,Queue(${CDR(campaign)},tTkKc,,,600,,,,,)
exten=> _XXXXXXXX,38,Read(__customerfeedback,feedback,2,,2,10)
exten=> _XXXXXXXX,39,GotoIf($["${customerfeedback}"=""]?41:40)
exten=> _XXXXXXXX,40,Set(customerfeedback=${ODBC_Repo(INSERT INTO customer_feedback(`datetime`\,agent\,campaign\,guid\,interaction\,qualification\,comment\,`from`) VALUES (NOW()\,'${CDR(accountcode)}'\,'${CDR(campaign)}'\,'${guid}'\,'call'\,'${customerfeedback}'\,''\,'${CALLERID(num)}'))})
exten=> _XXXXXXXX,41,Hangup()
exten=> _XXXXXXXX,42,Set(dentroDeHora=1)
exten=> _XXXXXXXX,43,Goto(entrantes,${EXTEN},25)



exten=> h,1,Set(CHANNEL(accountcode)=${MEMBERNAME})
exten=> h,2,Set(CDR(userfield)=${userfield})
exten=> h,3,Set(CDR(direction)=incoming)
exten=> h,4,Set(CDR(causecode)=${HANGUPCAUSE})
exten=> h,5,NoOp()
exten=> h,6,GotoIf($["${customerfeedback}"=""]?8:7)
exten=> h,7,Set(dummy=${ODBC_Repo(UPDATE customer_feedback set agent = '${CDR(accountcode)}' WHERE guid = '${guid}')})
exten=> h,8,GotoIf($["${ABANDONED}" == "TRUE" & "${VirtualHold}" == "VirtualHold" ]?10:9)
exten=> h,9,Hangup()
exten=> h,10,VirtualHold(Local/${CDR(campaign)}@virtualhold/n,${UNIQUEID},virtualhold,${Ani},1,${CDR(campaign)},)
exten=> h,11,Goto(entrantes,${EXTEN},9)


Para Hardphones si se quiere autoanswer setera el SIP Header: P-Auto-Answer: normal.

...

                 Codigos | true


Code Block
languagedelphi

...

exten=> _XXXXXXXX,34,SipAddHeader(CTI: {"Guid": "${guid}" , "Screen": "FALSE" , "Form": "Codigos" , "Campaign" : "${CDR(campaign)}" , "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" : "${CDR(campaign)}" , "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


Code Block
languagedelphi

...

exten=> _XXXXXXXX,34,SipAddHeader(CTI: {"Guid": "${guid}" , "Screen": "FALSE" , "Form": " http://www.observador.com.uy | Observa" , "Campaign" : "${CDR(campaign)}" , "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" : "${CDR(campaign)}" , "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. (numero de teléfono del agente)

  •  Setear  Setear en la campaña la estrategia wrandom.

  •  En  En el Workflow setear las variables con el mismo número (el de la penalización del agente por el que se quiere comenzar), y en el workflow en la actividad de Queue setear la regla que se quiera o sea la que esta entre [] en el archivo queuerules.conf conf .


    Code Block
    languagedelphi
    theme
    Midnight
    QUEUE_MIN_PENALTY y QUEUE_MAX_PENALTY 


  • En /etc/asterisk/queuerules.conf agregar una regla

    que después de

    que después de X tiempo si no lo pudo contactar comience a saltar por los agentes disponibles.


Code Block
languagedelphi

...

[regla]
penaltychange => 30,+1000,-1000


Significa: 

Code Block
Después de 30 segundos, ajustar las variables QUEUE_MAX_PENALTY en +1000 y ajustar QUEUE_MIN_PENALTY en - 1000
Code Block
esto hace que luego de este tiempo ya salte entre otros agentes.



Ejemplo


Code Block
languagedelphithemeMidnight
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()

...