FPBX/Asterisk option to replace Avaya IPO "Campaigns"


Is there any way to make it use the existing email body for Voicemail instead of creating a custom one? That way it’s tied to the modifications that would be made if the system admin changes that content (and it would look like a regular voicemail). :slight_smile:

(Dickson) #22

@kristiandg here you go!

This is BETA RELEASE 3 of the code.


This is beta 3, the instructions posted above are still relevant, but the code has had enough subtle changes that I would just erase what I’ve put in before and replace with this:

Instead of the recording being directly emailed, it instead is left on an extension voicemail system and is sent using that mechanism. You will need to have an extension with a voicemail box setup that, ideally nobody answers. If someone does, it will play the message and it wont be subsequently recorded and emailed.

Additional macro called, “macro-questionanswer1”

Changes to leave the recordings as ULAW not WAV (i had problems getting the system to play wav files to callers)

I’ve tested this in the FreePBX Distro using worked ok as a beta test. It may need alteration for your own environments, however I am using commands that have been around a long time so should be compatible with most versions.
Code from strangers should never be tested in a production environment.

What this code does.
The system will ask questions, after each it will record the caller for a maximum of 15 seconds (you can change this of course) or until the users presses # key, whichever comes first.
This code allows for two questions and answers to be given.

In this example, after the 2nd answer is given, the system will play back both recordings together so you can hear it.

If caller press # the call will stop recording and continue to next questions

If caller either doesn’t say anything for 3 seconds, the system continues to next question (changeable of course)

Once the questions are done, the caller is hungup on.

The system generates a .call file which will contact an extension of your choice, one that goes directly to voicemail.

The file that is recorded is saved to thevoicemail box, then the call hangsup.
Your asterisk system will send the email to the recipient using your voicemail parameters.

To make the code simpler, for those not versed in asterisk dialplan, any line starting with a ; semicolon is a remark line and can be safely removed for ease of viewing. Lines with ; are there to either leave a comment, or to have the system not execute that line of code.

open up "extensions_custom.conf"
Copy the code below between the ------ lines into the bottom of extensions_custom.conf and then save the file.
Replace code from previous BETA 1 & 2 releases


exten => s,1,answer()
exten => s,n,playback(/var/lib/asterisk/sounds/en/custom/question1)
exten => s,n,Record(${UNIQUEID}.ulaw,3,15,a)

exten => s,n,playback(/var/lib/asterisk/sounds/en/custom/question2)
exten => s,n,Record(${UNIQUEID}.ulaw,3,15,a)

;Generate .call file that asterisk will use to send the call to a voicemail box
;Change XXXXX to be an extension in your system that you want called and have the message left on
exten => s,n,system(echo “Channel: LOCAL/XXXXX” > /var/lib/asterisk/sounds/recording.call)
exten => s,n,system(echo “Context: macro-questionanswer1” >> /var/lib/asterisk/sounds/recording.call)
exten => s,n,system(echo “Extension: s” >> /var/lib/asterisk/sounds/recording.call)
exten => s,n,system(echo “Setvar: playfile=${UNIQUEID}” >> /var/lib/asterisk/sounds/recording.call)

exten => s,n,system(mv /var/lib/asterisk/sounds/recording.call /var/spool/asterisk/outgoing)
exten => s,n,hangup()

