hipbot 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|