How to turn your PHP application into a bot

Connect almost any PHP application to an IRC server and make information available anywhere

A freely available module allows your PHP application to attach to an IRC server and respond to messages. To illustrate how to use the module, this article shows you how to create an IRC bot in PHP that can tell you the weather on demand for a ZIP code.

Jack Herrington (jherr@pobox.com), Senior Software Engineer, Studio B

Jack D. Herrington is a senior software engineer with more than 20 years of experience. He's the author of three books: Code Generation in Action, Podcasting Hacks, and PHP Hacks. He has also written more than 30 articles.



17 January 2006

Ever wanted to chat with one of your PHP applications? Are you addicted to instant messaging? If so, do I have a module for you! This module, which is found at the PHP Application and Extension Repository (PEAR), allows your PHP application to attach to an Internet Relay Chat (IRC) server and respond to its messages. In essence, the PEAR module turns your PHP application into a bot.

What is a bot?

If you don't know what a bot is, you aren't alone. A bot is a program that logs onto a system (for example, an IRC system or a backgammon server) and answers questions or plays the game.

The value of a bot is that you can communicate with it through a mechanism that you use often: instant messaging. If you are always in chat rooms, now you don't need to leave them to find out what the local weather is. This article shows you how to create an IRC bot in PHP that can tell you the weather on demand for your ZIP code.

IRC basics

In case you aren't familiar with the IRC system, here's a primer. An IRC system has two components: a server and a client. The server creates several virtual channels that people log into to communicate with each other. The channels are given familiar names that are supposed to map to a topic or theme for the conversation.

IRC client software then attaches to the server by specifying a host name, port number, and requested nickname. After the client successfully attaches to the server, it can join any number of channels and start sending and receiving messages. To send a message, you simply type the message into a text box and press Enter, just like any other instant messaging client. The client then sends that message to the server, which in turn broadcasts the message to all the other clients that have joined that channel. IRC client software is available for every operating system, as well for portable devices.

Bots act like any other client. They attach to a server, then join one or more channels. Generally speaking, bots don't send out messages independently. Rather, they listen for messages from users in the channels that fit a specific format. The bots send out messages in response to those specially formatted requests.

The bot in this article looks for users who start messages with the word weather, followed by a ZIP code. (To start out, however, I just look for the word weather to keep the example simple.)


Installing the PEAR modules

It all starts with installing a few PEAR modules. PEAR is a repository of user-contributed modules. These modules cover everything from reading and writing different types of files, using different Web services, science modules, and more.

A great feature of PEAR is that the site offers scripts for the Microsoft® Windows®, Linux®, and Mac OS X operating systems that make it easy for you to install PEAR modules from your computer's command line. Below is my session with a Windows command prompt window, from which I installed the Net_SmartIRC module:

Listing 1. Session with Windows command prompt window
    C:\ >pear install Net_SmartIRC
    downloading Net_SmartIRC-1.0.0.tgz ...
    Starting to download Net_SmartIRC-1.0.0.tgz (185,991 bytes)
    ........................................done: 185,991 bytes
    install ok: Net_SmartIRC 1.0.0

Installing an IRC server

Tips

To use the code in this article, you need to install the Net_SmartIRC and Services_Weather modules, along with all their dependent modules (see Resources for download locations). For example, Services_Weather requires XML_Serializer (among other modules). The PEAR script lists all the components you must install. NOTE: If the PEAR script tells you that no released version of the module exists, use the force option (-f) to force installation of the module.

The next step in creating an IRC bot is to set up a server the bot can log into. You could have the bot log into a public server, but I recommend first installing a server locally for testing.

I chose to run the "beware ircd" server for Windows. (A version of the beware ircd server is available for Linux, as well.) I looked at a few servers, and this one was the easiest to use. Installing the beware ircd server is easy, and I placed it in C:\ircd. From that directory, I ran the server by opening a command prompt and typing the following:

    C:\ircd> bircd

