Class: Jabbot::Bot

Inherits:
Object
  • Object
show all
Includes:
Handlers
Defined in:
lib/jabbot/bot.rb

Overview

The main Bot class.

It handles the connection as well as the method dispatching.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Handlers

#add_handler, #dispatch, #handlers

Constructor Details

#initialize(options = {}) ⇒ Bot

Public: Initialize a Bot instance.

options - A Jabbot::Config options instance or a Hash of key-value

configuration options (default: {}).


53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/jabbot/bot.rb', line 53

def initialize(options={})
  @config = if options.kind_of?(Jabbot::Config)
    options
  else
    Jabbot::Config.new(options)
  end
  @log = nil
  @abort = false
  @users = []

rescue Exception => krash
  raise SystemExit.new(krash.message)
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



45
46
47
# File 'lib/jabbot/bot.rb', line 45

def client
  @client
end

#usersObject (readonly)

Returns the value of attribute users.



46
47
48
# File 'lib/jabbot/bot.rb', line 46

def users
  @users
end

Instance Method Details

#closeObject Also known as: quit

Public: Close the server connection.

Returns nothing.



170
171
172
173
174
175
# File 'lib/jabbot/bot.rb', line 170

def close
  if connected?
    @connected = false
    client.close
  end
end

#configObject

Public: Get the current configuration settings.

Returns the configuration Hash.



294
295
296
# File 'lib/jabbot/bot.rb', line 294

def config
  @config
end

#configure {|@config| ... } ⇒ Object

Public: Set configure options for the bot.

Returns the configure Hash.

Yields:



287
288
289
# File 'lib/jabbot/bot.rb', line 287

def configure
  yield @config
end

#connectObject

Internal: Connect to Jabber and join channel.

