IVR Entries Report


(Itzik) #1

Hi guys,

Does anyone know of a solution (other than QueueMetrics*) that allows you to run reports against IVR entries?

Or, does anyone know of a way to easily log/grep IVR entries?

Thank you

(* We are using FOP2 and CC Stats, I am afraid that the QueueMetrics module will break FOP2/Asterisk CC Stats)


(TheJames) #2

@lgaetz had opened a ticket a while back where channel variables would be set or something.
I don’t recall the specifics. I don’t think it ever made it in to code. Some people wanted this functionality for things like surveys.


(Itzik) #3

If every selection would start with a Noop() which includes some information, for example:

exten => 1,1,Noop(Caller pressed 1 in IVR Foo)
exten => 1,n,; continue
exten => 2,1,Noop(Caller pressed 2 in IVR Foo)
exten => 2,n,; continue

That way we can easily come back later and grep the data.
But I’ll be honest, I’ve never done a pull request and not even sure what lines in the IVR module I’m looking at.

I hope to have time over the weekend and get my hands a lil dirty…


(Lorne Gaetz) #4

Use the Dynamic Routes module. With it you can store the caller DTMF selection to a channel var and the store that wherever you want with a hangup handler.


(Itzik) #5

Meaning, I should point each IVR option to a different DynRoute record?
(I’ve never used Dynamic Routes, I’ll install it tomorrow)


(Lorne Gaetz) #6

You can replace the IVR entirely with a dynroute.


#7

