Sunday, April 22, 2007

Blueprint for An Emergency SMS Messaging System

An hour or two after my last post, I talked with the members of my group about possibly implementing an alert system that would send out an SMS text message to faculty, staff, and students at the university, something that would help get the word out should a shooting occur at our university. That was Tuesday morning.

By Friday afternoon, I had finished two ColdFusion-powered portlets for our still-relatively new university portal: one that let members of the university enter their SMS information, and another that let select individuals send out an alert message using that information.

The code is unremarkable, but I wanted to share the ideas behind those portlets as inspiration or guidance for others.

We decided to design the system to use the SMS gateways provided by the cell phone service providers themselves: almost all of the major providers allow you to send an SMS to someone via an e-mail address comprised of the recipient's cell phone number and an e-mail domain specific to the cell phone provider (for example: 555555555@tmomail.net would be the e-mail address to send an SMS to a T-Mobile user with a cell phone number of 555-555-5555). My manager found a list of these gateways on a LiveJournal page, and I found a similar page at Wikipedia.

The sign-up portlet (if put into production) will appear in everyone's portal page. The portal takes care of authentication, so the portlet retrieves the unique portal ID of the user from the portal without requiring additional authentication. The portlet window contains some text explaining the service and how it will be used followed by a simple form: a select box containing the names of the different cell phone services that provide cell service in the area, and a text box for the user to provide their cell phone number or their cell service username.

The form is followed by three form buttons. The first button, the "Save" button, submits the form data to be saved to a database table. Basic JavaScript validation is used to make sure that the user has selected a cell service provider and has provided a phone number or username: if the user has JavaScript disabled, similar server-side validations will take place.

If the data is valid, it will be recorded in the user's database record. The record will contain the user's unique ID, the unique ID of the cell service provider (which matches up with a record in the table containing the service providers and their SMS gateway addresses), an encrypted copy of their cell phone number/username (so that data is protected if the database table itself is compromised), and the current date signifying the last time the information was updated. Once the information is recorded, the user will see a message at the top of the portlet indicating whether the data submission was successful or not.

The second button, the "Save and Test" button, triggers the same actions as the regular "Save" button but also executes code to send the user a test SMS message using the SMS information they provided. The message is sent using a tag directed to the e-mail address comprised of the phone number/username and the SMS gateway of the cell service provider. The message contains a unique test message ID number that corresponds to the primary key value of a test message log table. The records in that log table also contain the ID of the user who generated the test message, the IP address of the user's computer, the SMS gateway and an encrypted form of the number/username the message was sent to, and the date and time the test message was sent. This log can be used to determine if anyone is misusing the test mechanism to send spam SMS messages to other individuals. The user's own database record is also updated with the date they sent a test message so that we can determine if the user has tested (and therefore verified) their SMS information. Again, once the information has been saved and the test message has been sent, the user will receive a feedback message, and will be told that they should receive the test SMS shortly.

The third button is a "Removal" button so users can remove their SMS information if they no longer wish to use the service or if they are leaving the university. The button triggers code that removes the SMS gateway and phone/username data from the user's database record, but it does not remove any data the user generated in the test log (to ensure that anyone abusing the testing tool cannot cover their tracks). Again, the user will see a message indicating whether or not the action was successful.

Once users have submitted their SMS information, they will see that information populated in the form on subsequent visits to the portlet. If the "last updated" date in their database record is over 6 months old, they will see a message at the top of the portlet window indicating that they should review their information to make sure it is current and to click the "Save" button to indicate this (thereby resetting the "last updated" date).

The administrative portlet, like the sign-up portlet, retrieves the unique portal ID of the user from the portal without requiring any additional action from the user. However, it then compares that portal ID with the records in a database table that lists the authorized users of the administrative portlet. That table contains the records for two types of users: technical administrators who can only use the portlet to send test messages to users who have agreed to be testers of the service (such users have an additional data field populated in their user database record), and emergency administrators who are allowed to send an alert SMS to all users of the system in an emergency.

If the portal user is a technical or emergency administrator, the portlet redirects them to the appropriate starting page, while unauthorized users are prevented from proceeding (technically, unauthorized users would not have access to the portlet at all anyway). Technical administrators are presented with a single hyperlink that gives them the option to compose and send a test message to the test users. Emergency administrators have that hyperlink as well as the hyperlink to the form for sending a true alert message.

