Freepbx Survey

If is it posible to send the automatically to ivr then give them option to take a survey press 1 or just hangup

Thank you.

i’ll code something up tomorrow and post something for you to try

Thank you so much

Here’s a demo, let me know if this is what you are looking for? If so I’ll build in some more logic checks around wrong answers.
Again, this code atm is DEMO for you to try out and see if it will do what you want:

What this does:
When activated, it will ask a question, then allow the user to place an answer. This demo asks 2 questions.
Once the caller answers the questions and hangs up, the values entered are written to the “USERFIELD” in the CDR table.

You can go to the CDR module in freepbx and see the values for each caller in this database.

Some code around the values entered to make sure they are in range IE 1-3 valid, but user enter 5
Having it automatically triggered at end of agent call.

create your ‘questions’ in system recordings. I called mine “question1” and “question2”
Create a thank you message. My file was saved as “thankyouforyourtime”.

open up /etc/asterisk/extensions_custom.conf
Go to the bottom of the file, paste in the following: (noted the portion /custom/questionX the last bit is your file name, so if you saved them differently, you’ll need to update the filename name in the code)

exten => s,1,answer()

;this asks the first question (based on your recording) and stores them in variable
exten => s,n(question1),Read(answer1,/var/lib/asterisk/sounds/en/custom/question1,1,,1,2)
exten => s,n,GotoIf($[ ${answer1} < 4 ]?question2:question1)

;this asks the first question (based on your recording) and stores them in variable
exten => s,n(question2),Read(answer2,/var/lib/asterisk/sounds/en/custom/question2,1,,1,2)
exten => s,n,GotoIf($[ ${answer2} < 4 ]?finish:question1)

;this line puts the two answers together and separates them with a | symbol.
exten => s,n(finish),set(answer=${answer1}|${answer2})

;this saves the answers into the CDR field of "userfield"
exten => s,n,Set(CDR(userfield)=${answer})

;This line will send an email with the subject saying "Survey John Smith 555-123-4455 3|2"
exten => s,n,system(mail -s "Survey ${CALLERID(name)} ${CALLERID(number)} ${answer}" [email protected] < /dev/null)

;play a thankyou message.  you can just remove this line for anyone who doesn't want the thankyou.
exten => s,n,playback(/var/lib/asterisk/sounds/en/custom/thankyouforyourtime)

exten => s,n,hangup() 

SAVE changes

In FreePBX goto CUSTOM DESTINATIONS and create a new custom destination
TARGET= macro-survey,s,1
Description=enter something so you know what this dos. “queuesurvey” for example

Save Changes

Create a ring group number
(we’ll use a ring group failover destination as a way to trigger this code)
Extension list = put in a dummy number that doesnt’ exist in your pbx. I usually put in “1”.
go down to “Destination if no answer” and select CUSTOM DESTINATION -> queuesurvey

save your changes and apply them with the red button.

Call your ring group.
You should hear your first question. Press “2”
You should now hear your second question, Press “3”
Call will hang up

Go to CDR reports and run a report (usually can just hit SEARCH) and it will show the most recent calls. You should see your call, and in “USERFIELD” you’ll see “2|3”

2 is the first answer, “|” (pipe) is a delimiter, and 3 is the second answer.

1 Like

Hi Dickson, thank you so much I will give a try and I will let you know how it worked and again thank you so much

Hi Dickson,
I did test it and it did worked good i have the output to CDR
Hangup s [macro-survey] ANSWERED 00:20 1|3
I have 2 question.
1 I would like when the question 2 is answered to go and read thank you recording saying " thank you for participation on the survey goodbye" then hangup.

2 how i would know for which Agent was this survey entered
I have 2 queues with 3 to 5 agents per each queue if I’m a costumer and i spoke to agent A and I take the survey how i know what survey was for Agent A

Thank you For your help

Also, is there a possibility to email the results?

I added a line in the code example above for the “thankyou” message.
just record a file and call it “thankyouforyourtime”. give it a test.

Insert the “playback” line below in between the existing lines show below.

exten => s,n,Set(CDR(userfield)=${answer})

;play a thank you message.  you can just remove this line for anyone who doesn't want the thank you.
exten => s,n,playback(/var/lib/asterisk/sounds/en/custom/thankyouforyourtime)

exten => s,n,hangup()

Save your changes and from the CLI type in

asterisk -rx 'core reload’

I’ll work on the agent bit now


Add the line in the box below under neath the code in bold to get the system to send an email after the entry.
exten => s,n,Set(CDR(userfield)=${answer})

;This line will send an email with the subject saying "Survey John Smith 555-123-4455 3|2"
exten => s,n,system(mail -s "Survey ${CALLERID(name)} ${CALLERID(number)} ${answer}" [email protected] < /dev/null)

The code in my original post has been updated with these above entries if you just want to copy/paste the whole thing again.


Thank you Dickson that worked i did a test works grate thank you.

Dear Dickson.

It’s so touching to see your effort to help with this important project.

Just a little thing, please:
I get the idea of demo testing using the ring-group failover option.
But in real life - my big difficulty is how to automatically forward the customer to this destination when the agent hang-up.
I think the main issue here is how to catch the call before hang-up after the destination cannel is not there already.

Would you please clarify or demonstrate this?

Many thanks for this!

Queues Pro has an option for this. Caller post hang up destination.

Agent post hangup. If the caller hangs up you have no way of playing anything…

1 Like

As far as I understand, until now, the discussion was about solution that will not require a commercial module.

