Home » Search results for 'allison ivr' (Page 11)

Search Results for: allison ivr

The Most Versatile VoIP Provider: FREE PORTING

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...

    Nerd Vittles Birthday Bash: freePBX 2.2.0, TrixBox for Macs, CallerID Trifecta for Asterisk, and…

    We made some New Year’s Resolutions this year… that we intend to keep. So, no, we’re not going to discuss losing weight. Our most important resolution was to stop getting caught up in upgrade-itis with Asterisk® and TrixBox. After all, we’re building phone systems that folks expect to be considerably more reliable than their Windows desktop machines… which doesn’t take much. We’ve gotten literally hundreds of emails asking the same two questions: when do we plan to switch to TrixBox 2.0 and how about upgrading to Asterisk 1.4? Our answer is always the same to both questions: not anytime soon. Why? Because there is almost nothing that can’t already be done with TrixBox 1.2.3. It’s 99% reliable, at least once you NerdVittlize It using our upgrade script. So what do these upgrades buy you other than another version number? Who knows? We’d suggest you do a lot of reading before making the leap. Start with Chris Sherwood’s Guide and see if there’s some new feature you really can’t live without. And then check out the TrixBox Help Forum to determine if you can deal with the reported problems. That’s the balancing act we all have to perform, and we’ll let you know when we finally take the plunge. For now, we’re happy with the feature set in TrixBox 1.2.3, and it lets us build reliable snap-on applications that really make a phone system hum. If there are features you don’t need or use, just turn them off. That’s what WebMin is for! Think of it as TrixBox 2.0 in reverse. Instead of enabling apps, you disable them. Are you really that short on disk space? As for the feature set, you’re not missing much. Our home phone system has so many gimmicks and gizmos that some callers (mostly my perverted friends) ask to speak to Allison when they call. She doesn’t live with us. She’s a nice Canadian girl, but you might still enjoy listening to her recent interview with Ronald Lewis.

    Having said all that, there’s one new product for Asterisk that is nothing short of incredible. That’s the Rob Thomas & Co. upgrade of freePBX to 2.2.0. While the developers have conservatively numbered the new version, don’t be deceived. It’s more like 3.0 compared to the 2.1.3 version that ships with TrixBox 1.2.3. Why the enthusiasm? Because freePBX now includes the toolset that lets developers add unlimited new functionality without mucking around in the basic freePBX code. We’ll show you what we mean in a little bit so hang in there. Our diatribe is almost over.

    We’ve also gotten a lot of questions about whether we’ve looked at AsteriskNOW, the new "appliance" from Digium. Yes, we’ve looked and we’ve read some excellent documentation. If all you want to do is set up some extensions around your house and replace your answering machine, it looks like an interesting product. What’s missing? Well, the 80 million things you can do with freePBX for openers. So we actually thought about writing a HOW-TO covering installation of freePBX 2.2.0 with AsteriskNOW, but then we remembered our New Year’s Resolution, not to mention the Asterisk 1.4 wrinkle with a bunch of missing commands. They call them "deprecated." It’s a nice word for throwing the baby out with the bath water. To save a few lines of code, the Asterisk developers removed some important, old commands from the product. So now application developers have to review and update every piece of code they’ve ever written for Asterisk to make sure there aren’t any deprecated commands lurking. To make matters worse, you have to have different versions of applications to run on Asterisk 1.2 and Asterisk 1.4. Dumb idea not to mention a huge waste of time and talent! So… here’s our bottom line: why reinvent the wheel when TrixBox 1.2.3 is rock-solid reliable and when TrixBox uses the very best tools in the business: Asterisk 1.2.12.1, Apache, MySQL, PHP, Flite, SendMail, SugarCRM, and on and on we go. Aside from the IAX security hole which our upgrade script patches, every one of these applications is a proven winner which brings us back to freePBX.

    You really, really need freePBX 2.2.0! We plan to build all of our future goodies using it so climb on board today. We promise. You’ll enjoy the ride… every week! If you’re using TrixBox 2.0, you’re all set. If not, here’s how to upgrade your TrixBox 1.2.3 system to freePBX 2.2.0 in about 10 minutes! There’s nothing hard about any of this. The remainder of this article does assume that you have installed TrixBox 1.2.3 from the original .iso image and then NerdVittlized it on a dedicated Linux machine OR that you’ve installed our VMware/Windows XP version of TrixBox 1.2.3 which comes NerdVittlized out of the box. Otherwise, as they say, YMMV. If you’re new to all of this and have no idea what NerdVittlizing means, read up on the gerund here, and then come back and join us once you’ve secured your system and added all of the the Nerd Vittles goodies.

    When we get finished with the freePBX upgrade to your TrixBox 1.2.3 system, everything that worked before you started the upgrade will still work when you get finished. Of course, we recommend you try this out on a non-production system and verify for yourself that your system still functions reliably. That’s what VMware is for! But we think you’ll find that you still have a system that is ready to put in production: phones ring, applications run just as before, and all the things you have come to rely upon in your phone system will still function. And we’ll have an essential, new building block to add all sorts of additional features to your system in coming weeks without breaking anything. We’re even going to add a few goodies today just to get you started!

    Upgrading to freePBX 2.2.0. The upgrade process is straight-forward, but you need to pay attention and perform the steps in the order we’ve outlined below. Winging it will result in a system that either doesn’t work at all or one that may exhibit all sorts of quirky behavior. So, be reasonable. Do it our way! We’ve tested this about a dozen times on all sorts of different machines which is something you’re probably not going to find all that exciting to replicate.

    First, make sure that your TrixBox 1.2.3 server is working reliably. It handles incoming calls correctly, voicemail works, outbound calls work, etc. Once you’re certain that you have a stable TrixBox 1.2.3 system, then log into your server as root and issue the following commands in order. If, for some reason, the freePBX mirror site is unavailable, substitute bestof.nerdvittles.com/applications/callerid for mirror.freepbx.org below:

    cd /usr/src
    wget http://mirror.freepbx.org/freepbx-2.2.0.tar.gz
    tar zxvf freepbx-2.2.0.tar.gz
    cd freepbx-2.2.0
    ./install_amp  (When prompted whether to overwrite existing files, type a)
    

    Once the installation is completed, don’t reboot your system or restart Asterisk! Instead, using a web browser (IE 6 works great) point the browser to the IP address of your web server. Choose System Administration and type the username maint followed by your password to gain access. Now choose freePBX. Whatever you do, don’t click the Red Bar to update settings until you’ve completed all of the steps below.

    Pass #1. We’re going to make three passes through the FreePBX module update process before we’re ready to click the Red Bar. So choose Tools then Module Admin then click Check for Updates online. Click Download all at the top, far right side of your browser window. Then click the Process button followed by the Confirm button. Wait for the downloads to be processed. Then click the Return button at the bottom of the browser window.

    Pass #2. Click Upgrade all at the top, far right side of your browser window. Then click the Process button followed by the Confirm button. Wait for the upgrades to be processed. Then click the Return button at the bottom of the browser window.

    Pass #3. Click Upgrade all at the top, far right side of your browser window. Then click the Process button followed by the Confirm button. Wait for the upgrades to be processed. Then click the Return button at the bottom of the browser window.

    Finally, click the Red Bar to apply the configuration changes. Count to 20. Now let’s log into your server as root again and make a minor correction or two, and you’ll be ready to reboot and go. Once you’re logged in, issue the following commands to fix the initial voice prompts with our Stealth Autoattendant:

    cd /var/lib/asterisk/sounds/custom
    mv nv-greeting.wav nv-greeting.wav.bak
    mv nv-menu.wav nv-menu.wav.bak
    

    Now edit line 428 in the extensions.conf file to resolve a freePBX bug with Enum Lookups:

    nano -w /etc/asterisk/extensions.conf
    Ctrl-W and type: arg3 is pattern
    press Enter key
    Ctrl-W again and press Enter key
    

    You can verify the line number by pressing Ctrl-C in Nano. You should be positioned on line 428 which begins like this:

    exten => s,1,GotoIf($["{$ARG3}" = 
    

    Just insert an exclamation point (!) immediately before the equals sign (=) so that it looks like this != and save your change: Ctrl-X, Y, then press Enter.

    Now restart your server, and you’re done: shutdown -r now. Congratulations! You now should have a functioning freePBX 2.2.0 system. Be sure to take a look at the Release Notes and the freePBX Wiki.

    Adding Free Directory Assistance to freePBX. We’ll have a whole bunch more to say about freePBX 2.2.0 in coming weeks, but we wanted to give you a couple of sneak previews of new functions which are incredibly powerful. First, there’s a new way to add loads of functionality to your system without having to be a programmer. For example, here’s how to integrate free Directory Assistance into your system by simply dialing 411 from any phone connected to your Asterisk system.

    Using your web browser, go back into freePBX (System Admin, freePBX, Setup) and choose Misc Destination. Make the following entries:

    description  Directory Assistance
    dial  8003733411
    

    Then click the Submit Changes button followed by the Red Bar to reload your configuration into memory.

    Now choose Misc Application and make the following entries:

    description  Information
    Feature Code  411
    Status  Enabled
    Destination  Misc Destination:Directory Assistance
    

    Then click the Submit Changes button followed by the Red Bar to reload your configuration into memory. Now dial 411 from any phone on your system and enjoy free Directory Assistance.

    Checking Your AutoAttendant. The real beauty of the new Misc Application function is that you can use it for internal testing of almost anything. For example, to try out your Stealth AutoAttendant by dialing 412 from any extension, add the following Misc Application:

    description  Test AutoAttendant
    Feature Code  412
    Status  Enabled
    Destination  IVR:Stealth AutoAttendant
    

    Click the Submit Changes button followed by the Red Bar to reload your configuration into memory. Now dial 412 from any phone on your system and you can try out the Nerd Vittles Stealth AutoAttendant without having to dial into your system from an outside phone.

    Accessing the VoiceMail System. Another nice trick is to add hidden extensions to access VoiceMail. Let’s assume you want to do this for extension 500 and for the hidden extension number we add another zero: 5000. Here’s how to set up the Misc Application:

    description  VoiceMail 500
    Feature Code  5000
    Status  Enabled
    Destination  Core:voicemail box 500
    

    Click the Submit Changes button followed by the Red Bar to reload your configuration into memory. Now dial 5000 from any phone on your system to access the VoiceMail box for extension 500. It’s an easy way to leave messages for someone else on your system without dialing in from an outside phone. You can also use it to retrieve voicemail. Just press the asterisk (*) button while the voicemail prompt is playing on the phone. Then enter your voicemail password for extension 500. You should be catching on by now. Build a few more just for fun.

    Happy Birthday to Us. We’ll close by mentioning that it’s a big week here at Nerd Vittles. And we have a couple more surprises for you. This Friday marks our Second Birthday. Hard to believe it’s been two years. We spent our first six months covering what you could do with a $500 Mac mini. But the last 18 months have been devoted almost exclusively to Asterisk. Our gift to you is the brand new Best of Nerd Vittles web site. Have a look. There’s an RSS Feed for the new site as well. We think you’ll enjoy both the new format and the content. And, it’ll only get better as time marches on.

    And your gift to us? Glad you asked. What a great time to send along a modest contribution through the PayPal link at the top of the page. If every person that reads Nerd Vittles each week donated just ten bucks with any major credit card, we’d have the resources to pull off some really slick projects and hire a little help. Those additions just aren’t feasible without Yankee Dollars. So skip that overpriced cheeseburger today and do your part for the cause. We promise to spend it wisely, and, just like your church, we won’t come calling again (at least not too often) until this time next year. Finally, an apology for the yo-yo’s at PayPal. Once in a while, their system tacks on a shipping charge to donations. No shortage of Village Idiots, is there? If it happens to you, just reduce the amount of your donation accordingly. We’ve screamed and hollered for two years, but it still happens once in a while for no apparent reason. We’ve gotten two generous contributions in recent days for $47.50, not the sort of number someone usually pulls out of their hat. But thanks nevertheless and our apologies for the shipping charge! Now back to the party. All together now… Happy Birthday, Nerd Vittles… and to all a good night.

    From the Really Cool Dept. We’ve got a few more surprises to pull out of our hat so hang in there. What’s this? A New Bunny! We received a rather unique birthday gift from a fan. It’s a new Nabaztag/tag Wi-Fi Rabbit. We’ve named him PatTheNerd, what else? In addition to blinking lights and wiggly ears, you get a talking bunny with one of the best voice synthesizers on the planet. And it all runs over a self-configured wireless network connection on your LAN. Want to try it out? Feel free to send us a voice message. Just click on the bunny (inset). And soon, you’ll be able to issue voice commands directly to your bunny as well. Who’s Yo Daddy?

    If you’ve never heard of these little guys, you’ve got some serious reading to do. Start here and then head to their Forum. Every kid should have one! And, once you get yours, leave it to Nerd Vittles to turn your little critter into a Weather Bunny, maybe not as cute as the one at your local television station, but still pretty cool. Your Weather Bunny will tell you the latest weather conditions in any city in the United States as often as you like. Just add an entry to your Asterisk crontab! Sound familiar? You can download our WeatherBunny for NabazTag application written in PHP at your convenience. And now there’s a News Bunny as well! We’ll continue NerdVittlizing Pat in the coming weeks so stay tuned. Pat should be great at providing message alerts and reading emails and voicemail. Someone has even set up an Asterisk voicemail box for their rabbit. So what are you waiting for? Order one for yourself and put a bunny to work! Thanks, anonymous!

    News Flash! For Intel-based Mac users, the wait is over. A beta of VMware is now available simply by filling out this form. Once installed, you should be able to run the VMware version of TrixBox 1.2.3 or the VMware version of TrixBox 2.0 on your Mac Desktop. Let us know how it goes! We’re jealous and wishing we had an Intel Mac ourselves. All we got was a dumb bunny.

    CallerID Trifecta. NOTE: This application has been superseded. Continue reading the latest article here.

    Finally, we’ll leave you with some seriously good, new software if we do say so. It’s been almost a year since we last discussed CallerID Tips and Tricks. Seems to be our favorite topic on Nerd Vittles around the time of our birthday celebration. Don’t ask us why? But we wanted to continue the tradition this year by introducing an all-new CallerID Trifecta. Thanks to freePBX 2.2.0, with just a couple minutes of effort, you can snap our code into the web directory on your Asterisk server, make a couple of freePBX entries, and, presto, you get instant CallerID name lookups for all your incoming calls using AsteriDex, the Google Residential Phonebook, and AnyWho. We’ll add more sources including SugarCRM in the coming weeks. For today, you’ll find the documentation and download at this link on the Best of Nerd Vittles site. Particularly for those outside the U.S, we think you’ll find the PHP code easy to follow if you want to build additional directory resources on your own. Just be careful to always exit from the procedure rather than letting it just play out, or freePBX gets squirrelly and often just dumps incoming calls into voicemail. Guess how we know. Enjoy and thanks for visiting!


    Some Recent Nerd Vittles Articles of Interest…

    Introducing a Complete Podcast Studio for Everyman: Your Telephone

    With apologies to the Univ. of Wisc. for this spoofFor those that have been chomping at the bit to play with podcasting, today's your lucky day. We're going to show you how to do anything you've ever wanted to do with podcasts using your plain old telephone. All you need is a shiny new TrixBox server or any Asterisk® server with freePBX installed. If you don't have a TrixBox system, take advantage of our new one that'll run on your Windows Desktop. The free download and 15-minute installation tutorial are both here. Once you get everything installed, you're half way there. As it happens, freePBX (included as part of every TrixBox) has a podcast recording system built right in. It uses a free service called GabCast. To start podcasting, just sign up for a free GabCast account.

    GabCast Overview. Out of the box, there are two things you can do with your TrixBox system and GabCast. First, you can create podcasts. And, second you can host conference calls. Today Nerd Vittles adds the third leg to the stool. With the new GabCast Player for Asterisk, you'll be able to listen to any GabCast channel feed using a garden-variety, touchtone phone. So long as you know the channels you want to listen to, you can kiss your iPod and web browser goodbye and listen to these podcasts by telephone from anywhere. We'll show you how.

    We're not going to spend much time talking about conference calls today. Suffice it say, with GabCast, the first 30 minutes are free. After that, it's 10¢ a minute. It takes about 30 seconds to set up a conference call and start using it. The steps to create your own podcast are pretty simple as well. You set up a GabCast account. You configure the GabCast module in freePBX. You dial into GabCast from a phone on your Asterisk system or by calling a toll-free number and entering your channel number and password. Then you start recording your podcast. Press the pound key and decide whether to publish your masteripiece. It's that simple. Once you post your new recording on the system, GabCast automatically generates an RSS Feed alerting subscribers that you've added an episode to your channel. The podcasts can be played back either using a web browser, iTunes, or today's addition: a plain old telephone. Before we get started, we've set up a demo system as usual so you can take the new GabCast Player for Asterisk for a spin. Just dial the number in the left margin and enter 1707 when prompted for the channel number. Enjoy the Nerd Vittles (sick) Joke of the Day. We promise not to add any more! Give us a break. It's just a demo site. If you're interested in some good Asterisk podcasts, try Phoneboy's channel 229 or one of the many Asterisk and TrixBox channels: 292, 1327, and 1493 to name a few. Now where were we?

    GabCast Signup. Getting set up with GabCast couldn't be any easier. Go to their web site. Click the Sign Up tab. Agree to the Terms of Service and tell 'em you're older than 13. Fill in the blanks on the form including the password you want to use and a valid email address that you'll use to sign in. Wait for your return email, and you're all set. Log in to your account and click Create a new channel. Fill in the form and be sure to assign a numeric password to the channel. Click Submit and you're done. You'll use your channel number and the numeric password assigned for this channel to access your account by phone and record podcasts. Sign out of GabCast for the time being.

    freePBX Setup. Setting up your TrixBox system for GabCast is equally simple. Log in to the freePBX administration section of your TrixBox server using a web browser: http://192.168.0.125/admin. Be sure to use your IP address, not ours. Type maint for your username and whatever password you created when you set up your system. Click on the Setup tab, and Gabcast should be in the list of options in the left column if you set up your system using the Nerd Vittles tutorial. If not, click Tools->ModuleAdmin, Connect to On Line Repository, check the Gabcast module, and then Download and Install it. Now reread this paragraph.

    By clicking on the Gabcast link under the Setup tab, you can assign a phone number on your system that you dial to record new podcasts. Just enter the gabcast channel, the numeric password for the channel, and the extension number to be assigned to this channel. Save your settings and click the Red Bar to reload Asterisk. The alternative is to dial *422 (which spells G-A-B) to access GabCast. Then you'll be prompted for your channel number and password. Either way works ... unless you happen to be using a Sipura device for POTS phones. In this case you'll have to activate *422 in the Sipura dial plan to use it. Otherwise, you'll get a fast busy when you dial *422.

    Sipura SPA-1001 Setup. If you took our recommendation and are using a Sipura device to enable use of plain old telephones in your home or office, then you'll need to modify the Dial Plan slightly. Point a web browser to the IP address of your device and then click Admin Login and then Advanced. Now click on the Line 1 tab and scroll to the bottom of the form. You'll see a field named Dial Plan. Carefully insert *422| after the first vertical bar in the field. So your dial plan entry should now look like this:

    (*xx*xxxxxxxxxxx.|*422|*x*xxxxxxxxxxx.|[3469]11|0|00|[2-9]xxxxxx|xxxxxxxxxxxx.)

    Click the Submit All Changes button and wait for your Sipura device to restart. Then pick up a phone connected to the device and dial *422, enter your channel number and password, and begin your recording career. Move over Elvis!

    Accessing Your GabCasts. The gabcast site explains in detail the available options for listening to gabcasts. Just click on the Listen tab. Then click on a channel, and you can play the feed in your web browser. Or you can Subscribe to a channel and plug the RSS Feed into your favorite RSS Reader/Player including iTunes, Safari, and more than a dozen web portals. You also can insert a Player right into your web site.

    Introducing GabCast Player for Asterisk. What was missing from all these features was a simple way to play gabcasts on your plain old telephone. Leave it to Nerd Vittles to close the gap, and today we do by introducing our new Gabcast Player for Asterisk. Once installed, you just pick up a phone and dial 422 for G-A-B. Choose the Channel you want to listen to and select the desired Episode to play. Then just sit back and listen on any phone or speakerphone connected to your Asterisk system. If you really want to get fancy, you can redirect a DID on your system to extension 422, and the whole world can dial into your GabCast Player from anywhere on the planet.

    GabCast Player Installation. To get everything working, there are four steps. We'll add a little code to your dialplan in the extensions_trixbox.conf file in the /etc/asterisk folder. Then we'll download the player into /var/lib/asterisk/agi-bin and add a few custom sounds from Allison. And finally we'll add a new Misc Destination using freePBX Setup.

    Adding the Dialplan Code. There are a couple of ways to add dialplan code. You can either log in to your server as root and use the nano editor to modify the dialplan (nano -w /etc/asterisk/extensions_trixbox.conf, or you can use the TrixBox web interface pointed to the IP address of your server: http://192.168.0.125/maint. Then choose Config Edit and pick extensions_trixbox.conf to edit. So pick your poison and add the following code into to the [from-internal-trixbox] context (a.k.a. section) of the file. Then save your changes.

    exten => 422,1,Answer
    exten => 422,2,Wait(1)
    exten => 422,3,DigitTimeout(5)
    exten => 422,4,ResponseTimeout(7)
    exten => 422,5,Read(GABCAST,custom/gabcast-channel,5)
    exten => 422,6,NoOp(${GABCAST})
    exten => 422,7,AGI(gabcast.php|${GABCAST})
    exten => 422,8,Playback(thank-you-for-calling)
    exten => 422,9,Playback(custom/gabcast-visit)
    exten => 422,10,Playback(goodbye)
    exten => 422,11,Hangup

    With nano, you save your updates by pressing Ctrl-X, Y, then Enter. With the web editor, you simply click the Update button. Remember that anytime you change your dialplan you'll need to reload your Asterisk settings for the changes to take effect. We're not going to do that just yet because we have to make a change in freePBX which will automatically reload Asterisk when we click the big Red Bar.

    Installing the GabCast Player and Sound Files. Custom Asterisk apps such as our Gabcast Player live in /var/lib/asterisk/agi-bin on your Asterisk server. Custom sound bites go in the /var/lib/asterisk/sounds/custom directory. So log in as root and issue the following commands in order:

    cd /var/lib/asterisk/agi-bin
    wget http://nerdvittles.com/gabcast/player.zip
    unzip player.zip
    rm -f player.zip
    chown asterisk:asterisk gabcast.php
    chmod 775 gabcast.php
    cd /var/lib/asterisk/sounds/custom
    wget http://nerdvittles.com/gabcast/sounds.zip
    unzip sounds.zip
    rm -f sounds.zip
    chown asterisk:asterisk gabcast*
    chmod 664 gabcast*

    Adding a Miscellaneous Destination to freePBX. One more step and we're finished. Start up freePBX using the IP address of your server: http://192.168.0.125/admin. Click Setup then Misc Destinations. For the Description, type gabcast. For Dial, type 422. Leave the --featurecode-- the way it is and click Submit Changes then the Red Bar. We're done. Just pick up a phone on your system and dial 422. When prompted for the channel, press 1707#. When prompted for the epidsode, just pick one or two and press the pound key... with apologies (in advance) to the ladies and others that are easily offended. You're a gabcast expert now. Enjoy!

    Nerds' Corner. Today we introduce a new addition to our free software articles. In Nerds' Corner, we'll provide some insights into the programming hurdles, tips and tricks, and even some feeble insights into the actual code writing to give would-be Asterisk programmers a leg up with future projects. Let us hasten to add a disclaimer. We don't write PHP code that most good PHP programmers would be proud to claim. But our way makes this a one-day project instead of a week or a month. And our code is easy to read and easy to follow, almost self-documenting (which is every programmer's wet dream). It is anything but efficient. But with today's computers and the interactive nature of the applications we are writing, it really doesn't matter. If you'd prefer to study good PHP code writing, study the code for freePBX or a2billing, not ours. Having said that, let us hasten to add that our code works and is usually pretty close to bug-free. Why? Because we can actually read it and find problems before you do. Here's hoping we haven't jinxed ourselves. Be sure to also read the Comments posted below this article just in case.

    The difficult issues implementing a player for gabcast all revolved around the MP3 files that actually store the podcasts. First, you need a way to figure out the filenames since they are stored in a hidden directory. Second, you need a way to convert the files into a format that Asterisk can play. And third, of course, you need a player that works with Asterisk and a telephone. Let's tackle them in reverse order. Asterisk includes an MP3Player command which would appear the likely candidate for playing MP3 files. Wrong! It doesn't work on TrixBox systems so we needed a way to convert the MP3 podcasts into a format that a TrixBox system actually could play. As luck would have it, the folks over at the Michigan Telephone Blog already had tackled this issue for podcasts so we started there. The final sticky wicket had to do with actually deciphering the file names of the MP3 files containing the podcasts. Well, the good folks at GabCast.com solved that one for us. It was so obvious it almost bit us. The RSS feed for each channel actually includes an enclosure tag with the MP3 filename in the metadata for each gabcast episode. It was smooth sailing after that. Take the channel number and retrieve the RSS feed for that channel. Then parse the metadata to strip out the MP3 filenames and subjects for each episode. Then prompt the caller for the desired episode, convert the MP3 file (using lame) to an MP3 format that will actually play using the Asterisk AGI playback command. It can play MP3 files if they are in the correct format and if you don't include .mp3 in the filename on the playback command line. Also embedded in the gabcast.php code, you'll find a good example of how to implement IVR technology in an Asterisk PHP script. In this case, we tell the user how many episodes are available and then prompt the user for the desired episode to play after using Flite to play the subjects of the five most recent episodes. If the user enters a number which is outside the appropriate range of existing episodes, then we play the most recent episode whether the user likes it or not. One final gotcha has to do with the numbering of the available episodes. If you look at a few channels on the gabcast site (such as ours), you'll notice that it isn't uncommon for a publisher to delete certain episodes leaving episode numbers which might look like this: 1, 4, 6, 8, 9. This information is available in the RSS feed, but it would complicate the IVR system. So we chose to merely count the episodes in the RSS feed and then number them from 1 to the total number of episodes reserving the highest number for the most recent episode. For most folks, this won't pose a problem because they probably won't be retrieving podcasts with both a web browser and a phone. Thus the mismatched numbering shouldn't matter. If it does, oh well!

    One final note of caution. As distributed, the Nerd Vittles Gabcast Player is implemented as a single-user system. Each time someone calls 422, the system erases all existing podcast MP3 files from the previous session. Simultaneous calls would obviously be a problem with this architecture. But we did it so that the code would run efficiently even on a VMware TrixBox implementation. These MP3 files can be quite large depending upon the length of the podcast which can be up to 60 minutes long. The bottom line is that, if you plan to deploy this in a multi-user environment with multiple people simultaneously calling 422, then you'll need to modify the section of the code that deletes the previous MP3 files. You'll find it at line 165 with some commented-out code above it that will work better in a multi-user environment (but will consume more disk space saving prior MP3 podcast sessions).

    Finally a special word of thanks to Allison Smith for doing her usual fine job recording voice prompts for this application. One day turnaround would be shocking and downright laughable in most businesses. Not so with Allison. It's her usual way of doing business which makes articles and applications like this one possible. Thanks, Allison!

    BroadVoice Strikes Again. The BroadVoice geniuses are burning the midnight oil again. They've finally implemented Basic 911 "Service" for customers in the United States. Here is the important part of last night's customer announcement:

    BroadVoice's main concern is customer safety and
    satisfaction. For this reason, BroadVoice has made
    Basic 911** service available to all U.S Customers.
    ...
    ** Basic 911 service is available for all U.S. customers.
    Customers who have basic 911 service will receive one (1)
    free 911 emergency call per year. Any subsequent calls
    within a year will have a fee of $100.00 per call.

    [BV goes on to say that "Enhanced" 911 Service calls are free
    IF you register your address AND IF you agree to the following:]

    YOU ACKNOWLEDGE AND UNDERSTAND THAT BROADVOICE
    WILL NOT BE LIABLE FOR ANY SERVICE OUTAGE AND/OR
    INABILITY TO DIAL 911 USING THE BROADVOICE SERVICE
    OR TO ACCESS EMERGENCY SERVICE PERSONNEL DUE TO
    THE CHARACTERISTICS AND LIMITATION OF THE BROADVOICE
    SERVICE AS SET FORTH IN THIS DOCUMENT. YOU AGREE TO
    DEFEND, INDEMNIFY, AND HOLD HARMLESS BROADVOICE,
    ITS OFFICERS, DIRECTORS, EMPLOYEES, AFFILIATES, AND
    AGENTS AND ANY OTHER SERVICE PROVIDER WHO FURNISHES
    SERVICES TO YOU IN CONNECTION WITH THE SERVICE, FROM
    ANY AND ALL CLAIMS, LOSSES, DAMAGES, FINES, PENALTIES,
    COSTS, AND EXPENSES (INCLUDING, WITHOUT LIMITATION,
    REASONABLE ATTORNEY FEES) BY, OR ON BEHALF OF, YOU OR
    ANY THIRD PARTY USER OF THE SERVICE RELATING TO THE
    FAILURE OR OUTAGE OF THE SERVICE, INCLUDING THOSE
    RELATED TO THE BV 911 SERVICE.


    We're guessing that the BroadVoice Bean Counters decided that, if they made the disclaimer obnoxious enough and the fee high enough for this great new service, it might cause all of their customers to have heart attacks which in turn would generate loads of 911 calls. Talk about kicking your customers while they're down. Now read the first sentence again... and then the part in the BIG LETTERS. They really do think the world is full of idiots, don't they? Yikes!


    Nerd Vittles Demo Hot Line. You now can take a number of Nerd Vittles projects for a test drive... by phone! The current demos include NewsClips for Asterisk (latest news headlines in dozens of categories), MailCall for Asterisk with password 1111 (retrieve your email by phone), and Nerd Vittles Weather Forecasts by U.S. Airport Code. 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.

    Hosting Provider Special. Just an FYI that the Nerd Vittles hosting provider, BlueHost, has raised the bar again on hosting services. For $6.95 a month, you can host up to 6 domains with 30GB of disk storage and 750GB of monthly bandwidth. Free domain registration is included for as long as you have an account. That almost doubles last month's deal, and it really doesn't get any better than that. Their hosting services are flawless! We oughta know. We've tried the best of them. If you haven't tried a web hosting provider, there's never been a better time. Just use our link. You get a terrific hosting service, and we get a little lunch money.

    Want More Projects? For a complete catalog of all our previous Asterisk projects, click here. For the most recent articles, click here and just scroll down the page.

    Headline News for the Busy Executive and the Lazy Loafer. Get your Headline News the easy way: Planet Asterisk, Planet Gadget, Planet Mac, and Planet Daily. Quick read, no fluff.

    Got a PDA or Web-Enabled Smartphone? Check out our new PDAweather.org site and get the latest weather updates and forecasts from the National Weather Service perfectly formatted for quick download and display on your favorite web-enabled PDA, cellphone, or Internet Tablet. And, of course, it's all FREE!

    Asterisk Call Queues: The Smarter Way to Manage Incoming Calls

    Ever wished you could screen incoming calls and route them to another person, or to an autoattendant, or to voicemail without the caller knowing what you're up to? Need a free Automatic Call Distribution (ACD) System for your business (with Elevator Music no less) that will balance incoming call workload among your employees? Ever wanted to prioritize incoming calls from different groups of callers? How about a simple way to access hidden features on your Asterisk® system when you're away from your home or office? Well, the latest Asterisk (1.2.4) now can do all of this without breaking a sweat... with Call Queues. And, with Asterisk@Home 2.5 and its included Asterisk Management Portal, you can build a complete Call Queue System in about half an hour.

    Prerequisites: For today's project, you'll need at least Asterisk@Home 2.5. It can even be installed on your Windows desktop if you just want to experiment. We haven't yet tested this with Asterisk@Home 2.6, but we can always use a good guinea pig to report back. Just about any kind of incoming trunk should work: SIP, IAX2, or ZAP/PSTN. Then you'll need at least one Asterisk extension and a few external phone numbers we can play with to demonstrate how everything works. Depending upon what features you decide to use in your own system, you may also need a few customized voice prompts from Allison Smith although we'll provide some samples to get you started. The main voice prompt to explain to callees how to manage incoming calls from the call queue was funded previously by readers just like you. For the freeloaders, that's what the donate button is for ... to keep the goodies coming. To order your own voice prompts, you first sign up for an account at thevoice.digium. com. Then you go to digium.com and order 1 voice prompt (20 words) for $12 or 5 voice prompts with up to 20 words each ($50). When you sign up for your Digium account to actually pay for the prompts, make sure you use the same email address that was used when you signed up for your account on thevoice.digium.com (where you'll request creation of the prompts from Allison). After your check clears, Digium will deposit voice prompt credits in your thevoice.digium.com account. You then can log in there, type out what you want your prompts to say, and a few days later the prompts will be sitting there for you to review and download. It doesn't get much easier than that.

    Overview. We're going to build a new flavor of our original Stealth AutoAttendant except today we're going to take advantage of a Call Queue to enhance the functionality of the original system. Along the way, we'll also show you how to expand this into a full-blown Automatic Call Distribution System for your business, large or small. The way today's system will work goes something like this. A caller calls your home. Asterisk answers the call and plays a message that says something like the following: "Hi. You've reached the Rockefeller's residence. Someone will be with you in a moment." Asterisk will then crank up Music on Hold and will direct the call to your Home Call Queue. This call queue will simultaneously ring all of your house phones and, if desired, your cell phone, Aunt Betty's phone at the nursing home, and your office extension. The CallerID displayed on all the ringing phones will be that of the incoming call. As with all Asterisk calls, whoever answers the call first gets the call. And there's no limit to the number of call queues on your system. It's just another "extension" to Asterisk. So it's easy to set up individual call queues for you and your spouse as well as each of the kids. Each can have its own incoming DID and a separate list of numbers to call when incoming calls arrive. Same goes for business use except you can add the ACD functionality of spreading out the incoming call workload to various employees.

    When an incoming call arrives, if you don't answer the call, Asterisk optionally can play an AutoAttendant menu after a time limit that you specify giving the user choices of calling you or your spouse on your cellphone, calling your vacation home, or simply leaving a message on your voicemail system. Whatever you want it to say and do is pretty much up to you. If the incoming caller doesn't take tha bait and press a button, the phone extensions and outside numbers you've designated will all start ringing again. If the second attempt fails, the caller will get the IVR menu again after which the caller will be dumped into voicemail if the caller fails to choose an option. Again, you can set this scenario up in any way you like. That's just the way we've set it up for the example.

    If the caller chooses an option, the call will be transferred to the appropriate number inside or outside your Asterisk PBX system. If you happen to be calling in to your own system, you can press single-digit numbers for other options that weren't identified in the IVR voice prompt to activate other Asterisk features such as DISA or reading your voicemail. If you'd prefer to dump calls you don't answer directly into your voicemail system, that can be done as well although you would lose the IVR features including the hidden functionality we've outlined. There are lots of options. Experiment!

    If someone does answer the incoming call from the Call Queue, Asterisk will play instructions about available choices. We've sprung for that voice prompt, and the choices go something like this:

  • Press the star key (*) to immediately answer the incoming call.
  • Press the pound or hash key (#) and enter a phone number to transfer the incoming call elsewhere. The caller won't have a clue!
  • Press the pound or hash key (#) followed by 86 (that's VM for Voice Mail in case you're wondering) to transfer the incoming call to your voicemail.
  • Continue to wait for the tone and the call will automatically be connected.
  • You can add other obnoxious options here if you'd like. Basically, you can transfer any incoming call to any extension number for which you've created a custom context. These give you the full flexibility of the Asterisk programming language. For our purposes today, they can be used to irritate or annoy people who are irritating or annoying. Here's an example. Adding the following code to the [from-internal-custom] context of extensions_custom.conf and then transferring a call by pressing #-3-8-3 (D-U-D) will play a message that everyone in your household is busy taking other calls from telemarketers and to please try the call again later. Works great for calls with no CallerID if you want to personally review these. Click!

    exten=>383,1,Answer
    exten=>383,2,Wait(1)
    exten=>383,3,Background(tt-allbusy)
    exten=>383,4,SetMusicOnHold,default
    exten=>383,5,WaitMusicOnHold,30
    exten=>383,6,Background(thank-you-for-calling)
    exten=>383,7,Background(goodbye)
    exten=>383,8,Congestion
    exten=>383,9,Hangup

    Gotcha Alerts. We discovered one anomaly in building this on our Asterisk system. By the way, we've loved that word "anomaly" ever since it was first used by Ashton-Tate, the folks that marketed dBASE. They just never could bring themselves around to calling anything a bug. Anyway, here's the Call Queue problem which didn't appear for us until about the third day of testing.

    Sometimes, when transferring a call either to another number or to voicemail, the transfer occurs on your end before the transfer is executed on the caller's line. This means the person receiving the transfer from you (or your voicemail system) may actually answer the call and start yacking well before the transfer kicks in on the caller's end so that they can hear what's being said. The delay on our system was about 10 seconds so it shouldn't pose a problem for calls transferred to another person. It'll usually take them that long to get to a phone anyway. For voicemail transfers, our solution was to add an 11 second delay in the script which connects the queued call to voicemail. We'll show you in the code below how to adjust that should you need to.

    Keep in mind that Asterisk is managing two separate voice channels: the caller's incoming call and your outbound call either to voicemail or another number. There doesn't appear to be a good synchronization mechanism to assure that both transfers happen at or near the same time. We used a clunker PC for testing so this may just be a result of our system's slow processor and 128MB of available memory. Or it may be a bug in the code that will get improved down the road. We'd be interested in hearing from others so that we can report it as a bug if, in fact, it is.

    Call Queues also work in Asterisk@Home 1.5 ... sort of. What doesn't work is breaking out of the connection by pressing * or #. In short, a message will play to the callee announcing the call, and then the caller is connected. You'll need a different Allison recording than what we're providing today to do this, since the standard options don't function. But it will work with this one limitation. And you can accomplish almost the same thing by hitting the # key immediately after the announcement prompt completes and the calling party is connected to you.

    Today's Game Plan. We're going to begin by downloading some sample voice prompts, then create some Ring Groups to handle cellphones or external phone numbers (we covered Ring Groups last week if you need a refresher course), then build an IVR menu, then create a sample Call Queue, and finally take it for a spin. Once it's working, we'll show you how to further customize it for business use or to meet your own special requirements. Some of the voice prompts are ones we use on our home system so they're not going to be much help except to give you an idea what's possible. Just follow along and, once you've built the sample system, it's easy to order your own voice prompts and swap them with our samples. We'll also point you to some generic prompts that come with Asterisk. These may suffice especially for home use without spending a dime.

    Call Queue Voice Prompts. Every Call Queue has at least two voice prompts: one that answers the incoming call to your Asterisk system and a second one that announces the call to you or whoever the recipient of the call happens to be. A third voice prompt is required if you want to provide the caller with an IVR menu of choices if or when no one answers the incoming call.

    The first two voice prompts are in .gsm format and need to be copied to the /var/lib/asterisk/sounds/custom directory on your Asterisk system. To create an IVR menu using the Asterisk Management Portal, you'll need a third voice prompt in .wav format which can be stored anywhere on your Asterisk server. We've provided ours just so you can see how it works in the example, and we'll save it to the custom directory also just to keep things simple. There's another advantage to storing stuff in this custom directory. They get backed up as part of the AMP backup system script. To download the prompts, log in to your Asterisk server as root and then switch to user asterisk: su asterisk. Now issue the following commands:

    cd /var/lib/asterisk/sounds/custom
    wget http://nerdvittles.com/aah2/callqueue.zip
    unzip callqueue.zip
    rm -f callqueue.zip
    ls -all

    Now look in the list of files displayed and check to see if you have any existing files that begin with aa_. These are existing sound files for autoattendants you've already created. If there aren't any, then do the following:

    mv nothome.wav aa_1.wav
    exit

    If you have existing autoattendant sound files in the directory, just add one to the number of the highest one shown and then issue the move and exit commands above. For example, if you have an aa_1.wav and aa_2.wav files already, then mv nothome.wav aa_3.wav. We'll need this in a bit.

    VoiceMail Redirector. For today's project, we've built a generic voicemail redirector. When you transfer a call to extension 86 (that's VM for VoiceMail), it will send the caller to the voicemail account matching the extension number of the phone on which you picked up the call. The code below assumes all of your extensions are 3 digits. If not, change the number 3 in lines 20, 30, and 40 to the actual number of digits in your extensions. If the number of digits varies, you'll need to seek "professional help" at Voxilla or SourceForge. If you need something different or if you want to reroute all incoming calls to one particular voicemail box, you can adjust the code accordingly. Using a web browser, go to the IP address of your Asterisk system and log in to the Asterisk Management Portal (AMP) as maint using your password. Then go to Maintenance->Config Edit->extensions_custom.conf. In the [from-internal-custom] context, add the following code:

    exten => 86,1,Answer ; V-M
    exten => 86,2,Wait(1)
    exten => 86,3,GotoIf($["${CHANNEL:0:3}" = "SIP"]?20)
    exten => 86,4,GotoIf($["${CHANNEL:0:3}" = "ZAP"]?20)
    exten => 86,5,GotoIf($["${CHANNEL:0:4}" = "IAX2"]?30)
    exten => 86,6,GotoIf($["${CHANNEL:0:5}" = "Local"]?40)
    exten => 86,7,Playback(hangup-try-again)
    exten => 86,8,Playback(goodbye)
    exten => 86,9,Wait(1)
    exten => 86,10,Hangup
    exten => 86,20,VoiceMail(${CHANNEL:4:3}@default)
    exten => 86,21,Goto(99)
    exten => 86,30,VoiceMail(${CHANNEL:5:3}@default)
    exten => 86,31,Goto(99)
    exten => 86,40,VoiceMail(${CHANNEL:6:3}@default)
    exten => 86,41,Goto(99)
    exten => 86,99,Hangup

    If you want to force a specific extension to a different voicemailbox, add two lines to the top of this code that look like this using your extension instead of 400 (in both lines) and the voicemail box number instead of 444 before @default in the first line:

    exten => 86/400,1,VoiceMail(444@default)
    exten => 86/400,2,Hangup

    And finally, as noted above, if you find that calls are not immediately transferring the caller to VoiceMail when you transfer the calls with #86, adjust exten=>86,2, Wait(1) to a longer delay. exten=>86,2, Wait(11) does the trick on our old clunker PC. Hopefully, someone with a better performing PC and more RAM will report back in a Comment indicating whether such a fix is necessary on more robust systems.

    Once you add the above code to your extensions_custom.conf file, save your changes and then reload Asterisk by clicking: AMP->Setup->Incoming Calls->Submit Changes->Red Bar.

    Creating Ring Groups for External Phone Numbers. AMP isn't the sharpest tool in the shed and only knows about local extensions. So, if you want to use external phone numbers (such as cellphones) in your Dialplan, then you need to set them up as Ring Groups so AMP can handle them just like a local extension. Let's create three just so we'll have some to use in our example. You can go back and change these later to meet your own needs. Using a web browser, go to the IP address of your Asterisk system and log in to the Asterisk Management Portal (AMP) as maint using your password. Then go to Setup->Ring Groups->Add Ring Group. Add a Ring Group for each cellphone or external phone number you want to integrate into your Dialplan. Use extension numbers (for the Group Numbers) that aren't already in use on your system. Each entry should look something like this (be sure to use a dial string that matches your outbound trunk):

  • Group Number: 411
  • Ring Strategy: ringall
  • Extension List: 16781234567#
  • Ring Time: 40
  • Destination if No Answer: some voicemail account on your system
  • Click the Submit Changes button after you complete each Ring Group and then click the Red Bar to reload the new Ring Group into Asterisk. Repeat for at least 3 external numbers.

    Creating an IVR Menu with AMP. To keep things simple today, we're going to build a quick Interactive Voice Response (IVR) menu using AMP. Using a web browser, go to the IP address of your Asterisk system and log in to the Asterisk Management Portal (AMP) as maint using your password. Then go to Setup->Digital Receptionist->Create New Voice Menu. Enter an extension number that can be used for you to interact with AMP while you're building this. On the Record Menu page, you can record your own voice prompt. For the example, let's use the one we've provided from Allison Smith. Just pick up the extension you chose to use in building this and dial *99. You should hear the Mundy's nothome IVR message. If not, go back to the Call Queue Voice Prompts section above and complete the steps. Otherwise, name the menu: Unavailable Menu and enter the following in the description: 1-MaryCell 2-WardCell 3-BeachHouse 4-Voicemail. Then click the Continue button.

    In the Options for Menu form, leave the Directory Context the way it is. For the number of menu options, enter 4 and click Continue. You can go back and increase this number later to support stealth options. The only trick to stealth options is adding the stealth contexts to the bottom of your extensions_custom.conf with context names beginning with custom. For example, to add a DISA option with a password, you could include something like the following and add a fifth option to your autoattendant:

    [custom-disa]
    exten => s,1,Wait(1)
    exten => s,2,Authenticate(1234)
    exten => s,3,DISA(no-password|from-internal)
    exten => s,4,Hangup()

    In the next screen, you actually associate tasks on your system with the choices given in your voice prompt. For options 1, 2, and 3, pick Ring Groups corresponding to the first three choices in your voice prompt. For option 4, choose a voicemail account for callers to leave voicemail messages. Click the Continue button and then the Red Bar to update your configuration.

    Creating a Call Queue. Now we're ready to actually create a call queue to process incoming calls. Using a web browser, go to the IP address of your Asterisk system and log in to the Asterisk Management Portal (AMP) as maint using your password. Then go to Setup->Queues->Add Queue. Fill out the form with the following entries substituting a Queue Number (extension number) which doesn't conflict with existing numbers on your system, a Static Agents entry which includes at least one local extension number on your system, and a Failover to Voicemail number which matches an existing voicemailbox on your system. Do NOT use external numbers in the Static Agents field although you can use Ring Group numbers which point to external numbers.

  • Queue Number: 299
  • Queue Name: queue1
  • Queue Password: leave blank
  • CID Name Prefix: q:
  • Static Agents: 201
  • Agent Announcement: callqueue
  • Hold Music Category: default
  • Maximum Wait Time: 1 minute
  • Maximum Callers: 2
  • Join Empty: yes
  • Leave When Empty: no
  • Ring Strategy: ringall
  • Agent Timeout: 30 seconds
  • Retry: 2 seconds
  • Wrapup Time: 0
  • Call Recording: no
  • Frequency: 30 seconds
  • Announce Position: no
  • Announce Hold Time: no
  • Voice Menu: Unavailable Menu
  • Join Announcement: welcome
  • Failover to Voicemail: 201
  • Click the Submit Changes button after you complete the entries and then click the Red Bar to reload the Queue into Asterisk.

    Once you finish creating the call queue, we need to set it to handle incoming calls. Click the Incoming Calls tab in AMP, and set the Regular Hours and/or After Hours destination to the Call Queue we just created above. Click the Submit Changes button once again and then click the Red Bar to reload your changes into Asterisk. Now place either an internal call to the extension number of your call queue or just dial the external number that connects to your Asterisk system to take your new Queue for a test run.

    Customizing Voice Prompts. To customize the system with a voice announcement for your home or office, simply order a voice prompt to replace our welcome voice prompt. The agent announcement voice prompt should be fine as delivered. Once you download your new voice prompt from Allison, log into your system as root and copy the file to the /root folder. Then convert the .wav file to a .gsm file with a command like this using the name of the .wav file provided to you by Allison Smith:

    sox r16212345-4105.wav -r 8000 -c 1 welcome.gsm

    Now copy the file to your /var/lib/asterisk/sounds/custom directory and change the ownership of the file from root:

    cp welcome.com /var/lib/asterisk/sounds/custom
    chown asterisk:asterisk /var/lib/asterisk/sounds/custom/welcome.gsm

    If you'd prefer something more generic until your customized sound file arrives, change the Join Announcement entry from welcome to pls-wait-connect-call or one of the other Asterisk sound files we've provided in the download. As another interim solution, you might want to try Loquendo synthesized voice files which can be created and then downloaded from here using the Firefox or Safari browsers. Once you play your creation, just choose File, Save As and give it a name to download the .wav file to your desktop. Then convert it to .gsm as shown above. We never could get a download to work with Internet Explorer, but maybe it was just late.

    Implementing an Automatic Call Distribution System. For those that use Asterisk@Home at work, it's a two-minute drill to convert what we've built today into a full-blown Automatic Call Distribution (ACD) System. For each department in your office, simply create a separate queue and route that department's DID trunks to the queue. Then add a list of the department extensions separated by carriage returns in the Static Agents field. Finally, adjust the Ring Strategy and Caller Announcement options to meet your business requirements. Hovering the cursor over the Queue and Caller Announcement Options will show what choices are available and what the various options do.


    Headline News for the Busy Executive and the Lazy Loafer. Get your Headline News the easy way: Planet Asterisk, Planet Gadget, Planet Mac, and Planet Daily. Quick read, no fluff.

    Got a PDA or Web-Enabled Smartphone? Check out our new PDAweather.org site and get the latest weather updates and forecasts from the National Weather Service perfectly formatted for quick download and display on your favorite web-enabled PDA, cellphone, or Internet Tablet. And, of course, it's FREE!


    Some Recent Nerd Vittles Articles of Interest...

    Introducing TeleYapper 2.5: The Free Asterisk Message Broadcasting System

    It's been a busy few weeks with two new versions of Asterisk@Home, but today we're back to the fun stuff: cleaning up the carnage from the new updates. We're beginning with TeleYapper 2.5, an updated version of our Asterisk@Home-based telephone broadcasting service that actually works with Asterisk@Home 2.5 (Asterisk 1.2.4 for "purists"). If you're running an earlier version of Asterisk, use our previous code and tutorial. And, just like the original, TeleYapper 2.5 can be used for neighborhood association announcements, schools, little leagues, fundraisers, municipal governments, and anyone else that just wants to pester folks with annoying, but free, prerecorded phone calls.

    Everything you'll need to get TeleYapper 2.5 dialing away is in this article. And functionally, TeleYapper still works identically to version 1. The only problem was version 1 didn't work at all with AAH 2.4 and 2.5. For those new to TeleYapper, here's what happens. You create a recorded message using Asterisk. Then you create a list of phone numbers to call in a MySQL database using a tool such as phpMyAdmin which is bundled with Asterisk@Home. Finally, you place a phone call either to kick off TeleYapper or to redial calls that failed the first time around. The software will dutifully swing into action and call qualifying phone numbers from any of ten calling categories that you specify when you set up your database of callees. TeleYapper then will deliver the message you've recorded. It works much like call-em-all.com and numerous other telephone broadcasting services with one important difference: TeleYapper is FREE! So, instead of paying 15¢ a call or $35 to $100 a month for a commercial service or spending thousands of dollars for a commercial dialer, now you can do it yourself using TeleYapper and your (also free) Asterisk@Home 2.5 PBX. Today we'll actually get TeleYapper making calls and emailing you the results of those calls. Don't be intimidated by the length of the article. You can still complete this project in about 30 minutes. It's mostly a cut-and-paste exercise. We've done all the hard work for you. But, first things first. We live in a litigious society so let's get the 'Miranda warnings' out of the way.

    Legalese. For those that are used to buying flawless software such as Microsoft Windows or Microsoft Office, let's be sure we're all on the same page up front. First, you're not buying this software. It's FREE! And, yes, sometimes you get what you pay for. Second, don't assume today's version is error-free. It's probably not. We try pretty hard to write reliable code, but even the best among us make mistakes. Third, by downloading or using this software, you are agreeing to assume all risks associated with use of the software. NO WARRANTIES EXPRESS OR IMPLIED INCLUDING ITS FITNESS FOR USE OR MERCHANTABILITY ARE PROVIDED WITH THIS SOFTWARE. And, finally, read or reread Part I of this series concerning Do Not Call statutes in your jurisdiction and make sure you are in compliance before placing any calls. Failure to heed this advice may subject you to serious criminal and civil penalties. If any of this gives you heartburn, exercise your constitutional right to not use the software.


    Overview. Today's installment provides a good framework for anyone wanting to write Asterisk AGI scripts using PHP with the latest version of Asterisk. The code is well-documented to demonstrate how to pass variables to an AGI script from your dialplan and how to retrieve variables from an Asterisk AGI script into your dialplan. We needed this for TeleYapper because we're using a phone call to an Interactive Voice Response (IVR) session embedded in the dialplan to begin the calling process. We use the IVR session not only to determine which group of callees to call but also to give the caller the option of placing a call to everyone in the group or just those to whom the initial call was unsuccessful. After the caller hangs up, the results are passed to the teleyapper.php application to do the heavy lifting. The PHP program takes advantage of an AGI script's ability to actually set dialplan code in motion once a call is answered. In order to log calls and track which ones are successful, we have to pass variables into that dialplan code and then execute another PHP script when the call is completed. Stated another way, every call requires two round-trips from the Asterisk dialplan to PHP/AGI scripts. So, if you can't figure out how to pass variables back and forth using this application, perhaps you should consider another endeavor. For those that just want to use the TeleYapper application and not learn much of anything about programming, you're welcome to do that subject to the license agreement which follows. We hope you'll put it to good use for the betterment of a school, an intramural sports program, or a neighborhood in which you live.

    Creative Commons LicenseLicensing. We are retaining ownership of this software as well as the copyright. It is licensed for use under the terms of the Creative Commons Attribution Non-Commercial license. A Plain English summary is available here. We've done this primarily to do our part to stamp out the telemarketing creeps of the world. Those wishing to use TeleYapper in a commercial environment must first request a license outlining your proposed terms of use. We will promptly respond with a yay or nay. Telemarketers need not apply!

    TeleYapper in a Nutshell. Before we get to the code, let's briefly cover how this message broadcasting system works. When you dial 674, the TeleYapper system will answer and prompt you for your password. Once you correctly enter the password, an interactive voice response (IVR) system will swing into action and give you several choices. That's what the [yapper] context handles. Pressing 1 lets you listen to your prerecorded TeleYapper message (if you have one). You don't yet so don't press 1. Pressing 2 lets you record a new TeleYapper message. This is handled by the [yapper2] context. Do this first and record something ... anything. You can rerecord a new message at any time by choosing option 2 again. Pressing 3 lets you kick off a TeleYapper dialing spree. It's handled by the [yapper3] context. Don't do this until we add your new database below, or you'll get smoke out of your system. If you choose option 3 to initiate a TeleYapper calling session, the system will first prompt you for a group option number to use. This is managed by the [yapper-options] context. Simply stated, when you build your database of callees for TeleYapper, you can specify a one-digit group number for each entry in the file. Then, when you begin a calling session, you can narrow down the calling group by telling TeleYapper which group of callees to call. If you want a callee to be in more than one group, you simply enter that callee into the database multiple times with different group numbers. If you want everyone in the same group, then enter 0 for every person in your database.


    Once you specify the group number during your TeleYapper session, the system will actually look up and report back how many messages will be delivered to the callee group you've chosen. Allison will say something like this assuming there were 146 calls to be placed: "The number I have is one hundred and forty six messages." This will give you the count of qualifying records in the database and the option of proceeding with the calls, cancelling the transaction, or just redialing the numbers of the calls that failed to this group on the previous pass through the database. As noted previously, we've endeavored to build this entire application using the voice prompts that are delivered with Asterisk@Home 2.5 so they're not quite perfect. But they work reasonably well once you understand how the pieces fit together. You're supposed to be nodding in agreement now.

    TeleYapper's Calling Process. For those that like lists, it may help to visualize how all the TeleYapper code fits together by laying out the actual program steps in a typical call:

  • 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 (which 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 TeleYapper code not only handles the actual dialing of the callees you've entered in your MySQL database (teleyapper.php), it also plays your message when a callee answers (dialplan contexts), and documents what happened during the calls (teleyapper2.php). Call progress is documented in two ways. First, when a call is completed, TeleYapper will log the date and time of the call as well as a best guess of what happened during the call in your MySQL database. So browsing entries in your TeleYapper database will always show the date, time, and status of the last completed call to each callee. We'll build a web interface for this one of these days. Second, when you install the TeleYapper PHP components, there are some configuration options which will also let you create a detailed log of what happened during the TeleYapper calls. If you have email working reliably on your Asterisk system, you also can enter your email address and tell TeleYapper to email you every log that is produced. There are log entries for the initial call setup (handled by teleyapper.php) and for the placement of the individual calls (handled by teleyapper2.php). Finally, you have the option of creating a new log with each series of calls that are placed (the default setting), or you can configure TeleYapper to keep adding to the end of the initial log. In the latter case, it's up to you to erase the log before it fills up your disk. Individual call entries, if logged, will be appended to the main TeleYapper call setup log (/var/log/asterisk/teleyapper.txt).

    To keep things simple, everything you'll need to make TeleYapper work is covered in this article even though we've covered some of this in the version 1 articles. Here are the components that make up the complete TeleYapper system, and we'll cover them below in the order which simplifies the installation process:

  • TeleYapper MySQL database
  • Code Snippet to Answer M-S-G Calls
  • AutoAttendant Contexts
  • checkgroup.php AGI script
  • Call Processing Contexts
  • teleyapper.php AGI script
  • teleyapper2.php AGI script
  • Creating the TeleYapper Database. We use Asterisk@Home's MySQL database management system to manage the list of callees for TeleYapper to dial. It can handle a database of almost any size and generally stands up well in performance comparisons with Oracle. So you're covered on the database front.

    To create the MySQL database to support TeleYapper, the easiest way is using the Asterisk Management Portal (AMP) to gain access to phpMyAdmin: AMP->Maintenance->phpMyAdmin. When phpMyAdmin loads, click on the SQL icon in the left column. When the SQL window appears, clear the existing SQL query and then cut-and-paste the following SQL code into that box and then click the Go button. When the import completes, click the teleyapper.callees table entry in the left column to open the file. Then click the Insert tab at the top of the right column to add entries to the table. You only need to add information for the name, phonenum, and group fields in the corresponding values column. The id, lastokcall, and lastcall fields should be left as is. The id field gets calculated automatically. The lastokcall will record the time and date of the last successful call using TeleYapper. And the lastcall field identifies what happened during the last call to this person, e.g. ok means the call was completed successfully, no answer means no one answered the call, or answering machine means an answering machine took the call.


    You can add up to two records at a time and, by clicking the Insert Another New Row button, you will be returned to this data entry screen after you save your entries by clicking the Go button. The name field allows you to quickly review entries you've made. It won't be used when making TeleYapper calls. The phonenum field is the important one. This is the exact dial string required to place a call on your Asterisk system to this callee using whatever VoIP or PSTN outbound trunk you plan to use with TeleYapper. For example, if your preferred provider requires 11-digit phone numbers with a 1, area code, and number, then that's the way the numbers should be entered into the TeleYapper database. The group field has already been discussed. Just enter a number between 0 and 9 to identify the group with whom this individual should be associated. Finally, after adding records to the table, you can click the Browse tab to review your entries. And, while Browsing, you can click the Pencil icon beside any record entry to edit it. Clicking the red X icon beside a record entry deletes the record. If, for some reason, you wish to delete ALL the records in the file, click the Empty tab at the top of the right column. Under no circumstances should you click on the Drop tab as this removes not only the table's contents but also the table structure itself. In short, you'd have to import the database table again.

    Answering the Incoming Call. This is a simple addition to your dialplan to actually answer calls to M-S-G (extension 674) and pass them to the TeleYapper contexts for processing. Using a web browser, open the Asterisk Management Portal (AMP) by entering the IP address of your Asterisk@Home 2.5 machine. To add TeleYapper to your dialplan, just cut-and-paste the following code into the [from-internal-custom] context near the top of extensions_custom.conf: AMP->Maintenance->Config Edit->extensions_custom.conf. Be sure to change the 1234 password below to something secure for your system since this will be used to gain access to your TeleYapper system!

    exten => 674,1,Answer ; dial MSG on any extension to manage your TeleYapper system
    exten => 674,2,Wait(1)
    exten => 674,3,Authenticate(1234)
    exten => 674,4,Goto(yapper,s,1)

    If you're a long-time reader of Nerd Vittles and you're using either our Stealth AutoAttendant or some other AutoAttendant, then you already know why you need to be careful about putting extensions like 6-7-4 in your extensions_custom.conf file because anyone can call you, dial 6-7-4 while your AutoAttendant is playing, and insert their own obscene message into your TeleYapper system. The solution is adding your own secure password in line 3 above rather than using the default 1234. Another precaution you should always perform is to first play your outgoing TeleYapper message to yourself to make certain it says what you think it should before you kick off a dialing spree to a thousand of your closest friends or business associates.

    AutoAttendant Contexts for TeleYapper. Now insert the following chunk of code at the bottom of extensions_custom.conf (AMP->Maintenance->Config Edit->extensions_custom.conf):

    [yapper]
    exten => s,1,DigitTimeout(7)
    exten => s,2,ResponseTimeout(10)
    exten => s,3,Background(T-to-hear-cur-ancmnt)
    exten => s,4,Background(press-1)
    exten => s,5,Background(to-rerecord-yr-message)
    exten => s,6,Background(press-2)
    exten => s,7,Background(to-place-outgoing-call)
    exten => s,8,Background(press-3)
    exten => s,9,Background(to-hear-menu-again)
    exten => s,10,Background(press-4)
    exten => s,11,Background(to-hang-up)
    exten => s,12,Background(press-5)
    exten => 1,1,Playback(custom/broadcast)
    exten => 1,2,Wait(2)
    exten => 1,3,Goto(s,3)
    exten => 2,1,Goto(yapper2,s,1)
    exten => 3,1,Goto(yapper-options,s,1)
    exten => 4,1,Goto(s,3)
    exten => 5,1,Playback(goodbye)
    exten => 5,2,Hangup
    exten => t,1,Goto(s,3)
    exten => i,1,Goto(s,3)
    exten => o,1,Goto(s,3)
    exten => h,1,Hangup

    [yapper2]
    exten => s,1,Playback(after-the-tone)
    exten => s,2,Playback(say-temp-msg-prs-pound)
    exten => s,3,Wait(2)
    exten => s,4,Record(custom/broadcast:gsm)
    exten => s,5,Wait(2)
    exten => s,6,Playback(custom/broadcast)
    exten => s,7,Wait(2)
    exten => s,8,Playback(your-msg-has-been-saved)
    exten => s,9,Wait(2)
    exten => s,10,Goto(yapper,s,1)

    [yapper3]
    exten => s,1,AGI(checkgroup.php|${GROUP})
    exten => s,2,NoOp(tmp variable: ${tmp})
    exten => s,3,GotoIf($[${tmp} = 0]?9,1)
    exten => s,4,Set(COUNTER=${tmp}|g)
    exten => s,5,Playback(the-num-i-have-is)
    exten => s,6,SayNumber(${COUNTER})
    exten => s,7,Playback(vm-messages)
    exten => s,8,Wait(1)
    exten => s,9,DigitTimeout(7)
    exten => s,10,ResponseTimeout(10)
    exten => s,11,Background(to-call-this-number)
    exten => s,12,Background(press-1)
    exten => s,13,Background(to-hang-up)
    exten => s,14,Background(press-2)
    exten => s,15,Background(vm-advopts)
    exten => 1,1,Goto(yapper-gen,s,1)
    exten => 2,1,Playback(goodbye)
    exten => 2,2,Hangup
    exten => 3,1,Goto(yapper-redial,s,1)
    exten => 9,1,Playback(dir-nomatch)
    exten => 9,2,Wait(1)
    exten => 9,3,Goto(yapper,s,1)
    exten => t,1,Playback(goodbye)
    exten => t,2,Hangup
    exten => i,1,Playback(goodbye)
    exten => i,2,Hangup
    exten => h,1,Hangup

    [yapper-options]
    exten => s,1,Wait(1)
    exten => s,2,Playback(you-have-these-options)
    exten => s,3,Playback(digits/0)
    exten => s,4,Playback(through)
    exten => s,5,Playback(digits/9)
    exten => s,6,Playback(press-star-cancel)
    exten => s,7,Read(tmp,vm-enter-num-to-call,1)
    exten => s,8,Set(GROUP=${tmp}|g)
    exten => s,9,NoOp(${GROUP})
    exten => s,10,GotoIf($["foo${GROUP}" = "foo"]?s,78)
    exten => s,11,GotoIf($["foo${GROUP}" = "foo*"]?s,88)
    exten => s,12,GotoIf($["foo${GROUP}" = "foo#"]?s,98)
    exten => s,13,Goto(yapper3,s,1)
    exten => s,78,Playback(connection-timed-out)
    exten => s,79,Wait(1)
    exten => s,80,Goto(yapper,s,1)
    exten => s,88,Playback(cancelled)
    exten => s,89,Wait(1)
    exten => s,90,Goto(yapper,s,1)
    exten => s,98,Playback(option-not-implemented)
    exten => s,99,Goto(yapper,s,1)

    [yapper-gen]
    exten => s,1,Playback(speed-dial)
    exten => s,2,Playback(activated)
    exten => s,3,Wait(1)
    exten => s,4,Playback(goodbye)
    exten => s,5,Hangup
    exten => h,1,DeadAGI(teleyapper.php|${GROUP}|${COUNTER}|1)
    exten => h,2,Hangup

    [yapper-redial]
    exten => s,1,Playback(speed-dial)
    exten => s,2,Playback(activated)
    exten => s,3,Wait(1)
    exten => s,4,Playback(goodbye)
    exten => s,5,Hangup
    exten => h,1,DeadAGI(teleyapper.php|${GROUP}|${COUNTER}|3)
    exten => h,2,Hangup


    Call Processing Contexts for TeleYapper. Finally insert the following chunk of code at the bottom of extensions_custom.conf:

    [broadcast]
    exten => s,1,Answer
    exten => s,2,Wait(2)
    exten => s,3,Playback(system-status-msg)
    exten => s,4,Wait(2)
    ;exten => s,5,BackgroundDetect(custom/broadcast|1000|50|3000)
    exten => s,5,Playback(custom/broadcast)
    exten => s,6,Goto(talk,1)
    exten => t,1,Goto(talk,1)
    exten => i,1,Goto(talk,1)
    exten => o,1,Goto(talk,1)
    exten => h,1,NoOp(Callee hung up call before menu. Dialed: ${DIAL} ID: ${ID}.)
    exten => h,2,Set(STATUS='EarlyHangup'|g)
    exten => h,3,DeadAGI(teleyapper2.php|${ID}|${STATUS}|${DIAL})
    exten => h,4,Hangup
    exten => talk,1,Goto(broadcast2,s,1)

    [broadcast2]
    exten => s,1,Set(STATUS='Answered'|g)
    exten => s,2,DigitTimeout(4)
    exten => s,3,ResponseTimeout(4)
    exten => s,4,Background(to-hear-msg-again)
    exten => s,5,Background(press-1)
    exten => s,6,Background(to-blklist-last-caller)
    exten => s,7,Background(digits/2)
    exten => s,8,Background(otherwise-press)
    exten => s,9,Background(digits/3)
    exten => t,1,NoOp(Callee's Answering Machine probably answered. Dialed: ${DIAL} ID: ${ID}.)
    exten => t,2,Set(STATUS='AnsMachine'|g)
    exten => t,3,Background(restarting)
    exten => t,4,Wait(1)
    exten => t,5,Playback(custom/broadcast) ; playing again for ans machine
    exten => t,6,Background(goodbye)
    exten => t,7,Hangup
    exten => h,1,DeadAGI(teleyapper2.php|${ID}|${STATUS}|${DIAL})
    exten => h,2,Hangup
    exten => i,1,Goto(1,1)
    exten => o,1,Goto(1,1)
    exten => 1,1,Set(STATUS='ReplayedMsg'|g)
    exten => 1,2,Goto(t,3)
    exten => 2,1,Set(STATUS='Zap'|g)
    exten => 2,2,Background(num-was-successfully)
    exten => 2,3,Background(removed)
    exten => 2,4,Background(goodbye)
    exten => 2,5,NoOp(Callee Requested to have number removed. Dialed: ${DIAL} ID: ${ID}.)
    exten => 2,6,Hangup
    exten => 3,1,Set(STATUS='OK'|g)
    exten => 3,2,Background(goodbye)
    exten => 3,3,NoOp(Callee Acknowledged Call. Dialed: ${DIAL} ID: ${ID}.)
    exten => 3,4,Hangup

    Once you finish adding all of the new contexts above to extensions_custom.conf, click the Update button to save your changes to disk. There's no need to reload Asterisk just yet. We've still got our AGI scripts to install.

    For those that are curious, you'll notice there is a commented out line 5 in the [broadcast] context. It's an Asterisk command called BackgroundDetect. What this command is supposed to do is play a sound file while listening for silence at the callee's end of the call. Once silence is detected, the call processing drops to talk. We couldn't get it to work reliably so the current release blindly plays your message and then asks for an acknowledgment. If it doesn't get one, it plays your message again, and then hangs up. The theory here is that, even if a callee has an answering machine, the second playing of your message should get recorded. We'll see what the feedback from the pioneers reveals. Just be aware that there may be further adjustments in the coming days and weeks. So check back and read the latest comments to this blog entry.

    Update: Asterisk 1.4 Modifications. If you plan to use this application on an Asterisk 1.4 system, a few minor changes in the autoattendant and call processing contexts need to be made. See Comment 26 below for details. Thanks, Bill.

    Installing checkgroup.php AGI Script. Now let's install the checkgroup.php script in your /var/lib/asterisk/agi-bin directory and change file ownership and permissions on the file. Log in to your Asterisk server as root, and then execute the following commands:

    cd /var/lib/asterisk/agi-bin
    wget http://nerdvittles.com/checkgroup.zip
    unzip checkgroup.zip
    rm checkgroup.zip
    chmod 775 checkgroup.php
    chown asterisk:asterisk checkgroup.php

    This script includes a debug log. The default settings are to create a new log file (/var/log/asterisk/telecheck.txt) each time the script is executed. This doesn't take up much room and is always there for you to read if something comes unglued: cat /var/log/asterisk/telecheck.txt. There are some other options. You can turn off the log file entirely ($debug=0). You can choose not to erase the previous log file each time the script is run ($newlogeachdebug=0) in which case the file continues to grow until your hard disk fills up. And you can have the log file emailed to you each time the script is executed ($emaildebuglog=1) by adding your email address ($email=youremailaddress). The last option obviously assumes you have followed our previous tutorials and gotten outbound email working reliably on your system. The functions are controlled by the following lines at the top of the checkgroup.php file. 1 means yes, and 0 means no. Just edit the file carefully: nano -w checkgroup.php. And save your changes when you're finished: Ctrl-X, Y, then press Enter.

    $debug = 1;
    $newlogeachdebug = 1;
    $emaildebuglog = 0;
    $email = "yourname@yourdomain" ;


    Installing teleyapper.php AGI Script. This code only works with Asterisk@Home 2.4 or 2.5. To install the teleyapper.php script in your /var/lib/asterisk/agi-bin directory, execute the following commands while logged into your server as root:

    cd /var/lib/asterisk/agi-bin
    wget http://nerdvittles.com/aah2/teleyapper25.zip
    unzip teleyapper25.zip
    rm teleyapper25.zip
    chmod 775 teleyapper.php
    chown asterisk:asterisk teleyapper.php

    The teleyapper.php script has a number of configuration options including a debug log. Edit the file carefully while positioned in the correct directory: nano -w teleyapper.php. And save your changes when you're finished: Ctrl-X, Y, then press Enter. All of the options are shown below.

    $maxretries=1 ;
    $retrytime=60 ;
    $waittime=60 ;
    $callspread=1 ;
    $debug = 1;
    $newlogeachdebug = 1;
    $emaildebuglog = 0;
    $email = "yourname@yourdomain" ;
    $trunk = "local" ;
    $callerid = chr(34) . "TeleYapper" . chr(34) . " <6781234567>" ;

    The first three options are implemented but not fully tested. If you have more than one outbound trunk and you're using the local trunk setting, give us some feedback. What it's supposed to do is retry failed calls. The callspread variable determines the spacing of calls to your various callees. The default is one minute which means the call to the second callee begins one minute after the first one starts. If your broadcast message is more than about 20 seconds long, you probably will need to increase this number to 2 to allow sufficient time to complete the first call before the next one begins. Otherwise, calls will fail if you only have a single outbound trunk.

    The debug flags in this file are set the same way as in the checkgroup.php script above: 1 means yes, and 0 means no. The default settings are to create a new log file (/var/log/asterisk/teleyapper.txt) each time the script is executed. This doesn't take up much room and is always there for you to read if something comes unglued: cat /var/log/asterisk/teleyapper.txt. There are some other options. You can turn off the log file entirely ($debug=0). You can choose not to erase the previous log file each time the script is run ($newlogeachdebug=0) in which case the file continues to grow until your hard disk fills up. And you can have the log file emailed to you each time the script is executed ($emaildebuglog=1) by also adding your email address ($email=youremailaddress).

    Two settings you will need to review and perhaps adjust to get calls to complete properly are the trunk and callerid variables. If you wish to use a specific trunk in your dialplan for outbound calls, the syntax for the outbound trunk is the same as it is in your dialplan, e.g. sip/telasip-gw or iax2/voxee. Look at the OUT settings at the top of your extensions_additional.conf file if you're not sure. At the request of a number of users, we've now added a new option which allows all outbound TeleYapper calls to be placed using the default dialplan rules on your server. The advantage of this approach is that different VoIP providers can be used automatically for different types of calls in your TeleYapper database. To use your default dial rules, set the trunk in all lowercase letters to local and TeleYapper will handle the rest of the setup for you.

    The callerid variable should be set to the callerid number of your outbound trunk unless your service provider allows callerid spoofing (most don't!). The callerid setting is ignored if you choose to use your default dialplan rules with a trunk setting of local. Don't delete the variable! Just leave the default value.

    Finally keep in mind that the format of the numbers to be dialed in your database must exactly match the syntax your trunk provider is expecting to see unless you're using your default dialplan rules. Otherwise, all of the outbound calls will fail. For example, if your provider requires that calls begin with a 1 followed by a 3-digit area code and 7-digit number, then that's the way the numbers must be entered in your TeleYapper database.


    Installing teleyapper2.php AGI Script. Install the teleyapper2.php script in your /var/lib/asterisk/agi-bin directory, change file ownership and permissions on the file, and decide if you want to adjust the default debug configuration setup. Log in to your Asterisk server as root, and then execute the following commands:

    cd /var/lib/asterisk/agi-bin
    wget http://nerdvittles.com/aah2/teleyapper2.zip
    unzip teleyapper2.zip
    rm teleyapper2.zip
    chmod 775 teleyapper2.php
    chown asterisk:asterisk teleyapper2.php

    The only configuration options in the teleyapper2.php script are for the debug log on individual calls that are placed. We recommend you leave the existing settings, or you'll get a new email every time a call is placed by TeleYapper. You can edit the file while positioned in the correct directory: nano -w teleyapper2.php. And save your changes when you're finished: Ctrl-X, Y, then press Enter. All of the options are shown below.

    $debug = 1;
    $emaildebuglog = 0;
    $email = "yourname@yourdomain" ;

    The debug flags in this file are set the same way as in the teleyapper.php script above: 1 means yes, and 0 means no. The default settings are to append individual call information onto the teleyapper.txt log file (/var/log/asterisk/teleyapper.txt) each time a new call is placed. Unless you're planning to call hundreds of thousands of people, this doesn't take up much room and is there for you when something comes unglued. The other options are as follows. You can turn off the individual call logging entirely ($debug=0). And you can have the entire teleyapper.txt log file emailed to you each time a call is placed ($emaildebuglog=1) by also adding your email address ($email=youremailaddress). For your initial test calls, this may be desirable just so you can see what's going on ... if you're too lazy to read the log.

    Taking TeleYapper for a Spin. Once you restart Asterisk (amportal stop then amportal start), you should have a Broadcast Message System that works. First, start up the Asterisk Command Line Interface (CLI) by typing asterisk -r from the command prompt on your system after you've logged in as root. Then issue the following command: set verbose 10. The CLI now will track the progress of your TeleYapper sessions.

    Using phpMyAdmin, add your cellphone number to your TeleYapper database and specify Group 0 for the entry. Now dial 674 and provide your password, record a message (Option #2), and then place a call (Option #3) to Group 0. Press 1 to kick off the TeleYapper calling spree. Check your CLI and TeleYapper logs if your cellphone doesn't ring in the next two minutes. Enjoy!

    Real-World Test of TeleYapper. Be sure to check out our follow-up article on TeleYapper for a real-world example dialing 700+ neighbors with information about a rezoning meeting.

    TeleYapper Wish List. Some things are still on our TO-DO list, and we'll get to them one of these days. For those with loads of outbound trunks, we'll try to add a feature that lets you adjust the number of simultaneous oubound calls. For those that want appointment reminders on dates in the future, we've completed that project for AAH 1.5 and 2.2. Here's the link. Within the next week or so, we'll have a new version that supports Asterisk@Home 2.5. We also plan to build a web interface to the TeleYapper MySQL database which will let you add, edit, and delete entries as well as run some simple reports. If you have other suggestions, post a comment.

    Want More Projects? For a complete catalog of all our previous Asterisk projects, click here. For the most recent articles, click here and just scroll down the page. Get your Headline News the easy way: Planet Asterisk, Planet Gadget, Planet Mac, and Planet Daily. Quick read, no fluff.

    Got a PDA or Web-Enabled Smartphone? Check out our new PDAweather.org site and get the latest weather updates and forecasts from the National Weather Service perfectly formatted for quick download and display on your favorite web-enabled PDA, cellphone, or Internet Tablet. And, of course, it's FREE!

    From Our Legal Department, moi: The TeleYapper product name (our feeble attempt at humor through parody) has absolutely no affiliation with TeleZapper, the terrific hardware product designed to keep telemarketers from bugging the hell out of you while you're eating your dinner. We confess that our sense of humor got the better of us in coming up with the name for this non-commerical (aka "free") utility designed primarily as an educational vehicle to assist the Asterisk community in recognizing the almost limitless potential of AGI and PHP programming. Our parody seeks to amuse, not to confuse. Our telephony software Yaps. Their telephony hardware Zaps. Other than a telephone line, there is no product similarity as the two conjoined words make clear. And, yes, that is the whole point! The products are opposites, not identical nor even similar. One letter makes all the difference in Night and Light. So it is with Yapper and Zapper. Brand confusion in trademark law arises from synonyms, not antonyms. It is systems like what we're writing about today that TeleZapper is designed to protect against. And it does that very well. In fact, we use TeleZapper hardware in our own home and have for many years. The only problem, of course, is when that tornado comes rolling down the neighbor's street, it would have been nice to get that automated phone call from TeleYapper at the neighborhood headquarters. But, who cares, right? It's only your house. Class dismissed.

    Who Is This Guy? Ward Mundy, the author of this Asterisk@Home series of articles, is a retired attorney who spent more than 30 years providing legal and technology assistance to the federal courts in the United States. Today he serves as a principal in Ward Mundy & Associates, a technology consulting firm in Atlanta, Georgia.


    Some Recent Nerd Vittles Articles of Interest...

    Deploying Voice Over Wi-Fi with Asterisk

    EZgo PC

    Getting Wi-Fi to play nice is another one of those grammatically incorrect, but thorny Linux problems that Asterisk® inherits because of its roots. In the Windows and Mac worlds, we've become accustomed to plug-and-play for things like Wi-Fi USB sticks, but it ain't that easy with Linux unfortunately. Once you get the right device, this project will take you less than 30 minutes to complete. But we've invested almost a week getting everything to work ... so you won't have to. If the Linux community ever wants to see Linux used as a desktop PC, this piece of the puzzle needs some work! Even with the correct hardware and drivers, there is virtually nothing available on either the net or in the 1,000 page Linux tomes that makes this project simple. Admittedly, we're anything but Linux gurus, but we can read. And it shouldn't be this hard to find the answer to the following simple question: how do I set up a WiFi connection on my Linux box. Now that we know how, we would hasten to add that you shouldn't have to bury code in numerous obscure places in the operating system and issue dozens of unintelligible Linux commands to make a Wi-Fi adapter come to life! So, why do it, you might be asking. Keep reading, and we'll get to that.

    Who needs it? Anyone in the emergency preparedness and continuity of operations business oughta have a WiFi PBX in their suitcase! Can you spell K-A-T-R-I-N-A. And if you or your organization wants the flexibility of an instant, high performance telephone system on a moment's notice, then WiFi is a must-have. Ever been to a convention with your entire office but didn't want to leave all your phones behind? Now you don't have to. Using Wi-Fi IP phones, this entire phone system can be deployed WITH NO WIRES using a battery-operated notebook computer or, better yet, a small-footprint PC (see inset) plugged in to a $200 generator or a low-cost UPS if electricity is flowing. And someday we may get Asterisk running on our Nokia 770, but not this year.

    What to Use. The easiest solution for Voice Over Wi-Fi is a WiFi USB stick and an Asterisk@Home server. Why USB? Because you can use it with almost any modern PC on the planet without having to install a card in the machine. There are now close to two dozen different WiFi sticks available at stores such as CompUSA, MicroCenter, and Fry's. The only problem is the scarcity of Linux drivers for ALL of them. Luckily, there is one chipset that works without a dog-slow Windows driver emulator (such as ndiswrapper): the ZD1211 chipset. Both the Safecom SWLU-5400 and SWLUZ-5400 have this chipset. The real beauty of this USB adapter is that it can function as a host in an Ad Hoc Wi-Fi network, or it can be configured in Infrastructure Mode to take advantage of an existing Wi-Fi access point serving as a Master. The device also can be configured as a Master or Repeater and supports both WEP and WPA encryption as well as 802.11B and G. Bottom line: This WiFi stick has the flexibility to function in virtually any type of existing or newly created Linux Wi-Fi network. That was our theory anyway. Read on.

    Where to find one. Finding the right product turned out to be the easy part. If you're in the U.S, the more difficult task is finding a USB adapter with this chipset. In Europe, they're a dime a dozen. While they are FCC approved and include a chipset manufactured by Texas Instruments, they're almost impossible to find stateside. One possible source is eBay. Search for Safecom USB WiFi and be sure to check the Search title and description box. There's almost always at least one for sale. If not, check back in a day or two or request an email when one is listed. With shipping, you should be able to find one from various U.K. distributors for about $30. Be sure the ad states that the product uses the ZD1211 chipset, or you're wasting your money. NEWS FLASH: IOgear now makes the GWU523 which reportedly has the same chipset (although we have not actually tested one). Here's the PriceGrabber link of sources. One that we now have tested with the same chipset is AirLink's AWLL3026 which is on sale this week at Fry's or Outpost.com. If you get in a crunch and can't find one, contact us. We have a few spares (not on sale) that were used only to verify that they worked.


    Wi-Fi Deployment Issues. There are many ways to deploy a Wi-Fi network and adding an Asterisk PBX to the mix just multiplies the number of available choices. To keep things simple, we've chosen what we believe is the easiest approach, but your needs may vary so we'll point out other options as we go along. We're assuming you have an Asterisk@Home 2.2 server already running because it's the easiest way to deploy Asterisk on the Linux platform. CentOS/4 is built right in. Here's our 90-minute step-by-step guide if you need it. We're also assuming you have a WiFi access point or router (802.11B or 802.11G) already in place and working with at least one wireless device. If not, start there and come back.

    Our Wi-Fi lab (aka home) and test server for this project may or may not be typical. The PC is an EZgo which is roughly the size of a Mac mini or about 4 stacked CD cases (see inset above). You can see the USB stick hanging out the back of it. It's only about 2 inches long. And, yes, I hear someone asking, "Why not just use a Mac mini?" The short answer is that, while Asterisk runs on the Mac, it's no walk in the park. And, by the time you build a Mac system with the tools bundled in Asterisk@Home and get them all talking to each other, even my kids may be out of college. Let's just say you will quickly come to appreciate the real beauty of Asterisk@Home. For another painful approach to building a small-footprint Asterisk system, check out Tom's Networking. No, thanks.

    We have a fairly large house so we have a WiFi router at one end and a Wi-Fi access point at the other. The two devices are hard-wired together with a 100 megabit, CAT5 network cable so they're both on the same network segment: 192.168.0.1 through 192.168.0.254. Several dozen devices are scattered around the various rooms on the three levels of the house to keep me entertained but mostly to keep me out of the Little Mrs. hair. A burglar's paradise, you might be saying ... well, yes, except we'd get your picture on the way in and out.

    The ESSID on both WiFi Masters is the same: MundyLANd. You need this setup for moving around a large WiFi network. The trick is that one unit operates on WiFi channel 1 while the other is set to channel 11. That way the signals don't step on one another, and your client device has the smarts to transparently switch from one access point to the other when it needs to... much like cellphones moving between cellphone towers. For purposes of this article, we will assume that your devices operate with 128-bit WEP encryption since it's the easiest to configure. Note: We didn't say WEP was secure. We just said it was easy to configure.

    In the middle of the house, we have a new addition from Santa, a Sony wireless TV that operates as a Master on WiFi channel 6. We'll have more to say about it in a future column. And, yes, we still hate Sony after their rootkit fiasco! But Santa didn't know any better, and who are we to turn down free toys. Why is it that Sony never acted this way until an American took over the top job at the company? I'm sure our European and Asian readers will have a quick answer.

    For now, what you need to know is that our home maxes out ALL of the existing U.S. WiFi channels, much to the chagrin of our closest neighbors. Because of the overlap between Wi-Fi channels, the only practical channels to deploy are 1, 6, and 11. This becomes important for this project because we want to make sure the new Linux Wi-Fi dongle plays nicely by not using an intermediate channel or, worse yet, the Sony WiFi channel (6) which doesn't provide access to the Internet without knowing a different ESSID and password, both of which are about as long as your arm.


    The reason for this lengthy diatribe was to lay the groundwork to get you thinking Wi-Fi, and it also exposed the only technical wrinkle we observed in this project. When configured in Managed mode, the Safecom USB WiFi adapter is supposed to seek out the nearest access point and set itself to that channel. It doesn't. Our experience using this Linux driver with CentOS/4 which is bundled with Asterisk@Home 2.2 has been that this rarely works as it should. The channel selection appears to be almost totally random. When the device sets itself up on the wrong channel, all sorts of ugly things can happen. For openers, you probably won't get the network connectivity you expect. Many of the Macs and PCs in our house couldn't talk to the WiFi-enabled Asterisk box until we got the adapter correctly set to the channel of the nearest WiFi Master, channel 1 in our case. Obviously, if the device configured itself for Channel 6 or a nearby channel, we were out of luck ever talking to the box. That turned out to be a headache, but we'll show you a little discovery we made that makes it less painful. Just be aware that this may be a manual drill each time you reboot the WiFi Asterisk server or move it (not often, if you're smart!). We've had much worse luck with Windows PCs and WiFi devices over the years, so this really wasn't a deal breaker in our book. Connectivity works. The Linux driver works. Encryption works. And the phones ring. Those were the critical pieces in this puzzle from our perspective. Now on with the countdown!

    Downloading the Linux WiFi Driver. After obtaining the hardware device, the next step is finding a Linux driver for it. There happen to be two, and someday when our hair grows back, we may try the other one. In the meantime, you'll need the Linux zd1211 driver which is available from SoureForge. Just find the site closest to you and download the compressed tarball from here. Here's where you'll find the other one just in case someone else enjoys water torture. Wasn't that easy? Well, not so fast.

    Once you unzip and untar the driver bundle (tar -zxvf zd1211-XXXX.tar.gz), you'll find a README file which is actually pretty good. It only leaves out one little thing: the device name of the WiFi dongle on your Linux box. The answer is wlan0 (that's a zero on the end) so write it down. You're going to need it ... a lot!


    Compiling and Installing the WiFi Driver. Now we're getting to the fun part. We're assuming you will be installing this on a freshly installed Asterisk@Home 2.2 system built using the ISO image. You can read all about how to do that here. Will it work with another version of Asterisk@Home? Maybe. Try it. Heh heh! This isn't the Windows or Mac world so drivers have to be compiled for the Linux box on which you wish to run the software using the Linux kernel that was in place when you compiled the software. So, here's gotcha #1. If you ever get an updated kernel with CentOS/4 (as you will when you run yum -y update after installing Asterisk@Home 2.2), you will need to repeat this drill and recompile and reinstall the driver. HINT: Run yum -y update on your Asterisk@Home 2.2 server before continuing! Now you see why Linux folks aren't overly enthusiastic about kernel upgrades.

    To begin the WiFi driver install, just rename the downloaded driver folder from SourceForge to zd1211 and copy it to a safe place on your Linux machine while logged in as root, e.g. /root works great. Now switch to that folder (cd /root/zd1211) and issue the following commands to compile and install the driver:

    make
    make install

    Once this finishes, you'll need to manually load the driver. The README has some pretty good hints about this, but no cigar. Finding the correct answer requires that you first know the question to ask: find / -name *zd1211*.ko. This tells us where to find the little cream puff we want to load. Keep in mind that the "answer" will be different each time the Linux kernel version changes. If you're not running 2.6.9-22.0.1.EL, then this won't work. So how do you know which kernel you're running? Just type this simple (but obscure) command: uname -a. Now let's load the USB driver:

    insmod /lib/modules/2.6.9-22.0.1.EL/net/zd1211_mod.ko

    Once you've loaded the driver, we need to be sure it really, really is loaded: lsmod | more. Just scroll down the list with the enter key until you see an entry that starts with zd1211. Then press q to quit lsmod.

    zd1211_mod 191876 0

    Are we there yet? Why no, we're just getting started. Isn't Linux fun!

    Firing Up the Wi-Fi Adapter. Actually, we're closer to being finished than you may have thought. There are just a couple more steps. We want to manually make sure things are working. Then we'll need to configure Linux to automatically load the WiFi driver each time you reboot your system. You'll find it's easier to get the kinks out of network drivers by first doing things manually, and then recording what you've done for posterity. For openers, you'll need an IP address for this WiFi adapter. That address obviously needs to be on the same subnet as the access point with which it will be communicating. For purposes of this example, we've chosen 192.168.0.77 on the subnet of our WiFi router which has IP address 192.168.0.1. YMMV. You also need to know some other things such as the subnet mask, the router's IP address, and an IP address for your DNS (name) server, but we'll get to that. Once you've chosen an IP address, let's fire up the adapter and then check to be sure it's running:

    ifconfig wlan0 192.168.0.77
    ifconfig | more

    You should get a response that looks something like this:

    lo Link encap:Local Loopback
    inet addr:127.0.0.1 Mask:255.0.0.0
    inet6 addr: ::1/128 Scope:Host
    UP LOOPBACK RUNNING MTU:16436 Metric:1
    RX packets:12146 errors:0 dropped:0 overruns:0 frame:0
    TX packets:12146 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:985362 (962.2 KiB) TX bytes:985362 (962.2 KiB)

    wlan0 Link encap:Ethernet HWaddr 00:E0:98:F2:BB:40
    inet addr:192.168.0.77 Bcast:192.168.0.255 Mask:255.255.255.0
    inet6 addr: fe80::2e0:98ff:fef2:bb40/64 Scope:Link
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:10638 errors:0 dropped:0 overruns:0 frame:0
    TX packets:3483 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:1301983 (1.2 MiB) TX bytes:335569 (327.7 KiB)

    You'll see that wlan0 is in the list, and it has the IP address that we assigned. That's good news. You'll also note that there is no eth0 device shown even though our machine has an Ethernet adapter built into it. This is another little gotcha to keep in mind. Make sure, if your box has an internal Ethernet adapter, that you configure the main adapter to use DHCP to obtain its address. You do this by issuing the command netconfig and using the space bar to choose Use Dynamic IP Configuration. Then tab to OK and press Enter. The reason for this is very important. Lots of Linux software makes the assumption that eth0 is the default network adapter if it happens to be running. So we want to make sure it isn't running by unplugging the Ethernet cable before booting the machine. If you have a fixed IP address for eth0, then it will load eth0 whether a cable is connected or not. If you configure eth0 for DHCP, then eth0 will not be loaded unless an IP address can be obtained from a DHCP server. With the cable unplugged, you're pretty safe. So, if your machine is showing an eth0 device, reconfigure eth0 for DHCP, and reboot the machine. Then reissue the ifconfig command after logging back in as root. When your display shows two network devices like ours (loopback and wlan0), you're ready to proceed. Another clue: When Asterisk@Home starts up and you log in to your server, it normally tells you the IP address for accessing the Asterisk Management Portal using a web browser. This gets broken when you're using a Wi-Fi adapter that isn't on eth0 because Andrew's setup is merely regurgitating the IP address of eth0. Don't worry! It still works when you enter the correct IP address of your WiFi adapter.


    Configuring the WiFi Adapter for Your Wi-Fi Network. Now that we have the WiFi adapter running, we'd like it to communicate with the WiFi network in our home or office. You obviously have to have a WiFi network up and running in your home or office for this to work. But we'll assume you've taken care of that little detail. 25+ years in the technology business has taught me to restate the obvious once in a while just in case something isn't quite as obvious to others. What we'll need now is the name of your WiFi network, the ESSID. And we need to know the channel on which your nearest WiFi access point is broadcasting. Finally, we need a way to identify this access point if you have more than one. Lucky for us, there's a Linux command that will tell us everything except your WiFi WEP password if you're using WEP encryption on your wireless LAN (you are using some sort of encryption, aren't you?).

    iwlist wlan0 scanning

    You'll get a result that looks something like the following:

    wlan0 Scan completed :
    Cell 01 - Address: 00:06:25:55:C4:E3
    ESSID:"MundyLANd"
    Mode:Master
    Frequency:2.412GHz (Channel 1)
    Quality:68/92 Signal level=54/154 Noise level=0/154
    Encryption key:on
    Bit Rate:1Mb/s
    Bit Rate:2Mb/s
    Bit Rate:5.5Mb/s
    Bit Rate:11Mb/s

    Cell 02 - Address: 00:01:4A:10:EE:60
    ESSID:"LF-X1U.00014A10EE60"
    Mode:Master
    Frequency:2.437GHz (Channel 6)
    Quality:4/92 Signal level=35/154 Noise level=0/154
    Encryption key:on
    Bit Rate:1Mb/s
    Bit Rate:2Mb/s
    Bit Rate:5.5Mb/s
    Bit Rate:11Mb/s
    Bit Rate:6Mb/s
    Bit Rate:9Mb/s
    Bit Rate:12Mb/s
    Bit Rate:18Mb/s
    Bit Rate:24Mb/s
    Bit Rate:36Mb/s
    Bit Rate:48Mb/s
    Bit Rate:54Mb/s

    Cell 03 - Address: 00:09:5B:2A:A2:AC
    ESSID:"MundyLANd"
    Mode:Master
    Frequency:2.462GHz (Channel 11)
    Quality:4/92 Signal level=36/154 Noise level=0/154
    Encryption key:on
    Bit Rate:1Mb/s
    Bit Rate:2Mb/s
    Bit Rate:5.5Mb/s
    Bit Rate:11Mb/s

    Here's where things get a little buggy. You're supposed to be able to set the the ESSID, the broadcast Mode, the access point and the WiFi channel for the zd1211 using the Linux iwconfig tool. As mentioned previously, in standard Managed mode (meaning you'll be connecting to an Access Point on your WiFi network), you have no control over the channel or the access point. The theory was that the adapter would set itself automatically. Unfortunately it doesn't although your mileage may vary if you have only a single access point within range of your zd1211.

    As we indicated on the front end, our WiFi network is somewhat atypical. So the best solution for you is to execute the following commands and see what happens on your own wireless LAN:

    ifconfig wlan0 192.168.0.77 (use your designated IP address)
    iwconfig mode Auto
    iwconfig wlan0 essid "MundyLANd" (use your ESSID)
    iwconfig wlan0 key F57EC678F1B061BAC59EC593EFE (use your WEP key)
    iwconfig mode Managed
    iwlist wlan0 scanning (reports the cell numbers of each access point in range)
    iwpriv wlan0 connect 01 (use the cell number of the access point closest to your zd1211)
    ifconfig
    iwconfig
    iwlist freq

    Now go to another machine in your network and see if you can ping your WiFi Asterisk@Home box:

    ping 192.168.0.77 (use the IP address of your WiFi AAH machine)

    If you're successful, great! Reboot your WiFi AAH machine and repeat the test. If it works twice, you're probably safe skipping the next section.


    Forcing the WiFi Adapter to a Specific Access Point and Channel. If you're getting random results with the above approach, then here's the solution that works. Unfortunately, it requires a set of eyeballs each time you reboot your system unless there's only one access point within range of your Asterisk Wi-Fi box:

    ifconfig wlan0 192.168.0.77 (use your designated IP address)
    iwconfig mode Managed
    iwconfig wlan0 essid "MundyLANd" (use your ESSID)
    iwconfig wlan0 key F57EC678F1B061BAC59EC593EFE (use your WEP key)
    iwlist wlan0 scanning (reports the cell numbers of each access point in range)
    iwpriv wlan0 connect 01 (use the cell number of the access point closest to your zd1211)
    iwconfig (should show the MAC address of the access point from step above)
    iwlist freq (should show the channel in use that matches your access point's broadcast channel)

    To be sure you have connectivity on your local area network, issue this command: ping 192.168.0.1 using the correct internal IP address of your own router/firewall.

    This setup should work every time except you have to manually look at the results of the scanning report to decipher the proper cell number because the order of the list can change each time you run it. If only one access point is reported, you're in luck! Just test it several times to be sure. Once you're sure, you should be safe in executing the iwlist wlan0 scanning command followed by iwpriv wlan0 connect 01. Don't skip the scanning step, however, as this appears to "prime the pump." One other word of warning: don't execute the scanning command without first assigning an IP address to wlan0 using ifconfig, or you'll get an unrecoverable kernel panic.

    That about covers all the gotcha's. The important lesson here is to get the network connectivity stable before you automate the process so that it autoloads when you boot your system. If you can't get stability in the channel and access point connectivity, at least make certain that you understand the limitations of your solution before making things automatic.

    Adding Internet Connectivity. We haven't mentioned getting out to the Internet yet. For that to work, you'll need access to a name server (aka DNS). Here's another little Linux "feature" to bite you. The interactive mode of netconfig is designed to handle the eth0 interface. To get things working on the wlan0 interface, issue a command like this:

    netconfig --gateway=192.168.0.1 --ip=192.168.0.77 --nameserver=68.87.68.162 --netmask=255.255.255.0 --device=wlan0

    Be sure you adjust gateway (IP address of your router); ip (IP address of your new Asterisk box); nameserver (from a Mac or Windows machine: here's how to find it; on a Linux machine: nslookup mundy.org returns your DNS server's IP address on first line following Server:; netmask (you can find this with iwconfig); device=wlan0 (leave this alone). By the way, you only have to execute this command once, not every time you boot your system.

    To make sure you've got Internet connectivity now, issue this command: ping novell.com. You should get a response showing the IP address of Novell's server. If not, check your entries above and try again.


    Activating WiFi on Startup. One last piece and we're finished. We obviously want to activate WiFi connectivity on bootup and, if you only have one WiFi access point and no neighbors like me, you shouldn't have to manually tweak your system thereafter. As we stated initially, this ain't your daddy's Windows or Mac machine, so where to put what isn't quite obvious. You're also going to need to do this in two boot cycles because there are two separate pieces. If the second piece works and the first one doesn't, you'll get a seg fault and crash every time. Do you need to ask how I know?

    Step 1: While logged in as root, create the following new file: nano -w /etc/sysconfig/network-scripts/ifcfg-wlan0 using your IP address, netmask, and gateway settings from the netconfig drill above:

    DEVICE=wlan0
    ONBOOT=yes
    BOOTPROTO=static
    IPADDR=192.168.0.77
    NETMASK=255.255.255.0
    GATEWAY=192.168.0.1

    When you're finished adding the above commands, save the new file: Ctrl-X, Y, the press Enter. Now reboot your server: shutdown -r now. Once the system comes back up, log in as root, and issue the following command: ifconfig. Make sure that the display shows an IP address (inet addr) for your wlan0:

    lo Link encap:Local Loopback
    inet addr:127.0.0.1 Mask:255.0.0.0
    inet6 addr: ::1/128 Scope:Host
    UP LOOPBACK RUNNING MTU:16436 Metric:1
    RX packets:425 errors:0 dropped:0 overruns:0 frame:0
    TX packets:425 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:32582 (31.8 KiB) TX bytes:32582 (31.8 KiB)

    wlan0 Link encap:Ethernet HWaddr 00:E0:98:F2:BB:40
    inet addr:192.168.0.77 Bcast:192.168.0.255 Mask:255.255.255.0
    inet6 addr: fe80::2e0:98ff:fef2:bb40/64 Scope:Link
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:976 errors:0 dropped:0 overruns:0 frame:0
    TX packets:592 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:91331 (89.1 KiB) TX bytes:75930 (74.1 KiB)

    Step 2: While logged in as root, edit the following file: nano -w /etc/rc.d/rc.local. The existing file should look like the following. You'll note that this is where Asterisk@Home is actually started on bootup so be careful with your typing.

    #!/bin/sh
    #
    # This script will be executed *after* all the other init scripts.
    # You can put your own initialization stuff in here if you don't
    # want to do the full Sys V style init stuff.

    touch /var/lock/subsys/local
    /usr/local/sbin/motd.sh > /etc/motd
    /usr/sbin/amportal start

    Above the touch line, add a couple of blank lines and then cut-and-paste the following code using your ESSID and the password of your wireless LAN:

    /sbin/iwconfig wlan0 mode Auto > /dev/null
    /sbin/iwconfig wlan0 essid "MundyLANd" > /dev/null
    /sbin/iwconfig wlan0 key F57EC678F1B061BAC59EC593EFE > /dev/null
    /sbin/iwconfig wlan0 mode Managed > /dev/null
    /sbin/iwlist wlan0 scanning > /dev/null
    /sbin/iwpriv wlan0 connect 01 > /dev/null

    Leave the mode Auto line alone. On the essid line, enter the name of your WiFi LAN in quotes. If you're using WEP encryption on your wireless LAN, enter the hex key in the next line. Otherwise, just delete the line: Ctrl-K. Leave the mode Managed line as is. Leave the iwlist scanning and iwpriv lines the way they are. Now save your changes: Ctrl-X, Y, then press Enter. Reboot again: shutdown -r now. Log in as root. Then issue the following commands:

    iwconfig
    iwlist freq

    The iwconfig command will tell you if you're connected to your Access Point and also indicate the Frequency (which tells you the channel your zd1211 is on). The iwlist freq decodes frequencies into channels and tells you which one you're talking on. If it's the same as the default channel on your access point, you're done. If it's not, run the command iwlist wlan0 scanning command again and eyeball the cell number which matches your access point. Then reset the channel by issuing the following command with the cell number you deciphered instead of 01: iwpriv wlan0 connect 01. Whew! Congratulations! You're now the proud owner of an Asterisk-based Voice Over Wi-Fi PBX, and you're getting darn close to being a Linux guru. Enjoy!

    Free U.S. Calls. Everybody loves free samples so here's one for you. You may remember Gene Willingham and the good folks at TelaSIP, the winner and least expensive provider in our unlimited U.S. long distance calling shootout. In a moment of weakness, TelaSIP's agreed to let you try out some free U.S. phone calls on their nickel. The service uses our Asterisk server and TelaSIP's long distance bandwidth. Calls are limited to 10 minutes after which the callee will hear "Goodbye" followed by a click. You'll get two beeps followed by a fast busy. In other words, time's up! Here's how to use this free service. Call from a phone in the U.S. with CallerID. Call the number shown on the map (inset) which is one of our DIDs in Charleston, South Carolina. The call will never be answered so you won't be billed for the long distance call. Within 10 seconds, you should hear a fast busy. Hang up, and our Asterisk server will call you back within 30 seconds assuming you have caller ID enabled. You won't believe how many calls we receive each day from folks with caller ID disabled. HINT: No return call = No caller ID. If you do get a call back, listen carefully when you answer! You'll be provided a random password for your call, and then you'll be prompted to key it in. With your phone keypad, do that and press the pound key (#). If you get a message that it's incorrect, try again (HINT: We told you to listen carefully). Once you successfully enter the password, you'll then get a DISA dial tone. Dial 1 and then the area code and phone number of someone you love (in the United States only). This is an excellent way for you to check out the voice quality of TelaSIP calls without spending a dime. Just don't abuse the offer or this paragraph may magically disappear ... as will the free calls. For those that don't know us, we don't record your calls, and we don't store the number of the person you're calling although the Asterisk logs probably have it for a while anyway. For security purposes, we do log your CallerID and the time of your call just in case you do something you shouldn't be doing and the FBI traces the call back to us. If any of the above offends you, exercise your constitutional right to not use this free service. Believe it or not, someone wrote and asked why they couldn't use this service without CallerID enabled on their phone. Think about it! And you won't believe how many calls we receive each day with a CallerID of Asterisk. That won't work either.

    Nerd Vittles Allison Fund. As we mentioned last week, our next major project is an Appointment Reminder System. Using a touchtone phone, you can schedule an unlimited number of customized voice reminders for delivery at any future time to any phone numbers you desire. To make it work, we need customized voice prompts for the IVR interface. Unfortunately, these cost money. Allison, who records the Asterisk voice prompts for Digium, needs to eat. And so do we. We're springing for the costs of the prompts up front, but this is your golden opportunity to contribute to the cause. Provided we raise enough money to cover the costs, we'll put the voice prompts in the public domain. Otherwise, when the project is presented, those that didn't contribute will have to record their own voice prompts in order to use the system. The generous will get the Allison prompts either on a password-protected web site or by email.

    Last week's donations were a little disappointing. We raised a whopping $15 which means less than half of our regular readers have donated to the cause. And, until yesterday, there wasn't a single donor from the U.S. Thanks, Hollywood, for breaking the curse. Unless there's a surge of enthusiasm and generosity this week, better get those baritone voices tuned up. But, it's not too late to show your true colors! Go for broke and make a $5 non-tax-deductible contribution via PayPal using any major credit card. You'll sleep better! Just click on this link. And, you have our absolute commitment. If we hit a million bucks, we'll never pass the hat again. Of course, we might stop writing these silly articles, too. But, based upon last week's numbers, it doesn't look like there's much risk of a financial windfall here. We're just trying to recoup the costs of the voice prompts.

    Coming Attractions. We have a number of projects underway to keep us busy for the next few weeks and months, but we always love to hear from you. If there is a particular Asterisk project you'd like us to cover down the road, leave a comment. We read every one of them. On our short list at the moment are a HOW-TO on connecting two Asterisk servers together and all the great things you can do once you've done that such as building a failover Asterisk system, HOW-TO connect remote IP and IAX phones to your Asterisk system (both wired and WiFi), instant messaging, key system emulation with Asterisk@Home 2.2, DUNDI, HOW-TO let Asterisk read your emails to you over the phone, the new Appointment Reminder System mentioned above, plus a few surprises. Don't expect all of this overnight, but we'll get there. With most of this stuff, we usually write about it as we build it. So you're reading these articles while riding in the front seat most of the time. Come back and visit often and tell your friends about us.


    Some Recent Nerd Vittles Articles of Interest...

    Introducing TeleYapper: Free Asterisk Message Broadcasting System, Part II

    It's free software day again at Nerd Vittles, and today it's Part II of TeleYapper, an Asterisk@Home-based telephone broadcasting service for neighborhoods, schools, little leagues, fundraisers, municipal governments, and anyone else that just wants to pester folks with annoying, but free, prerecorded phone calls. Everything you'll need to get TeleYapper working is in this article, so there's no need to begin with Part I unless you just want to. TeleYapper works like this. You create a recorded message using Asterisk®. Then you create a list of phone numbers to call in a MySQL database using a tool such as phpMyAdmin which is bundled with Asterisk@Home. Finally, you place a phone call either to kick off TeleYapper or to redial calls that failed the first time around. The software will dutifully swing into action and call qualifying phone numbers from any of ten calling categories that you specify when you set up your database of callees. TeleYapper then will deliver the message you've recorded. It works much like call-em-all.com and numerous other telephone broadcasting services with one important difference: TeleYapper is FREE! So, instead of paying 15¢ a call or $35 to $100 a month for a commercial service or spending thousands of dollars for a commercial dialer, now you can do it yourself using TeleYapper and your (also free) Asterisk@Home 1.5 or 2.2 PBX. Today we'll actually get TeleYapper making calls and emailing you the results of those calls. Don't be intimidated by the length of the article. You can still complete this project in about 30 minutes. It's mostly a cut-and-paste exercise. We've done all the hard work for you. NOTE: For those using Asterisk@Home 2.4 or later, use this updated tutorial and software.

    Legalese. For those that are used to buying flawless software such as Microsoft Windows or Microsoft Office, let's be sure we're all on the same page up front. First, you're not buying this software. It's FREE! And, yes, sometimes you get what you pay for. Second, don't assume today's version is error-free. It's probably not. We try pretty hard to write reliable code, but even the best among us make mistakes. Third, by downloading or using this software, you are agreeing to assume all risks associated with use of the software. NO WARRANTIES EXPRESS OR IMPLIED INCLUDING ITS FITNESS FOR USE OR MERCHANTABILITY ARE PROVIDED WITH THIS SOFTWARE. And, finally, read or reread Part I of this series concerning Do Not Call statutes in your jurisdiction and make sure you are in compliance before placing any calls. Failure to heed this advice may subject you to serious criminal and civil penalties. If any of this gives you heartburn, exercise your constitutional right to not use the software.


    Overview. One of the reasons we continue to write software applications for Asterisk is to document for others how easy it is to create really useful software for this terrific open source platform. When we began using Asterisk, there was precious little code available with sufficient documentation to give much of a hint on how to write applications. There were lots of reasons for this not the least of which was a desire by existing Asterisk developers to protect their livelihood. We don't want to jeopardize anyone's ability to make a living, but the spread of an open source PBX with good applications will only lead to more business, not less. Today's installment provides a good framework for anyone wanting to write Asterisk AGI scripts using PHP. The code is well-documented to demonstrate how to pass variables to an AGI script from your dialplan and how to retrieve variables from an Asterisk AGI script into your dialplan. We needed this for TeleYapper because we're using a phone call to an Interactive Voice Response (IVR) session embedded in the dialplan to begin the calling process. We use the IVR session not only to determine which group of callees to call but also to give the caller the option of placing a call to everyone in the group or just those to whom the initial call was unsuccessful. After the caller hangs up, the results are passed to the teleyapper.php application to do the heavy lifting. The PHP program takes advantage of an AGI script's ability to actually set dialplan code in motion once a call is answered. In order to log calls and track which ones are successful, we have to pass variables into that dialplan code and then execute another PHP script when the call is completed. Stated another way, every call requires two round-trips from the Asterisk dialplan to PHP/AGI scripts. So, if you can't figure out how to pass variables back and forth using this application, you probably need to take up another line of work. For those that just want to use the TeleYapper application and not learn much of anything about programming, you're welcome to do that subject to the license agreement which follows. We hope you'll put it to good use for the betterment of a school, an intramural sports program, or a neighborhood in which you live.

    Creative Commons LicenseLicensing. We are retaining ownership of this software as well as the copyright. It is licensed for use under the terms of the Creative Commons Attribution Non-Commercial license. A Plain English summary is available here. We've done this primarily to do our part to stamp out the telemarketing creeps of the world. Those wishing to use TeleYapper in a commercial environment must first request a license outlining your proposed terms of use. We will promptly respond with a yay or nay. Telemarketers need not apply!

    Asterisk Version Issues. In our first installment, we were ambushed by some changes in the way the new version of Asterisk handles management of memory variables. We're trying not to fall in the same trap again. Suffice it to say, the Asterisk developers decided to change the name of the verb, and the syntax, and the functionality of storing data to memory variables. There may be a good reason for it, but we can't think of any. And we certainly can't think of a reason why you would eliminate the old way of doing things in a product that is barely a year old. Nevertheless, we're all stuck with it. The bottom line is that, so long as we try to maintain versions of our applications for both Asterisk@Home 1.5 and Asterisk@Home 2.2, you'll need to download code that is compatible with the version of Asterisk you are running.

    TeleYapper in a Nutshell. Before we get to the code, let's briefly cover how this message broadcasting system works. When you dial 674, the TeleYapper system will answer and prompt you for your password. Once you correctly enter the password, an interactive voice response (IVR) system will swing into action and give you several choices. That's what the [yapper] context handles. Pressing 1 lets you listen to your prerecorded TeleYapper message (if you have one). You don't yet so don't press 1. Pressing 2 lets you record a new TeleYapper message. This is handled by the [yapper2] context. Do this first and record something ... anything. You can rerecord a new message at any time by choosing option 2 again. Pressing 3 lets you kick off a TeleYapper dialing spree. It's handled by the [yapper3] context. Don't do this until we add your new database below, or you'll get smoke out of your system. If you choose option 3 to initiate a TeleYapper calling session, the system will first prompt you for a group option number to use. This is managed by the [yapper-options] context. Simply stated, when you build your database of callees for TeleYapper, you can specify a one-digit group number for each entry in the file. Then, when you begin a calling session, you can narrow down the calling group by telling TeleYapper which group of callees to call. If you want a callee to be in more than one group, you simply enter that callee into the database multiple times with different group numbers. If you want everyone in the same group, then enter 0 for every person in your database.


    Once you specify the group number during your TeleYapper session, the system will actually look up and report back how many messages will be delivered to the callee group you've chosen. Allison will say something like this assuming there were 146 calls to be placed: "The number I have is one hundred and forty six messages." This will give you the count of qualifying records in the database and the option of proceeding with the calls, cancelling the transaction, or just redialing the numbers of the calls that failed to this group on the previous pass through the database. As noted previously, we've endeavored to build this entire application using the voice prompts that are delivered with Asterisk@Home 1.5 or 2.x so they're not quite perfect. But they work reasonably well once you understand how the pieces fit together. You're supposed to be nodding in agreement now. If not, reread the last two paragraphs.

    TeleYapper's Calling Process. For those that like lists, it may help to visualize how all the TeleYapper code fits together by laying out the actual program steps in a typical call:

  • 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 (which 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 creates dialing scripts a minute apart for each call beginning two minutes after the initiating request. Scripts are placed in the wakeupcall 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.
  • Wakeup call queue is checked every minute by a cron job which moves qualifying calls to the Asterisk outbound call queue for dialing.
  • Asterisk places each call as it hits the call queue and 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 TeleYapper Components. Last week we provided the beginnings of the TeleYapper application for you to experiment with. This included the MySQL database and some chunks of code for your AAH dialplan (depending upon which version of AAH you were using) plus checkgroup.php (used to compute the number of callees in the group selected by caller). Today we want to update some of the original code. Then we'll add some additional pieces of code so that the application can do something meaningful ... like calling people with your broadcast message.


    Actually, the new code not only handles the actual dialing of the callees you've entered in your MySQL database (teleyapper.php), it also plays your message when a callee answers (dialplan contexts), and documents what happened during the calls (teleyapper2.php). Call progress is documented in two ways. First, when a call is completed, TeleYapper will log the date and time of the call as well as a best guess of what happened during the call in your MySQL database. So browsing entries in your TeleYapper database will always show the date, time, and status of the last completed call to each callee. We'll build a web interface for this one of these days. Second, when you install the TeleYapper PHP components, there are some configuration options which will also let you create a detailed log of what happened during the TeleYapper calls. If you have email working reliably on your Asterisk system, you also can enter your email address and tell TeleYapper to email you every log that is produced. There are log entries for the initial call setup (handled by teleyapper.php) and for the placement of the individual calls (handled by teleyapper2.php). Finally, you have the option of creating a new log with each series of calls that are placed (the default setting), or you can configure TeleYapper to keep adding to the end of the initial log. In the latter case, it's up to you to erase the log before it fills up your disk. Individual call entries, if logged, will be appended to the main TeleYapper call setup log (/var/log/asterisk/teleyapper.txt).

    To keep things simple, everything you'll need to make TeleYapper work is covered in this article even though we covered some of it last week. Where there is overlap with last week's article, we'll tell you, and you can skip that step. It simply didn't make much sense for new visitors to have to jump back and forth between the two articles to get a working system. That's one of the limitations of the blog format unfortunately. Here are the components that make up the complete TeleYapper system, and we'll cover them below in the order which simplifies the installation process:

  • TeleYapper MySQL database
  • Code Snippet to Answer M-S-G Calls
  • AutoAttendant Contexts
  • checkgroup.php AGI script
  • Call Processing Contexts
  • teleyapper.php AGI script
  • teleyapper2.php AGI script
  • Creating the TeleYapper Database. We use Asterisk@Home's MySQL database management system to manage the list of callees for TeleYapper to dial. It can handle a database of almost any size and generally stands up well in performance comparisons with Oracle. So you're covered on the database front. If you downloaded and installed this database in Part I, you can skip this section. Nothing has changed since Part I.

    To create the MySQL database to support TeleYapper, the easiest way is using the Asterisk Management Portal (AMP) to gain access to phpMyAdmin: AMP->Maintenance->phpMyAdmin. When phpMyAdmin loads, click on the SQL icon in the left column. When the SQL window appears, clear the existing SQL query and then cut-and-paste the following SQL code into that box and then click the Go button. When the import completes, click the teleyapper.callees table entry in the left column to open the file. Then click the Insert tab at the top of the right column to add entries to the table. You only need to add information for the name, phonenum, and group fields in the corresponding values column. The id, lastokcall, and lastcall fields should be left as is. The id field gets calculated automatically. The lastokcall will record the time and date of the last successful call using TeleYapper. And the lastcall field identifies what happened during the last call to this person, e.g. ok means the call was completed successfully, no answer means no one answered the call, or answering machine means an answering machine took the call.


    You can add up to two records at a time and, by clicking the Insert Another New Row button, you will be returned to this data entry screen after you save your entries by clicking the Go button. The name field allows you to quickly review entries you've made. It won't be used when making TeleYapper calls. The phonenum field is the important one. This is the exact dial string required to place a call on your Asterisk system to this callee using whatever VoIP or PSTN outbound trunk you plan to use with TeleYapper. For example, if your preferred provider requires 11-digit phone numbers with a 1, area code, and number, then that's the way the numbers should be entered into the TeleYapper database. The group field has already been discussed. Just enter a number between 0 and 9 to identify the group with whom this individual should be associated. Finally, after adding records to the table, you can click the Browse tab to review your entries. And, while Browsing, you can click the Pencil icon beside any record entry to edit it. Clicking the red X icon beside a record entry deletes the record. If, for some reason, you wish to delete ALL the records in the file, click the Empty tab at the top of the right column. Under no circumstances should you click on the Drop tab as this removes not only the table's contents but also the table structure itself. In short, you'd have to import the database table again.

    Answering the Incoming Call. This is a simple addition to your dialplan to actually answer calls to M-S-G (extension 674) and pass them to the TeleYapper contexts for processing. If you went through Part I, you can skip this step. Nothing has changed. Using a web browser, open the Asterisk Management Portal (AMP) by entering the IP address of your Asterisk machine. To add TeleYapper to your dialplan, just cut-and-paste the following code into the [from-internal-custom] context near the top of extensions_custom.conf: AMP->Maintenance->Config Edit->extensions_custom.conf. Be sure to change the 1234 password below to something secure for your system since this will be used to gain access to your TeleYapper system!

    exten => 674,1,Answer ; dial MSG on any extension to manage your TeleYapper system
    exten => 674,2,Wait(1)
    exten => 674,3,Authenticate(1234)
    exten => 674,4,Goto(yapper,s,1)

    If you're a long-time reader of Nerd Vittles and you're using either our Stealth AutoAttendant or some other AutoAttendant, then you already know why you need to be careful about putting extensions like 6-7-4 in your extensions_custom.conf file because anyone can call you, dial 6-7-4 while your AutoAttendant is playing, and insert their own obscene message into your TeleYapper system. The solution is adding your own secure password in line 3 above rather than using the default 1234. Another precaution you should always perform is to first play your outgoing TeleYapper message to yourself to make certain it says what you think it should before you kick off a dialing spree to a thousand of your closest friends or business associates.

    AutoAttendant Contexts for TeleYapper. The simplest solution for those that read Part I of the TeleYapper series is to just block delete the [yapper], [yapper2], [yapper3], [yapper-options], and [yapper-gen] contexts at the bottom of your extensions_custom.conf file. Then, for new and old readers alike, insert one of the following chunks of code at the bottom of extensions_custom.conf depending upon your version of Asterisk@Home. Last week we actually presented three approaches. Two used checkgroup.php to retrieve the group count for the autoattendant dialogue while one(for AAH 1.5 only) actually performed the MySQL group count lookups in the dialplan itself. We've given up on the latter approach as something we want to support. The Asterisk developers barely do, and it doesn't appear to work in Asterisk@Home 2.2 (Asterisk 1.5.1) anyway. For those that are curious, we've documented how it works in Part I if you want to wrestle with it.


    For users of Asterisk@Home 1.5, open the Asterisk Management Portal (AMP) by entering the IP address of your Asterisk machine. Cut-and-paste the following six contexts into the bottom of extensions_custom.conf: AMP->Maintenance->Config Edit->extensions_custom.conf:

    [yapper]
    exten => s,1,DigitTimeout(7)
    exten => s,2,ResponseTimeout(10)
    exten => s,3,Background(T-to-hear-cur-ancmnt)
    exten => s,4,Background(press-1)
    exten => s,5,Background(to-rerecord-yr-message)
    exten => s,6,Background(press-2)
    exten => s,7,Background(to-place-outgoing-call)
    exten => s,8,Background(press-3)
    exten => s,9,Background(to-hear-menu-again)
    exten => s,10,Background(press-4)
    exten => s,11,Background(to-hang-up)
    exten => s,12,Background(press-5)
    exten => 1,1,Playback(custom/broadcast)
    exten => 1,2,Wait(2)
    exten => 1,3,Goto(s,3)
    exten => 2,1,Goto(yapper2,s,1)
    exten => 3,1,Goto(yapper-options,s,1)
    exten => 4,1,Goto(s,3)
    exten => 5,1,Playback(goodbye)
    exten => 5,2,Hangup
    exten => t,1,Goto(s,3)
    exten => i,1,Goto(s,3)
    exten => o,1,Goto(s,3)
    exten => h,1,Hangup

    [yapper2]
    exten => s,1,Playback(after-the-tone)
    exten => s,2,Playback(say-temp-msg-prs-pound)
    exten => s,3,Wait(2)
    exten => s,4,Record(custom/broadcast:gsm)
    exten => s,5,Wait(2)
    exten => s,6,Playback(custom/broadcast)
    exten => s,7,Wait(2)
    exten => s,8,Playback(your-msg-has-been-saved)
    exten => s,9,Wait(2)
    exten => s,10,Goto(yapper,s,1)

    [yapper3]
    exten => s,1,AGI(checkgroup.php|${GROUP})
    exten => s,2,NoOp(tmp variable: ${tmp})
    exten => s,3,GotoIf($[${tmp} = 0]?9,1)
    exten => s,4,SetGlobalVar(COUNTER=${tmp})
    exten => s,5,Playback(the-num-i-have-is)
    exten => s,6,SayNumber(${COUNTER})
    exten => s,7,Playback(vm-messages)
    exten => s,8,Wait(1)
    exten => s,9,DigitTimeout(7)
    exten => s,10,ResponseTimeout(10)
    exten => s,11,Background(to-call-this-number)
    exten => s,12,Background(press-1)
    exten => s,13,Background(to-hang-up)
    exten => s,14,Background(press-2)
    exten => s,15,Background(vm-advopts)
    exten => 1,1,Goto(yapper-gen,s,1)
    exten => 2,1,Playback(goodbye)
    exten => 2,2,Hangup
    exten => 3,1,Goto(yapper-redial,s,1)
    exten => 9,1,Playback(dir-nomatch)
    exten => 9,2,Wait(1)
    exten => 9,3,Goto(yapper,s,1)
    exten => t,1,Playback(goodbye)
    exten => t,2,Hangup
    exten => i,1,Playback(goodbye)
    exten => i,2,Hangup
    exten => h,1,Hangup

    [yapper-options]
    exten => s,1,Wait(1)
    exten => s,2,Playback(you-have-these-options)
    exten => s,3,Playback(digits/0)
    exten => s,4,Playback(through)
    exten => s,5,Playback(digits/9)
    exten => s,6,Playback(press-star-cancel)
    exten => s,7,SetGlobalVar(GROUP=0)
    exten => s,8,Read(GROUP,vm-enter-num-to-call,1)
    exten => s,9,NoOp(${GROUP})
    exten => s,10,GotoIf($["foo${GROUP}" = "foo"]?s,78)
    exten => s,11,GotoIf($["foo${GROUP}" = "foo*"]?s,88)
    exten => s,12,GotoIf($["foo${GROUP}" = "foo#"]?s,98)
    exten => s,13,Goto(yapper3,s,1)
    exten => s,78,Playback(connection-timed-out)
    exten => s,79,Wait(1)
    exten => s,80,Goto(yapper,s,1)
    exten => s,88,Playback(cancelled)
    exten => s,89,Wait(1)
    exten => s,90,Goto(yapper,s,1)
    exten => s,98,Playback(option-not-implemented)
    exten => s,99,Goto(yapper,s,1)

    [yapper-gen]
    exten => s,1,Playback(speed-dial)
    exten => s,2,Playback(activated)
    exten => s,3,Wait(1)
    exten => s,4,Playback(goodbye)
    exten => s,5,Hangup
    exten => h,1,DeadAGI(teleyapper.php|${GROUP}|${COUNTER}|1)
    exten => h,2,Hangup

    [yapper-redial]
    exten => s,1,Playback(speed-dial)
    exten => s,2,Playback(activated)
    exten => s,3,Wait(1)
    exten => s,4,Playback(goodbye)
    exten => s,5,Hangup
    exten => h,1,DeadAGI(teleyapper.php|${GROUP}|${COUNTER}|3)
    exten => h,2,Hangup


    For users of Asterisk@Home 2.2, open the Asterisk Management Portal (AMP) by entering the IP address of your Asterisk machine. Cut-and-paste the following six contexts into the bottom of extensions_custom.conf: AMP->Maintenance->Config Edit->extensions_custom.conf:

    [yapper]
    exten => s,1,DigitTimeout(7)
    exten => s,2,ResponseTimeout(10)
    exten => s,3,Background(T-to-hear-cur-ancmnt)
    exten => s,4,Background(press-1)
    exten => s,5,Background(to-rerecord-yr-message)
    exten => s,6,Background(press-2)
    exten => s,7,Background(to-place-outgoing-call)
    exten => s,8,Background(press-3)
    exten => s,9,Background(to-hear-menu-again)
    exten => s,10,Background(press-4)
    exten => s,11,Background(to-hang-up)
    exten => s,12,Background(press-5)
    exten => 1,1,Playback(custom/broadcast)
    exten => 1,2,Wait(2)
    exten => 1,3,Goto(s,3)
    exten => 2,1,Goto(yapper2,s,1)
    exten => 3,1,Goto(yapper-options,s,1)
    exten => 4,1,Goto(s,3)
    exten => 5,1,Playback(goodbye)
    exten => 5,2,Hangup
    exten => t,1,Goto(s,3)
    exten => i,1,Goto(s,3)
    exten => o,1,Goto(s,3)
    exten => h,1,Hangup

    [yapper2]
    exten => s,1,Playback(after-the-tone)
    exten => s,2,Playback(say-temp-msg-prs-pound)
    exten => s,3,Wait(2)
    exten => s,4,Record(custom/broadcast:gsm)
    exten => s,5,Wait(2)
    exten => s,6,Playback(custom/broadcast)
    exten => s,7,Wait(2)
    exten => s,8,Playback(your-msg-has-been-saved)
    exten => s,9,Wait(2)
    exten => s,10,Goto(yapper,s,1)

    [yapper3]
    exten => s,1,AGI(checkgroup.php|${GROUP})
    exten => s,2,NoOp(tmp variable: ${tmp})
    exten => s,3,GotoIf($[${tmp} = 0]?9,1)
    exten => s,4,Set(COUNTER=${tmp}|g)
    exten => s,5,Playback(the-num-i-have-is)
    exten => s,6,SayNumber(${COUNTER})
    exten => s,7,Playback(vm-messages)
    exten => s,8,Wait(1)
    exten => s,9,DigitTimeout(7)
    exten => s,10,ResponseTimeout(10)
    exten => s,11,Background(to-call-this-number)
    exten => s,12,Background(press-1)
    exten => s,13,Background(to-hang-up)
    exten => s,14,Background(press-2)
    exten => s,15,Background(vm-advopts)
    exten => 1,1,Goto(yapper-gen,s,1)
    exten => 2,1,Playback(goodbye)
    exten => 2,2,Hangup
    exten => 3,1,Goto(yapper-redial,s,1)
    exten => 9,1,Playback(dir-nomatch)
    exten => 9,2,Wait(1)
    exten => 9,3,Goto(yapper,s,1)
    exten => t,1,Playback(goodbye)
    exten => t,2,Hangup
    exten => i,1,Playback(goodbye)
    exten => i,2,Hangup
    exten => h,1,Hangup

    [yapper-options]
    exten => s,1,Wait(1)
    exten => s,2,Playback(you-have-these-options)
    exten => s,3,Playback(digits/0)
    exten => s,4,Playback(through)
    exten => s,5,Playback(digits/9)
    exten => s,6,Playback(press-star-cancel)
    exten => s,7,Read(tmp,vm-enter-num-to-call,1)
    exten => s,8,Set(GROUP=${tmp}|g)
    exten => s,9,NoOp(${GROUP})
    exten => s,10,GotoIf($["foo${GROUP}" = "foo"]?s,78)
    exten => s,11,GotoIf($["foo${GROUP}" = "foo*"]?s,88)
    exten => s,12,GotoIf($["foo${GROUP}" = "foo#"]?s,98)
    exten => s,13,Goto(yapper3,s,1)
    exten => s,78,Playback(connection-timed-out)
    exten => s,79,Wait(1)
    exten => s,80,Goto(yapper,s,1)
    exten => s,88,Playback(cancelled)
    exten => s,89,Wait(1)
    exten => s,90,Goto(yapper,s,1)
    exten => s,98,Playback(option-not-implemented)
    exten => s,99,Goto(yapper,s,1)

    [yapper-gen]
    exten => s,1,Playback(speed-dial)
    exten => s,2,Playback(activated)
    exten => s,3,Wait(1)
    exten => s,4,Playback(goodbye)
    exten => s,5,Hangup
    exten => h,1,DeadAGI(teleyapper.php|${GROUP}|${COUNTER}|1)
    exten => h,2,Hangup

    [yapper-redial]
    exten => s,1,Playback(speed-dial)
    exten => s,2,Playback(activated)
    exten => s,3,Wait(1)
    exten => s,4,Playback(goodbye)
    exten => s,5,Hangup
    exten => h,1,DeadAGI(teleyapper.php|${GROUP}|${COUNTER}|3)
    exten => h,2,Hangup



    Call Processing Contexts for TeleYapper. All of this code is new. For new and old readers alike, insert one of the following chunks of code at the bottom of extensions_custom.conf depending upon your version of Asterisk@Home.

    For Asterisk@Home 1.5 users, cut-and-paste the following two contexts:

    [broadcast]
    exten => s,1,Answer
    exten => s,2,Wait(2)
    exten => s,3,Playback(system-status-msg)
    exten => s,4,Wait(2)
    ;exten => s,5,BackgroundDetect(custom/broadcast|1000|50|3000)
    exten => s,5,Playback(custom/broadcast)
    exten => s,6,Goto(talk,1)
    exten => t,1,Goto(talk,1)
    exten => i,1,Goto(talk,1)
    exten => o,1,Goto(talk,1)
    exten => h,1,NoOp(Callee hung up call before menu. Dialed: ${DIAL} ID: ${ID}.)
    exten => h,2,SetGlobalVar(STATUS='EarlyHangup')
    exten => h,3,DeadAGI(teleyapper2.php|${ID}|${STATUS}|${DIAL})
    exten => h,4,Hangup
    exten => talk,1,Goto(broadcast2,s,1)

    [broadcast2]
    exten => s,1,SetGlobalVar(STATUS='Answered')
    exten => s,2,DigitTimeout(4)
    exten => s,3,ResponseTimeout(4)
    exten => s,4,Background(to-hear-msg-again)
    exten => s,5,Background(press-1)
    exten => s,6,Background(to-blklist-last-caller)
    exten => s,7,Background(digits/2)
    exten => s,8,Background(otherwise-press)
    exten => s,9,Background(digits/3)
    exten => t,1,NoOp(Callee's Answering Machine probably answered. Dialed: ${DIAL} ID: ${ID}.)
    exten => t,2,SetGlobalVar(STATUS='AnsMachine')
    exten => t,3,Background(restarting)
    exten => t,4,Wait(1)
    exten => t,5,Playback(custom/broadcast) ; playing again for ans machine
    exten => t,6,Background(goodbye)
    exten => t,7,Hangup
    exten => h,1,DeadAGI(teleyapper2.php|${ID}|${STATUS}|${DIAL})
    exten => h,2,Hangup
    exten => i,1,Goto(1,1)
    exten => o,1,Goto(1,1)
    exten => 1,1,SetGlobalVar(STATUS='ReplayedMsg')
    exten => 1,2,Goto(t,3)
    exten => 2,1,SetGlobalVar(STATUS='Zap')
    exten => 2,2,Background(num-was-successfully)
    exten => 2,3,Background(removed)
    exten => 2,4,Background(goodbye)
    exten => 2,5,NoOp(Callee Requested to have number removed. Dialed: ${DIAL} ID: ${ID}.)
    exten => 2,6,Hangup
    exten => 3,1,SetGlobalVar(STATUS='OK')
    exten => 3,2,Background(goodbye)
    exten => 3,3,NoOp(Callee Acknowledged Call. Dialed: ${DIAL} ID: ${ID}.)
    exten => 3,4,Hangup


    For Asterisk@Home 2.2 users, cut-and-paste the following two contexts:

    [broadcast]
    exten => s,1,Answer
    exten => s,2,Wait(2)
    exten => s,3,Playback(system-status-msg)
    exten => s,4,Wait(2)
    ;exten => s,5,BackgroundDetect(custom/broadcast|1000|50|3000)
    exten => s,5,Playback(custom/broadcast)
    exten => s,6,Goto(talk,1)
    exten => t,1,Goto(talk,1)
    exten => i,1,Goto(talk,1)
    exten => o,1,Goto(talk,1)
    exten => h,1,NoOp(Callee hung up call before menu. Dialed: ${DIAL} ID: ${ID}.)
    exten => h,2,Set(STATUS='EarlyHangup'|g)
    exten => h,3,DeadAGI(teleyapper2.php|${ID}|${STATUS}|${DIAL})
    exten => h,4,Hangup
    exten => talk,1,Goto(broadcast2,s,1)

    [broadcast2]
    exten => s,1,Set(STATUS='Answered'|g)
    exten => s,2,DigitTimeout(4)
    exten => s,3,ResponseTimeout(4)
    exten => s,4,Background(to-hear-msg-again)
    exten => s,5,Background(press-1)
    exten => s,6,Background(to-blklist-last-caller)
    exten => s,7,Background(digits/2)
    exten => s,8,Background(otherwise-press)
    exten => s,9,Background(digits/3)
    exten => t,1,NoOp(Callee's Answering Machine probably answered. Dialed: ${DIAL} ID: ${ID}.)
    exten => t,2,Set(STATUS='AnsMachine'|g)
    exten => t,3,Background(restarting)
    exten => t,4,Wait(1)
    exten => t,5,Playback(custom/broadcast) ; playing again for ans machine
    exten => t,6,Background(goodbye)
    exten => t,7,Hangup
    exten => h,1,DeadAGI(teleyapper2.php|${ID}|${STATUS}|${DIAL})
    exten => h,2,Hangup
    exten => i,1,Goto(1,1)
    exten => o,1,Goto(1,1)
    exten => 1,1,Set(STATUS='ReplayedMsg'|g)
    exten => 1,2,Goto(t,3)
    exten => 2,1,Set(STATUS='Zap'|g)
    exten => 2,2,Background(num-was-successfully)
    exten => 2,3,Background(removed)
    exten => 2,4,Background(goodbye)
    exten => 2,5,NoOp(Callee Requested to have number removed. Dialed: ${DIAL} ID: ${ID}.)
    exten => 2,6,Hangup
    exten => 3,1,Set(STATUS='OK'|g)
    exten => 3,2,Background(goodbye)
    exten => 3,3,NoOp(Callee Acknowledged Call. Dialed: ${DIAL} ID: ${ID}.)
    exten => 3,4,Hangup


    Once you finish adding all of the new contexts to extensions_custom.conf, click the Update button to save your changes to disk. There's no need to reload Asterisk just yet. We've still got our AGI scripts to install.

    For those that are curious, you'll notice there is a commented out line 5 in the [broadcast] context. It's an Asterisk command called BackgroundDetect. What this command is supposed to do is play a sound file while listening for silence at the callee's end of the call. Once silence is detected, the call processing drops to talk. We couldn't get it to work reliably so the current release blindly plays your message and then asks for an acknowledgment. If it doesn't get one, it plays your message again, and then hangs up. The theory here is that, even if a callee has an answering machine, the second playing of your message should get recorded. We'll see what the feedback from the pioneers reveals. Just be aware that there may be further adjustments in the coming days and weeks. So check back and read the latest comments to this blog entry.


    Installing checkgroup.php AGI Script. We introduced this script in Part I to solve a bug in Asterisk@Home 2.2 which appears to be inherited from Asterisk 1.2.1. If you've already downloaded it, you can skip this section. Nothing has changed. For those just joining us, you'll need to install the checkgroup.php script in your /var/lib/asterisk/agi-bin directory and change file ownership and permissions on the file. Log in to your Asterisk server as root, and then execute the following commands:

    cd /var/lib/asterisk/agi-bin
    wget http://nerdvittles.com/checkgroup.zip
    unzip checkgroup.zip
    rm checkgroup.zip
    chmod 775 checkgroup.php
    chown asterisk:asterisk checkgroup.php

    This script includes a debug log. The default settings are to create a new log file (/var/log/asterisk/telecheck.txt) each time the script is executed. This doesn't take up much room and is always there for you to read if something comes unglued: cat /var/log/asterisk/telecheck.txt. There are some other options. You can turn off the log file entirely ($debug=0). You can choose not to erase the previous log file each time the script is run ($newlogeachdebug=0) in which case the file continues to grow until your hard disk fills up. And you can have the log file emailed to you each time the script is executed ($emaildebuglog=1) by adding your email address ($email=youremailaddress). The last option obviously assumes you have followed our previous tutorials and gotten outbound email working reliably on your system. The functions are controlled by the following lines at the top of the checkgroup.php file. 1 means yes, and 0 means no. Just edit the file carefully: nano -w checkgroup.php. And save your changes when you're finished: Ctrl-X, Y, then press Enter.

    $debug = 1;
    $newlogeachdebug = 1;
    $emaildebuglog = 0;
    $email = "yourname@yourdomain" ;


    Installing teleyapper.php AGI Script. This code is new. New and old readers will need to install the teleyapper.php script in your /var/lib/asterisk/agi-bin directory, change file ownership and permissions on the file, and then set some configuration options. Log in to your Asterisk server as root, and then execute the following commands:

    For Asterisk@Home 1.5 users:


    cd /var/lib/asterisk/agi-bin
    wget http://nerdvittles.com/aah15/teleyapper.zip
    unzip teleyapper.zip
    rm teleyapper.zip
    chmod 775 teleyapper.php
    chown asterisk:asterisk teleyapper.php

    For Asterisk@Home 2.2 users:


    cd /var/lib/asterisk/agi-bin
    wget http://nerdvittles.com/aah2/teleyapper.zip
    unzip teleyapper.zip
    rm teleyapper.zip
    chmod 775 teleyapper.php
    chown asterisk:asterisk teleyapper.php

    The teleyapper.php script has a number of configuration options including a debug log. Edit the file carefully while positioned in the correct directory: nano -w teleyapper.php. And save your changes when you're finished: Ctrl-X, Y, then press Enter. All of the options are shown below.

    $numcallattempts=3 ;
    $calldelaybetweenruns=20 ;
    $callspread=1 ;
    $debug = 1;
    $newlogeachdebug = 1;
    $emaildebuglog = 0;
    $email = "yourname@yourdomain" ;
    $trunk = "sip/telasip-gw" ;
    $callerid = "6781234567" ;

    The first two options are not yet implemented so leave them alone. The callspread variable determines the spacing of calls to your various callees. The default is one minute which means the call to the second callee begins one minute after the first one starts. If your broadcast message is more than about 20 seconds long, you probably will need to increase this number to 2 to allow sufficient time to complete the first call before the next one begins. Otherwise, calls will fail if you only have a single outbound trunk.

    The debug flags in this file are set the same way as in the checkgroup.php script above: 1 means yes, and 0 means no. The default settings are to create a new log file (/var/log/asterisk/teleyapper.txt) each time the script is executed. This doesn't take up much room and is always there for you to read if something comes unglued: cat /var/log/asterisk/teleyapper.txt. There are some other options. You can turn off the log file entirely ($debug=0). You can choose not to erase the previous log file each time the script is run ($newlogeachdebug=0) in which case the file continues to grow until your hard disk fills up. And you can have the log file emailed to you each time the script is executed ($emaildebuglog=1) by also adding your email address ($email=youremailaddress).

    [UPDATED: 1/13/05] Two settings you will need to adjust to get ANY calls to complete properly are the trunk and callerid variables. If you wish to use a specific trunk in your dialplan for outbound calls, the syntax for the outbound trunk is the same as it is in your dialplan, e.g. sip/telasip-gw or iax2/voxee. Look at the OUT settings at the top of your extensions_additional.conf file if you're not sure. At the request of a number of users, we've now added a new option which allows all outbound TeleYapper calls to be placed using the default dialplan rules on your server. The advantage of this approach is that different VoIP providers can be used automatically for different types of calls in your TeleYapper database. To use your default dial rules, set the trunk to local and TeleYapper will handle the rest of the setup for you. For those that installed TeleYapper before January 13, simply repeat the download and install steps for teleyapper.php above. Our thanks to both Tracy Carlton at VOIPSpeak and chandave at the Voxilla forum for the default dialplan solution.

    The callerid variable should be set to the callerid number of your outbound trunk unless your service provider allows callerid spoofing (most don't!). The callerid setting is ignored if you choose to use your default dialplan rules with a trunk setting of local. Don't delete the variable! Just leave the default value.

    Finally keep in mind that the format of the numbers to be dialed in your database must exactly match the syntax your trunk provider is expecting to see unless you're using your default dialplan rules. Otherwise, all of the outbound calls will fail. For example, if your provider requires that calls begin with a 1 followed by a 3-digit area code and 7-digit number, then that's the way the numbers must be entered in your TeleYapper database.


    Installing teleyapper2.php AGI Script. This code is also new. Install the teleyapper2.php script in your /var/lib/asterisk/agi-bin directory, change file ownership and permissions on the file, and decide if you want to adjust the default debug configuration setup. Log in to your Asterisk server as root, and then execute the following commands:

    For Asterisk@Home 1.5 users:


    cd /var/lib/asterisk/agi-bin
    wget http://nerdvittles.com/aah15/teleyapper2.zip
    unzip teleyapper2.zip
    rm teleyapper2.zip
    chmod 775 teleyapper2.php
    chown asterisk:asterisk teleyapper2.php

    For Asterisk@Home 2.2 users:


    cd /var/lib/asterisk/agi-bin
    wget http://nerdvittles.com/aah2/teleyapper2.zip
    unzip teleyapper2.zip
    rm teleyapper2.zip
    chmod 775 teleyapper2.php
    chown asterisk:asterisk teleyapper2.php

    The only configuration options in the teleyapper2.php script are for the debug log on individual calls that are placed. We recommend you leave the existing settings, or you'll get a new email every time a call is placed by TeleYapper. You can edit the file while positioned in the correct directory: nano -w teleyapper2.php. And save your changes when you're finished: Ctrl-X, Y, then press Enter. All of the options are shown below.

    $debug = 1;
    $emaildebuglog = 0;
    $email = "yourname@yourdomain" ;

    The debug flags in this file are set the same way as in the teleyapper.php script above: 1 means yes, and 0 means no. The default settings are to append individual call information onto the teleyapper.txt log file (/var/log/asterisk/teleyapper.txt) each time a new call is placed. Unless you're planning to call hundreds of thousands of people, this doesn't take up much room and is there for you when something comes unglued. The other options are as follows. You can turn off the individual call logging entirely ($debug=0). And you can have the entire teleyapper.txt log file emailed to you each time a call is placed ($emaildebuglog=1) by also adding your email address ($email=youremailaddress). For your initial test calls, this may be desirable just so you can see what's going on ... if you're too lazy to read the log. In the words of Forest Gump, "That's all I wanna say about that."


    Taking TeleYapper for a Spin. Once you restart Asterisk (amportal stop then amportal start), you should have a Broadcast Message System that works. First, start up the Asterisk Command Line Interface (CLI) by typing asterisk -r from the command prompt on your system after you’ve logged in as root. Then issue the following command: set verbose 10. The CLI now will track the progress of your TeleYapper sessions.

    Using phpMyAdmin, add your cellphone number to your TeleYapper database and specify Group 0 for the entry. Now dial 674 and provide your password, record a message (Option #2), and then place a call (Option #3) to Group 0. Press 1 to kick off the TeleYapper calling spree. Check your CLI and TeleYapper logs if your cellphone doesn't ring in the next two minutes. Enjoy!

    TeleYapper Wish List. Some things are still on our TO-DO list, and we'll get to them one of these days. For those with loads of outbound trunks, we'll try to add a feature that lets you adjust the number of simultaneous oubound calls. For those that want to use the system to send out appointment reminders on dates in the future, we've completed that project. Here's the link. TeleYapper does not yet automatically redial failed calls except in the reminder system, but we plan to address that down the road, too. We also plan to build a web interface to the MySQL database which will let you add, edit, and delete entries as well as run some simple reports. If you have other suggestions, post a comment.

    Want More Projects? For a complete catalog of all our previous Asterisk projects, click here. For the most recent articles including those you missed over the Christmas and New Year's holidays, click here and just scroll down the page.

    From Our Legal Department, moi: The TeleYapper product name (our feeble attempt at humor through parody) has absolutely no affiliation with TeleZapper, the terrific hardware product designed to keep telemarketers from bugging the hell out of you while you're eating your dinner. We confess that our sense of humor got the better of us in coming up with the name for this non-commerical (aka "free") utility designed primarily as an educational vehicle to assist the Asterisk community in recognizing the almost limitless potential of AGI and PHP programming. Our parody seeks to amuse, not to confuse. Our telephony software Yaps. Their telephony hardware Zaps. Other than a telephone line, there is no product similarity as the two conjoined words make clear. And, yes, that is the whole point! The products are opposites, not identical nor even similar. One letter makes all the difference in Night and Light. So it is with Yapper and Zapper. Brand confusion in trademark law arises from synonyms, not antonyms. It is systems like what we're writing about today that TeleZapper is designed to protect against. And it does that very well. In fact, we use TeleZapper hardware in our own home and have for many years. The only problem, of course, is when that tornado comes rolling down the neighbor's street, it would have been nice to get that automated phone call from TeleYapper at the neighborhood headquarters. But, who cares, right? It's only your house. Class dismissed.

    Nerd Vittles Allison Fund. One of our next projects will be an Appointment Reminder System. Using a touchtone phone, you can schedule an unlimited number of customized voice reminders for delivery at any future time to any phone numbers you desire. To make it work, we need customized voice prompts for the IVR interface. Some of our future projects will need these as well. Unfortunately, these cost money. Allison, who records the Asterisk voice prompts for Digium, needs to eat. And so do we. We're springing for the costs of these voice prompts up front, but this is your golden opportunity to contribute to the cause. Provided we raise enough money to cover the costs, we'll put the voice prompts in the public domain. If not, when the project is presented, those that didn't contribute will have to record their own voice prompts in order to use the system. The rest will get the Allison prompts either on a password-protected web site or by email. Seems fair, right? To make a $5 or $10 contribution via PayPal using any major credit card, just click on this link. If the pot grows to over a million bucks, we promise never to ask for money again. Thanks in advance for your support.

    Who Is This Guy? Ward Mundy, the author of this Asterisk@Home series of articles, is a retired attorney who spent more than 30 years providing legal and technology assistance to the federal courts in the United States. Today he serves as a principal in Ward Mundy & Associates, a technology consulting firm in Atlanta, Georgia.

    Introducing TeleYapper: Free Asterisk Message Broadcasting System

    There's nothing quite like starting the new year with an application that exposes an ugly bug in Asterisk® 1.2, but that's what yesterday's original article did. So here's a second stab at the article ... and Asterisk ... without reliance on the buggy code. The revised article requires and will work reliably with Asterisk@Home 1.5 or Asterisk@Home 2.2. For those using Asterisk@Home 2.4 or later, use this updated tutorial and software.

    It's free software day again at Nerd Vittles, and today we're pleased to (re)introduce the first of several tutorials on TeleYapper, an Asterisk@Home-based telephone broadcasting service for neighborhoods, schools, little leagues, fundraisers, municipal governments, and anyone else that just wants to pester folks with annoying, but free, prerecorded phone calls. It works like this. You create a recorded message using Asterisk. Then you create a list of phone numbers to call in a MySQL database using a tool such as phpMyAdmin which is bundled with Asterisk@Home. Finally, you place a phone call to kick off TeleYapper. The software will dutifully swing into action and call every phone number from any of ten calling categories that you specify when you set up your database of callees. TeleYapper then will deliver the message you've recorded. It's even smart enough to detect answering machines and wait for the announcement to end before playing your message. In short, it works much like call-em-all.com and numerous other telephone broadcasting services with one important difference: TeleYapper is FREE! So, instead of paying 15¢ a call or $35 to $100 a month for a commercial service or spending thousands of dollars for a commercial dialer, now you can do it yourself using TeleYapper and your (also free) Asterisk@Home 1.5 or 2.2 PBX. Of course, it also gives us an opportunity to introduce you to some new Asterisk@Home tips and tricks, not to mention bugs, that should keep you burning the midnight oil (like we did last night) with enhancements and tweaks for the next few weeks.

    What's the catch? Well, there are a couple actually. If you have residential VoIP service with unlimited calling, be very careful about using this software without first checking with your provider or at least reading your provider's terms of service. Many prohibit such uses of residential VoIP service, and it's very easy for automated systems to figure out what you're doing since TeleYapper can place literally hundreds of calls per hour in very rapid succession. We plan to throttle the application down to 60 calls per hour, but it still will set off red flags with many VoIP providers. If, on the other hand, you're paying by the call or by the minute, those VoIP providers typically could care less and some will even let you specify your CallerID for such calls. There's nothing quite like using the White House phone number to relay those Little League sports scores to your friends and neighbors. Heh heh!

    In case you've never gotten to experience pre-recorded phone calls before (not likely in the U.S. of A!), think of it as podcasting in reverse. It's the old "don't call us, we'll call you" deal. Instead of people pulling content from your site, you push it to theirs ... in this case, their phones. But seriously, there are some legitimate uses for such a tool other than bugging the crap out of your neighbors. Here are a few that come to mind: event reminders, announcement of sports scores or practice times and locations, emergency notifications, medical appointment reminders, inclement weather alerts and schedules (think T-O-R-N-A-D-O!), neighborhood security warnings, schedule changes, and utility outage alerts. In short, such a system is ideal for many constructive purposes in the business world as well as in charitible organizations, schools, athletic programs, and neighborhood associations. But, for most of these purposes, you need the callee's written permission before making any calls. Just don't abuse it, and the feds and your neighbors won't come calling on you. We strongly recommend that you either obtain the written permission of every person you intend to call using this software or consult with an attorney before making any calls because of new Do Not Call legislation enacted in many states as well as the federal Do Not Call List. Our foreign visitors are well advised to take similar precautions. Failure to heed this advice may result in serious civil and criminal penalties including substantial fines imposed on a per call basis. For an excellent summary of current statutes in the United States, visit this site which pretty well documents why you still need either a TeleZapper hardware device or Asterisk's Zapateller software to protect your own phones from unwanted calls.


    Creative Commons LicenseLicensing. We are retaining ownership of this software as well as the copyright. It is licensed for use under the terms of the Creative Commons Attribution Non-Commercial license. A Plain English summary is available here. We've done this primarily to do our part to stamp out the telemarketing creeps of the world. Those wishing to use TeleYapper in a commercial environment must first request a license outlining your proposed terms of use. We will promptly respond with a yay or nay. Telemarketers need not apply!

    Editor's Note: We'd suggest you stop reading here and move on to Part II which covers everything you'll need to get TeleYapper yapping. You'll also avoid having to do some things twice.

    In this updated first installment, we'll put the framework in place to let you actually record messages and begin building your MySQL database of callees to support TeleYapper calls. We'll also point out some of the differences between AAH 1.5 and AAH 2.2 for those of you contemplating a career in Asterisk programming. Part I also will give you something to play with until we tie everything together and get TeleYapper dialing away in Part II. And someday, if we get a burst of energy, we may actually build a little database application like AsteriDex to help you add and edit entries in your TeleYapper database instead of having to rely upon phpMyAdmin. But, first things first.

    Adding TeleYapper to Your Dialplan. We need a simple facility for building voice messages for the TeleYapper project and for managing the call process. Using some of Asterisk's built-in tools and voice prompts, we've created something that's easy to use and simple to maintain. While the voice prompts are not quite perfect for this application, they're close enough for government work. Using a web browser, open the Asterisk Management Portal (AMP) by entering the IP address of your Asterisk machine. To add TeleYapper to your dialplan, just cut-and-paste the following code into the [from-internal-custom] context near the top of extensions_custom.conf: AMP->Maintenance->Config Edit->extensions_custom.conf. Be sure to change the 1234 password below to something secure for your system since this will be used to gain access to your TeleYapper system!

    exten => 674,1,Answer ; dial MSG on any extension to manage your TeleYapper system
    exten => 674,2,Wait(1)
    exten => 674,3,Authenticate(1234)
    exten => 674,4,Goto(yapper,s,1)

    If you're a long-time reader of Nerd Vittles and you're using either our Stealth AutoAttendant or some other AutoAttendant, then you already know why you need to be careful about putting extensions like 6-7-4 in your extensions_custom.conf file because anyone can call you, dial 6-7-4 while your AutoAttendant is playing, and insert their own obscene message into your TeleYapper system. The solution is adding your own secure password in line 3 above rather than using the default 1234. Another precaution you should always perform is to first play your outgoing TeleYapper message to yourself to make certain it says what you think it should before you kick off a dialing spree to a thousand of your closest friends or business associates.


    Adding the TeleYapper IVR. Now that we have a way to call into the TeleYapper system, we need something for it to do once we connect. So you'll need to cut-and-paste some code to the bottom of the extensions_custom.conf file while you still have the file open. Just scroll down to the bottom of the file. The actual code you need to paste depends upon the version of Asterisk@Home you're running. We initially thought we could demonstrate how to use Asterisk's built-in MySQL tools for some of the IVR interaction, but there appears to be a bug in Asterisk 1.2 upon which AAH 2.2 relies. Every query yields a zero record set when a search is implemented using our original code so that obviously won't be of much use with AAH 2.2. Another issue that those using AAH 1.5 should be aware of is this. Asterisk has no built in MySQL function to return a count of records matching a given search criteria. The only way to get the count is to loop through all the matching records and count them as you go. This works fine with a handful of records, but I have no idea how it would work with 500 or more records. Using a PHP/AGI script on the other hand lets us decipher the count of matching records for a search in one line of code. Bottom line: We're providing the "old" internal way to use MySQL because no one ever has correctly documented how it works, and it does work with Asterisk@Home 1.5. Then we'll provide the "new" PHP/AGI script version for use with Asterisk@Home 1.5. And finally we'll provide the "new" PHP/AGI script version for use with Asterisk@Home 2.2. Why two new versions? Well, the Asterisk developers changed the way variables are stored in Asterisk 1.09 (included in AAH 1.5) and Asterisk 1.2.1 (included in AAH 2.2). Dumb move! It's one thing to add new commands to a programming language (which Asterisk is). It's quite another to eliminate existing commands (which breaks functioning code) or to change the way variables are initialized or set (which yields different results when existing code is executed). End of rant.

    Option #1 for Asterisk@Home 1.5 Only. For those that want to experiment with using Asterisk's internal MySQL commands, here is the original TeleYapper code for you to cut-and-paste to the bottom of extensions_custom.conf. This code only works with Asterisk@Home 1.5, not Asterisk@Home 2.2:

    [yapper]
    exten => s,1,DigitTimeout(7)
    exten => s,2,ResponseTimeout(10)
    exten => s,3,Background(T-to-hear-cur-ancmnt)
    exten => s,4,Background(press-1)
    exten => s,5,Background(to-rerecord-yr-message)
    exten => s,6,Background(press-2)
    exten => s,7,Background(to-place-outgoing-call)
    exten => s,8,Background(press-3)
    exten => s,9,Background(to-hear-menu-again)
    exten => s,10,Background(press-4)
    exten => s,11,Background(to-hang-up)
    exten => s,12,Background(press-5)
    exten => 1,1,Playback(custom/broadcast)
    exten => 1,2,Wait(2)
    exten => 1,3,Goto(s,3)
    exten => 2,1,Goto(yapper2,s,1)
    exten => 3,1,Goto(yapper-options,s,1)
    exten => 4,1,Goto(s,3)
    exten => 5,1,Playback(goodbye)
    exten => 5,2,Goto(h,1)
    exten => t,1,Goto(s,3)
    exten => i,1,Goto(s,3)
    exten => o,1,Goto(s,3)
    exten => h,1,Hangup

    [yapper2]
    exten => s,1,Playback(after-the-tone)
    exten => s,2,Playback(say-temp-msg-prs-pound)
    exten => s,3,Wait(2)
    exten => s,4,Record(custom/broadcast:gsm)
    exten => s,5,Wait(2)
    exten => s,6,Playback(custom/broadcast)
    exten => s,7,Wait(2)
    exten => s,8,Playback(your-msg-has-been-saved)
    exten => s,9,Wait(2)
    exten => s,10,Goto(yapper,s,1)

    [yapper3]
    exten => s,1,SetGlobalVar(COUNTER=0)
    exten => s,2,MYSQL(Connect connid localhost root passw0rd teleyapper)
    exten => s,3,MYSQL(Query resultid ${connid} SELECT `*` FROM `callees` WHERE `group` = ${GROUP})
    exten => s,4,MYSQL(Fetch foundRow ${resultid} var1 var2 var3 var4 var5 var6) ; fetch row
    exten => s,5,GotoIf($["${foundRow}" = "1"]?6:9) ; leave loop if no row found
    exten => s,6,NoOp(${var2}: ${var3})
    exten => s,7,SetGlobalVar(COUNTER=$[${COUNTER} + 1])
    exten => s,8,Goto(4) ; continue loop if row found
    exten => s,9,MYSQL(Clear ${resultid})
    exten => s,10,MYSQL(Disconnect ${connid})
    exten => s,11,GotoIf($["${COUNTER}" = "0"]?9,1)
    exten => s,12,Playback(the-num-i-have-is)
    exten => s,13,SayNumber(${COUNTER})
    exten => s,14,Playback(vm-messages)
    exten => s,15,Wait(1)
    exten => s,16,DigitTimeout(7)
    exten => s,17,ResponseTimeout(10)
    exten => s,18,Background(to-call-this-number)
    exten => s,19,Background(press-1)
    exten => s,20,Background(to-hang-up)
    exten => s,21,Background(press-2)
    exten => 1,1,MYSQL(Disconnect ${connid})
    exten => 1,2,Goto(yapper-gen,s,1)
    exten => 2,1,Playback(goodbye)
    exten => 2,2,MYSQL(Disconnect ${connid})
    exten => 2,3,Hangup
    exten => 9,1,Playback(dir-nomatch)
    exten => 9,2,Wait(1)
    exten => 9,3,MYSQL(Disconnect ${connid})
    exten => 9,4,Goto(yapper,s,1)
    exten => t,1,Playback(goodbye)
    exten => t,2,MYSQL(Disconnect ${connid})
    exten => t,3,Hangup
    exten => i,1,Playback(goodbye)
    exten => i,2,MYSQL(Disconnect ${connid})
    exten => i,3,Hangup
    exten => s,103,MYSQL(Disconnect ${connid})
    exten => s,104,Hangup
    exten => h,1,MYSQL(Disconnect ${connid})

    [yapper-options]
    exten => s,1,Wait(1)
    exten => s,2,Playback(you-have-these-options)
    exten => s,3,Playback(digits/0)
    exten => s,4,Playback(through)
    exten => s,5,Playback(digits/9)
    exten => s,6,Playback(press-star-cancel)
    exten => s,7,SetGlobalVar(GROUP=0)
    exten => s,8,Read(GROUP,vm-enter-num-to-call,1)
    exten => s,9,NoOp(${GROUP})
    exten => s,10,GotoIf($["foo${GROUP}" = "foo"]?s,78)
    exten => s,11,GotoIf($["foo${GROUP}" = "foo*"]?s,88)
    exten => s,12,GotoIf($["foo${GROUP}" = "foo#"]?s,98)
    exten => s,13,Goto(yapper3,s,1)
    exten => s,78,Playback(connection-timed-out)
    exten => s,79,Wait(1)
    exten => s,80,Goto(yapper,s,1)
    exten => s,88,Playback(cancelled)
    exten => s,89,Wait(1)
    exten => s,90,Goto(yapper,s,1)
    exten => s,98,Playback(option-not-implemented)
    exten => s,99,Goto(yapper,s,1)

    [yapper-gen]
    exten => s,1,Playback(speed-dial)
    exten => s,2,Playback(activated)
    exten => s,3,Wait(1)
    exten => s,4,Playback(goodbye)
    exten => s,5,Hangup

    Option #2 for Asterisk@Home 1.5 Only. For those that want to use the new PHP/AGI scripting solution, here is the new TeleYapper code for you to cut-and-paste to the bottom of extensions_custom.conf. This code only works with Asterisk@Home 1.5, not Asterisk@Home 2.2:

    [yapper]
    exten => s,1,DigitTimeout(7)
    exten => s,2,ResponseTimeout(10)
    exten => s,3,Background(T-to-hear-cur-ancmnt)
    exten => s,4,Background(press-1)
    exten => s,5,Background(to-rerecord-yr-message)
    exten => s,6,Background(press-2)
    exten => s,7,Background(to-place-outgoing-call)
    exten => s,8,Background(press-3)
    exten => s,9,Background(to-hear-menu-again)
    exten => s,10,Background(press-4)
    exten => s,11,Background(to-hang-up)
    exten => s,12,Background(press-5)
    exten => 1,1,Playback(custom/broadcast)
    exten => 1,2,Wait(2)
    exten => 1,3,Goto(s,3)
    exten => 2,1,Goto(yapper2,s,1)
    exten => 3,1,Goto(yapper-options,s,1)
    exten => 4,1,Goto(s,3)
    exten => 5,1,Playback(goodbye)
    exten => 5,2,Goto(h,1)
    exten => t,1,Goto(s,3)
    exten => i,1,Goto(s,3)
    exten => o,1,Goto(s,3)
    exten => h,1,Hangup

    [yapper2]
    exten => s,1,Playback(after-the-tone)
    exten => s,2,Playback(say-temp-msg-prs-pound)
    exten => s,3,Wait(2)
    exten => s,4,Record(custom/broadcast:gsm)
    exten => s,5,Wait(2)
    exten => s,6,Playback(custom/broadcast)
    exten => s,7,Wait(2)
    exten => s,8,Playback(your-msg-has-been-saved)
    exten => s,9,Wait(2)
    exten => s,10,Goto(yapper,s,1)

    [yapper3]
    exten => s,1,AGI(checkgroup.php|${GROUP})
    exten => s,2,NoOp(tmp variable: ${tmp})
    exten => s,3,GotoIf($[${tmp} = 0]?9,1)
    exten => s,4,SetGlobalVar(COUNTER=${tmp})
    exten => s,5,Playback(the-num-i-have-is)
    exten => s,6,SayNumber(${COUNTER})
    exten => s,7,Playback(vm-messages)
    exten => s,8,Wait(1)
    exten => s,9,DigitTimeout(7)
    exten => s,10,ResponseTimeout(10)
    exten => s,11,Background(to-call-this-number)
    exten => s,12,Background(press-1)
    exten => s,13,Background(to-hang-up)
    exten => s,14,Background(press-2)
    exten => 1,1,Goto(yapper-gen,s,1)
    exten => 2,1,Playback(goodbye)
    exten => 2,2,Hangup
    exten => 9,1,Playback(dir-nomatch)
    exten => 9,2,Wait(1)
    exten => 9,3,Goto(yapper,s,1)
    exten => t,1,Playback(goodbye)
    exten => t,2,Hangup
    exten => i,1,Playback(goodbye)
    exten => i,2,Hangup
    exten => h,1,Hangup

    [yapper-options]
    exten => s,1,Wait(1)
    exten => s,2,Playback(you-have-these-options)
    exten => s,3,Playback(digits/0)
    exten => s,4,Playback(through)
    exten => s,5,Playback(digits/9)
    exten => s,6,Playback(press-star-cancel)
    exten => s,7,SetGlobalVar(GROUP=0)
    exten => s,8,Read(GROUP,vm-enter-num-to-call,1)
    exten => s,9,NoOp(${GROUP})
    exten => s,10,GotoIf($["foo${GROUP}" = "foo"]?s,78)
    exten => s,11,GotoIf($["foo${GROUP}" = "foo*"]?s,88)
    exten => s,12,GotoIf($["foo${GROUP}" = "foo#"]?s,98)
    exten => s,13,Goto(yapper3,s,1)
    exten => s,78,Playback(connection-timed-out)
    exten => s,79,Wait(1)
    exten => s,80,Goto(yapper,s,1)
    exten => s,88,Playback(cancelled)
    exten => s,89,Wait(1)
    exten => s,90,Goto(yapper,s,1)
    exten => s,98,Playback(option-not-implemented)
    exten => s,99,Goto(yapper,s,1)

    [yapper-gen]
    exten => s,1,Playback(speed-dial)
    exten => s,2,Playback(activated)
    exten => s,3,Wait(1)
    exten => s,4,Playback(goodbye)
    exten => s,5,Hangup

    Option #3 for Asterisk@Home 2.2 Only. As indicated, only the new PHP/AGI scripting solution works with Asterisk@Home 2.2. Here is the new TeleYapper code for you to cut-and-paste to the bottom of extensions_custom.conf. Because of the way global variables are set, this code only works with Asterisk@Home 2.2, not Asterisk@Home 1.5:

    [yapper]
    exten => s,1,DigitTimeout(7)
    exten => s,2,ResponseTimeout(10)
    exten => s,3,Background(T-to-hear-cur-ancmnt)
    exten => s,4,Background(press-1)
    exten => s,5,Background(to-rerecord-yr-message)
    exten => s,6,Background(press-2)
    exten => s,7,Background(to-place-outgoing-call)
    exten => s,8,Background(press-3)
    exten => s,9,Background(to-hear-menu-again)
    exten => s,10,Background(press-4)
    exten => s,11,Background(to-hang-up)
    exten => s,12,Background(press-5)
    exten => 1,1,Playback(custom/broadcast)
    exten => 1,2,Wait(2)
    exten => 1,3,Goto(s,3)
    exten => 2,1,Goto(yapper2,s,1)
    exten => 3,1,Goto(yapper-options,s,1)
    exten => 4,1,Goto(s,3)
    exten => 5,1,Playback(goodbye)
    exten => 5,2,Goto(h,1)
    exten => t,1,Goto(s,3)
    exten => i,1,Goto(s,3)
    exten => o,1,Goto(s,3)
    exten => h,1,Hangup

    [yapper2]
    exten => s,1,Playback(after-the-tone)
    exten => s,2,Playback(say-temp-msg-prs-pound)
    exten => s,3,Wait(2)
    exten => s,4,Record(custom/broadcast:gsm)
    exten => s,5,Wait(2)
    exten => s,6,Playback(custom/broadcast)
    exten => s,7,Wait(2)
    exten => s,8,Playback(your-msg-has-been-saved)
    exten => s,9,Wait(2)
    exten => s,10,Goto(yapper,s,1)

    [yapper3]
    exten => s,1,AGI(checkgroup.php|${GROUP})
    exten => s,2,NoOp(tmp variable: ${tmp})
    exten => s,3,GotoIf($[${tmp} = 0]?9,1)
    exten => s,4,Set(COUNTER=${tmp}|g)
    exten => s,5,Playback(the-num-i-have-is)
    exten => s,6,SayNumber(${COUNTER})
    exten => s,7,Playback(vm-messages)
    exten => s,8,Wait(1)
    exten => s,9,DigitTimeout(7)
    exten => s,10,ResponseTimeout(10)
    exten => s,11,Background(to-call-this-number)
    exten => s,12,Background(press-1)
    exten => s,13,Background(to-hang-up)
    exten => s,14,Background(press-2)
    exten => 1,1,Goto(yapper-gen,s,1)
    exten => 2,1,Playback(goodbye)
    exten => 2,2,Hangup
    exten => 9,1,Playback(dir-nomatch)
    exten => 9,2,Wait(1)
    exten => 9,3,Goto(yapper,s,1)
    exten => t,1,Playback(goodbye)
    exten => t,2,Hangup
    exten => i,1,Playback(goodbye)
    exten => i,2,Hangup
    exten => h,1,Hangup

    [yapper-options]
    exten => s,1,Wait(1)
    exten => s,2,Playback(you-have-these-options)
    exten => s,3,Playback(digits/0)
    exten => s,4,Playback(through)
    exten => s,5,Playback(digits/9)
    exten => s,6,Playback(press-star-cancel)
    exten => s,7,Read(tmp,vm-enter-num-to-call,1)
    exten => s,8,Set(GROUP=${tmp}|g)
    exten => s,9,NoOp(${GROUP})
    exten => s,10,GotoIf($["foo${GROUP}" = "foo"]?s,78)
    exten => s,11,GotoIf($["foo${GROUP}" = "foo*"]?s,88)
    exten => s,12,GotoIf($["foo${GROUP}" = "foo#"]?s,98)
    exten => s,13,Goto(yapper3,s,1)
    exten => s,78,Playback(connection-timed-out)
    exten => s,79,Wait(1)
    exten => s,80,Goto(yapper,s,1)
    exten => s,88,Playback(cancelled)
    exten => s,89,Wait(1)
    exten => s,90,Goto(yapper,s,1)
    exten => s,98,Playback(option-not-implemented)
    exten => s,99,Goto(yapper,s,1)

    [yapper-gen]
    exten => s,1,Playback(speed-dial)
    exten => s,2,Playback(activated)
    exten => s,3,Wait(1)
    exten => s,4,Playback(goodbye)
    exten => s,5,Hangup

    Saving Your Additions. When you've finished pasting one of the three chunks of code above, click the Update button at the bottom of the editing window. Now reload your Asterisk configs: AMP->Setup->Incoming Calls->Submit Changes and then click the Red Bar. Don't be dialing 674 just yet. We haven't installed your database to support the application.

    Installing the CheckGroup PHP/AGI Script. If you're running Asterisk@Home 1.5 with the Option #1 code above, you can skip this step. For those using one of the new PHP/AGI script solutions (Option #2 or Option #3 above), you'll need to install the checkgroup.php script in your /var/lib/asterisk/agi-bin directory and change file ownership and permissions on the file. Log in to your Asterisk server as root, and then execute the following commands:

    cd /var/lib/asterisk/agi-bin
    wget http://nerdvittles.com/checkgroup.zip
    unzip checkgroup.zip
    rm checkgroup.zip
    chmod 775 checkgroup.php
    chown asterisk:asterisk checkgroup.php

    This script includes a debug log. The default settings are to create a new log file (/var/log/asterisk/telecheck.txt) each time the script is executed. This doesn't take up much room and is always there for you to read if something comes unglued: cat /var/log/asterisk/telecheck.txt. There are some other options. You can turn off the log file entirely ($debug=0). You can choose not to erase the previous log file each time the script is run ($newlogeachdebug=0) in which case the file continues to grow until your hard disk fills up. And you can have the log file emailed to you each time the script is executed ($emaildebuglog=1) by adding your email address ($email=youremailaddress). The last option obviously assumes you have followed our previous tutorials and gotten outbound email working reliably on your system. The functions are controlled by the following lines at the top of the checkgroup.php file. 1 means yes, and 0 means no. Just edit the file carefully: nano -w checkgroup.php. And save your changes when you're finished: Ctrl-X, Y, then press Enter.

    $debug = 1;
    $newlogeachdebug = 1;
    $emaildebuglog = 0;
    $email = "yourname@yourdomain" ;


    TeleYapper in a Nutshell. Before we get to the database, let's briefly cover how the above code works. When you dial 674, the TeleYapper system will answer and prompt you for your password. Once you correctly enter the password, an interactive voice response (IVR) system will swing into action and give you several choices. That's what the [yapper] context handles. Pressing 1 lets you listen to your prerecorded TeleYapper message (if you have one). You don't yet so don't press 1. Pressing 2 lets you record a new TeleYapper message. This is handled by the [yapper2] context. Do this first and record something ... anything. You can rerecord a new message at any time by choosing option 2 again. Pressing 3 lets you kick off a TeleYapper dialing spree. It's handled by the [yapper3] context. Don't do this until we add your new database below, or you'll get smoke out of your system. For the technically inclined, [yapper3] in the Option #1 version actually performs some pretty hairy MySQL database tricks that won't work unless you're using Asterisk@Home 1.5. Pure Asterisk needs major patches to jump through the same hoops! (ATTN: Code Junkies -- Assuming you're running AAH 1.5, now you know how to query any MySQL database from inside your Asterisk dialplan!) Pressing 4 repeats the IVR menu choices. And pressing 5 disconnects you from the system.

    If you choose option 3 to initiate a TeleYapper calling session, the system will first prompt you for a group option number to use. This is managed by the [yapper-options] context. Simply stated, when you build your database of callees for TeleYapper, you can specify a one-digit group number for each entry in the file. Then, when you begin a calling session, you can narrow down the calling group by telling TeleYapper which group of callees to call. If you want a callee to be in more than one group, you simply enter that callee into the database multiple times with different group numbers. If you want everyone in the same group, then enter 0 for every person in your database.

    Once you specify the group number during your TeleYapper session, the system will actually look up and report back how many messages will be delivered to the callee group you've chosen. Allison will say something like this assuming there were 146 calls to be placed: "The number I have is one hundred and forty six messages." This will give you the count of qualifying records in the database and the option of proceeding with the calls or cancelling the transaction. In short, it's a safety mechanism to make sure you don't actually set off a calling spree to Group 7 with 500 callees when you meant to choose Group 8 with only 5. You'll still need to know what types of callees are in each group of callees that you create. TeleYapper doesn't quite do everything. Once we add our new database to your system and plug in a couple of entries, you'll have all week to experiment with the IVR system before TeleYapper actually begins making calls. So experiment away until you're comfortable with the menu system. As noted previously, we've endeavored to build this entire application using the voice prompts that are delivered with Asterisk@Home 1.5 or 2.x so they're not quite perfect. But they work reasonably well once you understand how the pieces fit together. You're supposed to be nodding in agreement now. If not, reread the last three paragraphs after you get another cup of coffee.


    Creating the TeleYapper Database. Now we're ready to create the MySQL database to support TeleYapper. The easiest way to do this is using the Asterisk Management Portal (AMP) to gain access to phpMyAdmin: AMP->Maintenance->phpMyAdmin. When phpMyAdmin loads, click on the SQL icon in the left column. When the SQL window appears, clear the existing SQL query and then cut-and-paste the following SQL code into that box and then click the Go button. When the import completes, click the teleyapper.callees table entry in the left column to open the file. Then click the Insert tab at the top of the right column to add entries to the table. You only need to add information for the name, phonenum, and group fields in the corresponding values column. The id, lastokcall, and lastcall fields should be left as is. The id field gets calculated automatically. The lastokcall will record the time and date of the last successful call using TeleYapper. And the lastcall field identifies what happened during the last call to this person, e.g. ok means the call was completed successfully, no answer means no one answered the call, or answering machine means an answering machine took the call.

    You can add up to two records at a time and, by clicking the Insert Another New Row button, you will be returned to this data entry screen after you save your entries by clicking the Go button. The name field allows you to quickly review entries you've made. It won't be used when making TeleYapper calls. The phonenum field is the important one. This is the exact dial string required to place a call on your Asterisk system to this callee using whatever VoIP or PSTN outbound trunk you plan to use with TeleYapper. For example, if your preferred provider requires 11-digit phone numbers with a 1, area code, and number, then that's the way the numbers should be entered into the TeleYapper database. The group field has already been discussed. Just enter a number between 0 and 9 to identify the group with whom this individual should be associated. Finally, after adding records to the table, you can click the Browse tab to review your entries. And, while Browsing, you can click the Pencil icon beside any record entry to edit it. Clicking the red X icon beside a record entry deletes the record. If, for some reason, you wish to delete ALL the records in the file, click the Empty tab at the top of the right column. Under no circumstances should you click on the Drop tab as this removes not only the table's contents but also the table structure itself. In short, you'd have to import the database table again.


    Taking TeleYapper for a Spin. We're ready to try out the TeleYapper IVR. First, start up the Asterisk Command Line Interface (CLI) by typing asterisk -r from the command prompt on your system after you've logged in as root. Then issue the following command: set verbose 10. The CLI now will tell you every phone number that would have been called during your TeleYapper session if you review the CLI history after performing the following steps.

    Dial 6-7-4 from an extension on your system and enter your password. Choose option 2 from the IVR menu and record an outgoing message to be delivered to your callees. Once you've recorded a message, you can play it back by choosing IVR option 1. Assuming you've added your callees in group 0, choose IVR option 3 and enter 0 for the calling group. The system should report how many messages will be delivered to this group. Select 1 to simulate placing calls to this group. Then check the CLI and make sure the phone numbers for each member of the group correctly appear in the CLI history. If everything went according to plan, you're ready to move on to TeleYapper, Part II.

    Coming Attractions: TeleYapper, Part II. In our next chapter (available here), we'll actually wire the pieces together so that you can make a phone call from anywhere and start up a TeleYapper calling session. We'll be using some more new Asterisk tricks to make all of this work. We obviously don't want to stay on the line while TeleYapper makes all the outbound phone calls so we'll be using Asterisk's hangup functionality to execute a PHP script which does the heavy lifting. We'll start by passing the group number variable and the count of callees to the PHP script. For all you code warriors, we'll document the steps necessary to get a PHP session initialized to talk with Asterisk. And we'll show you how to read in the variables passed from the Asterisk IVR session. Then we'll do some standard MySQL processing to look up the correct records to obtain the phone numbers to call. Then we'll build the scripts to actually place the phone calls and interact with someone or some answering machine at the other end of the line. And finally we'll introduce a clever trick to let you schedule and place all of the outbound calls in the background ... after your PHP session and initiating phone call have ended. What is it? Well, it's none other than Andy Wysocki's WakeUp Calls engine which is already built into Asterisk@Home. By sending a five-line script to the wakeup call directory, we can kick off a phone call to anyone at any time we specify. And then leave it to Asterisk to sequentially place the calls after we've headed out to lunch. Pretty neat!

    Want More Projects? For a complete catalog of all our previous Asterisk projects, click here. For the most recent articles including those you missed over the Christmas and New Year's holidays, click here and just scroll down the page.

    From Our Legal Department, moi: The TeleYapper product name (our feeble attempt at humor through parody) has absolutely no affiliation with TeleZapper, the terrific hardware product designed to keep telemarketers from bugging the hell out of you while you're eating your dinner. We confess that our sense of humor got the better of us in coming up with the name for this non-commerical (aka "free") utility designed primarily as an educational vehicle to assist the Asterisk community in recognizing the almost limitless potential of AGI and PHP programming. Our parody seeks to amuse, not to confuse. Our telephony software Yaps. Their telephony hardware Zaps. Other than a telephone line, there is no product similarity as the two conjoined words make clear. And, yes, that is the whole point! The products are opposites, not identical nor even similar. One letter makes all the difference in Night and Light. So it is with Yapper and Zapper. Brand confusion in trademark law arises from synonyms, not antonyms. It is systems like what we're writing about today that TeleZapper is designed to protect against. And it does that very well. In fact, we use TeleZapper hardware in our own home and have for many years. The only problem, of course, is when that tornado comes rolling down the neighbor's street, it would have been nice to get that automated phone call from TeleYapper at the neighborhood headquarters. But, who cares, right? It's only your house. Class dismissed.

    Who Is This Guy? Ward Mundy, the author of this Asterisk@Home series of articles, is a retired attorney who spent more than 30 years providing legal and technology assistance to the federal courts in the United States. Today he serves as a principal in Ward Mundy & Associates, a technology consulting firm in Atlanta, Georgia.