Even though the processes for sending a test message and sending an emergency message are very similar, separate submission forms are used as a security measure to ensure that only emergency administrators can send an emergency message. Each form also checks the user's credentials to make sure they are authorized to perform those particular actions.

The forms for composing a test message and composing an emergency message both consist of a textarea control and a submit button. The directions preceding the forms are slightly different: emergency administrators using the emergency message form are reminded that while they can send more than one message, a second or third message may be delayed by increased cell traffic generated in response to the first message, and to keep that in mind when composing the initial message. Technical administrators (and emergency administrators using the test message form) are reminded that their test message should clearly indicate that the message is a test message and not a real one.

Beneath the textarea control are two text blocks, one that indicates the number of characters in the textarea and one that counts down the number of characters used from a starting number of 110. The number of characters an SMS message can contains varies between cell service providers. Based on the information we had on the SMS gateways our users would use, we decided that 110 characters was the number of characters almost all users would be able to receive, and that 140 characters was the upper limit of characters we would allow.

As the user types, a JavaScript function fires every time a key is released that counts the number of characters currently in the textarea and then uses that information to update both counters. Any user with JavaScript enabled will know exactly how long their message is and whether it exceeded the safe 110 character limit. If the message exceeds 140 characters when they submit the form, a JavaScript alert box will inform them that they need to shorten the message. If JavaScript is disabled, server-side validation code will perform a similar task.

Each of the form pages is followed by a confirmation page, where the user is asked to confirm their decision to send the test message or emergency message. The user is shown the message they composed one more time. Any characters beyond the 110 safe character limit in the message are shown in red to indicate to the administrator what text might be truncated and therefore not received by some recipients. Following the message are two form buttons, a confirmation button and a cancellation button.

If the user clicks the cancellation button, they will be sent back back to the composition screen along with the text of the message (so the contents of the message are not lost if the user merely wants to make some changes to the content).

The confirmation button for sending a test message retrieves the SMS data for all of the users identified as test users, while the confirmation button for sending the emergency message retrieves that information for ALL users. The code then loops through those query results. During each loop iteration, the user's cell phone number/username is decrypted and the message is sent via to the address comprised of the decrypted number/username and the SMS gateway of the user's cell service provider. Once all of the messages have been sent, a new record is recorded in a database table that logs all messages sent by technical and emergency administrators: each record contains the administrator's ID number, the text of the message, the date and time the message was sent, and a value indicating whether the message was a test message (that only went to test users) or not. These log records ensure that anyone who sends out an unauthorized message can be identified.

Once the message has been processed, the administrative user will be returned to the appropriate composition form and will see a message indicating whether or not the message was successfully sent out. The user can then opt to send another message or return to the initial portlet screen.

...so there you have it.

A stand-alone application designed to perform similar tasks would have to include an authentication system, and might have to run a scheduled task to check the age of each user's SMS data and send them an e-mail if their data was old, but I think everything else could be designed to work in a similar manner to the system I just outlined.

Tuesday, April 17, 2007

Twitter as Alert System?

Yesterday's tragedy at Virginia Tech underlined the importance of sending out warnings regarding dangerous situations as quickly as possible and through as many channels as possible.

Listening to the news last night, it sounded like the VT administration used every channel of communication at their disposal: the campus website, mass e-mails, broadcast phone messages to all campus phones, and a siren system. The university I work at (the University of Maryland) also has all of those means of getting the word out.

The one communication channel that wasn't mentioned, however, was cell phones. That's not surprising: I suspect few universities specifically collect cell phone numbers from their students, and most students would probably be hesitant to give their cell number to the university out of privacy concerns.

But in light of yesterday's events, maybe universities should rethink that issue. Messages sent to land-line phones and e-mail addresses are only received if the recipient is at their phone or is actively checking e-mail. A message sent to a cell phone, which folks usually carry with them, has a much better chance of getting the recipient's attention immediately, even if they are walking between classes. While not every student owns a cell phone, those that did and received the message could spread the word to the people around them, getting the word out much faster.

So let's assume universities offered to send emergency messages (and only emergency messages) to students who provided a cell phone number to contact: how would the university broadcast an alert to those phones?

A long-term solution would be to put a SMS messaging system in place at the university designed specifically for this purpose (universities like mine that run ColdFusion 7, for example, could build an application using the SMS Gateway service provided by the ColdFusion server).

A short-term solution could be Twitter. Twitter is a social networking tool where you can receive short messages from friends via a web page, IM, or via SMS.

