Telephone Reminders 4.0 for Asterisk 1.4

Now Supporting Recurring Reminders and Web Scheduling

Nerd Vittles' Telephone Reminder System lets you schedule reminders for future events by telephone or with a web browser. When the appointed date and time arrives, Asterisk swings into action and places a call to the number you designate to deliver a customized reminder message. Recurring reminders also are supported. And version 4 adds a text-to-speech web interface to schedule and deliver reminders using either Flite or Cepstral-generated messages. So you can set up reminders that place calls daily or on weekdays as well as weekly, monthly, and annually. This means it can be used to wake you up in the morning, or to remind Granny to take her medicine every day, or to remind your Little League team of practice times and locations, or to remind you and your customers of scheduled and recurring events.

Prerequisites

To get Telephone Reminders for Asterisk 1.4 working, we recommend a PBX in a Flash system with Cepstral. Any other Asterisk 1.4 system with a web server, PHP, and Perl should also work. To use Web Scheduling, you also will need at least one of the following text-to-speech applications: Flite and/or Cepstral. For best results, use Cepstral. Our detailed tutorial is available here. The Cepstral installation tutorial also been reworked elsewhere for trixbox. Instead of a dedicated Asterisk server, you also can use the VMware version of PBX in a Flash if you just want to experiment a bit. It runs in a window on your Windows Vista/XP/2000 or Mac desktop.

How It Works

The Telephone Reminder System is simple to use. Dial extension 1-2-3 on your Asterisk system and enter your password. You'll be prompted to record a reminder message. Next you enter the phone number, date, and time for delivery of the reminder message. Finally, you're prompted whether to schedule a single reminder or recurring reminders (weekdays, daily, weekly, monthly, or annually). When the appointed date and time arrives, Asterisk will place the call to the number you specified using your default dialing rules and will play the customized reminder when the call is answered. If the call is not answered, the call will be repeated the number of times you specify with a user-adjustable delay between calls. You'll get an email with the call reminder setup if desired.

Version 4 also adds Web Scheduling. Using any web browser, you access a web page stored on your PBX in a Flash server and simply fill out the form with the message to deliver and the phone number, date, and time of the reminder. Recurring reminders also are supported. Functionally, it works just like the telephone interface except that the Flite or Cepstral text-to-speech engine is used to generate the reminder message from the message text you enter on the web form. There's also a convenient web page that lets you review previously scheduled reminders on your system.

Installing Telephone Reminders for Asterisk 1.4

[zip] Telephone Reminders for Asterisk 1.4 Install Script (2KB)

Installation takes about 15 seconds. Log into your PBX in a Flash server as root and execute the following commands:

mkdir /root/reminders
cd /root/reminders
wget http://bestof.nerdvittles.com/applications/reminders4/reminders.pbx
chmod +x reminders.pbx
./reminders.pbx

Assuming you have Cepstral functioning on a trixbox ce system, the install script reportedly works fine although we have not tested it. If you're not using PBX in a Flash or trixbox, review the Telephone Reminders 3.0 tutorial and the latest Nerd Vittles article for more installation specifics.

Dialplan Setup

Most of the heavy-lifting for the Telephone Reminder System is handled by scripts in the Asterisk dialplan. With PBX in a Flash systems, these additions are made to the extensions_custom.conf file in /etc/asterisk. The only modification of the installed code that we recommend is changing the password for the telephony interface. Using nano, edit /etc/asterisk/extensions_custom.conf and search for 123. Or, from within FreePBX, click on the Tools tab, click Config Edit, and then click extensions_custom.conf. Replace the password 12345678 in line 3 of the 123 dialplan code with numbers that are known only by you and those you trust and save your changes.

exten => 123,1,Answer
exten => 123,2,Wait(1)
exten => 123,3,Authenticate(12345678)
exten => 123,4,Goto(reminder,s,1)

FreePBX Setup

While still connected to your PBX in a Flash server with FreePBX in your browser, click on the Setup tab and then Misc Destinations. Add a new entry for Telephone Reminders with 123 as the Dial entry.

 Add Misc Destination
description:
dial:   

Save your entry and reload your Asterisk dialplan when prompted to do so.

