hipbot 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +3 -3
- data/Gemfile +12 -1
- data/README.md +16 -8
- data/bin/hipbot +5 -0
- data/hipbot.gemspec +2 -1
- data/lib/hipbot.rb +7 -10
- data/lib/hipbot/adaptable.rb +60 -0
- data/lib/hipbot/adapter.rb +6 -6
- data/lib/hipbot/adapters/hipchat.rb +5 -48
- data/lib/hipbot/adapters/hipchat/client.rb +8 -0
- data/lib/hipbot/adapters/shell.rb +2 -9
- data/lib/hipbot/adapters/slack.rb +10 -0
- data/lib/hipbot/adapters/slack/client.rb +47 -0
- data/lib/hipbot/adapters/telnet.rb +2 -9
- data/lib/hipbot/adapters/xmpp.rb +59 -0
- data/lib/hipbot/adapters/{hipchat/initializer.rb → xmpp/client.rb} +35 -21
- data/lib/hipbot/bot.rb +5 -1
- data/lib/hipbot/callbacks/base.rb +20 -2
- data/lib/hipbot/callbacks/lobby_presence.rb +2 -1
- data/lib/hipbot/callbacks/presence.rb +1 -5
- data/lib/hipbot/callbacks/room_invite.rb +13 -0
- data/lib/hipbot/callbacks/room_message.rb +3 -9
- data/lib/hipbot/callbacks/room_presence.rb +10 -8
- data/lib/hipbot/callbacks/room_topic.rb +18 -0
- data/lib/hipbot/configuration.rb +11 -6
- data/lib/hipbot/helpers.rb +2 -0
- data/lib/hipbot/{http.rb → helpers/http.rb} +11 -7
- data/lib/hipbot/message.rb +2 -2
- data/lib/hipbot/presence.rb +0 -6
- data/lib/hipbot/reaction.rb +9 -7
- data/lib/hipbot/response.rb +1 -1
- data/lib/hipbot/room.rb +1 -1
- data/lib/hipbot/storages/hash.rb +5 -5
- data/lib/hipbot/storages/mongoid.rb +1 -1
- data/lib/hipbot/user.rb +4 -0
- data/lib/hipbot/{cache.rb → utilities/cache.rb} +0 -0
- data/lib/hipbot/{logger.rb → utilities/logger.rb} +0 -0
- data/lib/hipbot/version.rb +1 -1
- data/spec/integration/my_hipbot_spec.rb +1 -1
- data/spec/spec_helper.rb +7 -2
- data/spec/unit/match_spec.rb +7 -7
- data/spec/unit/message_spec.rb +2 -2
- data/spec/unit/reaction_spec.rb +14 -14
- metadata +28 -8
- data/lib/hipbot/callbacks/invite.rb +0 -11
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'hipbot/adapters/xmpp/client'
|
2
|
+
|
3
|
+
module Hipbot
|
4
|
+
module Adapters
|
5
|
+
class XMPP
|
6
|
+
include Hipbot::Adaptable
|
7
|
+
|
8
|
+
add_config_options :jid, :conference_host
|
9
|
+
|
10
|
+
attr_accessor :client
|
11
|
+
|
12
|
+
def start!
|
13
|
+
self.client = self.class::Client.new.client
|
14
|
+
end
|
15
|
+
|
16
|
+
def restart!
|
17
|
+
start!
|
18
|
+
end
|
19
|
+
|
20
|
+
def invite_to_room(room, users)
|
21
|
+
client.invite(user_ids(users), room.id)
|
22
|
+
end
|
23
|
+
|
24
|
+
def kick_from_room(room, users)
|
25
|
+
client.kick(user_ids(users), room.id)
|
26
|
+
end
|
27
|
+
|
28
|
+
def send_to_room(room, message)
|
29
|
+
client.send_message(:groupchat, room.id, message)
|
30
|
+
end
|
31
|
+
|
32
|
+
def send_to_user(user, message)
|
33
|
+
client.send_message(:chat, user.id, message)
|
34
|
+
end
|
35
|
+
|
36
|
+
def set_topic(room, topic)
|
37
|
+
client.send_message(:groupchat, room.id, nil, topic)
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_presence(status, type)
|
41
|
+
client.set_presence(status, type)
|
42
|
+
end
|
43
|
+
|
44
|
+
def join_room(room)
|
45
|
+
client.join(room.id)
|
46
|
+
end
|
47
|
+
|
48
|
+
def leave_room(room, reason = '')
|
49
|
+
client.exit(room.id, reason)
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
def user_ids users
|
55
|
+
Array(users).map(&:id)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -1,41 +1,52 @@
|
|
1
|
+
require 'xmpp4r-hipchat'
|
2
|
+
|
1
3
|
module Hipbot
|
2
4
|
module Adapters
|
3
|
-
class
|
4
|
-
class
|
5
|
+
class XMPP
|
6
|
+
class Client
|
5
7
|
attr_accessor :client
|
6
8
|
|
7
9
|
KEEP_ALIVE_INTERVAL = 60
|
8
10
|
|
9
11
|
def initialize
|
10
|
-
|
11
|
-
|
12
|
+
initialize_logger
|
13
|
+
|
14
|
+
Hipbot.logger.info("INITIALIZE XMPP Client")
|
12
15
|
initialize_client do
|
16
|
+
Hipbot.logger.info("INITIALIZE Rooms")
|
13
17
|
initialize_rooms
|
18
|
+
Hipbot.logger.info("INITIALIZE Users")
|
14
19
|
initialize_users
|
20
|
+
Hipbot.logger.info("INITIALIZE Bot user")
|
15
21
|
initialize_bot_user
|
22
|
+
Hipbot.logger.info("INITIALIZE Callbacks")
|
16
23
|
initialize_callbacks
|
24
|
+
Hipbot.logger.info("INITIALIZE Keep-alive")
|
17
25
|
initialize_keep_alive
|
18
26
|
end
|
19
27
|
end
|
20
28
|
|
21
29
|
protected
|
22
30
|
|
31
|
+
def initialize_logger
|
32
|
+
Jabber.logger = Hipbot.logger
|
33
|
+
if Hipbot.logger.level == Logger::DEBUG
|
34
|
+
Jabber.debug = true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
23
38
|
def initialize_client
|
24
|
-
self.client = ::Jabber::MUC::HipchatClient.new(
|
25
|
-
|
39
|
+
self.client = ::Jabber::MUC::HipchatClient.new(
|
40
|
+
Hipbot.configuration.jid,
|
41
|
+
Hipbot.configuration.conference_host,
|
42
|
+
)
|
43
|
+
yield if client.connect(Hipbot.configuration.password)
|
26
44
|
end
|
27
45
|
|
28
46
|
def initialize_rooms
|
29
47
|
room_ids = client.get_rooms.map do |room_data|
|
30
|
-
room = Room.find_or_create_by(id: room_data
|
31
|
-
room.update_attributes(
|
32
|
-
name: room_data[:item].iname,
|
33
|
-
topic: room_data[:details]['topic'],
|
34
|
-
privacy: room_data[:details]['privacy'],
|
35
|
-
hipchat_id: room_data[:details]['id'],
|
36
|
-
archived: room_data[:details].has_key?('is_archived'),
|
37
|
-
guest_url: room_data[:details]['guest_url'],
|
38
|
-
)
|
48
|
+
room = Room.find_or_create_by(id: room_data.id)
|
49
|
+
room.update_attributes(room_data.attributes)
|
39
50
|
room.id
|
40
51
|
end
|
41
52
|
clean_other_objects(Room, room_ids) if room_ids.any?
|
@@ -43,11 +54,11 @@ module Hipbot
|
|
43
54
|
|
44
55
|
def initialize_users
|
45
56
|
user_ids = client.get_users.map do |user_data|
|
46
|
-
user = User.find_or_create_by(id: user_data.
|
47
|
-
user.update_attributes(user_data)
|
57
|
+
user = User.find_or_create_by(id: user_data.id)
|
58
|
+
user.update_attributes(user_data.attributes)
|
48
59
|
|
49
60
|
if user.attributes['email'].nil?
|
50
|
-
user.update_attributes(client.get_user_details(user.id))
|
61
|
+
user.update_attributes(client.get_user_details(user.id).attributes)
|
51
62
|
end
|
52
63
|
user.id
|
53
64
|
end
|
@@ -55,18 +66,21 @@ module Hipbot
|
|
55
66
|
end
|
56
67
|
|
57
68
|
def clean_other_objects klass, object_ids
|
58
|
-
klass.all.select{ |r| !object_ids.include?(r.id) }.
|
69
|
+
klass.all.select{ |r| !object_ids.include?(r.id) }.tap{ |o|
|
70
|
+
Hipbot.logger.info("REMOVING #{o.count} objects from #{klass}")
|
71
|
+
}.each(&:destroy)
|
59
72
|
end
|
60
73
|
|
61
74
|
def initialize_bot_user
|
62
|
-
Hipbot.configuration.user = User.find(Hipbot.jid)
|
75
|
+
Hipbot.configuration.user = User.find(Jabber::JID.new(Hipbot.configuration.jid).node)
|
63
76
|
client.name = Hipbot.user.name
|
64
77
|
end
|
65
78
|
|
66
79
|
def initialize_callbacks
|
67
80
|
client.on_room_message{ |*args| Callbacks::RoomMessage.new(*args) }
|
81
|
+
client.on_room_topic{ |*args| Callbacks::RoomTopic.new(*args) }
|
68
82
|
client.on_private_message{ |*args| Callbacks::PrivateMessage.new(*args) }
|
69
|
-
client.
|
83
|
+
client.on_room_invite{ |*args| Callbacks::RoomInvite.new(*args) }
|
70
84
|
client.on_lobby_presence{ |*args| Callbacks::LobbyPresence.new(*args) }
|
71
85
|
client.on_room_presence{ |*args| Callbacks::RoomPresence.new(*args) }
|
72
86
|
client.activate_callbacks
|
data/lib/hipbot/bot.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
module Hipbot
|
2
2
|
class << self
|
3
|
-
attr_accessor :bot, :plugins
|
3
|
+
attr_accessor :bot, :plugins, :adapters
|
4
4
|
delegate :name, to: :bot
|
5
5
|
|
6
6
|
def plugins
|
7
7
|
@plugins ||= []
|
8
8
|
end
|
9
9
|
|
10
|
+
def adapters
|
11
|
+
@adapters ||= []
|
12
|
+
end
|
13
|
+
|
10
14
|
def method_missing name, *params, &block
|
11
15
|
bot.send(name, *params, &block)
|
12
16
|
end
|
@@ -4,11 +4,29 @@ module Hipbot
|
|
4
4
|
protected
|
5
5
|
|
6
6
|
def with_room params
|
7
|
-
yield Room.find_or_create_by(params)
|
7
|
+
yield Room.find_or_create_by(params) if valid_params?(params)
|
8
8
|
end
|
9
9
|
|
10
10
|
def with_user params
|
11
|
-
yield User.find_or_create_by(params)
|
11
|
+
yield User.find_or_create_by(params) if valid_params?(params)
|
12
|
+
end
|
13
|
+
|
14
|
+
def with_user_by_name_or_mention name_or_mention
|
15
|
+
return if !valid_value?(name_or_mention)
|
16
|
+
|
17
|
+
yield User.where(mention: name_or_mention).first ||
|
18
|
+
User.where(name: name_or_mention).first ||
|
19
|
+
User.create(name: name_or_mention, mention: name_or_mention)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def valid_params? params
|
25
|
+
params.any?{ |_, v| valid_value?(v) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def valid_value? value
|
29
|
+
!value.nil? && value.present?
|
12
30
|
end
|
13
31
|
end
|
14
32
|
end
|
@@ -5,7 +5,8 @@ module Hipbot
|
|
5
5
|
self.presence = presence
|
6
6
|
|
7
7
|
with_user(id: user_id) do |user|
|
8
|
-
|
8
|
+
Hipbot.logger.info("PRESENCE from #{user}: #{presence}")
|
9
|
+
user.update_attribute(:is_online, !offline_presence?)
|
9
10
|
end
|
10
11
|
end
|
11
12
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Hipbot
|
2
|
+
module Callbacks
|
3
|
+
class RoomInvite < Base
|
4
|
+
def initialize room_id, room_name
|
5
|
+
return unless Hipbot.configuration.join_on_invite
|
6
|
+
|
7
|
+
with_room(id: room_id, name: room_name) do |room|
|
8
|
+
Hipbot.join_room(room)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,21 +1,15 @@
|
|
1
1
|
module Hipbot
|
2
2
|
module Callbacks
|
3
3
|
class RoomMessage < Message
|
4
|
-
def initialize room_id,
|
4
|
+
def initialize room_id, user_name_or_mention, message_body
|
5
5
|
with_room(id: room_id) do |room|
|
6
|
-
|
7
|
-
with_user(name: user_name) do |user|
|
6
|
+
with_user_by_name_or_mention(user_name_or_mention) do |user|
|
8
7
|
return if ignore_message?(user, message_body)
|
8
|
+
|
9
9
|
Hipbot.react(user, room, message_body)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
14
|
-
protected
|
15
|
-
|
16
|
-
def update_topic room, topic
|
17
|
-
room.update_attribute(:topic, topic) unless topic.empty?
|
18
|
-
end
|
19
13
|
end
|
20
14
|
end
|
21
15
|
end
|
@@ -1,12 +1,13 @@
|
|
1
1
|
module Hipbot
|
2
2
|
module Callbacks
|
3
3
|
class RoomPresence < Presence
|
4
|
-
attr_accessor :room_id, :
|
4
|
+
attr_accessor :room_id, :user_name_or_mention
|
5
|
+
|
6
|
+
def initialize room_id, user_name_or_mention, presence, role
|
7
|
+
self.room_id = room_id
|
8
|
+
self.user_name_or_mention = user_name_or_mention
|
9
|
+
self.presence = presence
|
5
10
|
|
6
|
-
def initialize room_id, user_name, presence
|
7
|
-
self.presence = presence
|
8
|
-
self.user_name = user_name
|
9
|
-
self.room_id = room_id
|
10
11
|
handle_room_presence
|
11
12
|
end
|
12
13
|
|
@@ -14,13 +15,14 @@ module Hipbot
|
|
14
15
|
|
15
16
|
def handle_room_presence
|
16
17
|
with_room(id: room_id) do |room|
|
17
|
-
|
18
|
+
with_user_by_name_or_mention(user_name_or_mention) do |user|
|
19
|
+
Hipbot.logger.info("PRESENCE in ##{room} from #{user}: #{presence}")
|
18
20
|
Hipbot.react_to_presence(user, presence, room)
|
21
|
+
|
19
22
|
if offline_presence?
|
20
23
|
room.on_leave(user)
|
21
|
-
elsif online_presence? && !room.users.include?(user)
|
22
|
-
room.on_join(user)
|
23
24
|
else
|
25
|
+
room.on_join(user) if !room.users.include?(user)
|
24
26
|
# TODO: Availability status change handling
|
25
27
|
end
|
26
28
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Hipbot
|
2
|
+
module Callbacks
|
3
|
+
class RoomTopic < Message
|
4
|
+
def initialize room_id, topic
|
5
|
+
with_room(id: room_id) do |room|
|
6
|
+
Hipbot.logger.info("TOPIC in ##{room}: #{topic}")
|
7
|
+
update_topic(room, topic)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def update_topic room, topic
|
14
|
+
room.update_attribute(:topic, topic)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/hipbot/configuration.rb
CHANGED
@@ -1,24 +1,29 @@
|
|
1
1
|
module Hipbot
|
2
2
|
class Configuration
|
3
3
|
OPTIONS = [
|
4
|
-
:adapter, :
|
5
|
-
:plugins, :preloader, :rooms, :status, :storage, :teams, :user
|
4
|
+
:adapter, :case_insensitive, :exception_handler, :helpers, :join, :join_on_invite,
|
5
|
+
:logger, :password, :plugins, :preloader, :rooms, :status, :storage, :teams, :user
|
6
6
|
]
|
7
7
|
attr_accessor *OPTIONS
|
8
8
|
|
9
9
|
def initialize
|
10
|
-
self.
|
11
|
-
|
10
|
+
self.class.class_eval do
|
11
|
+
attr_accessor *Hipbot.adapters.flat_map(&:options).compact
|
12
|
+
end
|
13
|
+
|
14
|
+
self.adapter = Adapters::Hipchat
|
15
|
+
self.case_insensitive = true
|
16
|
+
self.exception_handler = proc do |e|
|
12
17
|
Hipbot.logger.error(e.message)
|
13
18
|
e.backtrace.each { |line| Hipbot.logger.error(line) }
|
14
19
|
end
|
15
20
|
self.helpers = Module.new
|
16
|
-
self.jid = ''
|
17
21
|
self.join = :all
|
22
|
+
self.join_on_invite = true
|
18
23
|
self.logger = Logger.new($stdout)
|
19
24
|
self.password = ''
|
20
25
|
self.plugins = Hipbot.plugins
|
21
|
-
self.preloader =
|
26
|
+
self.preloader = proc {}
|
22
27
|
self.rooms = {}
|
23
28
|
self.status = ''
|
24
29
|
self.storage = Storages::Hash
|
data/lib/hipbot/helpers.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
module Hipbot
|
2
3
|
module Http
|
3
|
-
class Request < Struct.new(:url, :
|
4
|
+
class Request < Struct.new(:url, :params, :method)
|
4
5
|
DEFAULT_HEADERS = { 'accept-encoding' => 'gzip, compressed' }.freeze
|
5
6
|
CONNECTION_SETTINGS = { connect_timeout: 5, inactivity_timeout: 10 }.freeze
|
6
7
|
ERROR_CALLBACK = ->(error){ Hipbot.logger.error(error) }
|
7
8
|
|
8
9
|
def initialize *args
|
9
10
|
super
|
10
|
-
|
11
|
+
self.params ||= {}
|
12
|
+
self.params = params.has_key?(:query) ? params : { query: params }
|
13
|
+
self.params = { head: DEFAULT_HEADERS }.merge(params)
|
14
|
+
Hipbot.logger.info("HTTP-REQUEST: #{url} #{params}")
|
11
15
|
end
|
12
16
|
|
13
17
|
def call &success_block
|
@@ -21,16 +25,16 @@ module Hipbot
|
|
21
25
|
|
22
26
|
def success
|
23
27
|
yield Http::Response.new(http)
|
24
|
-
rescue => e
|
25
|
-
instance_exec(e, &Hipbot.exception_handler)
|
26
28
|
end
|
27
29
|
|
28
|
-
def http
|
29
|
-
@http ||= connection.send(method,
|
30
|
+
def http options = {}
|
31
|
+
@http ||= connection.send(method, params.merge(options))
|
32
|
+
rescue => e
|
33
|
+
instance_exec(e, &Hipbot.exception_handler)
|
30
34
|
end
|
31
35
|
|
32
36
|
def connection
|
33
|
-
EM::HttpRequest.new(url, CONNECTION_SETTINGS)
|
37
|
+
@connection ||= EM::HttpRequest.new(url, CONNECTION_SETTINGS)
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
data/lib/hipbot/message.rb
CHANGED
@@ -5,11 +5,11 @@ module Hipbot
|
|
5
5
|
|
6
6
|
attr_accessor :body
|
7
7
|
|
8
|
-
MENTION_REGEXP = /@(\p{Word}++)
|
8
|
+
MENTION_REGEXP = /@(\p{Word}++):?/.freeze
|
9
9
|
|
10
10
|
def initialize *args
|
11
11
|
super
|
12
|
-
Hipbot.logger.info("MESSAGE from #{sender} in
|
12
|
+
Hipbot.logger.info("MESSAGE from #{sender} in ##{room}")
|
13
13
|
self.raw_body = raw_body.force_encoding('UTF-8')
|
14
14
|
self.body = strip_bot_mention
|
15
15
|
end
|