Share

Creating a Cinch plugin part 1: a word game bot for IRC

This is a tutorial for creating a plugin with Cinch, in multiple parts. It will take you through the basics of working with Cinch, creating a plugin and turning it into a gem. Plus, it will give you a highly addictive word game at the end.

The finished game is available on github.

Part 1: an introduction to cinch

The first part of this tutorial will introduce the game concept, a simple cinch bot, and install a basic plugin.

The game

The other week, I was sitting in an IRC channel for my local ruby user group when a discussion about IRC bots came up. One bot in particular was mentioned with obvious and mixed tones of love and fear: the word game bot.

I wasn't familiar with the game, so I pried further. The game worked like this: the bot would choose a random word, and then users in the channel would try and guess it. The bot would compare the guess to the actual word, and tell you whether the word comes before or after, alphabetically. This allows you to home in on the word fairly quickly, even with an entire dictionary of words, as you're essentially doing a binary chop - is it before or after?

Apparently the game was banned, due to the fact that it was so addictive. Also, the source code had long been lost. I had already been playing around with cinch, which is a ruby framework for creating IRC bots, so I decided to recreate the game.

Although it's stunningly simple to create a cinch plugin, I found that there wasn't a lot of help outside of example snippets. Therefore, I thought I'd write this tutorial to go through the steps of creating the word game as an IRC bot.

Creating a simple bot

Cinch allows you to create an IRC bot, which can join one or more channels on an IRC server, and listen and respond to activity. For instance, you can watch the messages posted by various users, and program responses to these messages.

Create a file with the following contents:

require 'cinch'

bot = Cinch::Bot.new do
  configure do |c|
    c.server = "irc.freenode.net"
    c.channels = ["#example-channel"]
    c.nick = "example-bot"
  end

  on :message do |m|
    m.reply %Q{#{m.user}: you said "#{m.message}"}
  end
end

bot.start

This bot will repeat every message that a user sends in the channel #example-channel, back to that user. Cinch uses callback blocks and events to control flow, making it very easy to respond to channel activity.

The configuration should be fairly self-explanatory: you can change the server with c.server and the bot's nickname with c.nick. The bot can join multiple channels by adding to the array, e.g. c.channels = ["#example-channel-1", "#example-channel-2"].

Installing a plugin

A plugin varies from the example above, as the logic exists externally. This means that you can include plugins from other files or gems. The cinchrb github account has a few plugins we can try, such as cinch-haiku. First, install it as a gem:

gem install cinch-haiku

Then add the require statement and plugin to the example code:

require 'cinch'
require 'cinch/plugins/haiku'

bot = Cinch::Bot.new do
  configure do |c|
    c.server = "irc.freenode.net"
    c.channels = ["#example-channel"]
    c.nick = "example-bot"
    c.plugins.plugins = [Cinch::Plugins::Haiku]
  end

  on :message do |m|
    m.reply %Q{#{m.user}: you said "#{m.message}"}
  end
end

bot.start

If you restart the bot, you will then able to use the command !haiku to print out a new haiku.

We want to use some similar functionality with our word game: it should be a plugin, so that the code is standalone and re-distributable, and we want to use commands to control the behaviour.

Summary

So far, we know how to create a simple cinch bot, get it to join a channel with a particular nickname and respond to messages. We also know how to use cinch plugins on a very basic level. In the next part, we'll create a simple version of the word game, in plugin form.

Read part 2

← Previous post: How I got stung by the Twitter gem and thread safety Next post: What you need to know about bash functions →
comments powered by Disqus