exten => s,1,wait(1)
exten => s,n,senddtmf(#)
exten => s,n,playback(/var/lib/asterisk/sounds/${playfile})

;delete sound file.
exten => s,n,system(rm /var/lib/asterisk/sounds/${playfile}.ulaw)
exten => s,n,hangup()


Click on “SAVE”

If you are updating this code from previous versions, you can stop here and test it out.

Create a new custom destination "questionanswer"
Set the target as
Save those changes

Create a way to trigger the application to run from dialplan.
For example, create a IVR, and set one of the numeric values a caller can enter to Custom Destination -> “questionanswer”"

Save your changes AND apply the configuration.

Create your question files.

Use system recordings, and either record them over your phone, or through a 3rd party sound recording application. If recording with another app, they must be saved as 8000khz MONO 16bit WAV PCM.

The recordings you make, set their name to “recording1” “recording2” “recording3

in /tmp/ create a file called "email.txt"
In that file put in something like
Here is a new recording to review.

Save changes.


Call and leave your recordings. System should leave the message and you should get an email alert with the message attached.

1> As previous, your recorded questions are played, and the answers are recorded into a single file.
2> After the last question is answered, the system will hangup.
3> Then the system internally places a call to the extension that you want the system to send the voicemail through.
4> When that system picks up, assuming voicemail, the system sends a “#” tone to the extension to bypass any greetings and additional instructions that voicemail systems have.
5> The system in the background plays the message that your caller left, and sends it as a voicemail.
6> Your recipient should get the message alert in their email.

Give it a test!


If you create .txt file with the proper calling parameter information, you can drop that file in the outgoing folder in asterisk and that will make your phone call happen.
Essentially these 4 lines generate the 4 line file.

The number you want to call, this example is extension 1234
exten => s,n,system(echo “Channel: LOCAL/1234” > /var/lib/asterisk/sounds/recording.call)

The context you want executed when the destination 1234 answers
exten => s,n,system(echo “Context: macro-questionanswer1” >> /var/lib/asterisk/sounds/recording.call)

The line you want executed in the context
exten => s,n,system(echo “Extension: s” >> /var/lib/asterisk/sounds/recording.call)

Variables you want passed to the system when 1234 answers
exten => s,n,system(echo “Setvar: playfile=${UNIQUEID}” >> /var/lib/asterisk/sounds/recording.call)

The variable is the most complicated piece. UniqueID is the unique number given for each call. When you are recording the calls, we use that number as the file number. However, when we call the new number to leave the voicemail, that generates a new unique ID. So in this code we set a temporary variable of “playfile” to store the unique number that is the file name. This temporary file is, in itself unique to this call, so it wont affect things if you have multiple question answers recording simultaneously…


Absolutely beautiful! Thank you!


Amazing. Your fantastic. Sure appreciate your time and efforts.



Finally got around to putting this into pre-production for the client - works wonderfully - I especially like how it maintains the voicemail notification format!!!

One thing I did notice is that, I’m guessing, because the system is making the call to voicemail, there’s no caller id. It says “from an unknown caller”.

Any way to have it call on behalf of the original CLID instead?

Also, I modified it to use the “SAME” function:
exten => s,1,answer()
same => n,playback(/var/lib/asterisk/sounds/en/custom/question1)
same => n,Record(${UNIQUEID}.ulaw,3,15,a)
same => n,playback(/var/lib/asterisk/sounds/en/custom/question2)

Thanks again for all this wonderful work!!!

(Dickson) #26

I’ll get this code back into a test system today and do some testing on the CLID. I’m sure that isn’t a big deal to resolve.


A gentleman and a scholar… Thank you, sir. :slight_smile:


Did you have any luck on this one? Thanks…


By chance, have you had a chance to explore the CLID component of this?


(Dickson) #30

Sorry, have not been able to work on this, but i’m installing it now.
I’ll update shortly.

(Dickson) #31

Again, sorry took so long to get to this, life eh?
Add the line in BOLD and it will give you the CLID info for the calls in the email and in the UCP

exten => s,n,system(echo “Channel: LOCAL/XXXXX” > /var/lib/asterisk/sounds/recording.call)
exten => s,n,system(echo “Context: macro-questionanswer1” >> /var/lib/asterisk/sounds/recording.call)
exten => s,n,system(echo “Extension: s” >> /var/lib/asterisk/sounds/recording.call)
exten => s,n,system(echo “Setvar: playfile=${UNIQUEID}” >> /var/lib/asterisk/sounds/recording.call)
exten => s,n,system(echo “CallerID: ${CALLERID(name)} ${CALLERID(number)}” >> /var/lib/asterisk/sounds/recording.call)

One thing I did notice was I have quotes my posts (EX: “Channel: LOCAL/XXXX”) and when I tested it on my system, it was balking at the quotes, so I removed them and it work. I know it must have worked at the time of testing, i’m not sure why it failed so just take note, maybe there was an update or i goofed pasting it. Just be aware.

So this might be what you will need
exten => s,n,system(echo Channel: LOCAL/2004 > /var/lib/asterisk/sounds/recording.call)
exten => s,n,system(echo Context: macro-questionanswer1 >> /var/lib/asterisk/sounds/recording.call)
exten => s,n,system(echo Extension: s >> /var/lib/asterisk/sounds/recording.call)
exten => s,n,system(echo Setvar: playfile=${UNIQUEID} >> /var/lib/asterisk/sounds/recording.call)
exten => s,n,system(echo CallerID: ${CALLERID(name)} ${CALLERID(number)} >> /var/lib/asterisk/sounds/recording.call)

(Dave Burgess) #32

You can probably get rid of all the quotes on that line.

(Dickson) #33

Maybe the quotes are from habit…

(Itzik) #34

Thank you!
I would use this in post agent queue hangup, anyway to add the agent name or ext the caller spoke with?



Hmmm - like an “after call survey”. NICE!

@dickson = Thanks so much. May want to update your official code above (now, Beta 4 I suppose). :wink:



Hello all - Circling back on this because after the Caller ID stuff was added, I didn’t get a chance to test/play, but the project is now getting close to being complete so I went to go build this and found a couple things.

The Call File is being dropped in the sounds directory, so I’ve played with actually writing to a new file in the /var/spool/asterisk/outgoing directory, but not only do I never see it appear there (could it really be that fast that maybe it’s not getting all the parts in there before the spooler snatches it up?). If I leave it how this code has it (dropped in the SOUNDS directory, of course it stays there and appears to have the proper format, but (as expected) nothing happens. No matter what, it’s like the “part 2” stuff isn’t being called.

So then I thought, in the Call File, maybe the Context needs to actually be the “part 2” macro (the example above shows the original macro).

Below is what the finalized code looks like - can someone gut-check it for me and see if they can figure out why it’s not calling the voicemail box to leave the nicely-formatted voicemail message?

exten => s,1,answer()
same => n,playback(/var/lib/asterisk/sounds/en/custom/qa–rx-refill-Q1)
same => n,Record(${UNIQUEID}.ulaw,2,8,a)
same => n,playback(/var/lib/asterisk/sounds/en/custom/qa–rx-refill-Q2)
same => n,Record(${UNIQUEID}.ulaw,2,12,a)
same => n,playback(/var/lib/asterisk/sounds/en/custom/qa–rx-refill-Q3)
same => n,Record(${UNIQUEID}.ulaw,2,5,a)
same => n,playback(/var/lib/asterisk/sounds/en/custom/qa–rx-refill-Q4)
same => n,Record(${UNIQUEID}.ulaw,2,15,a)
same => n,system(echo Channel: LOCAL/7909010 > /var/lib/asterisk/sounds/${UNIQUEID}.call)
same => n,system(echo Context: macro-rx-refill-hhky-part2 >> /var/lib/asterisk/sounds/${UNIQUEID}.call)
same => n,system(echo Extension: s >> /var/lib/asterisk/sounds/${UNIQUEID}.call)
same => n,system(echo Setvar: playfile=${UNIQUEID} >> /var/lib/asterisk/sounds/${UNIQUEID}.call)
same => n,system(echo CallerID: ${CALLERID(name)} ${CALLERID(number)} >> /var/lib/asterisk/sounds/${UNIQUEID}.call)
same => n,playback(/var/lib/asterisk/sounds/en/custom/qa–rx-refill-end)

exten => s,1,wait(1)
same => n,senddtmf(#)
same => n,playback(/var/lib/asterisk/sounds/${playfile})
;delete sound file.
same => n,system(rm /var/lib/asterisk/sounds/${playfile}.ulaw)
same => n,hangup()

In my latest example/test, a sound file with the unique ID was created, as well as a call file (with the unique ID - that was another tweak in case two calls hit at once).

Attached is the Call File it made (and yes, I’ve played with the CONTEXT being both the original and part2 macros - no difference).

Could the Outbound directory really be processing faster than the call file is being populated (meaning, should I write the file in the sound directory then move it into the outgoing folder instead)?

Any thoughts?



OK, turns out that was the issue - the call file needed to be completely written THEN moved into position. The only issue I have left is that the Caller ID isn’t showing up in the right format. It literally is smashing the two fields together back to back (even though there’s a space in the above generated.

According to the callfile format that I found somewhere, it should be in quotes and carets:

  • CallerID: “name” <number> Caller ID, Please note: It may not work if you do not respect the format: CallerID: “Some Name” <1234>

Here’s how the final code ended up (below) - @dickson, you may want to modify the final version based on this… But, does anyone know how I can do the CLID format as listed above? I tried just adding brackets - it didn’t like that (said unknown number).

This is the line that needs some tweaking:

same => n,system(echo CallerID: ${CALLERID(name)} ${CALLERID(number)} >> /var/lib/asterisk/sounds/${UNIQUEID}.call)

Thanks everyone…



exten =&gt; s,1,answer()
;Checks to see if there's any incomplete sound files that have been previously recorded that are over 1 day old (as to not impact other recordings currently going on), and deletes them. Also checks for any CALL files that may have failed to be moved, and clears them (also older than 1 day).
same =&gt; n,system(find /var/lib/asterisk/sounds/ -maxdepth 1 -type f -name \'*.*.ulaw\' -mtime +1 -delete)
same =&gt; n,system(find /var/lib/asterisk/sounds/ -maxdepth 1 -type f -name \'*.*.call\' -mtime +1 -delete)

;Question 1
same =&gt; n,playback(/var/lib/asterisk/sounds/en/custom/qa--Question1File)
same =&gt; n,Record(${UNIQUEID}.ulaw,2,8,a)

;Question 2
same =&gt; n,playback(/var/lib/asterisk/sounds/en/custom/qa--Question2File)
same =&gt; n,Record(${UNIQUEID}.ulaw,2,12,a)

;Question 3
same =&gt; n,playback(/var/lib/asterisk/sounds/en/custom/qa--Question3File)
same =&gt; n,Record(${UNIQUEID}.ulaw,2,5,a)

;Question 4
same =&gt; n,playback(/var/lib/asterisk/sounds/en/custom/qa--Question4File)
same =&gt; n,Record(${UNIQUEID}.ulaw,2,15,a)

;Assembles the Call File for Asterisk to Process
same =&gt; n,system(echo Channel: LOCAL/XXXXXXX &gt; /var/lib/asterisk/sounds/${UNIQUEID}.call)
same =&gt; n,system(echo Context: macro-qa-campaign1-part2 &gt;&gt; /var/lib/asterisk/sounds/${UNIQUEID}.call)
same =&gt; n,system(echo Extension: s &gt;&gt; /var/lib/asterisk/sounds/${UNIQUEID}.call)
same =&gt; n,system(echo Setvar: playfile=${UNIQUEID} &gt;&gt; /var/lib/asterisk/sounds/${UNIQUEID}.call)
same =&gt; n,system(echo "CallerID: \"${CALLERID(name)}\" &lt;${CALLERID(number)}&gt;" &gt;&gt; /var/lib/asterisk/sounds/${UNIQUEID}.call)

;Moves the Call File into the Outgoing directory for processing (Asterisk is too fast to simply assemble the file in that directory - must be completely generated, then moved into place)
same =&gt; n,system(mv /var/lib/asterisk/sounds/${UNIQUEID}.call /var/spool/asterisk/outgoing/${UNIQUEID}.call)

;Final closing message
same =&gt; n,playback(/var/lib/asterisk/sounds/en/custom/qa--ClosingSoundFIle)

;Optional destination after Q&amp;A is complete. Waits 2 seconds for the caller to hang up - if they didn't, then it transfers the call to the programmed destination (change XXXXXXX to the internal extension number)
same =&gt; n,wait(2)
same =&gt; n,Ringing()
same =&gt; n,wait(1)
same =&gt; n,Dial(local/XXXXXXX@from-internal)

exten =&gt; s,1,wait(1)
same =&gt; n,senddtmf(#)
same =&gt; n,playback(/var/lib/asterisk/sounds/${playfile})

;Deletes the sound file.
same =&gt; n,system(rm /var/lib/asterisk/sounds/${playfile}.ulaw)
same =&gt; n,hangup()


Try adding the ‘normal’ separators,

system(echo CallerID: “${CALLERID(name)}” <${CALLERID(number)}>

(Tom Ray) #39

@kristiandg So what happens with the voicemail that is left on the system? Do you auto delete it since you’re emailing notifications? Do they pile up until someone comes in and clears them out?


Oh no, in VM, it’s set to email and delete.