social irc bots 

in the Cloud

with

node.js

and

MongoDB


http://bit.ly/11Qft8j

presented by

ryan jarvinen / @ryanj
Open Platform Evangelist
at
Red Hat

ryanj@redhat.com

Agenda

  • Learn some IRC basics
  • Create a bot and teach it to speak
  • Learn some MongoDB basics
  • Build a social leaderboard
  • Go live with a MongoDB-powered IRC bot in ~30 mins

Code du jour

https://github.com/openshift-quickstart/irc-leaderboard-quickstart


Signup with Code - MONGODC13

IRC

is

just

multiplayer notepad

multiplayer notepad

Hello, nice to troll you!

IRC

is
  • just multiplayer notepad
  • a drama club for nerds

Acting / Emoting

An emote is an entry into a text-based chat client that indicates an action taking place. Unlike emoticons, they are not text art, and instead describe the action using words.

http://en.wikipedia.org/wiki/Emote

Real Drama

The Hamnet Players
http://www.hambule.co.uk/hamnet/


The Plaintext Players
http://yin.arts.uci.edu/~players/

The Cyposium?


http://www.cyposium.net/

Making a big entrance

To perform an action,

type '/me' followed by a description of an action:


/me rolls eyes at IRC over-actors

IRC Bots

irc bot

IRC Bots are

  • talking applications
  • scripted actors who appear to be another user in the room
  • generally benevolent (they fight for the users)

IRC Bot Abilities

  • most bots know a few simple jokes
  • many know how to assist with bug reports
  • they may offer links to relevant information
  • or even fight against spam

IRC is

  • just multiplayer notepad
  • drama club for nerds
  • an open protocol for realtime mutiuser communication via text (rfc1459)
  • found at the heart of every high-tech company that I've worked for
  • a serious contender for "most valuable communication tool" in many organizations
  • realtime communication

IRC IS

OPEN

Open clients

XCHAT, colloquy

Web Clients

Give it a try:

http://webchat.freenode.net/

Open servers

freenode

/join #openshift

OpenShift on freenode IRC

Hosting Options

DIY / on premise

Public IRC (Freenode)

Cloud Servers

IRC is built on an open standard, allowing you to host it as a service (on your own hardware), or from within a private network (for added security).


OpenShift was designed with many of the same characteristics in mind, minus the drama.

OpenShift IS

OPEN

Open client interface

https://github.com/openshift/rhc

Open cartridge format

OpenShift Cartridge

PaaS Source

OpenShift Origin

Hosting Options

OpenShift Origin / DIY

OpenShift Online

OpenShift Enterprise

Developer Preview

Sign up for an OpenShift Online account:

http://openshift.redhat.com/

  • Free-as-in-beer (no cost)
  • Free-as-in-freedom (open source)
  • 512 MB RAM / 1 GB storage per gear (3 free)
  • Need more resources? (just ask!)
  • REALLY a Developer Preview (GA this summer)

The Cloud Landscape

OpenShift is...

The big picture

OpenStack

IS OPEN

and

focused on IaaS

Buzz Words

Public Cloud + Private Cloud =

Hybrid Cloud

Getting Started with OpenShift

pre-requisites:

ruby, rubygems
git

Installing the 'rhc' client tool

sudo gem install rhc
and
make sure that node.js is available in your development environment

Help with client tools

Configuring your dev environment

rhc setup

Will automatically:

  • set your openshift email address
  • verify your ssh key configuration
  • configure your application namespace

Gearing up a new app on OpenShift

rhc app create APP_NAME APP_CARTRIDGE
or
rhc app create ircbot nodejs-0.6
Application Options
-------------------
  Namespace:  ryanj
  Cartridges: nodejs-0.6
  Gear Size:  default
  Scaling:    no

Creating application 'ircbot' ... done

Waiting for your DNS name to be available ... done

Downloading the application Git repository ...
Cloning into 'ircbot'...
ircbot @ http://ircbot-ryanj.rhcloud.com/ (uuid: 25918304bf8d406e89802a1e642063a0)
---------------------------------------------------
  Created:   10:23 PM
  Gear Size: small
  Git URL:  
ssh://25918304bf8d406e89802a1e642063a0@ircbot-ryanj.rhcloud.com/~/git/ircbot.git/
  SSH:       25918304bf8d406e89802a1e642063a0@ircbot-ryanj.rhcloud.com

  nodejs-0.6 (Node.js 0.6)
  ------------------------

RESULT:
Application ircbot was created.

Success!

You now have a basic node.js app up an running on OpenShift!


Your gear is now configured with:

  • it's own git repo
  • it's own web server
  • ssh access
  • logging
  • publicly accessible DNS

Building your bot

 cd ircbot 

Installing dependencies

Using Node's npm package manager:

npm install irc -S

Include the `-S` flag in order to save this dependency to your application's `package.json` file.

http://npmjs.org/package/irc/

Bot Basics

Add the following to your server.js to load and configure the irc library:

var irc = require('irc');
var bot_name = process.env.OPENSHIFT_APP_NAME || 'ircbot';
var bot = new irc.Client('chat.freenode.net', bot_name, {
    channels: ['#botzoo', '#botwar'],
    port: 8001,
    debug: true
});

