FPBX/Asterisk option to replace Avaya IPO "Campaigns"


That was the first thing I tried, and it got… wonky. :slight_smile:
The quotes seemed to make the NAME variable mad:

The resulting call file skips that line completely:

Even if I just remove the quotes (and leave the carets there), the resulting call file is missing that line completely - I think it’s because the carets are also use for the echo’s write command (though I was hoping that because it was double carets, the single caret wouldn’t impact - but it did):

(Tom Ray) #42

So all of this is to use the voicemail email template in the end? That is the whole goal of this?


It asks a series of questions, appends the answers into a single file, then sends the file into voicemail so that the resulting email is nicely formatted (the way Voicemail-to-Email messages are).

The subject line automatically has all the data necessary because of that VM2EM message format, and the information attached is all the answers to the questions - because of using this structure, transcription now also works without any special code in the actual macro.

(Tom Ray) #44

I understand what you’re doing with the recordings. I just wouldn’t create call files just to send the calls to voicemail for the option of a pretty formatted email.

I use the PHPMailer class for things like this. It does HTML, plain text, attachments, pretty much everything I need to do this. This is how I can send different branded VM notifications on my systems.

In this case I would have a single System() call that would send all my variables to a script that would load the PHPMailer class, and since I already use my own template for VM (based on Asterisk’s) I just call that in from another function that I can pass my variables to. This would load my template, set the email/smtp details, attach the recording and send it on it’s way and then delete the recording from the system.

The script would take a little more work than a half dozen echo lines but in the end it is much more versatile and can be used for much more than one thing. Plus it doesn’t keep calls going and having your system doing extra recordings because you’re recording once and sending it off immediately.


Based on the info in this article:

I was able to figure out the proper syntax, though the config editor thinks its invalid (red text), but it works…

I’m updating the above “final” code with this line:

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


The last piece of this is, right after the last sound file, I want it to wait for a second or two, then transfer the call into a queue extension, so I’m just figuring out what that last line (of part 1) would look like, but the initial intent’s “finished” product is listed above for others to use and tweak as they desire.

Thanks everyone to those that helped me create this “Avaya IPOffice Campaign Replacement”. :slight_smile:

(Dickson) #47

So all working for you now @kristiandg? Keep us posted on its performance!

@BlazeStudios the php approach would definitely be really nice alternative, can you post some code to show us how that would be done?


Yes sir, works perfectly - Thank you!!!
And I just figured out the line(s) to put after the below to make it then transfer the call:

same => n,wait(2)
;Transfers the call to x7901001
same => n,Dial(local/7901001@from-internal)

This also got me thinking about what happens when someone calls in and hangs up on the call before finishing the process (a bunch of old partially-recorded sound files. So, when you first hit the macro, I’ve added this (ok, this is silly, but the forum isn’t displaying the asterisks I have in between the file name - to prevent accidential deleteion of regular .ulaw files - all the files the $UniqueID variable generates has two file extensions (what I believe is milliseconds, then the .ulaw) - the star-dot-star-dot-ulaw format allows it to ONLY match those files, ignoring any other .ulaw sound files in the sounds directory):

;Deletes old sound files that were never completed by past callers - older than 1 day
same => n,system(find /var/lib/asterisk/sounds/ -maxdepth 1 -type f -name ‘..ulaw’ -mtime +1 -delete)

OK, I’ve now updated the previous post with the final touches (I need to walk away or I’m going to obsess over what all I can do with this thing). lol

(Tom Ray) #49

I can at some point this weekend. I have to finish this USAC filing report first.


If you use quotes within quotes they need to be escaped with a back-slash

echo "\"name of person\" <13235551212>" >> call.file


same => n,goto(ext-local,yourqueuediallednumber,1))

(Tom Ray) #52

@dickson @kristiandg OK so this is the rough draft that I threw together. You would need PHPMailer installed on the system. The current version will work in FreePBX v14. If you have FreePBX v13 you’ll need their legacy version and will need to make adjustments accordingly.