Three ways that spring to mind (I use the first):

  1. Set the destination of each option to a Set Caller ID and modify the cnam with something useful. Eg, Sales:${CALLERID(num)

This would then show up in the clid field.in the asteriskcdrdb. Do a count on the database, grouping by Linkedid to find the number of callers.

Advantage with this is you can let your agents know what type of call it is, sales, support etc etc.

  1. The other way I thought would be to set the destination to a custom bit of asterisk code with uses the userfield of the cdr. Again do your count ont he database grouping by Linkedid
    https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Function_CDR

  2. grep through the asterisk full files to see who pressed what!


(Itzik) #8

We’re already doing this for certain departments, but with the CID Name, not number. IMO it looks better to prepend to the CID name.

The problem is, that the CID is inherited across the call even when transferred to other destinations. Additionally, it’s being set from multiple places, not just IVRs, so it will definitely not be reliable.

That and technically your first option as well, means creating a record for each IVR entry, so with a system that has ~70 IVRs it’ll get messy very quick.

I asked above if anyone knows of a way to easily do that.

Thanks for responding


(Itzik) #9

Hi Lorne,

Trying DynRoutes for the first time.

It seems like there is a bug that it sets the DTMF input in a variable ‘dtmfinput’ but then checks the ‘dynroutes’ variable as if that would contain the DTMF responses.

yptest*CLI> dialplan show s@dynroute-1
[ Context 'dynroute-1' created by 'pbx_config' ]
  's' =>            1. Set(__DYNROUTE_RETRIES=0)                  [extensions_additional.conf:1555]
                    2. Read(dtmfinput,custom/01429291,1,,,5) [extensions_additional.conf:1556]
                    3. Set(__DYNROUTE_IVR1_Input=${dtmfinput})    [extensions_additional.conf:1557]
                    4. GotoIf($["${dynroute}" = "1"]?from-did-direct,101,1) [extensions_additional.conf:1558]
                    5. GotoIf($["${dynroute}" = "2"]?from-did-direct,102,1) [extensions_additional.conf:1559]
                    6. Goto(dynroute-1,1,1)                       [extensions_additional.conf:1560]

image
image

What am I missing?


(Lorne Gaetz) #10

Hey Pitzkey, only just seeing into this now. You are missing the config for the Source Type. So you have the DTMF input assigned to variable IVR_Input, if you read the tool tip for Saved Input variable name, you will see the input string will be saved to a Channel variable named, DYNROUTE_IVR_Input. To branch the call based on that value, you need to select Source type of Asterisk variable and use ${DYNROUTE_IVR_Input} in the var field. The resulting diaplan will look a bit different.

You’ve also configured a Saved result variable name which is not necessary for this use case.


(Ian Plain) #11

We do this in asternic light and our own port of it.

We do this by echoing an entry to the queue log drop me a line if you want details. Was east to setup and means you can run a report in your favourite cc reports package.


(Lorne Gaetz) #12

Why not share here for the benefit of everyone? You’re free to do whatever you want of course, but it’s not unusual for future users to see offers like this years later, long after the forum user has moved on.

If it’s a case where your method is overly complex, or if you fear you’re hijacking the thread, you can create a wiki page in the Community Documentation project, or start a new thread and link back here, whatever works best.


(Ian Plain) #13

Hi

Im happy to post here, It have put it out for anyone to use in the past, The method is very simple and works well and has been used with Hotel IVRS and customer satisfaction surveys.

at the moment its all a bit manic getting customers ready for christmas lockdowns that are changing day by day here in the UK. Ill dig the dialplan and post as soon as I can


(Ian Plain) #14

Here is the dialplan we use , its all added to the extensions_override_freepbx.conf but could be split over overide and custom conf files but prefered to keep in the same place for simplicities sake. Im sure it can be improved upon but it does its job.

    [ivr-track]
exten => s,1,Noop(Lets Build our IVR trail ${IVR_trail})
same => n,GotoIf($["${IVR_trail}"=""]?new:again)
same => n(new),Set(__IVR_trail=${IVR_CONTEXT}-Opt-${ARG1})
same => n,Goto(setting)
same => n(again),Set(__IVR_trail=${IVR_trail}->-${IVR_CONTEXT}-Opt-${ARG1})
same => n(setting),Set(CDR(userfield)=${IVR_trail})

same => n,QueueLog(${IVR_CONTEXT},${UNIQUEID},NONE,ENTERQUEUE,|option|${ARG1})
same => n,QueueLog(${IVR_CONTEXT},${UNIQUEID},option${ARG1},CONNECT,0|${UNIQUEID}|0)
same => n,QueueLog(${IVR_CONTEXT},${UNIQUEID},option${ARG1},COMPLETEAGENT,0|0|0)
;same => n,QueueLog(${IVR_CONTEXT},${UNIQUEID},NONE,INFO,IVR|${ARG1})
same => n,Set(__ivrreturn=0)
same => n,Return()

[ivr-3]
exten => 1,1,Gosub(ivr-track,s,1(${EXTEN}))
exten => 2,1,Gosub(ivr-track,s,1(${EXTEN}))
exten => 3,1,Gosub(ivr-track,s,1(${EXTEN}))
exten => 4,1,Gosub(ivr-track,s,1(${EXTEN}))

Revisting IVR -> Script
(Itzik) #15

Hey Ian,

I can’t thank you enough! This is genius!!!

I made a little change to the ivr-track which eliminates 3 lines

[ivr-track]
exten => s,1,Noop(Building IVR Trail for CDR ${IVR_trail})
exten => s,n,Set(__IVR_trail=${IF($["empty${IVR_trail}"="empty"]?${IVR_CONTEXT}-Opt-${ARG1}:${IVR_trail}->-${IVR_CONTEXT}-Opt-${ARG1})})
exten => s,n,Set(CDR(userfield)=${IVR_trail})
exten => s,n,QueueLog(${IVR_CONTEXT},${UNIQUEID},NONE,ENTERQUEUE,|option|${ARG1})
exten => s,n,QueueLog(${IVR_CONTEXT},${UNIQUEID},option${ARG1},CONNECT,0|${UNIQUEID}|0)
exten => s,n,QueueLog(${IVR_CONTEXT},${UNIQUEID},option${ARG1},COMPLETEAGENT,0|0|0)
exten => s,n,Set(__ivrreturn=0)
exten => s,n,Return()

The only downside is, that you manually have to set each IVR option in the override conf file. A wish we could do something like:

[ivr-1]
exten => _[0-9],1,Gosub(ivr-track,s,1(${EXTEN}))

But I guess we can’t do it at this time… which is quite annoying, because everytime we add an IVR option we need to remember to add it to the override conf file as well.

Maybe someone else has a solution for that.

Thank you again


(Ian Plain) #16

No worries, IVR track if you are interested tracked calls through multiple levels giving the flow, it was for a customer satisfaction system we built for an electricity supply company,


(Ian Plain) #17

you could use a prereload script I guess but its not too much of an issue to code manually