Is there an option to keep it that way?


Sorry, I should have given an update on this.
I’m working on the automatic survey right now. I got it to the point where i’ve intercepted the hangup, and can differentiate between the agent and caller, just can’t stop the caller from disconnecting.
I did code for something like this back in the Trixbox days, sadly most of their forum branches where I think I posted this are no longer available. Having to re-invent the wheel.

1 Like

Actually the field in FreePBX is called " Caller Post Hangup Destination"

Destination to send the caller to upon the agen hanging up the call

The other field is called “Agent Post Hangup Destination”

That field has to do with where to send the agent after a caller hangs up.

1 Like

I use Queue option c

c - Continue in the dialplan if the callee hangs up.

1 Like

@comtech I believe Caller Post Hangup Destination is a queue plus module though. The group asking don’t have it available. The “C” is the path i’ve been testing.

C - Mark all calls as “answered elsewhere” when cancelled.
c - Continue in the dialplan if the callee hangs up.

c is different of C

An example of queue

exten => 300,n(qcall),Queue(300,${QOPTIONS}c,${QAANNOUNCE},${QMAXWAIT},${QAGI},${QGOSUB},${QRULE},${QPOSITION})
exten => 300,n,Macro(blkvm-clr,)
exten => 300,n,Gosub(sub-record-cancel,s,1())
exten => 300,n,Set(__NODEST=)
exten => 300,n,Set(_QUEUE_PRIO=0)
exten => 300,n,Set(QDEST=${VQ_DEST})
exten => 300,n,Set(VQ_DEST=)
exten => 300,n(gotodest),GotoIf($["${QDEST}"=""]?survey,s,1:${CUT(QDEST,^,1)},${CUT(QDEST,^,2)},${CUT(QDEST,^,3)})

Try to create a queue with Fail Over Destination surveys, s, 1 copy the code from extensions_additional and make changes to extensiions_overryde.conf

@jersonjunior hit the nail on the head exactly the code change.

The ‘small c’ will allow the dialplan to continue on when the agent hangs up (vs triggering a hangup of both agent and caller).
Then it will automatically call the script and the caller into your queue will hear it and be able to respond.

We are copying the QUEUE code into the override file. Here is the caveat to this that you will need to remember for this particular code change.
ANY Changes that you need to make to the queues via the GUI will have NO effect on the queue’s behavior. Since we are using the override file. What this means is if you need to make changes to the queue, you will need to perform the steps below for those changes to take effect in your production PBX as well as allow the automatic message to play. Without doing it, you will make changes, but asterisk will continue with the code that is in the override file, ignoring the changes.
Its the price of free.


Open up extensions_addition.conf

Go [ext-queues] and copy everything from [ext-queues] all the way to ;–== end of [ext-queues] ==–;

include => ext-queues-custom
exten => 8860,1,Macro(user-callerid,)
exten => 8860,n,Answer
bla bla bla
bla bla bla
exten => 8860,n,Set(VQ_DEST=)
exten => 8860,n,Dial(Local/554@from-internal/n,)
exten => 8860,n(gotodest),GotoIf($["${QDEST}"=""]?app- 

exten => 8860*,1,Macro(agent-add,8860,) 

exten => 8860**,1,Macro(agent-del,8860)

exten => h,1,Macro(hangupcall,)

;--== end of [ext-queues] ==--;

Copy this into “extensions_override_freepbx.conf”

Now you will need to modify two lines in the override file.

1> For the section that reflects your queue (in my example my queue is 8860) that will look basically like this (just remember yours will reflect the number that you have assigned to your queue)

exten => 8860,n(qcall),Queue(8860,${QOPTIONS},,${QAANNOUNCE},${QMAXWAIT},${QAGI},,${QGOSUB},${QRULE},${QPOSITION})

The change you will make is

exten => 8860,n(qcall),Queue(8860,${QOPTIONS}c,,${QAANNOUNCE},${QMAXWAIT},${QAGI},,${QGOSUB},${QRULE},${QPOSITION})

specfically you will add a “c” (lower case) right after QOPTIONS and before the first “,” comma mark


Now, scroll down about 5 or so lines and you’ll see this:

exten => 8860,n,Set(VQ_DEST=)
exten => 8860,n(gotodest),GotoIf($["${QDEST}"=""]?app blackhole,hangup,1:${CUT(QDEST,^,1)},${CUT(QDEST,^,2)},${CUT(QDEST,^,3)})

Now between these lines insert the following line, except modify the XXXX value to be the number you dial to test your script with.

exten => 8860,n,Set(VQ_DEST=)
exten => 8860,n,Dial(Local/XXXX@from-internal/n,)
exten => 8860,n(gotodest),GotoIf($["${QDEST}"=""]?app blackhole,hangup,1:${CUT(QDEST,^,1)},${CUT(QDEST,^,2)},${CUT(QDEST,^,3)})

Now save your changes

from command line type in asterisk -rx 'core reload’


To backout this code if there is a problem that is affecting a production system, it the extensions_override_freepbx.conf file, change the heading [ext-queues] to [ext-queues-bypass]
save that change
then in the cli type in

asterisk -rx 'core reload’

This will revert the pbx back to the original code.

You can then identify the changes, remove the -bypass
save/reload the script and test.

1 Like

I can’t find a file named extensions_addition.conf. I did however find one named extensions_additional.conf, but when I open that and search for ext-queues I only get a line that says “include => ext-queues”. Any help?