This gives you a simple set of variables. You call on them by wrapping them in {} so CALLERID would be {CALLERID}
– CIDNAME : CallerID Name
– CIDNUM : CallerID Number
– CALLERID : CallerID Full
– DATETIME : Current Time Stamp of the notification

You can pass more vars by adding them to the $email_vars array and just calling on them by {name} in the template. So you could add $email_vars[‘user_id’] = 1; and then call on it in the template as {user_id}

same => n,System(/path/to/script.php “${CALLERID(name)}” ${CALLERID(number)} ${UNIQUEID}.wav)

The Script:

#!/usr/bin/php -q

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'path/to/PHPMailer/src/Exception.php';
require 'path/to/PHPMailer/src/PHPMailer.php';
require 'path/to/PHPMailer/src/SMTP.php';

 * Set Script VARS
$FROM_NAME = "FreePBX Recording"; // From Email Name
$FROM_EMAIL = "freepbx@pbx.domain.com"; // From Email Address
$TO_NAME = "Jane User"; // To User Name
$TO_EMAIL = "jane@domain.com"; // To User Email Address
$EMAIL_SUBJECT = "New Recording Notification"; // Email Subject 
$EMAIL_BODY = "/path/to/email/template.tpl"; // Path to the email body template
$EMAIL_ALT_BODY = "Please review attached recording"; // Alt Body in case of no HTML support

$SND_DIR = "/path/to/recording/dir/"; // Path to directory storing recordings. With trailing /

$SMTP_HOST = ""; 	// Your SMTP Host
$SMTP_PORT = 587; 	// Your SMTP Port
$SMTP_USER = ""; 	// Your SMTP Username
$SMTP_PWD = ""; 	// Your SMTP Password

 * Done Setting Vars. Touch nothing below here unless you need to and know what you're doing
// Raw CallerID Name
$v_cidname = $argv[1];

// Raw CallerID Num
$v_cidnum = $argv[2];

// Set Path to recording
$rec_file = $SND_DIR . $argv[3];

// Set Valid Flags to false
$valid_cnam = false;
$valid_cnum = false;

