Fun with Instant Messaging and Ruby

Introduction

As we all know, HTTP is the protocol used for communication between
Web servers and Web clients (browsers). Similarly, XMPP[1]
is a protocol for communication
between Instant Messaging (IM) servers and clients. Most of the popular
programming languages like C, Java, Python, etc., have XMPP libraries. Ruby
is my language of choice, because of the ease with which ideas can be
transformed into code.

Ruby also has an XMPP library known as xmpp4r. There is also a more
abstract xmpp4r-simple
library, which was built on top of xmpp4r. Let's use
xmpp4r-simple, as our goals are relatively simple.

xmpp4r-simple can be easily installed using Rubygems, Ruby's
packaging system:

sudo gem install xmpp4r-simple

Connecting to GoogleTalk and sending messages

Lets write a program that:

connects to the Gtalk server

authenticates with proper username and password.

sends an instant message "hello" to a predefined user (a user who
is already in the friends list).

Take a look at Program1.
Replace the 'gmailusername', 'gmailpassword', and
'destination_gmailusername' in the code with with actual ones. Log in to
destination_username via an Instant Messenger client, then run the program
as:

$ ruby chat0.rb

'Destination user' should now get a "hello" message.

Receiving Messages - Echo Chat

Now, let's look at receiving the messages sent to us by our IM friends;
here is a program that will receive an IM message and simply bounce it
back to the sender. Log in with your username, and keep this program running
for a while. This will baffle your IM friends for sure.

Auto Reply

Most e-mail providers provide a service called "Auto reply" or "Holiday
mail"; the idea is to send a predefined automated reply to all incoming mails.
Here is a program that implements the same functionality for Instant
Messenger. The program sends a predefined message in reply to every message
it receives from any user. Maybe when you are busy, instead of setting
status as "busy", you can simply run this program, so that it sends some
appropriate reply automatically.

Two-way chat program

In this program, user1 sends a message, user2 responds, then it's
user1's turn again, and so on. However, if user1 wants to send a message before
user2 responds, it's not possible - this is a single-threaded program which
will block while waiting for user2's response.

A Remote Shell with Instant Messenger

Run the program as "ruby remote_shell.rb" with user1 on a local machine.
Log in as another user into an IM client from a remote machine, and send
"ls" to user1 from that machine. Now, the "ls" command executes on the
user1's remote machine, and the result is sent back. Commands are executed
using the 'system' method, which internally uses an 'exec' system call to
execute the command.

How useful would it be if you could just say "geyser ON" in your IM on
your way home, which turns on the geyser at your home, so that you have
warm water ready by the time you reach home? Theoretically, we can do it
like this:

[ I love editing LG. Since the only 'geysers' I knew
of until this point were volcanic in origin, I had to research the Indian
meaning of the term; along the way, I found out that it is pronounced
'gee-zer' (as opposed to the American 'guy-ser' or 'guy-zer'), which leads
to much wordplay when the two cultures collide (what DO you do when a
geezer has a geyser?) In any case - in common Indian parlance, a 'geyser'
is a hot-water heater, usually turned off when one leaves home (solar ones
excluded, presumably.) Waiting for the water to warm up after you've
returned could be annoying - but using the author's ideas as noted in this
article could certainly alleviate the annoyance. On the other hand, if your
friends knew, they could create an even greater annoyance for you by having
a 'cron' job fire it up as soon as you left home - leading to a surprise
gas bill at the end of the month. Which leads us back to ancient computer
history:
"Hax0rin a
boilah" -- Ben ]

Connect the geyser to your parallel port (not directly, of course -
there should be some relay/switching device in between), so that a TTL 'high'
on one of the parallel port pins turns on the geyser.

Write a simple C program named "geyser" (or maybe in Ruby itself - I am
not sure if we can do it in Ruby directly) that talks to the parallel
port. On running this program with argument 'ON', it should produce a
'high' on one of the parallel port pins, while 'OFF' should make that pin
produce a 'low'.

Now, we can run this "geyser" program through our "IM remote shell".

IM-based Dictionary Service

You want to know the French equivalent for the word 'yesterday' - so you
send an IM to your friend 'french-bot', and he immediately sends you back
the French word for "yesterday". Wouldn't that be cool?

Artificial Intelligence and Instant Messaging - Eliza

Have you talked to Eliza? If not, try it now. She
is an AI chat bot. Won't it be fun if we could make Eliza talk to your IM
friends, on behalf of ourselves? :)

Since we already have Ruby programs that can talk to IM servers, an
interface to Eliza is the only thing we still need. Eliza's web
page, shows a plain HTML form, with a text field and a submit button.
The page source shows that the name of the text field is "Entry1". That's
all we need! Here's the Ruby interface for Eliza:

Now, whenever a chat message arrives, we simply call this 'eliza'
method, get a response string from Eliza, and send it as a reply. Here's
the full Ruby code for the Eliza chat
program.

Voice Chat

'Voice chat' is a little bit of an exaggeration - we are only going to
hear the received chat messages, not talk
to the program. The idea is to make our IM programs read the received messages
aloud, rather than us having to read it.

We will use a speech synthesis
system to convert the received IM text messages to speech.
Festival is an
excellent Open Source speech synthesizer that has had some previous
exposure here in the
Linux Gazette.

Conclusion

These are just a few simple ideas that came to my mind as soon as I
could control my Instant Messenger with my Ruby code. There can be tonnes
of such interesting ideas, which may not be very useful - but fun is
guaranteed. Start hacking!!!

[1]Rick Moen comments: It should be
noted that XMPP, the eXtensible Messaging and Presence Protocol, is the
underlying messaging/presence transport protocol of "Jabber" IM clients,
and that GoogleTalk (mentioned later in this article) is an extension
of XMPP that adds in VoIP functions.

(The term "Jabber" is now officially deprecated in favour of XMPP, but
persists in common usage anyway.)

Other IM protocols, many of them much more common than XMPP, include
Gadu-Gadu, IRC, MSN Protocol, AOL Instant Messager / ICQ's "OSCAR"
protocol, AOL Instant Messager's TOC and TOC2 protocols, and Yahoo
Messenger's YMSG protocol. (There are others.) XMPP is distinctive in
being openly documented, stable, and modern -- along with often serving
as the "glue" among otherwise incompatible services. A variety of
Linux
client implementations exist for sundry combinations of those
IM protocols, along with a couple of good XMPP/Jabber servers and
IM-gateway packages.