NOTE: No configuration changes are required.

But how do you know that the server is running? To verify that, you need to install an IRC client.


Installing an IRC client

To test the local server, as well as to communicate with the bot, you need to install an IRC client. I chose to install the popular mIRC client for Windows. (At the time of this writing, V6.16 was the most current version.) You can choose a client appropriate for your platform.

With the mIRC client installed, I launched the mIRC application from the Start menu. I then used the Connect command to connect to localhost. I used the join command from the menu to attach to the #weather channel, as shown in Figure 1.

Figure 1. Joining the #weather channel from the IRC client
Joining the #weather channel from the IRC client

After joining the channel, the window shown in Figure 2 appears. From here, I can talk with other people or with the bot.

Figure 2. Chat interface for the #weather channel
Chat interface for the #weather channel

Now, with the server running locally, the IRC client up and running, and the PEAR modules installed, I can write the PHP bot that will retrieve the weather conditions in my hometown.


It starts with connecting

I'm going to create several version of the script. Each version will add more functionality. The first version of the PHP bot script is shown in Listing 2. In this script, I'm logging in to the IRC server and creating a class that will respond to particular types of messages. This module is designed specifically to create bots for IRC.

Listing 2. The first, simple version of the bot
    <?php
    include_once('Net/SmartIRC.php');
    
    class weatherbot
    {
    function weather(&$irc, &$data)
    {
    $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
    'Yeah, weather');
    }
    }
    
    $host = "localhost";
    $port = 6667;
    $nick = "weather";
    $chan = "#weather";
    
    $bot = &new weatherbot( );
    $irc = &new Net_SmartIRC( );
    $irc->setUseSockets( TRUE );
    $irc->registerActionhandler( SMARTIRC_TYPE_CHANNEL,
    '^weather', $bot, 'weather' );
    $irc->connect( $host, $port );
    $irc->login( $nick, 'Weather bot', 0, $nick );
    $irc->join( array( $chan ) );
    $irc->listen( );
    $irc->disconnect( );
    ?>

The import parts of the script are in the registerActionhandler method, which connects a bot object with a particular action string and method. The ^weather string is a regular expression that, if it matches any text typed into the IRC channel, invokes the action handler.

The other import part of the script is the weather method in the Weatherbot class. This method responds to a weather request and sends back (at this point) "Yeah, weather." (By the end of this article, it will tell you the weather.)

To start the script, I run it from a command prompt with the following command:

    C:\ircd> php ircbot.php

The script logs in to the local IRC server, then goes through an infinite loop.

Figure 3 shows the weather bot logged in to the server. It also shows me typing weather into the text window and pressing Enter.

Figure 3. Talking to the weather bot
Talking to the weather bot

The weather bot then responds with the fixed string Yeah, weather.

That's a good start. Now, how do you get the weather?


Getting the weather

To get the weather, you use the Weather Web service PEAR module. Listing 3 shows the module, which I modified to provide weather conditions for my hometown.

Listing 3. A weather bot that reports the weather
<?php
include_once('Net/SmartIRC.php');
include_once('Services/Weather.php');

$weather = new Services_Weather();
$wdc = $weather->service( "Weatherdotcom" );

class weatherbot
{
  function weather(&$irc, &$data)
  {
     global $wdc;
     $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
            'Yeah, weather');

     $fc = $wdc->getForecast( 94587, 1 );
     foreach( $fc['days'] as $day )
     {
       $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
          "Condition: ".$day['day'][ 'condition' ] );
       $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
          "High: ".$day[ 'temperatureHigh' ] );
       $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
          "Low: ".$day[ 'temperatureLow' ] );
       $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
          "Wind: ".$day['day'][ 'wind' ] );
       $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
          "Wind Degrees: ".$day['day'][ 'windDegrees' ] );
       $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
          "Wind Direction: ".$day['day'][ 'windDirection' ] );
       $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
          "Precipitation: ".$day['day'][ 'precipitation' ] );
       $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
          "Humidity: ".$day['day'][ 'humidity' ] );
     }
  }
}