// Check the CallerID Name. 
// We only want A-Z, a-z, 0-9, underscore, space and apostrophe
if (preg_match('/[A-Za-z0-9_\' ', $v_cidname)) {
	$email_vars['CIDNAME'] = $v_cidname;
	$valid_cnam = true;

// Check CallerID Number
// We only want A-Z, a-z and 0-9
if (preg_match('/A-Za-z0-9/', $v_cidnum)) {
	$email_vars['CIDNUM'] = $v_cidnum;
	$valid_cnam = true;

// No Valid CNAM or CNUM just die.
if (!($valid_cnum && $valid_cnam)) {

// Set CallerID Name to CallerID Num if empty.
if ($email_vars['CIDNAME'] == '') {
	$email_vars['CIDNAME'] = $email_vars['CIDNUM'];

// Format Full CallerID
$email_vars['CALLERID'] = $email_vars['CIDNAME'] . " <" . $email_vars['CIDNUM'] . ">";

// Initiate PHPMailer & Build Mailer Object
$mailer = new PHPMailer;
$mailer->SMTPSecure = false;
$mailer->SMTPAutoTLS = false;
$mailer->SMTPAuth = true;
$mailer->Host = $SMTP_HOST;
$mailer->Port = $SMTP_PORT;
$mailer->Username = $SMTP_USER;
$mailer->Password = $SMTP_PWD;
$mailer->setFrom($FROM_EMAIL, $FROM_NAME);
$mailer->addAddress($TO_EMAIL, $TO_NAME);
$mailer->isHTML(true);                                  // Set email format to HTML
$mailer->Subject = $EMAIL_SUBJECT;
$mailer->Body    = buildEmail($email_vars, $EMAIL_BODY);
$mailer->AltBody = $EMAIL_ALT_BODY;

function buildEmail($vars, $template) {
	return preg_replace_callback('/\{([^\{]{1,100}?)\}/', 
								 function($match) use($vars) { 
									 return $vars[$match[1]]; 

This is the basic template.

			<td colspan="2"></td>
			<td colspan="2">Please review the attached recording</td>

(Dickson) #53

Ooo this is good! We’ve been wanting to make some changes with a client with a similar deployment. I’ll give this one a try tks!

(Tom Ray) #54

Let me know if you need anything.


Good morning. I know it’s been a while on this particular thread, but I got a report from the customer that this is no longer working. Yeah, I know that’s vague. They say it asks all the questions, but never actually emails the file. I haven’t looked yet (obviously I’ll check CDR and when the system isn’t so busy, run a trace), but the only thing I can think of was an upgrade to FPBX15/Asterisk 16, which occurred a few weeks ago (and yes, maybe they just now discovered it wasn’t working).

Any reason anyone can think of that this wouldn’t be compatible with Asterisk 16?

(Dave Burgess) #56

Check the /var/log/asterisk/full log instead. That way, you don’t have to wait for a lull and can check what actually happened when the script failed. The script should be represented “pretty much” line-for-line in the full log.


Yup, that worked like a charm. Thanks. Looks like the second part of this, where it calls the voicemail box to leave the voicemail, is failing:

Attempting call on LOCAL/7909010 for s@macro-rx-refill-hhky-part2:1 (Retry 1)
[2020-05-02 11:11:36] NOTICE[19556] core_local.c: No such extension/context 7909010@default while calling Local channel
[2020-05-02 11:11:36] NOTICE[19556] pbx_spool.c: Call failed to go through, reason (0) Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)
[2020-05-02 11:11:36] NOTICE[19556] pbx_spool.c: Queued call to LOCAL/7909010 expired without completion after 0 attempts
[2020-05-02 11:11:36] VERBOSE[18912][C-0001dca7] pbx.c: Executing [s@macro-rx-refill-hhky:16] Playback(“SIP/C1a-IN-00011777”, “/var/lib/asterisk/sounds/en/custom/qa–rx-refill-end”)

The extension it speaks of IS actually still built as a virtual extension. Per the logs, the call file is still valid, as it knows to make the call, so we’ll dig into that (make sure we can actually call that extension directly). and go from there. If I get stumped again, you’ll hear from me. :wink:

But this does raise the question - in FPBX 15, did the context change from “default” to something else?

Thank you!

(Dave Burgess) #58

I’m a relative newcomer (I’ve only been using Asterisk since 2004) but I don’t think FreePBX has ever supported the “default” context. If it used to work for you that way, you would have had to add it. On the other hand, it seems to me that voicemail boxes are listed like that.

I think the problem is more likely to be the Virtual Extension. I’m not sure that they can even have voicemail boxes, as there’s no way to set them up without manual intervention.


I’ve found that to be one of the great purposes for virtual boxes, for “mailbox only” or “follow-me only” applications. To set a greeting, you just call into the voicemail feature code and log in as that user - what a virtual box couldn’t do was have an MWI (since there was no device to notify).

Right now the programming has this line for the call file:

same => n,system(echo Channel: LOCAL/7909010 > /var/lib/asterisk/sounds/${UNIQUEID}.call)

Based on what I’m seeing, I’m thinking "… echo Channel: EXT-LOCAL/7909010 >… But not sure where to validate that’s the proper syntax. During it’s creation, I didn’t want to have to dictate the channel - I wanted it to be dynamic, so it would just call whatever was put in for a number (and LOCAL was suggested to me). I guess if that’s the issue now, I’m looking for the comparable and compatible channel command.


Well, tried a channel of “EXT-LOCAL” and that didn’t work - same issue.

[2020-05-05 13:31:42] VERBOSE[9094] pbx_spool.c: Attempting call on EXT-LOCAL/7909019 for s@macro-qa-test-part2:1 (Retry 1)
[2020-05-05 13:31:42] WARNING[9094] channel.c: No channel type registered for ‘EXT-LOCAL’

Anyone have any thoughts on why after our upgrade to FPBX15, this command no longer works:

same => n,system(echo Channel: LOCAL/7909010 > /var/lib/asterisk/sounds/${UNIQUEID}.call)

It’s claiming the extension is not valid, yet we can call it, and of course, it worked for over two years before the FPBX15 upgrade. Looking back at the dates of the sound files that are left behind from it, it died right after the upgrade.