Class: Aide::Bot

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

Overview

The Bot class is the workhorse of aide. It is responsible for representing and executing the logic described by the dsl, and interacts with xmpp4r in order to send and receive messages via the jabber protocol.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeBot

Creates a new Bot instance.



24
25
26
# File 'lib/aide/bot.rb', line 24

def initialize
  @actions = {}
end

Instance Attribute Details

#actions=(value) ⇒ Object (writeonly)

Hash[String, Block] - the match strings to look for, and the code to execute when found.



10
11
12
# File 'lib/aide/bot.rb', line 10

def actions=(value)
  @actions = value
end

#allow_listObject

Array - a list of jabber IDs to allow this bot to interact with. Precludes block_list.



17
18
19
# File 'lib/aide/bot.rb', line 17

def allow_list
  @allow_list
end

#block_listObject

Array - a list of jabber IDs to explicitly block. Ignored if allow_list is set.



19
20
21
# File 'lib/aide/bot.rb', line 19

def block_list
  @block_list
end

#password=(value) ⇒ Object (writeonly)

Password - the password for this bot to use.



15
16
17
# File 'lib/aide/bot.rb', line 15

def password=(value)
  @password = value
end

#username=(value) ⇒ Object (writeonly)

String - the username to sign this bot in with.



13
14
15
# File 'lib/aide/bot.rb', line 13

def username=(value)
  @username = value
end

Instance Method Details

#add_action(match, block) ⇒ Object

Adds an action to the bot.

Parameters:

  • match: String. The text to match for this action.

  • block: Proc. The code to execute when this action is fired.



166
167
168
# File 'lib/aide/bot.rb', line 166

def add_action(match, block)
  @actions[match] = block
end

#add_allow_list(list) ⇒ Object

Allows for appending to the allow_list.

Parameters:

  • list: Array. The list of users to add to the allow_list.



175
176
177
178
# File 'lib/aide/bot.rb', line 175

def add_allow_list(list)
  @allow_list ||= []
  @allow_list += list
end

#add_block_list(list) ⇒ Object

Allows for appending to the block_list.

Parameters:

  • list: Array. The list of users to add to the block_list.



185
186
187
188
# File 'lib/aide/bot.rb', line 185

def add_block_list(list)
  @block_list ||= []
  @block_list += list
end

#is_user_allowed?(username) ⇒ Boolean

Checks a given username to see if it is explicitly allowed or blocked.

Parameters

  • username: String. The username to check privileges for.

Returns

boolean - the value of this boolean depends on the level of privileges set when the Bot was configured. If an allow_list is defined, then that list has highest precedence - true is returned if the user is in that list, and false is returned otherwise. If allow_list is not defined, but block_list is, then the inverse check is performed (true is returned when the user is absent from the block_list, and vice-versa). If neither list is defined then the user is assumed to be authorized.

Returns:

  • (Boolean)


154
155
156
157
158
# File 'lib/aide/bot.rb', line 154

def is_user_allowed?(username)
  return @allow_list.member?(username) if @allow_list
  return !@block_list.member?(username) if @block_list
  return true
end

#loginObject

Logs this Bot instance in to the jabber network and starts it listening for messages.

Preconditions

This method assumes that the Bot has already been properly configured; specifically, that at least the username and password properties have been set.

Postconditions

  • The Bot will be logged on,

  • Its presence will be set to ‘chat,’ and

  • It will be listening for messages from privileged users in its own

process (see is_user_allowed?)

Returns

The thread that the bot is running in. Join it if you need to.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/aide/bot.rb', line 43

def 
  if @password == nil or @username == nil
    raise Aide::Login_Error, "credentials missing"
  end
  @client = Jabber::Client.new(Jabber::JID.new(@username))
  @client.connect
  
  #actual authentication with the host
  begin
    @client.auth(@password)
  rescue Jabber::ClientAuthenticationFailure => af
    raise Aide::Login_Error, "Authentication failure: #{af.message}", af.backtrace
  end
  
  @client.send(Jabber::Presence.new)
  
  @thread = Thread.new do
    @client.add_message_callback do |m|
      if m.type == :chat and is_user_allowed? m.from.to_s.split('/')[0]
        process_message m
      end
    end
   
    loop { sleep 0.01 }
  end

end

#logoutObject

Log the bot out of jabber and kill the process that is listening for messages.



109
110
111
112
# File 'lib/aide/bot.rb', line 109

def logout
  @client.close
  @thread.kill
end

#match(text) ⇒ Object

Given the text of a message, determines if that text matches any of the actions defined for this Bot.

Parameters

  • text: String. The text of the message to check for matches.

Returns

Hash[:action_name, :message] Where :action_name corresponds to the name of the action this text matches, and :message corresponds to everything in text after the match. Returns nil if no match was found.



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/aide/bot.rb', line 125

def match(text)
  result = nil
  return result unless text
  #tokenizing the string makes it easy to check for false matches
  #e.g. match("tokentastic") shouldn't successfully match "token"
  tokens = text.split
  @actions.each do |name, block|
    ntokens = name.split
    if tokens[0...ntokens.size] == ntokens
      result = { :action_name => name, :message => text[(name.size + 1)..text.size] }
    end
  end

  result
end

#process_message(message) ⇒ Object

Examines the given message to see if any actions need to be performed on it. If this message matches any actions defined for this Bot, an Aide::ActionContext is created and used to evaluate the block associated with that action.

Parameters

  • message: Jabber::Message. The message to process.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/aide/bot.rb', line 88

def process_message(message)
  results = match(message.body)
  return nil unless results #no need to do anything if there's no match
  
  context = Aide::ActionContext.new      
  block = @actions[results[:action_name]]
  context.message = results[:message]
  context.from = message.from
  context.to = message.to
  context.bot = self
  context.text = message.body
  context.type = message.type
  context.instance_eval(&block)
  
  nil #no need to complicate things by returning the results of the block
end

#send(message) ⇒ Object

Sends the given message.

Parameters

  • message: Jabber::Message. The message to send.



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

def send(message)
  @client.send message 
end