Voxeo, Tropo, & ORUG

I went out to ORUG tonight. Voxeo was presenting a thing they’re working on, Tropo. Disclosure: they bought us dinner. Full disclosure: I think this thing is really tight.

I used to help set up phone systems in high school, and phone trees have always seemed like kind of a mystery. Tropo lets you build whole phone apps, and it’s ridiculously easy. It’s basically a phone system DSL. They handle text-to-speech, speech-to-text, playing recorded sound files; there’s lots of convenience things for capturing different types of inputs, handling error cases, recording calls, transferring calls, etc. They give local phone numbers in different area codes, they’ve also got Skype integration, and a few other ways to connect to the system. The very cool part is that it’s all free to play around with, but once you start using it for commercial reasons, then you have to pay.

Ever hear of Google’s Grand Central? With this, you could easily make your own. I’ve been playing around with a few things using Tropo’s Ruby setup, and I’ve put the demo code on GitHub. Very cool stuff.

You can write apps in Ruby, PHP, Python, Javascript, and Groovy (“Java++”). There’s a bunch of example code on their site, and development is really easy to do. For example:

answer

digits = $currentCall.callerID.to_s.split('')

area_code = digits[0..2]
city_code = digits[3..5]
subscriber_number = digits[6..9]

# single dashes get spoken as 'dash', use doubles for a pause.
# Double commas don't work, neither do extra spaces
say "-- -- -- S-up. Your phone number is -- #{area_code.join(',')}--#{city_code.join(',')}--#{subscriber_number.join(',')}"

hangup

There is a debugger that you can print messages to. Right now there’s a *ton* of output to it, but you’ll find your messages in there.

One thing: I was getting a message that the caller was “not accepting calls at this time”. I realized this was a parse/compile error in my script. So, if you can’t get something to load, check it. The debugger doesn’t seem really helpful with this, I got a generic seeming Java Exception for a variable name typo. They use Java under the hood for tons of stuff, so even though I’m writing Ruby code, it gets interpreted in Java.

I did learn a cool fact about these phone trees. You know how a lot of phone trees suck when you try and talk to them? Well, for speech-to-text conversion, you can only get around an 80% success rate. The reason is that phones are only around 64kbps of data. There’s too much loss for the algorithms to work well. That’s why apps that run on the local computer/phone are able to do better — they embed part of the recognition algorithm in the client.

And, on a final note: skateboarding through downtown is awesome.

The HTML structure of webmail interfaces: Gmail, Hotmail, and Yahoo Mail

As part of the Zentact project I’ve been working on, we were asked to integrate with various webmail clients. This makes it easy to manage your contacts while sending email.

Doing this was a bit of a pain. Since all code is minified, and they all use Javascript events differently, there was a good bit of working to figure out the details. I wanted to share this info in a blog post for programmers who come along in the future. If you don’t know/care about HTML, Javascript events, the DOM, YUI, or AJAX, this post is not for you. Please enjoy one of my other fine posts, perhaps this post on military code names.

Before I begin: there was a ton of info learned (and already forgotten) about this process. This is not a complete guide, but is mostly a brain dump from implementing UI integration on three different webmail interfaces.

  • Gmail uses 6-character strings, [A-Za-z0-9] for all its classes. These classes remain the same from load-to-load, but I believe that they may change over time with minification. IDs are not as constant, and many are dynamically assigned. These start with a colon.
  • When you’re working with events, you may get inconsistent results. Some events are not fully propagated, they get captured and you can’t find out about them. If onclick doesn’t work, try listening for onmousedown or onmouseup. One of them may get you notified of the event you want. Same advice goes for onkeydown, onkeyup, and onkeypress. That being said, once you get into these, be sure to realize that these three events will occur in particular orders. Make sure you’ll be getting notified at the right time.
  • All of the webmail UIs use iframes. This lets them keep their code for loading the UI separate from the code to display the UI. I know there’s some cross-site scripting implications in this, but I’m not sure of all the details. Gmail’s loading screen (the loading bar they show you) is a different iframe than the one that shows you the inbox. All of these iframes are at the root of the document, and there’s nothing else in there.
  • You could use Firebug break points to pause the code and examine what’s going on, but nearly all JS is minified. Since breakpoints can only be set by line, and there’s multiple functions defined per line, it ends up not being helpful.
  • For its UI, Yahoo seems to use YUI, plus some other stuff on top of that. There’s some weird results because of this. The body of the email editor is a group of DIVs, some are invisible, some are for border decoration, and others are for the background of the editor.
  • When we inserted elements into Yahoo Mail using regular DOM operations, they would appear behind other page elements, until another part of the UI was interacted with, when the screen would redraw and then they would bump into place. YUI seems to have its own redraw/repaint functionality, and it won’t play nice with DOM manipulations.
  • Hotmail is strangely one of the less-exotic interfaces. They use consistent IDs. I don’t think they’re hand-coded, however, because they submit to a naming scheme that seems too machine-generated. But still, they are there, and you should take advantage of them.
  • When you’re using events, and you get notified of an event, use the event.originalTarget property to find out where in the DOM you are. That’s useful information when you’re dealing with a DOM tree of nonsense class names and IDs.
  • When you’re trying to figure out where in a DOM tree you are, don’t hesitate to go up several levels and check a great grandparent node, or a “cousin” node. Once you get a single point of reference, you can generally work out where everything else is, relative to it.
  • Some UIs open each message in its own iframe, which means that IDs are consistent since they’re in their own namespace.