A FreePBX Module supporting the Web Interface to Telephone Reminders also is available. To use it, click on the Tools tab and then Module Admin. Scroll to the bottom of the list and click on Reminders. Choose the Install option and then click the Process button. Once the install completes, reload the Asterisk dialplan when prompted to do so. Once installed, the Web Scheduling Module for Telephone Reminders is available by clicking the Tools tab and then Reminders in the Third Party Addon listing in the left column of the web page.

Crontab Setup

The Telephone Reminders System uses cron jobs to actually move reminders and recurring reminders into the Asterisk call processing directory on the day they are scheduled to run. No configuration is necessary! We're simply alerting you that two additions have been made to /etc/crontab.

0 0 * * * root /var/lib/asterisk/agi-bin/run_recurring >/dev/null 2>&1
3 0 * * * root /var/lib/asterisk/agi-bin/run_reminders >/dev/null 2>&1

Configuring the Telephony Interface

The telephony and web interfaces to the Telephone Reminder System must be configured separately. To configure the telephony interface, edit the reminder.php script while logged in as root:

nano -w /var/lib/asterisk/agi-bin/reminder.php

You'll notice a section of variables at the top of the file that looks like this:

 $endofmonthflag=1 ;
 $extensionmaxdigits=4 ;
 $debug = 1;
 $newlogeachdebug = 1;
 $emaildebuglog = 0;
 $email = "yourname@yourdomain" ;
 $trunk = "local" ;
 $callerid = "6781234567" ;
 $numcallattempts=6 ;
 $calldelaybetweenruns=300 ;
 $timetoring=40 ;
 $acctcode= "Reminder" ;

This is the only section of code you ought to change. Be very careful when editing this file. Don't remove any semicolons or quotation marks, or nothing will work! Here's a quick run-down on what each of the above variables does:

  • $endofmonthflag=1 ... Forces monthly recurring reminders scheduled on the last day of a month to the last day of every succeeding month
  • $extensionmaxdigits=4 ... Sets the maximum number of digits for treating outbound calls as calls to local extensions.
  • $debug = 1 ... If set to 1, then a debug log is created in /var/log/asterisk/reminder.txt. Instructions for deleting reminders are in the log.
  • $newlogeachdebug = 1 ... If set to 1, then a new debug log is created each time a reminder is scheduled. Otherwise, file grows and grows.
  • $emaildebuglog = 0 ... If set to 1, the debug log is emailed to the email address set below when each reminder is scheduled.
  • $email = "yourname@yourdomain" ... Enter your actual email address between the quotation marks. Only works if line above is set to 1.
  • $trunk = "local" ... If set to "local", calls are routed using your default dialplan rules. Otherwise, specify a trunk to use, e.g. "sip/telasip-gw".
  • $callerid = "6781234567" ... Specify your caller ID number. Only used if $trunk is not set to "local" above.
  • $numcallattempts=6 ... If there is no answer on the Reminder call, how many times should Asterisk attempt to deliver the reminder?
  • $calldelaybetweenruns=300 ... How many seconds delay should there be between failed call attempts to deliver a reminder?
  • $timetoring=40 ... How many seconds should the call ring when attempting to deliver a reminder?
  • $acctcode= "Reminder" ... What accouting code should be used for reminder calls?

Configuring the Web Interface

To configure the web interface to the Telephone Reminder System, edit the following index.php file while logged in as root:

nano -w /var/www/html/reminders/index.php

You'll notice a section of variables at the top of the file that looks amazingly similar to the variables for the telephony interace. There is one addition: $ttspick. It lets you choose the text-to-speech engine for Web Scheduling. Set it to 1 for Cepstral or 0 for Flite.

 $endofmonthflag=1 ;
 $extensionmaxdigits=4 ;
 $debug = 1;
 $newlogeachdebug = 1;
 $emaildebuglog = 0;
 $email = "yourname@yourdomain" ;
 $trunk = "local" ;
 $callerid = "6781234567" ;
 $numcallattempts=6 ;
 $calldelaybetweenruns=300 ;
 $timetoring=40 ;
 $acctcode= "Reminder" ;
 $ttspick = 1 ;

