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

    Be Sociable, Share!

    This article has 36 comments

    1. It Works! AAH 2.5 thank you very much for all the hard work.

      [WM: You bet!]

    2. Works great. I did find one thing that may need to be adjusted. If you have changed your root mysql password you will need to change it in the checkgroup.php, teleyapper.php and teleyapper2.php files. Otherwise you get a database connection error. Thanks for all the great work.

    3. I have a problem with the system. It seems to dial the callees endlessly. I realized after the fact that I had set the maxretries to zero thinking that only one call would go out. Does this actually force a state of infinite retries?

      [WM: That would appear to be the case. Try 1.]

    4. This is really a slick system. Worked like a charm the first time out. I have a lot of experience with Dialogic hardware and software like Spitfire/Sundialer. Some of the things that I would like to see include:

      1) You already mentioned it: A way to easily import phone numbers and run reports. Import from CSV would be terrific.

      2) A "failsafe" configuration option that prevents calls from being broadcast between certain hours (say 7pm to 10am).

      3) A way to initiate two different broadcast messages at the same time (each using half of the available trunk lines).

      4) Better answering machine detection is extremely desirable.

      5) A way to schedule broadcasts in advance, or at least queue them up so that they run one by one. This means functionality would have to be built to tie a phone number group to a message.

      6) A way to "reset" a set of phone numbers so that they will be called again when a new message is broadcast. Essentially, you want to be sure a phone number is only called once for each broadcast message. Not sure how the current system handles that.

    5. I am having a weird issue. The teleyapper worked for awhile. However,now when I try to use it the system hangs up if the far end party is in ringing state (after about 4 rings) but has not picked up the call yet.
      I have done the following to debug.
      1)Looked at the Debug logs from asterisk they tell me that the call fails with reason 3(pbx_spool.c), [I dont know what this reason 3 is as there is no documentation describing the reason].
      2) Made calls to the same number from another phone hooked to the asterisk box, and let the far end ring without answering, it waits for the answering machine to pick up.
      Any ideas , suggestions would be highly welcome.

      Thanks

      [WM: Adjust the timeout. 4 rings would be about 20 seconds so you may need to increase it.]

    6. Above you stated " 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"

      Did you guys ever get a chance to do this? It would be a big help! thanks

      [WM: Not yet. My vacations keep getting in the way of my hobby, but we’ll get there one day soon… after the move.]

    7. I would like to modify teleyapper to confirm appointments at our office. The appointments are in our scheduler using a pervasive sql data base on a windows pc.
      Does it sound too crazy (hard/weird/not possible) for me to make a C# program on a windows pc that access tomorrows’ appointments in pervasive database, then inserts them to mysql on my asterisk box? I’ll just add some columns for date and time of appt and have allison read it to them.

      [WM: Sounds interesting, and it’s certainly possible. You can even open a MySQL connection remotely from your Windows machine. Just go find a good O’Reilly book about MySQL, and it’ll tell you everything you need to do. Can’t help much on the C#, but it sounds like you’ve got that covered.]

    8. For tips on inserting data into your TeleYapper MySQL database using C# with Microsoft Visual Studio, here’s a great link.

    9. First off, I’d like to say a big "Thank You!". Your program is wonderful. I’ve been making various changes to the dialplan to see if I can better detect an answering machine. After I start a call session, there is a minute delay before the calls go out. For debug/testing, can the calls go out right away?

    10. I found BackgroundDetect unreliable as well, Ward. I tried all kinds of settings and gave up.

      However, WaitForSilence(2000) seems to work very well for human voices and machines. As you know, WaitForSilence() falls down through the rest of the asterisk code instead of going to the talk extension automatically. So, you will need to add a goto after the waitforsilence command and maybe get rid of or decrease some wait() delays.

      Curiously, with WatiForSilence if you just answer the phone with a long montone yell, it falls through pretty early, but if you talk naturally for a long while (like normal people), it will wait for you to stop.

      For Mike,
      You’ll have to go into the php code itself to change this setting which I don’t recommend. Might get some unexpected timing issues; maybe you can do some email or ebaying while you wait for the first call.

      The line you are looking to modify is in teleyapper.php:

      date("Hi",mktime(date("H"),$thisminute+2,0,date("m",date("d"),…..

      where the +2 is where the first call is set 2 minutes in the future.

      As far as answering machines, there are some asterisk apps out there that specifically try detect answering machines – one called AMD, and another called MachineDetect. Not sure if AAH 2.5 has either of these installed by default, or if you will have to compile them into your system.

      Good luck!

      [WM: Great tip, David. I’ll work on it … soon.]

    11. We are trying to set up Teleyapper and are having problems getting the broadcast2 part to work properly. Basically, every call is considered to be an answering machine – no DTMF responses are acknowledged. We are using TrixBox version 1.0 with Asterisk 1.2.7.1. Our trunks are IAX2 (voipjet and voxee) and we have tried both "local" and "IAX2/voipjet" or "IAX2/voxee" for the $trunk setting in teleyapper.php.

      Can anyone stear us in the right direction?

      Thanks in advance, Oh, and thanks for a great service to the Asterisk community!!
      -nic

    12. Got TeleYapper to work with Trixbox 1.1.1, however call results are not written to the SQL database. Thought it might have beenm a permissions problem, but checked and rechecked, they look OK..Any Ideas???

      Bill

      [WM: It’s on my list to wrestle with shortly.]

    13. Finally took the plunge and have TrixBox 1.1 working and writing to SQL – it just worked!

      WaitFor Silence works very well for us. We poll mobile phones in the UK and they always goto a message – wrong number, voice mail etc. Using CallProgress as well, we seem to be pretty near 100% accurate in either leaving a message after the voice mail prompt or talking to the recipient after they answer.

      Fantastic product – redial seems to work as well.

      Thank you Ward

    14. Is it possible to initalize more than 1 call at a time?

      [WM: Not the way the current code is written. Sorry.]

    15. Is there a way to have multiple Teleyapper Voicmail Boxes. This way I could assign a Teleyapper Extension per coach and not have them share the same voicemail box?

    16. Hi WM,
      First I want to thank you for that remarkable effort and I managed to get teleyapper working on my Asterisk except for writting the status of the call to the file (LastOkcall , lastcallstatus) in Callees table. Is there any specifics to get it working? I checkd the teleyapper.php. I do not think there is code to do that step. Is it still under developement?
      Thanks in advance.

    17. can teleyapper work as a interactively
      that is if were working for a hospital. we call our patients and give his schedule,if he accepts it he has to press 1 or to reschedule he has to press 2 or to contact the operator press 3

    18. First off, THANK YOU for a wonderful program.

      Secondly, a few comments on my use. I have been using it successfully to queue up multiple calls at once. Here’s how I do it. I split my list up into 100 contacts each. Group each one from 0 to 9 as usual. Then I dial-in and queue each one up one right after the other, so that I usually have 3 or 4 going at once (300 or 400 contacts.) That way instead of 300 or 400 minutes to send out, it only takes about 100.

      I use VoicePulse Connect for outgoing. I get two trunks of 4 simultaneous channels. I’ve never went over 4, so I am not sure if it would roll over properly to the 2nd trunk or not? But from the billing detail, I have had as many as 4 channels active at the same time with Teleyapper. Very cool.

      Seems to work just fine. I inserted my number into the middle of my lists so that I get "test" calls throughout to check quality. They all come through loud and clear.

      Finally, a request. How hard would it be to have Teleyapper transfer the caller into an IVR instead of just playing a message? That would add so much capability, and I could REALLY use it. I don’t care if it is voicemail, answering machine or answered, I’d like them all sent to an IVR that I could setup. That would be so cool….

      [WM: Great suggestions, Sean. I’ll have a look at the IVR idea.]

    19. Can this extension be reached by external callers? If so how?

      [WM: Sure. Add the TeleYapper extension to your AutoAttendant and give out the password to those who need access.]

    20. When I dial internally it works fine. But if I setup in auto attendant no way to dial to extension "674″

      [WM: This is one of those issues that is best posted on the TrixBox forums together with the exact code from your autoattendant setup.]

    21. Hi,
      Great work. thanks for all your effort. I wanted to know if you have added the multiple simultaneous calls capability. That will help a lot, when a message has to be broadcast and the user can set the limit depending on the BW and the outbound trunks they have.

      Thanks
      MK

    22. I noticed you can select local to use default dial plan or pick an individual trunk sip/aix. I would like to choose an "outbound route" instead of an actuall trunk is that possible.

      [WM: Not as currently written. Sorry.]

    23. Also is there a way to automatically ad the prefix 1 so I don’t have to ad it to the database before you upload it to teleyapper?

    24. We would like to add a 4th option: “press 4 to speak to 1 of our representitives. Is It possible.

      Thanks in Advance.

    25. This is sweet! I’m using it successfully with a plain-jane 1.4.0 version of asterisk. I just needed to remove a couple of lines of deprecated code and it worked flawlessly. Took about an hour to get it working.

      thanks!

      [WM: Bill, send us the code changes. We’d love to publish them. Thanks.]

    26. Here are the changes:

      DigitTimeout and ResponseTimeout are deprecated in 1.4.0 so wherever DigitTimeout and ResponseTimeout are used, they need to be replaced with the SET() command.

      So we end up with:

      DigitTimeout(7)
      Becomes:
      Set(TIMEOUT(digit)=7)

      ResponseTimeout(10)
      Becomes:
      Set(TIMEOUT(response)=10)

      Thanks again for a great system.

      Bill

      [WM: An additional change needs to be made in checkgroup.php. See Comment #34 below.]

    27. Gee I guess im no expert at SQL. How exactly do you place in a phone number to test after being in the database? Thanks guys

      [WM: phpMyAdmin is an easy way, and it’s included in all the TrixBox builds.]

    28. Hi, Ward. Great work. Was there ever a web interface for adding numbers to the database? I would like to use this to call people that have an appointment on the next day to remind them. And my mom is NOT very technical and she’s the one that would setup the numbers to be dialed. Any ideas?

    29. Hey, great concept for so many purposes! I’m trying to get it running on Trixbox 2.2 but there’s no joy. I’m guessing that maybe the php modules need some tweeking? It gets to the part where it should tell me how many calls it’s going to make and then just hangs up. Doesn’t even produce a teleyapper.txt log file. I’m not a code-head at all.. any ideas on where to start?

      [WM: I’ve quit being a pioneer, but we do plan to use trixbox 2.2 when the appliance comes out. Give me a few weeks, and we should have more to report.]

    30. Also if you want to build a graphical interface in php for teleyapper, you got to change the group field in the database because it is a reserved word in php. I changed it grp.

    31. A modified version of this would combined with the wakeup call app would make a nice reminder system.

    32. It’s a great script and works well. I am going to test it with mock FXS ports of up to 10,000 to test it for time efficiency. One big problem that I have noticed is that there is no way to stop this script. How do you stop it in case you just don’t want to continue with the calls? I tried changing the tables name and now I get continuous errors on the page.

      [WM: Just delete all the files in the /var/spool/asterisk/outgoing folder.]

    33. Ward, I love the Yapper program and it fits perfectly with a new campaign my company is running. I have one question though. In the Yapper.php page where it does the actual writing of the .call files, how hard would it be to create a loop in the php? See we have 2 8port cards and want to use 12 of the 16 lines to broadcast. With the 60 second delay between calls, it only ever makes it to maybe line 2 of 12. If the code could write the the .call files for as many lines as you want, that would be incredible.

      Thanks again for a great, free product!

    34. I had to comment out lines 167-172 in checkgroup.php to get the script to function with Asterisk 1.4. The SET VARIABLE tmp $retcode line is empty each time.

    35. Where would you change the code to get it do multiple calls simultaneouly, as I want to be able to notify a large group of people pretty quickly?

    36. The trick now is to get people to actually listen to the entire message before they hang up …