Also, thanks to Nate Koechley for helping me get through some of the Yahoo details.

If you’ve got other questions, shoot me an email. I remember more stuff, but might need a good question to shake it loose.

A Javascript debugging tip for Firebug (or “Stop using alert()!”)

Did you know that if you’ve got Firebug for Firefox installed, you can use it for debugging your own code? By calling

console.log("Here's a message!");

Firebug will print the message to it’s internal message log. Neat!

Firebug message console

Now, that’s all good. But let’s say you’re on a project that’s not using a Javascript preprocessor to minify and strip debugging code — which would be the best option. You want the benefits of debugging, but not having to constantly remove debugging code for deployment. If a user doesn’t have Firebug installed, they won’t have a console object. So obviously leaving your debug code in is going to cause an error.

Or will it?

Try adding this code before any of your other Javascript. It will set up a fake console so that if Firebug is not installed, there won’t be any errors.

if(!console || !console.log) {
var console = new Array();
console.log = function () {}
}

Bonus idea! If you combine the idea shown here, with my previous post about debugging Firefox extensions, you can see how to prevent extension debugging from getting in the way of your users.

if(!Firebug || !Firebug.Console || !Firebug.Console.log) {
var Firebug = new Array();
Firebug.Console = new Array();
Firebug.Console.log = function () {}
}

How to use Extension Developer’s Extension in Firefox 3

Here’s a tip for developing Firefox Extensions in FF3.

You might have heard of the Extension Developer’s Extension (EDE). EDE is an extension that provides useful settings and features for people who are writing their own extensions. For example, EDE makes it easy to activate Javascript debug settings, interactively debug Javascript, and a few other goodies.

My personal favorite feature is the “Extension Builder” — it that lets you install a development copy of the extension . That is, you can run an extension from your working copy/dev folder. Without EDE, you’d have to — uninstall an extension, restart Firefox, install, restart — every time you wanted to test a change. With it, you can just restart Firefox one time, and your dev extension is reloaded. When doing heavy development, I have personally saved over an hour per day from this one feature.

The sad part is that this feature does not work in FF3. The option is just grayed out. But, there’s a workaround. Load up FF2 with the same profile that you use for FF3. Use EDE to install the extension from disk like you normally would. Then, quit FF2, and launch FF3. Since the extension is tied to your profile, FF3 will load your extension from your dev folder, just like in FF2.

Win!

Twitter Autocomplete (Tw-autocomplete Firefox Extension)

After lots of code, tests, and fun, I’ve produced a Firefox extension to add a useful, new feature to Twitter, as opposed to writing Twitter extensions as a joke 😀

Simply put, the extension provides autocomplete for Twitter usernames from your own list of friends while you’re using the web interface at twitter.com. It’s totally secure — no separate login required. Just install it, and use Twitter naturally.

When you start typing messages to people — using “@user” or “d user” — a list of matching contacts (along with icons) will drop in. You can click the person’s name to fill their username into the text box, or use the arrow keys along with tab/enter to select. As an added bonus, if you can’t remember their username at all, just type their first name, and the extension will figure it out.

There is another autocomplete script for Twitter, but it requires installing extra libraries, and I think this is simpler. Clearly it’s a feature in-demand.

The extension is hosted at addons.mozilla.org, a highly reputable site. They also provide lots of great management features that are handy to developers. I hope you enjoy using Tw-autocomplete.