A university could set up a Twitter account to use to send out emergency messages, then instruct students to get a Twitter account (which is free) and "follow" the university Twitter account. The students can then control whether they receive updates from the university Twitter account via their phone or not.

Granted, this is not what Twitter was designed for, but I think it could serve as a stop-gap measure for getting warnings out until a more robust system is put in place.

Friday, March 16, 2007

Tired of the Open Source/Closed Source Conflict

Yesterday I ran across Ryan Stewart's blog post Open web advocates: Get off your high horse, where he took another blogger, Brendan Eich, to task about a post he wrote, The Open Web and Its Adversaries, defending standard web technologies against the perceived encroachment of proprietary technologies like Flex.

A number of folks took Ryan to task for daring to defend those proprietary technologies. I was so annoyed over the whole discussion that I had to take the time to express my thoughts. This is what I wrote:

This isn't Good vs. Evil, people.

I hate how most discussions comparing "open" source to "closed" source end up as a "right" verses "wrong" debate. Injecting a nonexistent dimension of morality into these arguments makes for a confrontational discussion rather than an analytical one, and it doesn't really benefit anyone. It seems like the main concern of many of my fellow posters is that there's a danger of Adobe or Microsoft dictating how web sites and web applications will be built because their web application technologies (Flash/Flex and WPF/E) are not open to change and modification by developers. I can see where such a concern would cause supporters of open source software to view Adobe and Microsoft as potential adversaries, but is that concern really valid? Could Adobe or Microsoft really take over the web if they wanted to?

