Class: Jabber::Bot

Inherits:
Object
  • Object
show all
Defined in:
lib/jabber/bot.rb

Overview

Jabber::Bot

Jabber::Bot makes it simple to create and command a Jabber bot with little fuss. By adding custom commands powered by regular expressions to your bot’s repertoire, you and your new bot will be able to accomplish nearly anything.

Author

Brett Stimmerman ([email protected])

Version

1.1.1

Copyright

Copyright © 2007 Brett Stimmerman. All rights reserved.

License

New BSD License (opensource.org/licenses/bsd-license.php)

Website

socket7.net/software/jabber-bot

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Bot

Creates a new Jabber::Bot object with the specified config Hash, which must contain jabber_id, password, and master at a minimum.

You may optionally give your bot a custom name. If name is omitted, the username portion of jabber_id is used instead.

You may choose to restrict a Jabber::Bot to listen only to its master(s), or make it public.

You may optionally specify a Jabber presence, status, and priority. If omitted, they each default to nil.

By default, a Jabber::Bot has only a single command, ‘help [<command>]’, which displays a help message for the specified command, or all commands if <command> is omitted.

If you choose to make a public bot, only the commands you specify as public, as well as the default ‘help’ command, will be public.

# A minimally confiugured private bot with a single master.
bot = Jabber::Bot.new(
  :jabber_id => '[email protected]',
  :password  => 'password',
  :master    => '[email protected]'
)

# A highly configured public bot with a custom name, mutliple masters,
# Jabber presence, status, and priority.
masters = ['[email protected]', '[email protected]']

bot = Jabber::Bot.new(
  :name      => 'PublicBot',
  :jabber_id => '[email protected]',
  :password  => 'password',
  :master    => masters,
  :is_public => true,
  :presence  => :chat,
  :priority  => 5,
  :status    => 'Hello, I am PublicBot.'
)


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/jabber/bot.rb', line 93

def initialize(config)
  @config = config

  @config[:is_public] ||= false

  if @config[:name].nil? or @config[:name].length == 0
    @config[:name] = @config[:jabber_id].sub(/@.+$/, '')
  end

  unless @config[:master].is_a?(Array)
    @config[:master] = [@config[:master]]
  end

  @commands = { :spec => [], :meta => {} }

  add_command(
    :syntax      => 'help [<command>]',
    :description => 'Display help for the given command, or all commands' +
        ' if no command is specified',
    :regex => /^help(\s+?.+?)?$/,
    :alias => [ :syntax => '? [<command>]', :regex  => /^\?(\s+?.+?)?$/ ],
    :is_public => @config[:is_public]
  ) { |sender, message| help_message(sender, message) }
end

Instance Attribute Details

#jabberObject (readonly)

Direct access to the underlying Jabber::Simple object.



50
51
52
# File 'lib/jabber/bot.rb', line 50

def jabber
  @jabber
end

Instance Method Details

#add_command(command, &callback) ⇒ Object

Add a command to the bot’s repertoire.

Commands consist of a metadata Hash and a callback block. The metadata Hash must contain the command syntax, a description for display with the builtin ‘help’ command, and a regular expression (regex) to detect the presence of the command in an incoming message.

The metadata Hash may optionally contain an array of command aliases. An alias consists of an alias syntax and regex. Aliases allow the bot to understand command shorthands. For example, the default ‘help’ command has an alias ‘?’. Saying either ‘help’ or ‘?’ will trigger the same command callback block.

The metadata Hash may optionally contain a is_public flag, indicating the bot should respond to anyone issuing the command, not just the bot master(s). Public commands are only truly public if the bot itself has been made public.

The specified callback block will be triggered when the bot receives a message that matches the given command regex (or an alias regex). The callback block will have access to the sender and the message text (not including the command itsef), and should either return a String response or nil. If a callback block returns a String response, the response will be delivered to the Jabber id that issued the command.

