hipbot 0.2.0 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/Gemfile +1 -0
- data/Gemfile.lock +15 -0
- data/README.md +28 -20
- data/hipbot.gemspec +2 -2
- data/lib/hipbot.rb +1 -0
- data/lib/hipbot/adapters/hipchat/connection.rb +46 -41
- data/lib/hipbot/adapters/hipchat/hipchat.rb +1 -1
- data/lib/hipbot/adapters/telnet/connection.rb +4 -5
- data/lib/hipbot/bot.rb +61 -48
- data/lib/hipbot/collection.rb +34 -9
- data/lib/hipbot/configuration.rb +15 -7
- data/lib/hipbot/helpers.rb +10 -4
- data/lib/hipbot/logger.rb +0 -4
- data/lib/hipbot/match.rb +48 -0
- data/lib/hipbot/message.rb +13 -13
- data/lib/hipbot/patches/hipchat_client.rb +50 -12
- data/lib/hipbot/plugin.rb +24 -5
- data/lib/hipbot/reactable.rb +27 -42
- data/lib/hipbot/reaction.rb +33 -34
- data/lib/hipbot/response.rb +14 -11
- data/lib/hipbot/room.rb +4 -11
- data/lib/hipbot/user.rb +8 -2
- data/lib/hipbot/version.rb +1 -1
- data/spec/integration/hipbot_spec.rb +96 -68
- data/spec/integration/my_hipbot.rb +104 -0
- data/spec/spec_helper.rb +3 -2
- data/spec/unit/hipbot_spec.rb +45 -34
- data/spec/unit/message_spec.rb +17 -18
- metadata +10 -5
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -6,7 +6,14 @@ GEM
|
|
6
6
|
multi_json (~> 1.0)
|
7
7
|
addressable (2.3.3)
|
8
8
|
coderay (1.0.9)
|
9
|
+
colorize (0.5.8)
|
9
10
|
cookiejar (0.3.0)
|
11
|
+
coveralls (0.6.7)
|
12
|
+
colorize
|
13
|
+
multi_json (~> 1.3)
|
14
|
+
rest-client
|
15
|
+
simplecov (>= 0.7)
|
16
|
+
thor
|
10
17
|
daemons (1.1.9)
|
11
18
|
diff-lcs (1.2.2)
|
12
19
|
em-http-request (1.0.3)
|
@@ -37,6 +44,7 @@ GEM
|
|
37
44
|
lumberjack (1.0.3)
|
38
45
|
metaclass (0.0.1)
|
39
46
|
method_source (0.8.1)
|
47
|
+
mime-types (1.23)
|
40
48
|
mocha (0.13.3)
|
41
49
|
metaclass (~> 0.0.1)
|
42
50
|
multi_json (1.7.2)
|
@@ -46,6 +54,8 @@ GEM
|
|
46
54
|
method_source (~> 0.8)
|
47
55
|
slop (~> 3.4)
|
48
56
|
rake (10.0.4)
|
57
|
+
rest-client (1.6.7)
|
58
|
+
mime-types (>= 1.16)
|
49
59
|
rspec (2.13.0)
|
50
60
|
rspec-core (~> 2.13.0)
|
51
61
|
rspec-expectations (~> 2.13.0)
|
@@ -54,6 +64,10 @@ GEM
|
|
54
64
|
rspec-expectations (2.13.0)
|
55
65
|
diff-lcs (>= 1.1.3, < 2.0)
|
56
66
|
rspec-mocks (2.13.0)
|
67
|
+
simplecov (0.7.1)
|
68
|
+
multi_json (~> 1.0)
|
69
|
+
simplecov-html (~> 0.7.1)
|
70
|
+
simplecov-html (0.7.1)
|
57
71
|
slop (3.4.4)
|
58
72
|
thor (0.18.1)
|
59
73
|
xmpp4r (0.5)
|
@@ -63,6 +77,7 @@ PLATFORMS
|
|
63
77
|
|
64
78
|
DEPENDENCIES
|
65
79
|
activesupport
|
80
|
+
coveralls
|
66
81
|
daemons
|
67
82
|
em-http-request
|
68
83
|
eventmachine
|
data/README.md
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
[![Build Status](https://secure.travis-ci.org/pewniak747/hipbot.png?branch=master)](http://travis-ci.org/pewniak747/hipbot)
|
4
4
|
[![Code Climate](https://codeclimate.com/github/pewniak747/hipbot.png)](https://codeclimate.com/github/pewniak747/hipbot)
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/pewniak747/hipbot/badge.png?branch=master)](https://coveralls.io/r/pewniak747/hipbot)
|
6
|
+
[![Dependency Status](https://gemnasium.com/pewniak747/hipbot.png)](https://gemnasium.com/pewniak747/hipbot)
|
7
|
+
[![Gem Version](https://badge.fury.io/rb/hipbot.png)](http://badge.fury.io/rb/hipbot)
|
5
8
|
|
6
9
|
Hipbot is a XMPP bot for HipChat, written in ruby & eventmachine.
|
7
10
|
|
@@ -17,7 +20,7 @@ gem install hipbot
|
|
17
20
|
|
18
21
|
Create `bot.rb` file, subclass `Hipbot::Bot` and customize the responses.
|
19
22
|
|
20
|
-
```
|
23
|
+
```ruby
|
21
24
|
require 'hipbot'
|
22
25
|
|
23
26
|
class MyCompanyBot < Hipbot::Bot
|
@@ -27,7 +30,6 @@ class MyCompanyBot < Hipbot::Bot
|
|
27
30
|
c.password = 'secret' # required
|
28
31
|
c.teams = { vip: ['John', 'Mike'] }
|
29
32
|
c.rooms = { project_rooms: ['Project 1', 'Project 2'] }
|
30
|
-
c.plugins = [ PluginClass ]
|
31
33
|
end
|
32
34
|
|
33
35
|
on /^hello/ do
|
@@ -49,7 +51,9 @@ class MyCompanyBot < Hipbot::Bot
|
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
52
|
-
class PluginClass
|
54
|
+
class PluginClass
|
55
|
+
include Hipbot::Plugin
|
56
|
+
|
53
57
|
on /^plugin/ do
|
54
58
|
reply('this is from plugin!')
|
55
59
|
end
|
@@ -60,7 +64,7 @@ MyCompanyBot.start!
|
|
60
64
|
|
61
65
|
You can create a response by providing simple regexp:
|
62
66
|
|
63
|
-
```
|
67
|
+
```ruby
|
64
68
|
on /^hello/ do
|
65
69
|
reply('hello!')
|
66
70
|
end
|
@@ -68,7 +72,7 @@ end
|
|
68
72
|
|
69
73
|
Responses can pass arguments from regexps:
|
70
74
|
|
71
|
-
```
|
75
|
+
```ruby
|
72
76
|
on /my name is (.*)/ do |user_name|
|
73
77
|
reply('hello #{user_name}!')
|
74
78
|
end
|
@@ -76,7 +80,7 @@ end
|
|
76
80
|
|
77
81
|
Define multiple regexps for a response:
|
78
82
|
|
79
|
-
```
|
83
|
+
```ruby
|
80
84
|
on /my name is (.*)/, /I am (.*)/ do |name|
|
81
85
|
reply('hello #{user_name}!')
|
82
86
|
end
|
@@ -84,7 +88,7 @@ end
|
|
84
88
|
|
85
89
|
Use :from to only match messages from certain users or user groups defined in configuration
|
86
90
|
|
87
|
-
```
|
91
|
+
```ruby
|
88
92
|
configure do |c|
|
89
93
|
# ...
|
90
94
|
c.teams = { vip: ['John', 'Mike'] }
|
@@ -97,7 +101,7 @@ end
|
|
97
101
|
|
98
102
|
Use :room to only match messages in certain hipchat rooms
|
99
103
|
|
100
|
-
```
|
104
|
+
```ruby
|
101
105
|
configure do |c|
|
102
106
|
# ...
|
103
107
|
c.rooms = { project_rooms: ['Project 1', 'Project 2'] }
|
@@ -110,7 +114,7 @@ end
|
|
110
114
|
|
111
115
|
Use :global to react to messages that are not sent directly to @robot
|
112
116
|
|
113
|
-
```
|
117
|
+
```ruby
|
114
118
|
on /hey I just met you/, global: true do
|
115
119
|
reply('and this is crazy...')
|
116
120
|
end
|
@@ -124,7 +128,7 @@ For more examples, check out (https://github.com/pewniak747/hipbot/tree/master/e
|
|
124
128
|
|
125
129
|
Use http helpers (`get`, `post`, `put`, `delete`) to preform a http request:
|
126
130
|
|
127
|
-
```
|
131
|
+
```ruby
|
128
132
|
on /curl (\S+)/ do |url|
|
129
133
|
get url do |response|
|
130
134
|
reply(response.code)
|
@@ -134,7 +138,7 @@ on /curl (\S+)/ do |url|
|
|
134
138
|
end
|
135
139
|
```
|
136
140
|
|
137
|
-
```
|
141
|
+
```ruby
|
138
142
|
on /ping site/ do
|
139
143
|
get 'http://example.com', ping: "1" # issues http://example.com?ping=1
|
140
144
|
end
|
@@ -149,7 +153,7 @@ Inside response you have access to following variables:
|
|
149
153
|
|
150
154
|
You can define your own helpers and use them inside responses like this:
|
151
155
|
|
152
|
-
```
|
156
|
+
```ruby
|
153
157
|
module HipbotHelpers
|
154
158
|
def project_name
|
155
159
|
"#{room.name}-project"
|
@@ -170,10 +174,11 @@ end
|
|
170
174
|
|
171
175
|
#### Plugins
|
172
176
|
|
173
|
-
To define a plugin,
|
177
|
+
To define a plugin, include `Hipbot::Plugin` and add responses like in bot:
|
174
178
|
|
175
|
-
```
|
176
|
-
class GreeterPlugin
|
179
|
+
```ruby
|
180
|
+
class GreeterPlugin
|
181
|
+
include Hipbot::Plugin
|
177
182
|
on /^hello/ do
|
178
183
|
reply('hello there!')
|
179
184
|
end
|
@@ -182,12 +187,11 @@ end
|
|
182
187
|
|
183
188
|
You can gain access to plugin data inside reaction with `plugin` helper:
|
184
189
|
|
185
|
-
```
|
186
|
-
class GreeterPlugin
|
190
|
+
```ruby
|
191
|
+
class GreeterPlugin
|
192
|
+
include Hipbot::Plugin
|
193
|
+
|
187
194
|
attr_accessor :language
|
188
|
-
def initialize(language)
|
189
|
-
self.language = language
|
190
|
-
end
|
191
195
|
|
192
196
|
on /^hello/ do
|
193
197
|
case plugin.language
|
@@ -200,6 +204,10 @@ class GreeterPlugin < Hipbot::Plugin
|
|
200
204
|
end
|
201
205
|
end
|
202
206
|
end
|
207
|
+
|
208
|
+
GreeterPlugin.configure do |c|
|
209
|
+
c.language = :jp
|
210
|
+
end
|
203
211
|
```
|
204
212
|
|
205
213
|
For a collection of open-source plugins, see https://github.com/netguru/hipbot-plugins
|
data/hipbot.gemspec
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
require File.expand_path('../lib/hipbot/version', __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
|
-
gem.authors = ["Tomasz Pewiński"]
|
6
|
-
gem.email = ["pewniak747@gmail.com"]
|
5
|
+
gem.authors = ["Bartosz Kopiński", "Tomasz Pewiński"]
|
6
|
+
gem.email = ["bartosz.kopinski@netguru.pl", "pewniak747@gmail.com"]
|
7
7
|
gem.description = "Hipbot is a bot for HipChat, written in ruby & eventmachine."
|
8
8
|
gem.summary = "Hipbot is a bot for HipChat, written in ruby & eventmachine."
|
9
9
|
gem.homepage = "http://github.com/pewniak747/hipbot"
|
data/lib/hipbot.rb
CHANGED
@@ -2,10 +2,8 @@ module Hipbot
|
|
2
2
|
module Adapters
|
3
3
|
module Hipchat
|
4
4
|
class Connection
|
5
|
-
def initialize
|
6
|
-
|
7
|
-
@bot.connection = self
|
8
|
-
|
5
|
+
def initialize
|
6
|
+
Hipbot.connection = self
|
9
7
|
setup_error_handler && setup_bot && setup_timers
|
10
8
|
end
|
11
9
|
|
@@ -15,71 +13,78 @@ module Hipbot
|
|
15
13
|
end
|
16
14
|
|
17
15
|
def send_to_room(room, message)
|
16
|
+
Hipbot.logger.info("REPLY in #{room}: #{message}")
|
18
17
|
@client.send_message(:groupchat, room.id, message)
|
19
18
|
end
|
20
19
|
|
21
20
|
def send_to_user(user, message)
|
21
|
+
Hipbot.logger.info("REPLY to #{user}: #{message}")
|
22
22
|
@client.send_message(:chat, user.id, message)
|
23
23
|
end
|
24
24
|
|
25
25
|
def set_topic(room, topic)
|
26
|
+
Hipbot.logger.info("TOPIC set in #{room} to '#{topic}'")
|
26
27
|
@client.send_message(:groupchat, room.id, nil, topic)
|
27
28
|
end
|
28
29
|
|
29
30
|
def set_presence(status = nil, type = :available)
|
31
|
+
Hipbot.logger.info("PRESENCE set to #{type} with '#{status}'")
|
30
32
|
@client.set_presence(type, nil, status)
|
31
33
|
end
|
32
34
|
|
33
|
-
|
35
|
+
protected
|
34
36
|
|
35
37
|
def setup_bot
|
36
38
|
initialize_client do
|
37
39
|
initialize_rooms
|
38
40
|
initialize_users
|
39
41
|
initialize_callbacks
|
42
|
+
set_bot_user
|
40
43
|
join_rooms
|
41
44
|
set_presence('Hello humans!')
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
45
48
|
def initialize_client
|
46
|
-
@client = ::Jabber::MUC::HipchatClient.new(
|
47
|
-
yield if @client.connect(
|
49
|
+
@client = ::Jabber::MUC::HipchatClient.new(Hipbot.jid)
|
50
|
+
yield if @client.connect(Hipbot.password)
|
48
51
|
end
|
49
52
|
|
50
53
|
def initialize_rooms
|
51
|
-
@client.get_rooms.each do |
|
52
|
-
Room.
|
54
|
+
@client.get_rooms.each do |room_data|
|
55
|
+
room = Room.find_or_create_by(id: room_data[:item].jid.to_s)
|
56
|
+
room.update_attributes({
|
57
|
+
name: room_data[:item].iname,
|
58
|
+
topic: room_data[:details]['topic'],
|
59
|
+
})
|
53
60
|
end
|
54
|
-
true
|
55
61
|
end
|
56
62
|
|
57
63
|
def initialize_users
|
58
|
-
@client.get_users.each do |
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
User.create(v[:item].jid, v[:item].iname, params)
|
64
|
+
@client.get_users.each do |user_data|
|
65
|
+
user = User.find_or_create_by(id: user_data.delete(:jid))
|
66
|
+
user.update_attributes(user_data)
|
67
|
+
|
68
|
+
if user.attributes['email'].nil?
|
69
|
+
user.update_attributes(@client.get_user_details(user.id))
|
70
|
+
end
|
66
71
|
end
|
67
|
-
|
72
|
+
end
|
73
|
+
|
74
|
+
def set_bot_user
|
75
|
+
Hipbot.configuration.user = User[Hipbot.jid]
|
76
|
+
@client.name = Hipbot.user
|
68
77
|
end
|
69
78
|
|
70
79
|
def join_rooms
|
71
|
-
with_rooms do |
|
72
|
-
|
73
|
-
@client.join(r.id)
|
74
|
-
end
|
80
|
+
with_rooms do |room|
|
81
|
+
@client.join(room.id)
|
75
82
|
end
|
76
83
|
end
|
77
84
|
|
78
85
|
def exit_all_rooms
|
79
|
-
with_rooms do |
|
80
|
-
|
81
|
-
@client.exit(r.id, 'bye bye!')
|
82
|
-
end
|
86
|
+
with_rooms do |room|
|
87
|
+
@client.exit(room.id, 'bye bye!')
|
83
88
|
end
|
84
89
|
end
|
85
90
|
|
@@ -93,40 +98,40 @@ module Hipbot
|
|
93
98
|
|
94
99
|
def message_callback room_jid, user_name, message
|
95
100
|
with_sender(room_jid, user_name) do |room, user|
|
96
|
-
room.
|
97
|
-
return if user_name ==
|
98
|
-
|
101
|
+
room.update_attribute(:topic, message.subject) if message.subject.present?
|
102
|
+
return if user_name == Hipbot.name || message.body.blank?
|
103
|
+
Hipbot.react(user, room, message.body)
|
99
104
|
end
|
100
105
|
end
|
101
106
|
|
102
107
|
def invite_callback room_jid, user_name, room_name, topic
|
103
|
-
Room.create(room_jid, room_name, topic: topic)
|
108
|
+
Room.create(id: room_jid, name: room_name, topic: topic)
|
104
109
|
@client.join(room_jid)
|
105
110
|
end
|
106
111
|
|
107
112
|
def presence_callback room_jid, user_name, pres
|
108
113
|
with_sender(room_jid, user_name) do |room, user|
|
109
114
|
if pres == 'unavailable'
|
110
|
-
if user_name ==
|
115
|
+
if user_name == Hipbot.name
|
111
116
|
room.delete
|
112
117
|
elsif user.present?
|
113
|
-
room.
|
118
|
+
room.users.delete(user)
|
114
119
|
end
|
115
|
-
elsif pres.blank? && room.
|
116
|
-
room.
|
120
|
+
elsif pres.blank? && room.users.exclude?(user)
|
121
|
+
room.users << user
|
117
122
|
end
|
118
123
|
end
|
119
124
|
end
|
120
125
|
|
121
126
|
def private_message_callback user_jid, message
|
122
127
|
with_user(user_jid) do |user|
|
123
|
-
|
128
|
+
Hipbot.react(user, nil, message.body) if user.name != Hipbot.name
|
124
129
|
end if message.body.present?
|
125
130
|
end
|
126
131
|
|
127
132
|
def with_rooms
|
128
|
-
return
|
129
|
-
yield
|
133
|
+
return Hipbot.logger.error 'No rooms found' if Room.empty?
|
134
|
+
Room.each{ |room| yield room }
|
130
135
|
end
|
131
136
|
|
132
137
|
def with_sender room_id, user_id
|
@@ -143,15 +148,15 @@ module Hipbot
|
|
143
148
|
|
144
149
|
def setup_timers
|
145
150
|
::EM::add_periodic_timer(60) do
|
146
|
-
@client.keep_alive(
|
151
|
+
@client.keep_alive(Hipbot.password) if @client.present?
|
147
152
|
end
|
148
153
|
end
|
149
154
|
|
150
155
|
def setup_error_handler
|
151
156
|
::EM.error_handler do |e|
|
152
|
-
|
157
|
+
Hipbot.logger.error e.inspect
|
153
158
|
e.backtrace.each do |line|
|
154
|
-
|
159
|
+
Hipbot.logger.error line
|
155
160
|
end
|
156
161
|
end
|
157
162
|
end
|
@@ -2,14 +2,13 @@ module Hipbot
|
|
2
2
|
module Adapters
|
3
3
|
module Telnet
|
4
4
|
class Connection < EM::Connection
|
5
|
-
def initialize
|
6
|
-
|
7
|
-
@bot.connection = self
|
5
|
+
def initialize
|
6
|
+
Hipbot.connection = self
|
8
7
|
end
|
9
8
|
|
10
9
|
def receive_data(data)
|
11
|
-
sender, room, message =
|
12
|
-
|
10
|
+
sender, room, message = data.strip.split(':')
|
11
|
+
Hipbot.react(sender, room, message)
|
13
12
|
end
|
14
13
|
end
|
15
14
|
end
|