How could they? Neither company has a monopoly on the core/base technologies that make the web possible: the network of wires and cables, networking hardware and software, TCP/IP, DNS, and web browsing software (granted, Microsoft is a strong player in the browser world, but I think it's clearly been demonstrated that they cannot dictate terms to the browser industry as a whole). Without that level of control, they cannot stop the use of traditional web technologies (HTML/CSS/JavaScript).

So what's really the concern here? That developers will abandon HTML/CSS/JavaScript for Flash and WPF, perceiving these technologies as the "next generation" of the web, in such numbers as to give Adobe and Microsoft a strong influence over web technologies in general? Well, yes, that could happen. That's the nature of a free market: people are free to choose the technology/methodology that they believe works best for them, and sometimes the end result is that one product or process ends up being the front runner. Does that mean its competitors are doomed to extinction? Heck no: it just means they need to innovate and offer something the front runner cannot.

One of the basic tenants of the open source movement is that open code allows a product or technology to benefit from the creativity of countless developers, leading to more and faster innovations. If that tenant is true in practice, then on a level playing field an open source product should be able to out-innovate and out-evolve a proprietary product, and therefore active competition between an open source product and a proprietary product works in favor of the open source product.

There's plenty of room on the web for all of these technologies. Developers should feel free to use whatever technology (at whatever cost) they deem is best suited to meeting the needs of their particular project. Limiting their options by strict adherence to an ideal or concept is a disservice to themselves and to their clients, paying or otherwise.

I do have one question for the open source community regarding their view of HTML/CSS/JavaScript: other than the fact that one organization makes money and the other (I assume) does not, what is the difference, in the eyes of an individual developer, between having conventions and standards for Flash controlled by Adobe, and having conventions and standards for HTML/CSS/JavaScript controlled by the W3C? Unless you are a high-level member of either organization, your ability to use their technologies is subject to their authoritative decisions, is it not?

Friday, January 5, 2007

Using Conditional CSS Selectors

The CSS I use in my applications is pretty straightforward. I stick with the basics, assigning styles based on element id, classes, and pseudo-classes.

When situations arise that require similar page elements to utilize differnet styles, I use ColdFusion or JavaScript code to evaluate the condition and assign the appropriate CSS class.

This article I found today is an excellent description about how to use CSS selectors to act only on page elements that meet a certain description--no JavaScript or server-side coding required:

Showing Hyperlink Cues with CSS

Since he makes a point of saying these selectors will work in IE 7, I can only assume that they won`t work (or at least not well) in IE 6, so you may not want to use these selectors unless you have a backup plan for mimicking the end-result using another method or you know your audience has upgraded to IE 7. Still, something worth knowing and a feature to look forward to as IE 6 rides off into the sunset.

Thursday, January 4, 2007

Catching Errors When Consuming RSS Feeds

Yesterday, Ben Forta blogged about an article by Ben Cortese on Consuming RSS Feeds with ColdFusion.

The article does a great job of providing simple, straightforward code for accessing an RSS feed and displaying it to the user. However, a few more lines of code would shield the user from errors caused by the feed not being available or by the malformed content within the feed.

As the article pointed out, you can retrieve the RSS feed from the remote site through the use of the tag, and then you can convert the XML in the feed to an XML object using the xmlParse function. If you enclose each of these steps within a block, you can intercept the errors and give your user a simple error message that explains there`s a problem with the feed.

For example, say you wanted to consume the main news feed from Digg.com (http://www.digg.com/rss/index.xml). Here`s how you would retrieve the feed and then convert it to an XML object with error-handling:

It`s a good idea to include this kind of error-handling whenever your application relies on external data in order to function properly so that the user knows that the problem lies with the source of the data rather than the application itself. And in the case of RSS feeds, the problem with the feed could be resolved within the next few minutes or so: the server providing the feed could come back up, or the problem entry in the feed could be removed (this is especially true of Web 2.0 user-driven sites where the feed content is updated frequently).

Friday, December 8, 2006

Using a Compound List to Simulate a Compound Boolean Statement

I was once asked to build an application that would use the demographic information submitted by would-be students to ensure that they were eligible to participate in certain social and cultural discussion sections. Each discussion section would have a number of enrollment rules that would not only determine which students were eligible, but would also set a limit on how many students could enroll for that discussion under that rule. For example, one of these enrollment rules would say "allow 5 students who are freshman or sophomores and were born in the U.S. and are atheists or agnostics and who grew up in a rural or suburban area to enroll in this discussion."

I knew I had to find a way to handle these complex evaluations in a flexible manner without resorting to multiple layers of if/else statements. Fortunately, I figured out a way to use compound lists to evaluate a student`s eligibility.

For any non-ColdFusion programmers who might be listening, ColdFusion has a number of functions for processing lists, lists being strings that can be divided into separate pieces by a delimiter character, usually a comma. For example, the function ListGetAt("red,blue,green,yellow",2,",") would return the value "blue" (the second item in the string where each item is separated/delimited by a comma). Other functions in ColdFusion can make use of lists, such as the tag, which can loop through each item in a list one at a time.

Because it`s possible to designate any characters (or even a string of characters) as the delimiter in a list function, the same string can be evaluated as different lists, and I used this fact to create my evaluation routine. I wrote code that translated the enrollment rules into lists where an AND operator was represented by a pipe (|) character and the OR conditions were separated by commas. So the enrollment rule I used earlier was translated into:

freshman,sophomore|USborn|atheist,agnostic|rural,suburban

I then wrote code to write all of the demographic data that was entered by the student into a simple comma-delimited list.

To determine if a student was eligible to enroll in a discussion, the evaluation code would count the number of AND operators in the enrollment rule (in this example, 4). The code would then run an outer loop that would loop through all of the AND operators one at a time. Inside this outer loop would be a second loop that would loop through all of the OR conditions one at a time. If the ListFind function determined that any of the OR conditions in the enrollment rule were present in the demographic list, a counter variable would be incremented. If, at the end of both loops, the counter variable value matched the number of AND operators in the enrollment rule, that meant that the student was eligible. Here is the code:

For more information on ColdFusion functions regarding lists, check out the List functions at cfQuickDocs, an AJAX-powered ColdFusion documentation site.

Wednesday, November 29, 2006

Web Developers and User Interfaces

Web application developers (the folks who program the functionality of the web application) are lousy user interface developers. That`s an assertion one hears a lot in the web designer and developer community, and was repeated again today in to an article entitled "This Is What Happens When You Let Developers Create UI."

But in application development, as in life, there are no absolutes. I`m sure there are many web developers like me who have to handle every aspect of the development process, including the design of the UI.

I've learned that the best way to avoid designing a programmer-friendly UI instead of a user-friendly UI is to work with your client to come up with the user interface first, and let the user interface dictate the functionality of your application instead of having the functionality drive the design of the interface. This is one of the ideas behind the Fusebox Lifecycle Process (FLiP), a development methodology where the user interface is finalized and the application structure is completely planned out and architected before any programming is done. Although originally designed for use with the Fusebox application framework, FLiP can be applied to any software development process, and going through the process of hashing out the user interface with your client before coding any of the application logic goes a long way towards removing any surprises or last-minute course changes at the end of the development process.

And there is one advantage to being both the programmer and the interface designer: I can make sure that the interface doesn`t require any functionality that is beyond my ability to program. :)