It will exit the process and log any exception on ‘$stderr` on failure.

Returns nothing.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/jabbot/bot.rb', line 86

def connect
  @jid = Jabber::JID.new(config.)
  @mucjid = Jabber::JID.new("#{config.channel}@#{config.server}")

  if @jid.node.nil?
    raise "Your Jabber ID must contain a user name and therefore contain one @ character."
  elsif @jid.resource
    raise "If you intend to set a custom resource, define so in the config."
  elsif @mucjid.node.nil?
    raise "Please set a room name, e.g. [email protected]"
  elsif @mucjid.resource
    raise "The MUC room must not contain a resource. Remove the slash!"
  else
    @jid.resource = config.resource
    @mucjid.resource = config.nick
    @users << config.nick
  end

  @client = Jabber::Client.new(@jid)
  @client.on_exception do |*args|
    $stderr.puts "got an intern EXCEPTION, args where:"
    $stderr.puts args.inspect
    $stderr.puts "exiting..."

    EventMachine.stop_event_loop
    exit
  end
  begin
    @client.connect
    @client.auth(config.password)
    @muc = Jabber::MUC::SimpleMUCClient.new(@client)
    muc_handlers.call(@muc)
    @muc.join(@mucjid, config.channel_password)
    @connected = true
  rescue => errmsg
    @connected = false
    $stderr.write "#{errmsg.class}\n#{errmsg}, #{errmsg.backtrace.join("\n")}"
    exit 1
  end
end

#connected?Boolean

Internal: Get information if the bot is still connected.

Returns the connection state as a Boolean.

Returns:

  • (Boolean)


163
164
165
# File 'lib/jabbot/bot.rb', line 163

def connected?
  @connected
end

#debug!Object

Internal: Enable debugging mode.

All xmpp4r-internal calls to Jabber::Debuglog are printed to $stderr by default. You may change the logger by using

Jabber::Logger = Logger.new()

Returns nothing.



76
77
78
# File 'lib/jabbot/bot.rb', line 76

def debug!
  Jabber::debug = true
end

#dispatch_messages(type, messages) ⇒ Object

Internal: Dispatch a collection of messages.

type - The Symbol type to be processed. messages - An Array of String messages to be dispatched.

Returns the Integer count of messages dispatched.



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

def dispatch_messages(type, messages)
  messages.each { |message| dispatch(type, message) }
  messages.length
end

#logObject

Internal: Instanciates a logger.

Returns logger instance.



276
277
278
279
280
281
282
# File 'lib/jabbot/bot.rb', line 276

def log
  return @log if @log
  os = config.log_file ? File.open(config.log_file, "a") : $stdout
  @log = Logger.new(os)
  @log.level = Logger.const_get(config.log_level ? config.log_level.upcase : "INFO")
  @log
end

#muc_handlersObject

Internal: Assigns handlers for different xmpp messages.

The handled messages are:

* public messages
* private messages
* joins
* leaves
* subject changes

Returs a Proc to be called to assign the handlers.



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/jabbot/bot.rb', line 199

def muc_handlers
  Proc.new do |muc|
    muc.on_message do |time, nick, text|
      if time.nil? # Don't process messages from the past.
        begin
          dispatch_messages(:message, [Message.new(nick, text, Time.now, :public)]) unless nick == config.nick
        rescue Exception => boom
          log.fatal boom.inspect
          log.fatal boom.backtrace[0..5].join("\n")
        end
      end
    end

    muc.on_private_message do |time, nick, text|
      if time.nil? # Don't process messages from the past.
        begin
          dispatch_messages(:private, [Message.new(nick, text, Time.now, :private)]) unless nick == config.nick
        rescue Exception => boom
          log.fatal boom.inspect
          log.fatal boom.backtrace[0..5].join("\n")
        end
      end
    end

    muc.on_join do |time, nick|
      unless @users.include? nick
        @users << nick
      end
      if time.nil? # Don't process messages from the past.
        begin
          dispatch_messages(:join, [Message.new(nick, "join", Time.now, :join)]) unless nick == config.nick
        rescue Exception => boom
          log.fatal boom.inspect
          log.fatal boom.backtrace[0..5].join("\n")
        end
      end
    end

    muc.on_leave do |time, nick|
      @users.delete(nick)
      if time.nil? # Don't process messages from the past.
        begin
          dispatch_messages(:leave, [Message.new(nick, "leave", Time.now, :leave)])
        rescue Exception => boom
          log.fatal boom.inspect
          log.fatal boom.backtrace[0..5].join("\n")
        end
      end
    end

    muc.on_subject do |time, nick, subject|
      if time.nil? # Don't process messages from the past.
        begin
          dispatch_messages(:subject, [Message.new(nick, subject, Time.now, :subject)])
        rescue Exception => boom
          log.fatal boom.inspect
          log.fatal boom.backtrace[0..5].join("\n")
        end
      end
    end
  end
end

#nickObject

Public: Easy access to the bot’s nickname

Returns the configured nick String.



301
302
303
# File 'lib/jabbot/bot.rb', line 301

def nick
  @config.nick
end

#run!Object

Public: Starts the jabber bot.

Internally it starts the jabber connection inside of ‘EventMachine.run`, so you are free to use all EventMachine tasks out there for asynchronously working on input data.

Returns nothing.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/jabbot/bot.rb', line 134

def run!
  puts "Jabbot #{Jabbot::VERSION} imposing as #{config.} on #{config.channel}@#{config.server}"

  onclose_block = proc {
    close
    puts "\nAnd it's a wrap. See ya soon!"
    exit
  }

  Kernel.trap(:INT, onclose_block)
  Kernel.trap(:QUIT, onclose_block) rescue nil

  debug! if config.debug

  # Connect the bot and keep it running.
  EventMachine.run do
    connect

    stop_timer = EventMachine.add_periodic_timer(1) do
      if !connected?
        EventMachine.stop_event_loop
      end
    end
  end
end

#send_message(msg, to = nil) ⇒ Object

Public: Send a message to a given user or publicly.

msg - A String message. to - A String username to send to (default: nil).

Returns nothing.



184
185
186
# File 'lib/jabbot/bot.rb', line 184

def send_message(msg, to=nil)
  @muc.say(msg.to_s, to) if connected?
end