$host = "localhost";
$port = 6667;
$nick = "weather";
$chan = "#weather";

$bot = &new weatherbot( );
$irc = &new Net_SmartIRC( );
$irc->setUseSockets( TRUE );
$irc->registerActionhandler( SMARTIRC_TYPE_CHANNEL,
  '^weather', $bot, 'weather' );
$irc->connect( $host, $port );
$irc->login( $nick, 'Weather bot', 0, $nick );
$irc->join( array( $chan ) );
$irc->listen( );
$irc->disconnect( );
?>

The first update I made was to add the include directive to reference the weather services module. Then I created a weather service object. In the weather method, I invoked the getForecast method and requested the forecast for a given ZIP code -- in my case, 94587, which is Union City, Calif.

From there, I got the weather information for the first day and sent out the weather results as messages through the IRC channel. Figure 4 shows the resulting text window.

Figure 4. The weather response with a hard-coded ZIP code
The weather response with a hard-coded ZIP code

But I'm sure you don't want the weather conditions in my hometown. So, how do you get the weather for your city?


Getting the weather information you need

Getting the weather information that's relevant to you requires parsing the text of the request. And that means making the minor change in the weather method as shown in Listing 4.

Listing 4. The new weather method
    class weatherbot
    {
    function weather(&$irc, &$data)
    {
    global $wdc;
    
    $zip = $data->messageex[1];
    
    $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
    "Yeah, weather for $zip");
    
    $fc = $wdc->getForecast( $zip, 1 );
    foreach( $fc['days'] as $day )
    {
    $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
    "Condition: ".$day['day'][ 'condition' ] );
    $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
    "High: ".$day[ 'temperatureHigh' ] );
    $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
    "Low: ".$day[ 'temperatureLow' ] );
    $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
    "Wind: ".$day['day'][ 'wind' ] );
    $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
    "Wind Degrees: ".$day['day'][ 'windDegrees' ] );
    $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
    "Wind Direction: ".$day['day'][ 'windDirection' ] );
    $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
    "Precipitation: ".$day['day'][ 'precipitation' ] );
    $irc->message(SMARTIRC_TYPE_CHANNEL, $data->channel,
    "Humidity: ".$day['day'][ 'humidity' ] );
    }
    }
    }

The IRC module nicely breaks down the message the user typed into words that you can reference as an array in the messageex array. In this case, the first item will be the ZIP code.

Figure 5 shows how to use the weather request with a ZIP code. As you can see, I typed 19081, which is the ZIP code for Swarthmore, Pa., home of Swarthmore College.

Figure 5. The weather for Swarthmore, Pa.
The weather for Swarthmore, Pa.

Of course, I should have included more error-checking and such to make sure that the ZIP code is valid. But I'll leave that up to you.


Thinking outside the box

This article covers the basics of connecting your PHP application to IRC. You can use this application as a starting point and hook up your own PHP classes to the code. Then you can use your Web application with the browser and through IRC.

I'm a strong advocate of coming to users in the way they prefer to communicate -- sending out e-mail messages or through an instant messaging client. This article provides just one example of putting another type of interface on your PHP application. I encourage you to think outside the standard Web box with your PHP code.

On a related note, I encourage you to contribute your own modules to PEAR. It's a good introduction to cleanly encapsulated code, and it helps the community.

Resources

Learn

  • Visit IRC.org to find more information about the IRC chat system.
  • Then there's the Bot-Depot, where you can talk with other programmers who are writing bots.
  • Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products.

Get products and technologies

Discuss

  • Join the developerWorks community, a professional network and unified set of community tools for connecting, sharing, and collaborating.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Open source on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source
ArticleID=101946
ArticleTitle=How to turn your PHP application into a bot
publish-date=01172006