Putting TeleYapper to the Test

For those that are new to Nerd Vittles, you may not recall that, on Valentine's Day in 2006, we released TeleYapper, a telephone broadcasting system that distributes reminders and other messages to large or small groups of people by phone, of course. Believe it or not, it still works with almost all versions of TrixBox and Asterisk@Home 2.5 or later. But, it's one thing to develop a piece of software that can send unattended telephone reminders to your clients, patients, or Little League team. It's quite another to actually use it for a huge project and find out where all the warts are. As the resident cheerleader in our new neighborhood, I was wrestling with how to get detailed information about a meeting to review a proposed zoning change to a group of 700+ homeowners... in a hurry. Delivering flyers door-to-door was not going to happen. E-mail was certainly an option, but that unfortunately is hit and miss these days. With spam blockers, spam filters, missing email addresses, and verification requirements from companies such EarthLink, we decided we could only count on a delivery success rate of about 50 per cent.

The one piece of technology that everyone in the neighborhood had was a telephone. And our neighborhood database showed only 7 people with unlisted or do-not-call telephone numbers. So it was time to dust off our very own, free TeleYapper software and put it to the test using Asterisk®. Could it really deliver 700 phone calls using Voice Over IP with a home broadband connection in a reasonable time at a reasonable cost without any problems? To preserve our existing home phone system, we decided to really push the envelope by running it on a Windows desktop using our out-of-the-box VMware version of TrixBox 1.2.3.

Picking a Provider. It may not sound like a big deal, but choosing a really good VoIP provider matters when all of your neighbors are going to be listening to a 60 second message that has your name all over it. Can you imagine getting complaints from all your neighbors that go something like this: "I got some funny message from you last night on my answering machine, and I couldn't understand a single word of it. There was all this echoing, and I finally deleted the message after listening to about 10 seconds of gibberish." So, yes, there was the personal reputation to preserve. And picking a high-quality VoIP service provider was crucial in getting the actual message content delivered reliably. But there was more to consider as well.

First, you can't really use an all-you-can-eat VoIP service for something like this because it will trigger virtually every safeguard mechanism providers have put in place to make certain that folks aren't making unlimited, automated business calls on a residential phone plan. Second, with the exception of TelaSIP, most all-you-can-eat providers won't let you adjust the CallerID of the outbound calls. We wanted to do this to identify the call as coming from the neighborhood association's telephone number, not mine! Then there's the cost factor. We didn't mind paying by the minute within reason, but 2¢ per minute was just too expensive, and we'll explain why in a moment.

We ended up picking Vitelity for a number of reasons. Most importantly, they have outstanding VoIP service with support for unlimited outbound trunks if you have the bandwidth to support it. We chose to use up to 4 simultaneous trunks which worked well using Comcast broadband service. They also have the best and most flexible configuration options in the business. You can even create your own sub-accounts. Thus, we could set up a new TrixBox system with a sub-account even though we also use Vitelity as a fallback provider on our home system. Most providers don't support sub-accounts or even multiple accounts. With any other provider, you would have been forced to disable the existing trunk on your main system before you could use it on another system. With a Vitelity sub-account, none of this juggling is necessary. Vitelity also provides adjustable CallerID and excellent call accounting with detailed, tailorable logs which made it easy to print a report and get reimbursed for the calls. And, last but not least, their pricing was reasonable at 1.39ยข per minute with six second billing increments and no charges for failed calls. We made the right choice. Setup was easy using their Asterisk and TrixBox templates, and the calls were flawless with no hiccups.

Setting Up the Database. Now things get interesting. As installed, TeleYapper comes with a MySQL database that is preconfigured to work with TeleYapper. The problem is that you either have to do a lot of typing to get the data into that database before you make the first call, or you need a way to quickly assimilate information from an alternate source. Since we were working with a fairly large number of records, we didn't relish banging in 700+ names and phone numbers. So here's a little trick that works with just a little bit of database knowledge. There is no easy way to "import" data from a text file or other MySQL database because the fieldnames and field sizes won't match up. However, you can do something similar. What we did was export the neighborhood database into a comma-delimited ASCII text file. Then, using phpMyAdmin which comes with TrixBox, you can create a MySQL database table using this file as your source. There are hundreds of good tools for importing data into MySQL. Just do a little Googling. Or you can try Navicat which works for many formats. That's only half the battle unfortunately.