Scheduling a Reminder By Phone

We are ready to take the Reminder System for a trial run. Make sure you have reloaded your Asterisk system (amportal restart), and then dial 123 from an extension on your system. Enter the password you set up for your reminder system and then press the pound key.

Entering a Reminder Message. You'll first be prompted to record a reminder message. This is the message that will be played when someone answers the reminder call. If you're not scheduling this reminder for yourself, then the message ought to explain who's calling and what the purpose of the call is. Once you've recorded your message, press the pound key (#) to end the recording. You can replay or rerecord the reminder if desired while you're in this step of the reminder creation process.

Entering the Callback Number. When prompted for the reminder callback number, there are a couple of things to keep in mind. First, if you've specified "local" as the trunk to use for reminders in the reminder.php script, then the phone numbers can be entered in any format supported by your dialplan. Press the pound key after entering the appropriate number. The calls will be placed using the trunks specified in your dialplan rules. The one exception is extensions on your local Asterisk system since these can't be routed by your PBX in a Flash system using outbound call dialplan rules. The way we determine whether a phone number is an outside call or to an extension is by examining the length of the phone number. At the top of reminder.php and index.php , you can specify the maximum number of digits for local extensions by setting $extensionmaxdigits. So long as the callback number is less than or equal to this number of digits, the system has the smarts to correctly route the call to a local extension.

If you have designated a particular trunk for placement of reminder calls, then you'll need to make certain that the format of the phone numbers entered for reminders on your system matches a dial string supported for this outbound trunk in your dialplan. For example, if this trunk requires that calls be entered with a 1 and then an area code and 7-digit number, then that is the only format that should be used for entering callback numbers in your reminders. Again, the one exception is calls to local extensions. So long as the number of a local extension is entered with less than or equal the number of digits set for the $extensionmaxdigits variable in reminder.php and index.php, the call will be routed properly to the local extension regardless of the trunk setting.

Finally, here's a shortcut that can be used if the phone you're using to schedule the reminder is the same one on which you want to get the reminder callback. In this case, just press the pound key when prompted for the number to which to deliver the reminder message. This will set the callback number as the caller ID of the phone you used to schedule the call. If it's a local extension, then the caller ID will be set to the local extension number of the phone from which you placed the reminder scheduling call. Just be sure your $extensionmaxdigits is set correctly or calls to local extensions will fail.

Entering the Date of the Reminder. Once you accept the reminder message, you'll be prompted to enter the date on which this reminder will be delivered. Dates are entered using a four-digit year, then a two-digit month, and then a two-digit day using the time zone of the Asterisk system running the Telephone Reminders System. There is some error correction but not much. You obviously can't schedule reminders in the past! And you don't need to press the pound key after entering the eight digits. You also can press the pound key (#) instead of entering an 8-digit date, and the system will set the reminder date to today. Once you've entered a date, the system will tell you what date you entered including the day of the week. If the entry is correct, just press 1 to move on.

Entering the Time of the Reminder. Now you'll be prompted to enter the delivery time for your reminder. Times are entered as a two-digit hour and two-digit minute using the time zone of the Asterisk system running the Telephone Reminders System. For times less than 1200, you will be prompted whether you meant AM or PM. For those that understand military time, you can avoid this step by entering times using the format: 1345 which means 1:45 p.m. You don't need to press the pound key after entering the four-digit time for delivery of your reminder. Keep in mind that you cannot schedule a reminder for delivery in the first five minutes after midnight or within 5 minutes of the current time. Other times "in the midnight hour" should be entered in the format: 0045 which means 12:45 a.m. Remember, reminder times always must be at least 5 minutes in the future. Finally, you cannot schedule two reminders for the exact same date and time for delivery to the same phone number. Once you enter a delivery time, the system will play back both the date and time for the reminder as a precaution. Press 1 to accept your entries.

Entering Recurring Reminders. Finally you now will be prompted whether to schedule (1) a single reminder, (2) a recurring reminder every weekday (M-F), (3) a recurring reminder every day, (4) a recurring reminder every week, (5) a recurring reminder every month, or (6) a recurring reminder every year. Once you make a selection, your reminder will be scheduled. If you choose an option other than 1 through 6, a single reminder will be scheduled.

Scheduling a Reminder Using Web and FreePBX Modules

The web module can be accessed in two ways. The Web Interface to Telephone Reminders is housed in the /reminders directory just below the root page of your PBX in a Flash web site: http://ipaddress/reminders/. It also is available through the FreePBX web interface. The Web Scheduling Module for Telephone Reminders is available by clicking the Tools tab and then Reminders in the Third Party Addon listing in the left column of the FreePBX main web page.

To schedule a reminder using the Web Scheduling Module is virtually identical to the phone methodology above with one exception. Instead of recording your reminder message using a telephone, you type the desired reminder in the Message field and let your chosen text-to-speech engine generate the sound file before the reminder is delivered. There is little error correction in the web module. Reminders scheduled in the past will be delivered instantaneously. Sometimes this may be the desired effect. Usually not. One tip we would offer in generating clear speech from text messages is this. For a longer pause between sentences, use a colon (:) instead of a period.

Web Interface to Scheduled and Orphaned Telephone Reminders

We've built a very simple web page that will let you review which reminders are pending on your system. You can access the web page directly at http://192.168.0.111/reminders/ using the IP address of your Asterisk system. Once the page displays, simply click on the Review Existing Reminders button.

Telephone Reminders 101

There are actually two files that make up each reminder: the .call file which places the actual call and the .gsm file which is the reminder message itself. The file naming convention is HourMinute.Date.PhoneNumber with either a .call or .gsm extension. The sound files are all stored in /var/lib/asterisk/sounds/custom. For recurring reminders, duplicates of the .call script and the .gsm message are stored in /var/spool/asterisk/recurring with the date of the next recurring reminder. At midnight on the next scheduled date, the two files are copied to the /var/spool/asterisk/reminders and /var/lib/asterisk/sounds/custom folders respectively. Then the next scheduled reminder date is set in the two filenames. For single reminders, prior to the delivery date of the reminder message, the .call file is stored in /var/spool/asterisk/reminders. Then, at 12:03 am on the date the reminder is scheduled for delivery, the run_reminders script in /var/lib/asterisk/agi-bin moves the affected .call files to /var/spool/asterisk/outgoing. The .call files in the outgoing directory are reviewed every minute of the day by Asterisk. By examining the time stamp of the file, Asterisk looks for a match with the current hour and minute of the day. Once the time for the call arrives, Asterisk processes the .call script and places the call. All dialing retries are handled internally by Asterisk with no user or program control so it's important to set your default values correctly in the reminder.php script as explained above. Once the .call file is processed, Asterisk discards the file whether the call was successful or not. As noted above, the reminder message file is only discarded if the call is completed successfully. So, from time to time, you do need to review the contents of /var/lib/asterisk/sounds/custom and discard reminder messages, if any, with dates in the past. Note also that, if you begin scheduling a reminder and change your mind and hang up after recording a reminder message, that recorded message will still exist in /var/lib/asterisk/sounds/custom.

Here's a word of caution about the reminder message files: be very careful in deleting these files. The message files and .call files are linked by filename only, and there is no error detection or correction if the message file gets discarded before the time for the reminder call arrives. What would happen in such a situation is the call would be placed, someone would answer, Allison would say "please hold for an important reminder," and then there would be a brief silence followed by Allison saying "to repeat this reminder, press 1; otherwise, press 2" which is not entirely helpful. To delete a recurring reminder, delete both the .call and .gsm files from /var/spool/asterisk/recurring. Note that the .call file will have an additional extension which tells the recurring type, e.g. .daily, .weekly, etc.

After scheduling your first reminder, be sure to check for the pending reminder by clicking Review Existing Reminders in the Web Interface. You should see both a .call file and a .gsm with otherwise matching file names. If the .gsm file is missing, one of two things has happened. If you haven't installed Cepstral and you haven't changed the default TTS engine, then solve it by doing one or the other. If Cepstral is working on your system (swift "Hello world." at command prompt), then you may be missing the sox application. To install it, log into your system as root and type: yum install sox. Then schedule another reminder to be sure things are working properly.

E-Mail Delivery of Telephone Reminders

Assuming you have email messaging working on your PBX in a Flash system, Telephone Reminders has the ability to deliver an email copy of reminders to the recipient in addition to a phone call. Be advised that, if the phone call is never completed, the email copy of the reminder will not be delivered. The reason for this is because Asterisk never passes the call to the context which handles delivery of the email message until the call is connected. So ... no connection, no email. However, if the recipient has an answering machine or voice mail, that would trigger delivery of the email message.

The contexts to support email messaging are automatically installed. Step two is registering email addresses for extensions and phone numbers to which you want email reminders delivered. Log in to your Asterisk server as root, and start up the Command Line Interface (CLI): asterisk -r. For each extension and phone number for which you want to activate email reminders, enter a command at the CLI prompt that looks like this:

database put EMAIL 6781234567 joe@schmo.com

6781234567 is the phone number of the reminder recipient and joe@schmo.com is the recipient's email address. You can display all existing EMAIL addresses that have been entered into your Asterisk database with this command:

database show EMAIL

If you need to modify an existing entry, simply delete it and reenter it. To delete an existing entry, use the following syntax:

database del EMAIL 6781234567

If you'd prefer to enter any of the above commands from the Linux command prompt rather than from the Asterisk CLI, here is the correct syntax:

asterisk -rx "database put EMAIL 6781234567 joe@schmo.com"

asterisk -rx "database show EMAIL"

asterisk -rx "database del EMAIL 6781234567"

Securing Telephone Reminders

In many multi-user installations, you may find it desirable to password-protect the Telephone Reminders web interface. With PBX in a Flash systems, it's easy. Log into your server as root and edit pbx.conf in the /etc/pbx/httpdconf directory. Add an entry that looks something like the following. Simply list the user account names that can gain access after entering a correct password. Everyone else will be excluded.

#Password protect /var/www/html/reminders
<Directory /var/www/html/reminders>
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /usr/local/apache/passwd/wwwpasswd
Require user wwwadmin maint
</Directory>
After inserting the new entry, save the file and then restart the Apache web server: apachectl restart. For other security options, take a look at the PBX in a Flash Forum.

Programmer's Corner

For those just getting into PHP and AGI programming with Asterisk, take a careful look at reminder.php. In particular, take a look at the section of code that begins with parse agi headers into array. As best we can tell, our initial tutorial on Telephone Reminders was the first version of this subroutine written in PHP that actually worked. If you review the log file (/var/log/asterisk/reminder.txt), you will see a listing of all the AGI headers which are passed by Asterisk to PHP. But this is the first code we've seen that correctly reads the headers into variables where you can actually retrieve the content. We call it a feature. For example, the commented out line ($tmp = $agi['dnid']) shows the syntax to retrieve the DNID value from Asterisk. Just make a mental note that the parse AGI headers code in reminder.php actually works. Here's the complete list of AGI headers that can be saved to variables in your PHP code should the need ever arise:

read: agi_request: reminder.php
read: agi_channel: SIP/204-6a1a
read: agi_language: en
read: agi_type: SIP
read: agi_uniqueid: 1138010325.1367
read: agi_callerid: "Line2" <204>
read: agi_dnid: 123
read: agi_rdnis: unknown
read: agi_context: reminder9
read: agi_extension: h
read: agi_priority: 2
read: agi_enhanced: 0.0
read: agi_accountcode: 

You'll also want to take note of a little quirk in Asterisk (compared to some PBXs). To decipher the extension which actually placed a call, you must parse the agi_channel variable for the data between the slash and hyphen characters since the DNID (dialed number identifier) returns the extension being called (as opposed to the originating extension) when an internal call is placed. Here's one PHP approach to get the answer which in this case happens to be extension 204. Regex wizards could probably save a line of code, but who cares.

$CallingID = substr(stristr($agi['channel'],"/"),1);
$CallingID = substr($CallingID,0,strrpos($CallingID,"-"));
Finally, a user on the PBX in a Flash Forum, has documented the process of automating posts to the Web Interface of Telephone Reminders from your favorite calendaring software. Have a look here.

Nerd Vittles Original Article (2/25/2008): Introducing Telephone Reminders for Asterisk 1.4