Examples:

 # Say 'puts foo' or 'p foo' and 'foo' will be written to $stdout.
 # The bot will also respond with "'foo' written to $stdout."
 add_command(
   :syntax      => 'puts <string>',
   :description => 'Write something to $stdout',
   :regex       => /^puts\s+.+$/,
   :alias       => [ :syntax => 'p <string>', :regex => /^p\s+.+$/ ]
 ) do |sender, message|
   puts "#{sender} says #{message}."
   "'#{message}' written to $stdout."
 end

 # 'puts!' is a non-responding version of 'puts', and has two aliases,
 # 'p!' and '!'
 add_command(
   :syntax      => 'puts! <string>',
   :description => 'Write something to $stdout (without response)',
   :regex       => /^puts!\s+.+$/,
   :alias       => [ 
     { :syntax => 'p! <string>', :regex => /^p!\s+.+$/ },
     { :syntax => '! <string>', :regex => /^!\s+/.+$/ }
   ]
 ) do |sender, message|
   puts "#{sender} says #{message}."
   nil
 end

# 'rand' is a public command that produces a random number from 0 to 10
add_command(
 :syntax      => 'rand',
 :description => 'Produce a random number from 0 to 10',
 :regex       => /^rand$/,
 :is_public   => true
) { rand(10).to_s }


180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/jabber/bot.rb', line 180

def add_command(command, &callback)
  name = command_name(command[:syntax])

  # Add the command meta - used in the 'help' command response.
  add_command_meta(name, command)

  # Add the command spec - used for parsing incoming commands.
  add_command_spec(command, callback)

  # Add any command aliases to the command meta and spec
  unless command[:alias].nil?
    command[:alias].each { |a| add_command_alias(name, a, callback) }
  end
end

#connectObject

Connect the bot, making it available to accept commands.



196
197
198
199
200
201
202
203
204
# File 'lib/jabber/bot.rb', line 196

def connect
  @jabber = Jabber::Simple.new(@config[:jabber_id], @config[:password])

  presence(@config[:presence], @config[:status], @config[:priority])

  deliver(@config[:master], "#{@config[:name]} reporting for duty.")

  start_listener_thread
end

#deliver(to, message) ⇒ Object

Deliver a message to the specified recipient(s). Accepts a single recipient or an Array of recipients.



208
209
210
211
212
213
214
# File 'lib/jabber/bot.rb', line 208

def deliver(to, message)
  if to.is_a?(Array)
    to.each { |t| @jabber.deliver(t, message) }
  else
    @jabber.deliver(to, message)
  end
end

#disconnectObject

Disconnect the bot. Once the bot has been disconnected, there is no way to restart it by issuing a command.



218
219
220
221
222
223
# File 'lib/jabber/bot.rb', line 218

def disconnect
  if @jabber.connected?
    deliver(@config[:master], "#{@config[:name]} disconnecting...")
    @jabber.disconnect
  end
end

#masterObject

Returns an Array of masters



226
227
228
# File 'lib/jabber/bot.rb', line 226

def master
  @config[:master]
end

#master?(jabber_id) ⇒ Boolean

Returns true if the given Jabber id is a master, false otherwise.

Returns:

  • (Boolean)


231
232
233
# File 'lib/jabber/bot.rb', line 231

def master?(jabber_id)
  @config[:master].include? jabber_id
end

#presence(presence = nil, status = nil, priority = nil) ⇒ Object

Sets the bot presence, status message and priority.



236
237
238
239
240
241
242
243
# File 'lib/jabber/bot.rb', line 236

def presence(presence=nil, status=nil, priority=nil)
  @config[:presence] = presence
  @config[:status]   = status
  @config[:priority] = priority

  status_message = Presence.new(presence, status, priority)
  @jabber.send!(status_message) if @jabber.connected?
end

#presence=(presence) ⇒ Object

Sets the bot presence. If you need to set more than just the presence, use presence() instead.

Available values for presence are:

* nil   : online
* :chat : free for chat
* :away : away from the computer
* :dnd  : do not disturb
* :xa   : extended away


256
257
258
# File 'lib/jabber/bot.rb', line 256

def presence=(presence)
  presence(presence, @config[:status], @config[:priority])
end

#priority=(priority) ⇒ Object

Set the bot priority. Priority is an integer from -127 to 127. If you need to set more than just the priority, use presence() instead.



262
263
264
# File 'lib/jabber/bot.rb', line 262

def priority=(priority)
  presence(@config[:presence], @config[:status], priority)
end

#status=(status) ⇒ Object

Set the status message. A status message is just a String, e.g. ‘I am here.’ or ‘Out to lunch.’ If you need to set more than just the status message, use presence() instead.



269
270
271
# File 'lib/jabber/bot.rb', line 269

def status=(status)
  presence(@config[:presence], status, @config[:priority])
end