class Del::XMPPConnection

An XMPP Connection

Attributes

configuration[R]

Public Class Methods

new(configuration:) click to toggle source
# File lib/del/xmpp_connection.rb, line 8
def initialize(configuration:)
  @configuration = configuration
  @rooms = {}
end

Public Instance Methods

connect(robot) click to toggle source
# File lib/del/xmpp_connection.rb, line 13
def connect(robot)
  record_exceptions
  connect_to_xmpp_server
  roster = discover_users
  listen_for_direct_messages(robot)
  update_status(:chat)
  discover_rooms(robot, roster)
end
deliver(jid, message) click to toggle source
# File lib/del/xmpp_connection.rb, line 22
def deliver(jid, message)
  message = Jabber::Message.new(jid, encode_string(message))
  message.type = :chat
  client.send(message)
end
deliver_to_room(jid, message) click to toggle source
# File lib/del/xmpp_connection.rb, line 28
def deliver_to_room(jid, message)
  @rooms[jid.strip.to_s]&.say(encode_string(message))
end
disconnect() click to toggle source
# File lib/del/xmpp_connection.rb, line 32
def disconnect
  Del.logger.info('byte me!')
  client.close
rescue IOError, SystemCallError => error
  Del.logger.error(error)
end
update_status(show = :chat, message: nil) click to toggle source

:chat, :away, :dnd, :xa

# File lib/del/xmpp_connection.rb, line 40
def update_status(show = :chat, message: nil)
  client.send(Jabber::Presence.new(show, message))
end

Private Instance Methods

client() click to toggle source
# File lib/del/xmpp_connection.rb, line 46
def client
  @client ||= Jabber::Client.new(jid)
end
connect_to_xmpp_server() click to toggle source
# File lib/del/xmpp_connection.rb, line 75
def connect_to_xmpp_server
  client.connect(configuration.host)
  sleep 0.0001 until client.is_connected?
  client.auth(configuration.password)
end
discover_rooms(robot, roster) click to toggle source
# File lib/del/xmpp_connection.rb, line 100
def discover_rooms(robot, roster)
  configuration.default_rooms.each do |room|
    room_jid = jid_for(room, configuration.muc_domain.dup, robot.name)
    stripped_jid = room_jid.strip.to_s
    next if @rooms[stripped_jid]

    muc = @rooms[stripped_jid] = Jabber::MUC::SimpleMUCClient.new(client)
    listen_for_room_messages(muc, room_jid, robot, roster)
  end
end
discover_users() click to toggle source
# File lib/del/xmpp_connection.rb, line 81
def discover_users
  roster = Jabber::Roster::Helper.new(client, false)
  roster.add_update_callback do |_old_item, item|
    configuration.users.upsert(item['jid'], item.attributes) if item
  end
  roster.get_roster
  roster.wait_for_roster
  roster
end
encode_string(item) click to toggle source
# File lib/del/xmpp_connection.rb, line 54
def encode_string(item)
  item.to_s.encode('UTF-8', invalid: :replace, undef: :replace)
end
find_user_with(nickname, roster) click to toggle source
# File lib/del/xmpp_connection.rb, line 121
def find_user_with(nickname, roster)
  other_jid = roster.items.find { |_jid, item| item.iname == nickname }
  user = configuration.users.find(other_jid)
  user.nil? ? User.new(other_jid[0], other_jid[1]) : user
end
jid() click to toggle source
# File lib/del/xmpp_connection.rb, line 50
def jid
  @jid ||= jid_for(configuration.jid, 'chat.hipchat.com', 'bot')
end
jid_for(jid, domain, resource) click to toggle source
# File lib/del/xmpp_connection.rb, line 58
def jid_for(jid, domain, resource)
  jid = Jabber::JID.new(jid)
  jid.resource = resource
  unless jid.node
    jid.node = jid.domain
    jid.domain = domain
  end
  jid
end
listen_for_direct_messages(robot) click to toggle source
# File lib/del/xmpp_connection.rb, line 91
def listen_for_direct_messages(robot)
  client.add_message_callback do |message|
    next if message.type == :error || message.body.nil?

    user = configuration.users.find(message.from.strip)
    robot.receive(message.body, source: Source.new(user: user))
  end
end
listen_for_room_messages(multi_user_chat, room_jid, robot, roster) click to toggle source
# File lib/del/xmpp_connection.rb, line 111
def listen_for_room_messages(multi_user_chat, room_jid, robot, roster)
  multi_user_chat.on_message do |_, nickname, message|
    Del.logger.debug([nickname, message].inspect)
    user = find_user_with(nickname, roster)
    source = Source.new(user: user, room: room_jid.strip.to_s)
    robot.receive(message, source: source)
  end
  multi_user_chat.join(room_jid)
end
record_exceptions() click to toggle source
# File lib/del/xmpp_connection.rb, line 68
def record_exceptions
  client.on_exception do |error, _connection, _error_source|
    Del.logger.error(error)
    disconnect
  end
end