Javascript Events, the DOM, and Firefox/Gecko

OK, here’s the deal, as quick as I can put it, but with enough words that Google will correctly index this post and make this information easier to find for the next person who needs it.

Let’s say you’re developing a Firefox extension, and you need to look at the HTML of the page. You know that Firefox is constantly throwing event notifications — there’s the MouseEvent “click” when something is clicked, the KeyboardEvent “keyup” when a key is release, and so on.

So, you figure “well, I need the HTML of the page, so I’ll wait until it loads, then grab the source/parse the DOM tree/unleash flying monkeys”. You know that the style of

window.onload = the_function_name;

is bad, because it only lets one function receive the load event. So, you write some code like

gBrowser.addEventListener(“load”, the_function_name, true);

because this is what you want. You wait for the “load” event to fire, and then run your function. Test this code out, and it will work well-enough, most of the time. Sometimes, it lags, sometimes it doesn’t even fire at all. WTF? Well, I’ve been there.

Here’s the thing: the “load” event fires when loading is done. If you’re looking at the whole window/document, it’s not done loading until the whole document is loaded, including bandwith-and-time-heavy images. And these things can be slow to load, or hang entirely. This can seriously mess with the concept of “loading”. You don’t care about any of these things, you just want the HTML.

Well, Firefox is a very deep project, and there’s a few secret events that aren’t widely used or documented. If you want to know when the HTML is loaded — or more accurately, when the DOM Tree’s content is loaded — there’s a special event you can monitor: “DOMContentLoaded”

gBrowser.addEventListener(“DOMContentLoaded”, the_function_name, true);

This is a very reliable way of knowing when the browser has loaded only the page. The catch is that it’s Firefox-internal only. Which means it only works from an extension — you can’t use this in a web page. There are techniques for duplicating this functionality in other browsers, but that’s getting beyond this post.

Javascript, Dates, Times, and One Man’s Dream

OK, so the title of this post might be a bit overstating.

But, if you work with Javascript and need to use dates/times, you should absolutely check out a JS library for formatted dates and times by Steven Levithan (who is obviously cool; his blog is titled “Flagrant Badassery”).

It’s a library that extends the stock Date object in Javascript to let you easily generate nicely formatted dates. Just put the code in a file and load it up. Then you can do neat things like this (adapted from his blog)

var now = new Date();

now.format(“m/dd/yy”);
// Returns, e.g., 6/09/07

// You can use one of several named masks
now.format(“isoDateTime”);
// 2007-06-09T17:46:21

// …Or add your own
dateFormat.masks.hammerTime = ‘HH:MM! “Can\’t touch this!”‘;
now.format(“hammerTime”);
// 17:46! Can’t touch this!

Javascripting

I’ve been writing a lot of JS lately, and I wanted to take this opportunity to drop some knowledge right here.

Lots of languages have support for some type of for-each-looping. This is great for looping over associative arrays, and even regular arrays, since it’s a bit cleaner than the standard for-loop. Sadly, Javascript doesn’t totally support this. There is a for-each equivalent in JS, but it’s a bad choice to use, since in JS, everything is an object, and objects can be accessed with different notations — you can either do thing.property or thing[“property”]. This notation should throw a hint as to why looping for-each isn’t the same as other language — if you try and loop over everything in an Array, you’ll also get methods that have been assigned to the Array object. Fortunately, Javascript isn’t totally foolish, you won’t get every single method, but you can definitely get some noise. Here’s Mozilla’s explanation of Javascript for-each:

Although it may be tempting to use this as a way to iterate over an Array, this is a bad idea. The for...in statement iterates over user-defined properties in addition to the array elements, so if you modify the array’s non-integer or non-positive properties (e.g. by adding a "foo" property to it or even by adding a method or property to Array.prototype), the for...in statement will return the name of your user-defined properties in addition to the numeric indexes. Also, because order of iteration is arbitrary, iterating over an array may not visit elements in numeric order. Thus it is better to use a traditional for loop with a numeric index when iterating over arrays.

It’s a shame, because a nice for-each is some of my favorite sugar in a programming language. But, I like Javascript enough that I will forgive it for this. I have a suspicion that with some type checking, a more traditional for-each might be possible, but that’s for another time.

I also found the site of a very cool dude, Kent Brewster. Just one example of his awesomeness is found in his article on hardened Javascript. I also really like that he makes notes and lists and saves information; it’s probably one key to his success.