lib/hipbot/adapters/hipchat/connection.rb in hipbot-0.0.5 vs lib/hipbot/adapters/hipchat/connection.rb in hipbot-0.1.0
- old
+ new
@@ -1,123 +1,156 @@
module Hipbot
module Adapters
module Hipchat
class Connection
def initialize bot
- initialize_bot(bot)
- initialize_jabber
- initialize_rooms
- join_rooms
+ @bot = bot
+ @bot.connection = self
+
+ return unless setup_bot
setup_timers
end
- def reply room, message
- send_message(room, message)
+ def restart!
+ exit_all_rooms # TODO: Nice quit
+ setup_bot
end
- def restart!
- leave_rooms
- initialize_jabber
+ def send_to_room(room, message)
+ @client.send_message(:groupchat, room.id, message)
+ end
+
+ def send_to_user(user, message)
+ @client.send_message(:chat, user.id, message)
+ end
+
+ def set_topic(room, topic)
+ @client.send_message(:groupchat, room.id, nil, topic)
+ end
+
+ def set_presence(status = nil, type = :available)
+ @client.set_presence(type, nil, status)
+ end
+
+ private
+
+ def setup_bot
+ return unless initialize_client
initialize_rooms
+ initialize_users
+ initialize_callbacks
join_rooms
+ set_presence('Hello humans!')
+ true
end
- private
+ def initialize_client
+ ::Jabber.debug = true
+ @client = ::Jabber::MUC::HipchatClient.new(@bot.jid + '/' + @bot.name)
+ @client.connect(@bot.password)
+ end
def initialize_rooms
- @muc_browser = Jabber::MUC::MUCBrowser.new(@jabber)
- @rooms = @muc_browser.muc_rooms('conf.hipchat.com').map { |jid, name|
- ::Hipbot::Room.new(jid, name)
- }
+ Room.bot = @bot
+ @client.get_rooms.each do |r|
+ Room.create(r[:item].jid, r[:item].iname, topic: r[:details]['topic'])
+ end
+ true
end
- def initialize_bot bot
- @bot = bot
- @bot.connection = self
+ def initialize_users
+ User.bot = @bot
+ @client.get_users.each do |v|
+ params = {
+ email: v[:vcard]['EMAIL/USERID'],
+ mention: v[:item].attributes['mention_name'],
+ title: v[:vcard]['TITLE'],
+ photo: v[:vcard]['PHOTO'],
+ }
+ User.create(v[:item].jid, v[:item].iname, params)
+ end
+ true
end
- def initialize_jabber
- @jabber ||= ::Jabber::Client.new(@bot.jid)
- @jabber.connect
- @jabber.auth(@bot.password)
- @jabber.send(::Jabber::Presence.new.set_type(:available))
+ def join_rooms
+ if Room.empty?
+ Jabber::debuglog "No rooms to join"
+ return false
+ end
+ Room.each do |room_jid, _|
+ @client.join(room_jid)
+ end
+ true
end
- def join_rooms
- rooms.each do |room|
- puts "Joining #{room.name}"
+ def exit_all_rooms
+ Room.each do |room_jid, _|
+ @client.exit(room_jid, 'bye bye!')
+ end
+ end
- # TODO rewrite (Simple)MUCClient to handle many rooms from one object
- # as there is no need to create distinct objects and callback for each
- # room since all of them have to process same data from @jabber stream.
- # We probably should be able to do something like this:
- # @jabber.set_presence([room1, room2], :available)
- # @jabber.on_event do |time, jid, message| # JID includes sender and room/chat
- # @jabber.send(jid, message)
- room.connection = ::Jabber::MUC::SimpleMUCClient.new(@jabber)
- room.connection.on_message do |time, sender, message|
- puts "#{room.name} > #{time} <#{sender}> #{message}"
- begin
- @bot.tell(sender, room, message)
- rescue => e
- puts e.inspect
- e.backtrace.each do |line|
- puts line
- end
+ def initialize_callbacks
+ @client.on_message do |room_jid, user_name, message|
+ room = Room[room_jid]
+ user = User[user_name]
+ next if room.nil? && user.nil?
+ room.params.topic = message.subject if message.subject.present?
+ next if user_name == @bot.name || message.body.blank?
+ Jabber::debuglog "[#{Time.now}] <#{room.name}> #{user_name}: #{message.body}"
+ begin
+ @bot.react(user, room, message.body)
+ rescue => e
+ Jabber::debuglog e.inspect
+ e.backtrace.each do |line|
+ Jabber::debuglog line
end
end
+ end
- # TODO Get and store all user data from HipChat API
- room.users = []
- room.connection.on_join do |time, nick|
- room.users << nick
+ @client.on_private_message do |user_jid, message|
+ user = User[user_jid]
+ next if user.blank? || user.name == @bot.name
+ if message.body.nil?
+ # if message.active?
+ # elsif message.inactive?
+ # elsif message.composing?
+ # elsif message.gone?
+ # elsif message.paused?
+ # end
+ else
+ @bot.react(user, nil, message.body)
end
- room.connection.on_leave do |time, nick|
- room.users.delete(nick)
- end
- room.connection.join("#{room.jid}/#{@bot.name}", nil, :history => false)
end
- # TODO handle sending private messages with 'reply'.
- # Simplest way is to add room object for each private chat with param
- # to distinguish whether to use conf or chat domain
- # rooms.first.connection.on_private_message do |time, jid, message|
- # send_message rooms.first, 'hello!', jid
+ @client.on_invite do |room_jid, user_name, room_name, topic|
+ Room.create(room_jid, room_name, topic: topic)
+ @client.join(room_jid)
+ end
- ## Alternative sending:
- # msg = ::Jabber::Message.new(jid, 'hello!')
- # msg.type = :chat
- # @jabber.send(msg)
+ @client.on_presence do |room_jid, user_name, pres|
+ room = Room[room_jid]
+ next if room.blank? || user_name.blank?
+ user = User[user_name]
+ if pres == 'unavailable'
+ if user_name == @bot.name
+ room.delete
+ elsif user.present?
+ room.user_ids.delete(user.id)
+ end
+ elsif pres.blank? && user.present? && room.user_ids.exclude?(user.id)
+ room.user_ids << user.id
+ end
+ end
- ## We can trigger normal message callback but 'reply' won't work since hipchat PM uses
- ## different jid (user_room@chat.hipchat.com/client_name)
- # rooms.first.connection.message_block.call(time, sender, message)
- # end
+ @client.activate_callbacks
end
- def leave_rooms
- rooms.each do |room|
- puts "Leaving #{room.name}"
- room.connection.exit
- end
- end
-
def setup_timers
- ::EM::add_periodic_timer(10) {
- if !@jabber.nil? && @jabber.is_disconnected?
- initialize_jabber
- join_rooms
- end
+ ::EM::add_periodic_timer(60) {
+ @client.keep_alive(@bot.password) if @client.present?
}
end
- def send_message room, message, jid = nil
- room.connection.say(message, jid)
- end
-
- def rooms
- @rooms || []
- end
end
end
end
end