You still need to get the data into a format that TeleYapper can use, or you have a good bit of programming work ahead of you. We wrote the TeleYapper code, but we still didn't want to muck around in it to make this database work. So here's the trick. When you create your new table (we'll call it XYZ), create it as part of the teleyapper database on your system. Then take a look at the callees table that comes with TeleYapper. You'll notice that it has the following fields with the field types and lengths shown in parentheses:

id (medium integer 9)
name (varchar 40)
phonenum (varchar 20)
group (tiny integer 1)
lastokcall (datetime)
lastcall (varchar 7)

Using phpMyAdmin, you want to modify the structure of your new XYZ table so that it includes the fields shown above. For example, if your XYZ table has a field called LASTNAME, simply rename it to name and adjust the field length. You won't lose your existing data. Do the same thing with the phone number field. You'll probably have to add new fields to your XYZ table for id, group, lastokcall, and lastcall. Don't leave any of the fields out or TeleYapper will croak when you try to run it. For the id field, be sure to choose the auto-increment and index options so you get a unique field in your table. Once you're finished, browse through the file and make sure everything looks right. For phone numbers, be sure they're in one of the two following formats: 404-123-4567 or 4041234567. That's what TeleYapper is expecting to find.

When we originally wrote TeleYapper, we weren't really focused on folks using external databases, but you may need to. So, if your phone numbers aren't in this format, you can edit the teleyapper.php file in /var/lib/asterisk/agi-bin and add a few lines of code that look like this to convert 404.123.4567 and (404) 123-4567 to 4041234567 and to get rid of spaces in entries like 404 123 4567:

$phonenum = str_replace( ".", "", $phonenum );
$phonenum = str_replace( " ", "", $phonenum );
$phonenum = str_replace( "(", "", $phonenum );
$phonenum = str_replace( ")", "", $phonenum );

This new code should be inserted immediately after existing line 231 which reads: $phonenum = $row["phonenum"].

Now where were we? Once your new database table looks good to go, delete the existing callees table using the Drop icon. Then rename your XYZ table to callees. Now your TeleYapper database is ready for use. If you want to be able to use subsets of the table to make calls, you'll need to fill in appropriate group numbers. Otherwise, every entry will have a group entry of zero.

Calling Logistics. We built some flexibility into TeleYapper to handle multiple, simultaneous calls as well as redials. Call us nervous, but we like to watch what's going on when calls are placed. And when you get too many things going on at the same time, it's difficult to monitor with asterisk -rvvvv. This is especially true if the length of the message you plan to deliver is 50 seconds or more. Why? Well, answering machines don't typically pick up on the first ring, and neither do people. So, if you only separate your calls by one minute and you permit redials for calls that go unanswered, you can quickly have 7 or 8 calls going on at the same time since TeleYapper is designed to replay your message once if an answering machine picks up or no one presses a key after the initial message plays out. Our solution was to space out the calls a bit more (2 minutes instead of 1) and turn off the automatic redial of failed calls. To do this, edit the TeleYapper app and make the following entries using your desired CallerID number, of course: nano -w /var/lib/asterisk/agi-bin/teleyapper.php:

$numcallattempts=0 ;
$callspread=2 ;
$callerid = "6781234567" ;

Unexpected Surprise. Some folks are never home when you try to call them, and we expected that when TeleYapper was designed. But, believe it or not, about 50 people out of 700 in our neighborhhood don't have an answering machine. In short, they don't seem to care if they miss that all-important call announcing that they've won the latest lottery sweepstakes in England. To be honest, I hadn't really appreciated the scope of that wrinkle when TeleYapper was being developed. Yes, there was a way to kick off another round of calling, but this quantity of redials forced us to adjust the redial option ($numcallattempts) to 0 to avoid dozens of simultaneous outbound calls. Here's a little tidbit of practical wisdom for would-be programmers. If someone isn't answering their phone at 10:02 on a weekday morning, chances are they're probably not going to answer at 10:04 a.m. either. They're at work, stupid! So you can waste the entire day with fruitless redials, or come up with a new Plan B. Our solution was pretty simple, we placed a round of calls beginning at 9 a.m. in the morning, and then we placed another round of calls (to pick up the failed calls) starting at 6 p.m. the following night. Keep in mind that, if you want to cancel your round of calls in the middle, you can't just shut down Asterisk and pick up where you left off the next day. Why? Because TeleYapper schedules each call for a specific time of the day on the specific day that you first run the application. If you shut down your system and restart it the following morning, it will try to place all the remaining calls at once. The solution is fairly simple. Just delete all the files in /var/spool/asterisk/outgoing with commands like this. The first command is a good idea when you first start your calling spree. Look at the last entry in the directory to decipher what time your last call will be placed. If it's in the middle of the night, you might want to delete some of the entries and place those calls on a subsequent day during daylight hours.

ls -all /var/spool/asterisk/outgoing
rm -f /var/spool/asterisk/outgoing/*

The next day when you're ready to pick up where you left off, initiate another TeleYapper session with the same group ID and choose option 3 to dial calls that never were completed.

TeleYapper's Calling Process. Here are the actual steps in the TeleYapper call setup process:

  • Caller with TeleYapper password places call to M-S-G (extension 674) to activate a TeleYapper session.
  • Asterisk answers the call, provides IVR menu: playback a message, record a new message, or place a call.
  • If caller chooses to place a call, IVR prompts for Group number to call (0-9).
  • Asterisk passes the Group number to MySQL (checkgroup.php) to look up the number of callees in the chosen Group.
  • Group count is passed back to Asterisk which uses Allison to tell the caller how many callees are in the chosen Group.
  • Caller has option of placing the call, hanging up, or choosing advanced options (This is Option 3. It redials previously unsuccessful calls in chosen Group again).
  • If caller chooses to place a new call, Asterisk thanks the caller, hangs up, and then passes control to teleyapper.php to handle placing the calls.
  • TeleYapper time stamps dialing scripts a minute apart for each call beginning two minutes after the initiating request. Scripts are placed in the Asterisk outgoing calls queue.
  • TeleYapper initializes the date/time and status fields for each record in the Group to be called. These are only filled in when a call is then answered.
  • If you've enabled logging in teleyapper.php, then the log is generated after all of the call setups have been completed.
  • If you've enabled emailing of the teleyapper.php log, then the log is emailed to your email address at the same time.
  • Asterisk checks its call queue each minute and places each call at the appointed time, Then it waits for the callee to answer.
  • If no one answers the call, nothing is posted to the MySQL database regarding call completion. That's how we identify unsuccessful calls.
  • If the call is answered, the callee is advised to hold for an important message and then your prerecorded message plays.
  • Callee is then prompted to press 1 to replay the message, press 2 to blacklist the last caller (you!), or press 3 to hang up.
  • If callee presses 1, your message is replayed, and then the call is disconnected. MySQL database will show date/time of call with ReplayedMsg as status.
  • If callee presses 2, log will reflect that caller requested blacklisting. MySQL will actually DELETE this person from your database. It's the LAW!
  • If callee presses 3, Allison says goodbye and Asterisk hangs up the call. MySQL database will show date/time of call with status of OK.
  • If callee makes no choice, Asterisk will replay your message, then hang up, and record the date/time of call with status of AnsMachine.
  • If you've enabled logging in teleyapper2.php, then the individual call log is generated and appended to the main log file after each call has been placed.
  • If you've enabled emailing in teleyapper2.php, then the call log is emailed to your email address after EACH call has been placed.
  • The Tab. You're probably wondering what the cost was to deliver all of the messages to 700 people since we were paying by the minute. Since the message was about a minute long, that translated into roughly a two minute call for calls in which an answering machine picked up since TeleYapper automatically replays a message if the callee doesn't press a button on their phone. That accounted for roughly 70% of the calls. Even with the large volume of calls to answering machines, the total tab for placing the 700 calls was just under $10. Enjoy!

    Nerd Vittles Demo Hot Line (courtesy of les.net). You now can take a number of Nerd Vittles projects for a test drive... by phone! The current demos include (1) MailCall for Asterisk with password 1111 (retrieve your email by phone), (2) NewsClips for Asterisk (latest news headlines in dozens of categories), (3) Weather Forecasts by U.S. Airport Code, and (4) Weather Forecasts by U.S. ZIP Code. You're not prompted for #4 yet, but it does work! Just call our number (shown in the left margin) and take any or all of them for a spin. The sound quality may not be perfect due to performance limitations of our ancient Intel 386 demo machine. But the price is right.

    Nerd Vittles Fan Club Map. Thanks for visiting! We hope you'll take a second and add yourself to our Frappr World Map compliments of Google. In making your entry, you can choose an icon: guy, gal, nerd, or geek. For those that don't know the difference in the last two, here's the best definition we've found: "a nerd is very similar to a geek, but with more RAM and a faster modem." We're always looking for the best BBQ joints on the planet. So, if you know of one, add it to the map while you're visiting as well.

    Some Recent Nerd Vittles Articles of Interest...

    Ringbinder theme by Themocracy