Teaching your bot to speak

Listen and respond to conversations as they happen:

bot.addListener('message', function(from, to, message) {
  if(  message.indexOf('Know any good jokes?') > -1
    || message.indexOf('good joke') > -1
  ) {
    bot.say(to, 'Knock knock!');
  }
});

Getting to the punchline:

bot.addListener('message', function(from, to, message) {
  if(  message.indexOf('who is there?') > -1
    || message.indexOf("who's there?") > -1
    || message.indexOf("Who's there?") > -1
    || message.indexOf("Who is there?") > -1
    )
    {
        bot.say(to, 'Doris');
    }
});
bot.addListener('message', function(from, to, message) {
    if(  message.indexOf('Doris who?') > -1
      || message.indexOf("doris who?") > -1
      )
    {
        bot.say(to, "Doris locked, that's why I'm knocking!");
    }
});

Committing your changes

git add package.json server.js

Commit your changes locally

git commit -m 'adding irc npm dependency, initializing irc library, adding a few jokes'

deployment

git push

Done! Your bot should now be live on IRC.

Interacting with your new bot

Login to IRC, and enter one of the channels that your bot has been configured to join:
/join #botzoo

If you don't already have an IRC client, you can connect to freenode on the web:

http://webchat.freenode.net/

Ask if anyone knows a good joke:

[guest]  Know any good jokes?
[ircbot] Knock knock!
[guest]  Who is there?
[ircbot] Doris
[guest]  Doris who?
[ircbot] Doris locked, that's why I'm knocking!
[guest]  meh...

Bot debugging and maintainance

If your bot decides to quit mid-conversation, it may be suffering from a bug.


Checking it's logs may reveal what set it off:

rhc tail ircbot

Or, debug it while running locally:

npm start

Teaching your bot to keep score

Setting up MongoDB on Openshift

rhc cartridge add mongodb-2.2
Adding mongodb-2.2 to application 'ircbot' ... Success

mongodb-2.2 (MongoDB NoSQL Database 2.2)
----------------------------------------
  Connection URL: mongodb://127.6.102.129:27017/
  Database Name:  ircbot
  Password:       T5xJwCiDZYGn
  Username:       admin

RESULT:
Added mongodb-2.2 to application ircbot
Adding mongodb-2.2 to application 'ircbot' ... Success

MongoDB 2.2 database added.  Please make note of these credentials:

   Root User: admin
   Root Password: T5xJwCiDZYGn
   Database Name: ircbot

Connection URL: mongodb://$OPENSHIFT_MONGODB_DB_HOST:$OPENSHIFT_MONGODB_DB_PORT/

You can manage your new MongoDB by also embedding rockmongo-1.1
The rockmongo username and password will be the same as the MongoDB credentials above.

RockMongo on Openshift

rhc cartridge add rockmongo-1.1

(optional)

Adding a Mongojs dependency

npm install -S mongojs

Connecting to MongoDB

var mongojs = require('mongojs');
var connection_string = bot_name;
if(process.env.OPENSHIFT_MONGODB_DB_PASSWORD){
  connection_string = process.env.OPENSHIFT_MONGODB_DB_USERNAME + ":" +
  process.env.OPENSHIFT_MONGODB_DB_PASSWORD + "@" +
  process.env.OPENSHIFT_MONGODB_DB_HOST + ':' +
  process.env.OPENSHIFT_MONGODB_DB_PORT + '/' +
  process.env.OPENSHIFT_APP_NAME;
}
var db = mongojs(connection_string, ['scoreboard']);

Setting a score

bot.addListener('message', function(from, to, message) {
    if(  message.indexOf('++') > -1 ){
        var subject = message.slice(0,message.indexOf('++'));
        db.scoreboard.findAndModify({
            query: { name: subject },
            update: { $inc: { score:1 }},
            new: true,
            upsert: true
        }, function(err, doc) {
            bot.say(to, "score: " + doc.score );
        });
    }
});

Showing the scoreboard

bot.addListener('message', function(from, to, message) {
    if(  message.indexOf('scoreboard') > -1 ){
        db.scoreboard.find().sort({score:-1}).limit(10).forEach(function(err, doc){
            if (doc && doc.name && doc.score ) {
                bot.say(to, doc.name + ": " + doc.score);
            }
        });
    }
});

updating your app

git add package.json server.js
git commit -m 'adding a social scoreboard'
git push

Social Rewards

Allocating points

term++
[raphael]   Anyone down for pizza?
[donatello] pizza++
[ircbot]    score: 43
[raphael]   Let's order two
[leonardo]  Good idea, Raph! raphael++
[ircbot]    score: 23

Checking the Scoreboard

ircbot scoreboard
[ircbot] ircbot: 7
[ircbot] ryanj: 4
[ircbot] doris: -2 

Bots on-demand

rhc app create ircbot nodejs-0.6 mongodb-2.2 --from-code=https://github.com/openshift-quickstart/irc-leaderboard-quickstart.git

You can find much more information about this npm IRC library here:

https://github.com/martynsmith/node-irc

References

irc bot

Thanks for following along!   --ryanj