In this guide, we will look at creating interactive surveys for capturing customer feedback. You can capture DTMF key responses as well as audio recordings from your callers and email them for further review. DTMF key responses are also stored in the CDR userfield allowing for easy statistics collection.
There are two ways to get a Caller to the survey at the conclusion of a call:
If you have paid for the Queues Pro/VQ Plus commercial module license from Sangoma, there is an option on the Queues Plus tab for automatically passing Callers to a Caller Post Hangup Destination
If you do NOT have the Queues Pro/VQ Plus license, your Agents can manually transfer Callers using the Asterisk in-call Blind Transfer feature code ## followed by the Misc Application number you'll create below and an ending # to send the Caller (the Agent dialed digits will NOT be heard by the Caller), which can be readily programmed as a Speeddial button on endpoints. Ex: ##7878# [##SURV#]
Requisites:
Plan out your desired questions and possible answers! You can ask yes(1)/no(2), rate (1-5), or any other numerical questions and ask that the caller record a message. Get creative!
Create audio recordings of your questions in standard wav format and upload via Admin > System Recordings
If you'd rather not record these in your own voice, use AWS Polly to record them for you: https://console.aws.amazon.com/polly/home/SynthesizeSpeech
Audio recording of a thank you/goodbye message to be played at the end of the survey, also uploaded via System Recordings
Getting Started:
First, you'll need to construct your survey dialplan macro in the extensions_custom.conf Asterisk config file. You can easily edit the file from the GUI via Admin > Config Edit and selecting the extensions_custom.conf file in the file list on the left panel.
If you have other custom dialplan contexts in this file already, don't fret. Just scroll to the bottom, add a few blanks lines (press Enter), then start adding this new context. This first part will be the same for all survey macros:
;----------- MACRO SURVEY ----------
[macro-survey]
; Answer the channel (in case of blind transfer)
exten => s,1,answer()
If you want to create multiple different surveys, just append macro-survey with a unique -1, -2, etc for each one.
Now we can ask our questions. There are several types of questions we can ask, but we'll start with the most common and easiest type.
Basic Single Digit Response Questions:
This question type accepts a simple single DTMF digit response and moves on. It contains 3 lines:
exten => s,n,Read(answer,/var/lib/asterisk/sounds/en/custom/question1,1,,1,3)
In the first line, we play the question audio file question1 (note the lack of an extension/.wav here!!!), wait for a single digit to be pressed (the first 1), and timeout 3 seconds after the audio has played or the last digit was keyed. Remember to change your language code (en) if you aren't using the default English.
exten => s,n,GotoIf($[ ${answer} <= 2 ]?:$[${PRIORITY}-1])
In the second line, we check if the answer is within range. In this example, if the response is greater than 2 (<= 2), we repeat the question; meaning that 0, 1, and 2 are all acceptable responses. You could specify other acceptable answers here like <= 5 for a rate 1-5.
exten => s,n,set(answers=${answers}|${answer})
The third line is standard for most questions, as it appends the current answer (if acceptable per the second line) to the string of answers, which are pipe | delimited.
Here's the complete question block:
exten => s,n,Read(answer,/var/lib/asterisk/sounds/en/custom/question1,1,,1,3)
exten => s,n,GotoIf($[ ${answer} <= 2 ]?:$[${PRIORITY}-1])
exten => s,n,set(answers=${answers}|${answer})
You can repeat this block as many times as you want, ensuring you change at least the question1 audio file for each block and never include the file extension. Each answer will be appended to the full answers string before moving onto the next question.
We'll cover some additional question types, including recording Caller feedback, at the end of this guide. For now, let's end our survey, record our answers to the CDR userfield, and send an email with the results.
These next two lines won't change and are what save the answers to the CDR; the first of which just adds a trailing pipe to end the answers string the same way it began ("|1|2|3|"):
exten => s,n,set(answers=${answers}|)
exten => s,n,Set(CDR(userfield)=${CDR(userfield)}${answers})
Note: We preserve anything that was already contained in the CDR userfield (pincode, etc) and simply append the answers to the survey
This next line is optional, but most want notification by email when a survey is submitted by a customer. It's long and all one line, so be sure to copy the entire thing:
exten => s,n,System(echo 'Survey was submitted by: ${CALLERID(name)} ${CALLERID(number)}\nTheir selections: ${answers}' | mail -s 'SURVEY SUBMISSION' 'email@company.com')
Here's a breakdown:
The text between the single quotes is the body of the email
In this example, we have included the CallerID Name and CallerID Number Asterisk variables of the Caller for easy identification. You can see a complete collection of Asterisk variables here:
Of course, you'll also want to include the ${answers} from the survey.
You can use \n (new line) and other common escape characters, so long as you do not use a non-escaped single quote/apostrophe in the body string (you must escape it as \')
SURVEY SUBMISSION is the Subject line of the email, which you can change to your desired text, again ensuring not to use an non-escaped single quote
email@company.com is the Email address you want your survey results sent to
You must have email properly configured on your instance via Admin > System Admin > Email Setup or by manually specifying an external SMTP server/relay in the postfix configuration files, just as you would for any other FreePBX/Asterisk emails to function correctly. AWS does NOT allow SMTP relaying from an instance
Finally, we'll want to thank the Caller for participating in the survey before hanging up the call:
exten => s,n,playback(/var/lib/asterisk/sounds/en/custom/surveythankyou)
exten => s,n,hangup()
;--== end of [macro-survey]==--;
Replace surveythankyou with your final audio file name (again, omitting the file extension) and, if necessary, change your language (en).
That completes the custom dialplan. Here's what it looks like all put together with two questions:
;----------- MACRO SURVEY ----------
[macro-survey]
; Answer the channel (in case of blind transfer)
exten => s,1,answer()
; Say Hello and Ask Question 1
exten => s,n,Read(answer,/var/lib/asterisk/sounds/en/custom/question1,1,,1,3)
exten => s,n,GotoIf($[ ${answer} <= 2 ]?:$[${PRIORITY}-1])
exten => s,n,set(answers=${answers}|${answer})
; Ask Question 2
exten => s,n,Read(answer,/var/lib/asterisk/sounds/en/custom/question2,1,,1,3)
exten => s,n,GotoIf($[ ${answer} <= 5 ]?:$[${PRIORITY}-1])
exten => s,n,set(answers=${answers}|${answer})
; Store results in CDR, preserving the existing contents of userfield
exten => s,n,set(answers=${answers}|)
exten => s,n,Set(CDR(userfield)=${CDR(userfield)}${answers})
; Email results
exten => s,n,System(echo 'Survey was submitted by: ${CALLERID(name)} ${CALLERID(number)}\nTheir selections: ${answers}' | mail -s 'SURVEY SUBMISSION' 'email@company.com')
; Say Thank You and Goodbye before Hanging up
exten => s,n,playback(/var/lib/asterisk/sounds/en/custom/surveythankyou)
exten => s,n,hangup()
;--== end of [macro-survey]==--;
With all that in your extensions_custom.conf file, you can now Save it, but do NOT click Apply Config just yet. We have two more dialplan functions to setup yet...
Custom Destination:
Now we need to make the FreePBX GUI aware of our new custom context, so it can be selected as a Destination in other FreePBX modules. Go to Admin > Custom Destinations and click Add Destination:
You should be able to pick your newly added context from the Destination Quick Pick dropdown. If you don't have this dropdown or it isn't populated with your macro, you can manually enter the Target:
macro-survey,s,1
If you have multiple surveys, be sure this reflects the right macro. EX: macro-survey-2
A Description is required, as this acts as the Name. You'll want to ensure Return is set to NO. You can then Submit the new Custom Destination. Do NOT Apply Config yet.
Misc Application:
Finally, let's setup the number that Agents will use to forward Callers to the survey manually. Go to Applications > Misc Applications and create a new Misc Application. You can specify whatever you want as the Feature Code, so long as you don't conflict with an existing number in the dialplan:
As previously mentioned at the start of this guide, your Agents can manually send a Caller to the survey at any time using the Asterisk in-call Blind Transfer code ## + MiscAppCode + # to complete the transfer. Per the example above, this sequence would be ##7878# while actively on the call with the customer. The Agent will be automatically disconnected and marked Available again per standard Queue rules (if call was sent from a Queue). If using physical endpoints, a Speeddial button can be easily programmed with this sequence for one-button transfers.
Queues Pro/VQ Plus:
If you have the Queues Pro/VQ Plus paid commercial module license from Sangoma, you can force transfer all Callers to the survey automatically after an Agent hangs up, without requiring the Agent to dial a code, also ensuring that all Callers get sent to the survey whether Agent wants feedback or not! Edit your Queue and go to the Queues Plus Options tab. Then select the Custom Destination as the Caller Post Hangup Destination:
THAT'S IT!
You've just created an interactive feedback survey you can customize to meet your needs. The rest of this guide will illustrate some other examples of questions and answers, as well as how to record an audio message from your Caller to be included in the survey email.
Multi-Digit Answer Question:
What if you'd like your Caller to record a numerical answer that is more than one digit long? That's pretty easy, too! Here's what the question block would look like, assuming we wanted them to enter a response of up to 3 digits in length, requiring at least 1 (> 0) digit to be entered:
exten => s,n,Read(answer,/var/lib/asterisk/sounds/en/custom/question1,3,,1,3)
exten => s,n,GotoIf($[ ${LEN(${answer})} > 0 ]?:$[${PRIORITY}-1])
exten => s,n,set(answers=${answers}|${answer})
Or we could ask that they enter their 10-digit (> 9) telephone number for a call back, while being flexible enough to accept a leading 1 (up to 11 digits total):
exten => s,n,Read(answer,/var/lib/asterisk/sounds/en/custom/question1,11,,1,3)
exten => s,n,GotoIf($[ ${LEN(answer)} > 9 ]?:$[${PRIORITY}-1])
exten => s,n,set(answers=${answers}|${answer})
Ask the Caller to Record a Message:
You can also ask the Caller to record a message and include that as an attachment to the Email with the survey answers:
exten => s,n,playback(/var/lib/asterisk/sounds/en/custom/question2)
exten => s,n,Record(${CALLERID(number)}.wav,10,90,ky)
In this case, we are saving the recorded message with filename consisting of the Caller's CallerID Number in wav format. The recording will be stopped after 10 seconds of silence or when the Caller presses any key, with a maximum recording time of 90 seconds.
Our Email line needs altered to include the wav file as an attachment and we need to ensure we delete the temporary file to save disk space after we've emailed it:
exten => s,n,System(echo 'Survey was submitted by: ${CALLERID(name)} ${CALLERID(number)}\nTheir selections: ${answers}' | mail -a /var/lib/asterisk/sounds/${RECORDED_FILE}.wav -s 'SURVEY SUBMISSION' 'email@company.com')
exten => s,n,System(rm -rf /var/lib/asterisk/sounds/${RECORDED_FILE}.wav)
Only Do 'B' if 'A' is 'Y':
Let's say you only wanted to record that message if the Caller answered a previous question a certain way. We can preserve an answer and test against it later. This gets a little more complicated, as we'll have to employ labels to skip around the macro. First, let's modify a question block to preserve an answer. We'll use a simple Yes/No (1/2) question:
exten => s,n,Read(answerMsg,/var/lib/asterisk/sounds/en/custom/question1,1,,1,3)
exten => s,n,GotoIf($[ ${answerMsg} <= 2 ]?:$[${PRIORITY}-1])
exten => s,n,set(answers=${answers}|${answerMsg})
Note how we are not using the generic "answer" variable for this question. We are using a variable unique (answerMsg) for this question, so it can be preserved for later testing
Towards the end of the survey, ideally right before we're ready to send the Email (for simplicity), we will now check that previous answerMsg and see if we need to record a message from the Caller (assume 1 means we want to record a message):
; If they answered Yes(1) before, we record and attach a message
exten => s,n,GotoIf($[ ${answerMsg} = 1 ]?:skipMsg)
exten => s,n,playback(/var/lib/asterisk/sounds/en/custom/pleaserecordmsg)
exten => s,n,Record(${CALLERID(number)}.wav,10,90,ky)
exten => s,n,System(echo 'Survey WITH MESSAGE was submitted by: ${CALLERID(name)} ${CALLERID(number)}\nTheir selections: ${answers}' | mail -a /var/lib/asterisk/sounds/${RECORDED_FILE}.wav -s 'SURVEY SUBMISSION' 'email@company.com')
exten => s,n,System(rm -rf /var/lib/asterisk/sounds/${RECORDED_FILE}.wav)
; When finished, we jump to goodbye
exten => s,n,Goto(goodbye)
; If we didn't record a message, we still need to email the survey answers
exten => s,n(skipMsg),System(echo 'Survey was submitted by: ${CALLERID(name)} ${CALLERID(number)}\nTheir selections: ${answers}' | mail -s 'SURVEY SUBMISSION' 'email@company.com')
; Say Thank You and Goodbye before Hanging up
exten => s,n(goodbye),playback(/var/lib/asterisk/sounds/en/custom/surveythankyou)
exten => s,n,hangup()
;--== end of [macro-survey]==--;
See how we employ labels to skip parts of the macro as needed? Using labels, you can accomplish all sorts of advanced call flows.