hipbot 1.0.0.rc2 → 1.0.0
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 +2 -1
- data/.travis.yml +6 -0
- data/Gemfile +1 -2
- data/README.md +482 -88
- data/Rakefile +1 -1
- data/bin/hipbot +4 -4
- data/hipbot.gemspec +9 -9
- data/lib/hipbot.rb +28 -11
- data/lib/hipbot/adapter.rb +80 -0
- data/lib/hipbot/adapters/hipchat.rb +53 -0
- data/lib/hipbot/adapters/hipchat/initializer.rb +83 -0
- data/lib/hipbot/adapters/shell.rb +37 -0
- data/lib/hipbot/adapters/telnet.rb +41 -0
- data/lib/hipbot/bot.rb +15 -52
- data/lib/hipbot/cache.rb +23 -0
- data/lib/hipbot/callbacks/base.rb +15 -0
- data/lib/hipbot/callbacks/invite.rb +11 -0
- data/lib/hipbot/callbacks/lobby_presence.rb +13 -0
- data/lib/hipbot/callbacks/message.rb +11 -0
- data/lib/hipbot/callbacks/presence.rb +17 -0
- data/lib/hipbot/callbacks/private_message.rb +12 -0
- data/lib/hipbot/callbacks/room_message.rb +21 -0
- data/lib/hipbot/callbacks/room_presence.rb +28 -0
- data/lib/hipbot/configurable.rb +22 -0
- data/lib/hipbot/configuration.rb +9 -3
- data/lib/hipbot/helpers.rb +4 -40
- data/lib/hipbot/http.rb +65 -0
- data/lib/hipbot/match.rb +21 -9
- data/lib/hipbot/matchable.rb +38 -0
- data/lib/hipbot/message.rb +24 -9
- data/lib/hipbot/plugin.rb +3 -3
- data/lib/hipbot/reactable.rb +14 -21
- data/lib/hipbot/reaction.rb +27 -15
- data/lib/hipbot/reaction_factory.rb +38 -0
- data/lib/hipbot/response.rb +18 -10
- data/lib/hipbot/room.rb +34 -2
- data/lib/hipbot/storages/base.rb +78 -0
- data/lib/hipbot/storages/hash.rb +89 -0
- data/lib/hipbot/storages/mongoid.rb +18 -0
- data/lib/hipbot/user.rb +8 -2
- data/lib/hipbot/version.rb +1 -1
- data/spec/integration/my_hipbot.rb +24 -4
- data/spec/integration/{hipbot_spec.rb → my_hipbot_spec.rb} +41 -23
- data/spec/spec_helper.rb +14 -2
- data/spec/unit/adapters/hipchat_spec.rb +5 -0
- data/spec/unit/{hipbot_spec.rb → bot_spec.rb} +13 -12
- data/spec/unit/match_spec.rb +148 -0
- data/spec/unit/message_spec.rb +14 -7
- data/spec/unit/reaction_factory_spec.rb +54 -0
- data/spec/unit/reaction_spec.rb +99 -0
- data/spec/unit/storages/hash_spec.rb +75 -0
- data/spec/unit/user_spec.rb +0 -2
- metadata +64 -54
- data/Gemfile.lock +0 -90
- data/examples/cleverbot.rb +0 -23
- data/examples/google_images.rb +0 -35
- data/lib/hipbot/adapters/hipchat/connection.rb +0 -166
- data/lib/hipbot/adapters/hipchat/hipchat.rb +0 -13
- data/lib/hipbot/adapters/telnet/connection.rb +0 -17
- data/lib/hipbot/adapters/telnet/telnet.rb +0 -14
- data/lib/hipbot/collection.rb +0 -72
- data/lib/hipbot/patches/hipchat_client.rb +0 -230
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef74572ebd12e87ab892010a3c8c0bae5b146584
|
4
|
+
data.tar.gz: 03a8912f6c9958a88d3e2294844f6fc5fa5b7bc9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8f9b8bd967a44c5b0b09057c63b257418f988a616e02cb63d91f55a26115f72da08ff3d82ead405ed48f38d7e24d8bf458bf6ed45d49bd16ab483c77d4e0bd2
|
7
|
+
data.tar.gz: e174318fef49cc39dc116ce31057d5377a015c35989f4b2be9451fbb7737b98dae68f6de96bd1a2c8111be5dbaa245e61ae081f938a3bee1b43078e625a315ce
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -3,11 +3,10 @@ source 'https://rubygems.org'
|
|
3
3
|
gem 'rake'
|
4
4
|
gem 'eventmachine'
|
5
5
|
gem 'em-http-request'
|
6
|
-
gem 'xmpp4r'
|
7
6
|
gem 'httparty'
|
8
7
|
gem 'activesupport'
|
9
|
-
gem 'i18n'
|
10
8
|
gem 'daemons'
|
9
|
+
gem 'xmpp4r-hipchat', github: 'bartoszkopinski/xmpp4r-hipchat', branch: 'master'
|
11
10
|
|
12
11
|
gem 'rspec'
|
13
12
|
gem 'guard-rspec'
|
data/README.md
CHANGED
@@ -1,161 +1,472 @@
|
|
1
1
|
# Hipbot
|
2
2
|
|
3
|
+
Hipbot is a XMPP bot for HipChat, written in Ruby with EventMachine.
|
4
|
+
|
3
5
|
[](http://travis-ci.org/pewniak747/hipbot)
|
4
6
|
[](https://codeclimate.com/github/pewniak747/hipbot)
|
5
7
|
[](https://coveralls.io/r/pewniak747/hipbot)
|
6
8
|
[](https://gemnasium.com/pewniak747/hipbot)
|
7
9
|
[](http://badge.fury.io/rb/hipbot)
|
8
10
|
|
9
|
-
|
11
|
+
### Compatibility
|
12
|
+
Hipbot is tested on:
|
10
13
|
|
11
|
-
|
14
|
+
* Ruby 1.9.2, 1.9.3 and 2.0.0
|
15
|
+
* JRuby 1.9 mode
|
16
|
+
* Rubinus 1.9 mode
|
12
17
|
|
13
|
-
|
18
|
+
### Dependencies
|
14
19
|
|
15
|
-
|
20
|
+
* daemons >= 1.1.8
|
21
|
+
* activesupport >= 3.2.12
|
22
|
+
* eventmachine >= 1.0.3
|
23
|
+
* em-http-request >= 1.0.3
|
24
|
+
* xmpp4r ~> 0.5
|
16
25
|
|
17
|
-
|
26
|
+
## Getting started
|
27
|
+
### Installation
|
28
|
+
|
29
|
+
```shell
|
18
30
|
gem install hipbot
|
19
31
|
```
|
20
32
|
|
21
|
-
###
|
33
|
+
### 1 minute setup on heroku
|
22
34
|
|
35
|
+
Follow the instructions on [hipbot-example](https://github.com/netguru/hipbot-example).
|
36
|
+
|
37
|
+
### Custom setup
|
23
38
|
Create `bot.rb` file, subclass `Hipbot::Bot` and customize the responses.
|
24
39
|
|
25
40
|
```ruby
|
26
41
|
require 'hipbot'
|
27
42
|
|
28
|
-
class
|
43
|
+
class MyBot < Hipbot::Bot
|
29
44
|
configure do |c|
|
30
|
-
c.jid = 'changeme@chat.hipchat.com'
|
31
|
-
c.password = 'secret'
|
32
|
-
c.teams = { vip: ['John', 'Mike'] }
|
33
|
-
c.rooms = { project_rooms: ['Project 1', 'Project 2'] }
|
45
|
+
c.jid = 'changeme@chat.hipchat.com'
|
46
|
+
c.password = 'secret'
|
34
47
|
end
|
35
48
|
|
36
|
-
on /^hello
|
37
|
-
reply(
|
49
|
+
on /^hello$/ do
|
50
|
+
reply("Hello!")
|
38
51
|
end
|
52
|
+
end
|
39
53
|
|
40
|
-
|
41
|
-
|
42
|
-
reply('restarting...')
|
43
|
-
end
|
54
|
+
MyBot.start!
|
55
|
+
```
|
44
56
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
57
|
+
### Running
|
58
|
+
Start Hipbot as a daemon by executing:
|
59
|
+
|
60
|
+
```shell
|
61
|
+
hipbot start
|
62
|
+
```
|
63
|
+
|
64
|
+
Run `hipbot` to see all available commands.
|
65
|
+
|
66
|
+
Start in shell:
|
67
|
+
|
68
|
+
```shell
|
69
|
+
ruby bot.rb
|
70
|
+
```
|
71
|
+
|
72
|
+
### Behavior
|
73
|
+
* On start and runtime:
|
74
|
+
* Fetches details and presences of all users in Lobby
|
75
|
+
* Pings XMPP server every 60 seconds to keep alive
|
76
|
+
* On new message:
|
77
|
+
* Invokes all matching reactions or falls back to default reaction
|
78
|
+
|
79
|
+
## Usage
|
80
|
+
### Configuration
|
81
|
+
Full configuration example:
|
82
|
+
```ruby
|
83
|
+
class MyBot < Hipbot::Bot
|
84
|
+
configure do |c|
|
85
|
+
# Account JID (required) - see https://hipchat.com/account/xmpp for your JID
|
86
|
+
c.jid = 'changeme@chat.hipchat.com'
|
87
|
+
|
88
|
+
# Account password (required)
|
89
|
+
c.password = 'secret'
|
49
90
|
|
50
|
-
|
51
|
-
|
91
|
+
# Custom helpers module (optional) - see below for examples
|
92
|
+
c.helpers = MyHipbotHelpers
|
93
|
+
|
94
|
+
# Logger (default: Hipbot::Logger.new($stdout))
|
95
|
+
c.logger = Hipbot::Logger.new($stdout)
|
96
|
+
|
97
|
+
# Initial status message (default: '')
|
98
|
+
c.status = "I'm here to help"
|
99
|
+
|
100
|
+
# Storage adapter (default: Hipbot::Storages::Hash)
|
101
|
+
c.storage = Hipbot::Storages::Hash
|
102
|
+
|
103
|
+
# Predefined room groups (optional)
|
104
|
+
c.rooms = { project_rooms: ['Project 1', 'Project 2'] }
|
105
|
+
|
106
|
+
# Predefined user groups (optional)
|
107
|
+
c.teams = { admins: ['John Smith'] }
|
108
|
+
|
109
|
+
# Auto join criteria (default: :all)
|
110
|
+
# Accepted values: :all, :public, :private, :none, "room name"
|
111
|
+
c.join = :private
|
52
112
|
end
|
53
113
|
end
|
114
|
+
```
|
115
|
+
### Reaction helpers
|
116
|
+
Inside the reaction block you have access to following context objects:
|
54
117
|
|
55
|
-
|
56
|
-
|
118
|
+
* `bot`
|
119
|
+
* `room`
|
120
|
+
* `sender`
|
121
|
+
* `message`
|
122
|
+
* `reaction`
|
57
123
|
|
58
|
-
|
59
|
-
|
60
|
-
|
124
|
+
### Joining rooms
|
125
|
+
Hipbot will join all accessible rooms by default on startup and invite.
|
126
|
+
|
127
|
+
To change auto join method use `join` configuration option:
|
128
|
+
```ruby
|
129
|
+
configure do |c|
|
130
|
+
# ...
|
131
|
+
c.join = :private
|
132
|
+
end
|
133
|
+
```
|
134
|
+
```ruby
|
135
|
+
configure do |c|
|
136
|
+
# ...
|
137
|
+
c.join = :none
|
61
138
|
end
|
139
|
+
```
|
140
|
+
```ruby
|
141
|
+
configure do |c|
|
142
|
+
# ...
|
143
|
+
c.join = ['Project Room', :public]
|
144
|
+
end
|
145
|
+
```
|
146
|
+
Notice: Archived rooms are always ignored
|
62
147
|
|
63
|
-
|
148
|
+
### Bot presence
|
149
|
+
Use `bot.set_presence` method to change Hipbot presence:
|
150
|
+
```ruby
|
151
|
+
on /^change status$/ do
|
152
|
+
bot.set_presence("Hello humans")
|
153
|
+
end
|
154
|
+
```
|
155
|
+
```ruby
|
156
|
+
on /^go away$/ do
|
157
|
+
bot.set_presence("I'm away", :away)
|
158
|
+
end
|
159
|
+
```
|
160
|
+
```ruby
|
161
|
+
on /^do not disturb$/ do
|
162
|
+
bot.set_presence(nil, :dnd)
|
163
|
+
end
|
64
164
|
```
|
65
165
|
|
66
|
-
|
166
|
+
### Rooms
|
167
|
+
Use `Hipbot::Room` for collection of available rooms.
|
168
|
+
```ruby
|
169
|
+
on /^list all rooms$/ do
|
170
|
+
all_rooms = Hipbot::Room.all.map(&:name)
|
171
|
+
reply(all_rooms.join(', '))
|
172
|
+
end
|
173
|
+
```
|
174
|
+
```ruby
|
175
|
+
on /^get project room JID$/ do
|
176
|
+
project_room = Hipbot::Room.find_by(name: 'project room')
|
177
|
+
reply(project_room.id)
|
178
|
+
end
|
179
|
+
```
|
180
|
+
Use `room` for current room object (it's `nil` if message is private):
|
181
|
+
```ruby
|
182
|
+
on /^where am I\?$/ do
|
183
|
+
reply(
|
184
|
+
"You are in #{room}\n" +
|
185
|
+
"JID: #{room.id}\n" +
|
186
|
+
"Topic: #{room.topic}\n" +
|
187
|
+
"Users online: #{room.users.count}\n" +
|
188
|
+
"Privacy: #{room.privacy}\n" +
|
189
|
+
"Hipchat ID: #{room.hipchat_id}\n" +
|
190
|
+
"Archived?: #{room.archived ? 'yes' : 'no'}\n" +
|
191
|
+
"Guest URL: #{room.guest_url}"
|
192
|
+
)
|
193
|
+
end
|
194
|
+
```
|
67
195
|
|
196
|
+
### Users
|
197
|
+
Use `Hipbot::User` for collection of all users:
|
198
|
+
```ruby
|
199
|
+
on /^list all users$/ do
|
200
|
+
all_users = Hipbot::User.all.map(&:name)
|
201
|
+
reply(all_users.join(', '))
|
202
|
+
end
|
203
|
+
```
|
204
|
+
```ruby
|
205
|
+
on /^get John Smith's JID$/ do
|
206
|
+
john = Hipbot::Room.find_by(name: 'John Smith')
|
207
|
+
reply(john.id)
|
208
|
+
end
|
209
|
+
```
|
210
|
+
Use `sender` for message sender object:
|
211
|
+
```ruby
|
212
|
+
on /^who am I\?$/ do
|
213
|
+
reply(
|
214
|
+
"You are #{sender}\n" +
|
215
|
+
"JID: #{sender.id}\n" +
|
216
|
+
"Mention: @#{sender.mention}\n" +
|
217
|
+
"E-mail: #{sender.email}\n" +
|
218
|
+
"Title: #{sender.title}\n" +
|
219
|
+
"Photo: #{sender.photo}"
|
220
|
+
)
|
221
|
+
end
|
222
|
+
```
|
223
|
+
Use `Room#users` method for online users array:
|
68
224
|
```ruby
|
69
|
-
on /^
|
70
|
-
reply('
|
225
|
+
on /^list online users$/ do
|
226
|
+
reply room.users.map(&:name).join(', ')
|
71
227
|
end
|
72
228
|
```
|
73
229
|
|
74
|
-
|
230
|
+
### Replying
|
231
|
+
Use `reply` method to send a message.
|
232
|
+
|
233
|
+
Reply in the same room / chat:
|
234
|
+
```ruby
|
235
|
+
on /^hello$/ do
|
236
|
+
reply("Hello!")
|
237
|
+
end
|
238
|
+
```
|
239
|
+
Reply in "help room":
|
240
|
+
```ruby
|
241
|
+
on /^I need help$/ do
|
242
|
+
help_room = Hipbot::Room.find_by(name: 'help room')
|
243
|
+
reply("#{sender} needs help in #{room}", help_room)
|
244
|
+
end
|
245
|
+
```
|
75
246
|
|
247
|
+
### Private messaging
|
248
|
+
```ruby
|
249
|
+
on /^send me private message$/ do
|
250
|
+
sender.send_message("Hello, #{sender}")
|
251
|
+
end
|
252
|
+
```
|
76
253
|
```ruby
|
77
|
-
on
|
78
|
-
|
254
|
+
on /^send private message to John$/ do
|
255
|
+
john = Hipbot::User.find_by(name: 'John Smith')
|
256
|
+
john.send_message("Hello, John!")
|
79
257
|
end
|
80
258
|
```
|
81
259
|
|
82
|
-
|
260
|
+
### Topics
|
261
|
+
```ruby
|
262
|
+
on /^current topic$/ do
|
263
|
+
reply("Current topic: #{room.topic}")
|
264
|
+
end
|
265
|
+
```
|
266
|
+
```ruby
|
267
|
+
on /^change topic here$/ do
|
268
|
+
room.set_topic("New Topic")
|
269
|
+
end
|
270
|
+
```
|
271
|
+
```ruby
|
272
|
+
on /^change topic there$/ do
|
273
|
+
there = Hipbot::Room.find_by(name: 'there')
|
274
|
+
there.set_topic("New Topic")
|
275
|
+
end
|
276
|
+
```
|
83
277
|
|
278
|
+
### Regexp matchdata
|
279
|
+
```ruby
|
280
|
+
on /^My name is (.*)$/ do |user_name|
|
281
|
+
reply("Hello, #{user_name}!")
|
282
|
+
end
|
283
|
+
```
|
84
284
|
```ruby
|
85
|
-
on
|
86
|
-
reply(
|
285
|
+
on /^My name is (\S*) (\S*)$/ do |first_name, last_name|
|
286
|
+
reply("Hello, #{first_name} #{last_name}!")
|
87
287
|
end
|
88
288
|
```
|
89
289
|
|
90
|
-
|
290
|
+
### Multiple regexps
|
291
|
+
```ruby
|
292
|
+
on /^My name is (.*)$/, /^I am (.*)$/ do |user_name|
|
293
|
+
reply("Hello, #{user_name}!")
|
294
|
+
end
|
295
|
+
```
|
91
296
|
|
297
|
+
### Sender restriction
|
298
|
+
Use `:from` option to match messages only from certain users or user groups defined in configuration.
|
299
|
+
It accepts string, symbol and array values.
|
92
300
|
```ruby
|
93
301
|
configure do |c|
|
94
302
|
# ...
|
95
|
-
c.teams = { vip: ['John', 'Mike'] }
|
303
|
+
c.teams = { vip: ['John Edward', 'Mike Anderson'] }
|
96
304
|
end
|
97
305
|
|
98
|
-
on
|
99
|
-
reply('
|
306
|
+
on /^report status$/, from: ['Tom Smith', 'Jane Doe', :vip] do
|
307
|
+
reply('All clear')
|
100
308
|
end
|
101
309
|
```
|
102
310
|
|
103
|
-
|
104
|
-
|
311
|
+
### Room restriction
|
312
|
+
Use `:room` option to match messages opny from certain HipChat rooms.
|
313
|
+
It accepts string, symbol, array and boolean values.
|
105
314
|
```ruby
|
106
315
|
configure do |c|
|
107
316
|
# ...
|
108
317
|
c.rooms = { project_rooms: ['Project 1', 'Project 2'] }
|
109
318
|
end
|
110
319
|
|
111
|
-
on
|
112
|
-
reply('
|
320
|
+
on /^hello$/, room: ['Public Room', :project_rooms] do
|
321
|
+
reply('Hello!')
|
322
|
+
end
|
323
|
+
```
|
324
|
+
Match only private messages:
|
325
|
+
```ruby
|
326
|
+
on /^private hello$/, room: false do
|
327
|
+
reply('Private hello!')
|
328
|
+
end
|
329
|
+
```
|
330
|
+
Match only room messages:
|
331
|
+
```ruby
|
332
|
+
on /^public hello$/, room: true do
|
333
|
+
reply('Public hello!')
|
113
334
|
end
|
114
335
|
```
|
115
336
|
|
116
|
-
|
337
|
+
### Global reaction
|
338
|
+
By default, Hipbot reacts only to its HipChat mention.
|
339
|
+
Use `global: true` option to match all messages:
|
117
340
|
|
118
341
|
```ruby
|
119
|
-
on
|
342
|
+
on /^Hey I just met you$/, global: true do
|
120
343
|
reply('and this is crazy...')
|
121
344
|
end
|
122
345
|
```
|
123
346
|
|
124
|
-
|
347
|
+
### Conditional reaction
|
348
|
+
Use `:if` option to specify certain dynamic conditions:
|
349
|
+
```ruby
|
350
|
+
on /^Is it friday\?$/, if: ->{ Time.now.friday? } do
|
351
|
+
reply('Yes, indeed')
|
352
|
+
end
|
353
|
+
```
|
354
|
+
```ruby
|
355
|
+
admins = ['John Smith']
|
356
|
+
on /^add admin (.*)$/, if: ->(sender){ admins.include?(sender.name) } do |user_name|
|
357
|
+
admins << user_name
|
358
|
+
end
|
359
|
+
```
|
360
|
+
```ruby
|
361
|
+
on /^choose volunteer$/, if: ->(room){ room.users.count > 3 } do
|
362
|
+
reply("Choosing #{room.users.sample}")
|
363
|
+
end
|
364
|
+
```
|
125
365
|
|
126
|
-
|
366
|
+
### Method reaction
|
367
|
+
Use symbol instead of block to react with a instance method:
|
368
|
+
```ruby
|
369
|
+
def hello(user_name)
|
370
|
+
reply("Hello #{user_name}!")
|
371
|
+
end
|
127
372
|
|
128
|
-
|
373
|
+
on /^My name is (.*)$/, :hello
|
374
|
+
```
|
129
375
|
|
130
|
-
|
376
|
+
### Scopes
|
377
|
+
Use `scope` blocks to extract common options:
|
378
|
+
```ruby
|
379
|
+
configure do |c|
|
380
|
+
# ...
|
381
|
+
c.teams = { admins: ['John Edward', 'Mike Anderson'] }
|
382
|
+
end
|
383
|
+
|
384
|
+
scope from: :admins, room: true do
|
385
|
+
on /^restart server$/ do
|
386
|
+
# Restarting...
|
387
|
+
end
|
388
|
+
|
389
|
+
scope global: true do
|
390
|
+
on /^deploy production$/ do
|
391
|
+
# Deploying...
|
392
|
+
end
|
393
|
+
|
394
|
+
on /^check status$/ do
|
395
|
+
# Checking...
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
```
|
400
|
+
|
401
|
+
### Default reactions
|
402
|
+
Default reaction can take the same options as regular one.
|
403
|
+
Hipbot fall backs to default reactions if there is no matching normal reaction.
|
404
|
+
```ruby
|
405
|
+
default do
|
406
|
+
reply("I don't understand you!")
|
407
|
+
end
|
408
|
+
```
|
409
|
+
```ruby
|
410
|
+
default from: 'Mike Johnson' do
|
411
|
+
reply("Not you again, Mike!")
|
412
|
+
end
|
413
|
+
```
|
131
414
|
|
415
|
+
### Descriptions
|
416
|
+
Use `desc` modifier to describe following reaction:
|
417
|
+
```ruby
|
418
|
+
desc '@hipbot restart server_name - Restarts the server'
|
419
|
+
on /^restart (.*)$/ do |server|
|
420
|
+
if server.empty?
|
421
|
+
reply("Usage: #{reaction.desc}")
|
422
|
+
else
|
423
|
+
# Restarting...
|
424
|
+
end
|
425
|
+
end
|
426
|
+
```
|
427
|
+
You can fetch the descriptions and create help reaction, eg:
|
132
428
|
```ruby
|
133
|
-
on
|
134
|
-
|
429
|
+
on /^help$/ do
|
430
|
+
reply Hipbot.reactions.map(&:desc).compact.join("\n")
|
431
|
+
end
|
432
|
+
```
|
433
|
+
|
434
|
+
### User managment
|
435
|
+
This behavior is experimental and not officially supported by HipChat. Bot must be an admin in order to perform this actions.
|
436
|
+
```ruby
|
437
|
+
on /^kick (.*)/ do |user_name|
|
438
|
+
user = Hipbot::User.find_by(name: user_name)
|
439
|
+
room.kick(user)
|
440
|
+
end
|
441
|
+
```
|
442
|
+
```ruby
|
443
|
+
on /^invite (.*)$/ do |user_name|
|
444
|
+
user = Hipbot::User.find_by(name: user_name)
|
445
|
+
room.invite(user)
|
446
|
+
end
|
447
|
+
```
|
448
|
+
|
449
|
+
### HTTP helpers
|
450
|
+
Use `get`, `post`, `put` and `delete` helpers to preform a HTTP requests:
|
451
|
+
```ruby
|
452
|
+
on /^curl (\S+)$/ do |url|
|
453
|
+
get(url) do |response|
|
135
454
|
reply(response.code)
|
136
455
|
reply(response.headers)
|
137
456
|
reply(response.body)
|
138
457
|
end
|
139
458
|
end
|
140
459
|
```
|
141
|
-
|
142
460
|
```ruby
|
143
|
-
on
|
144
|
-
get
|
461
|
+
on /^ping site/ do
|
462
|
+
get('http://example.com', ping: '1') # GET http://example.com?ping=1
|
145
463
|
end
|
146
464
|
```
|
147
465
|
|
148
|
-
|
149
|
-
|
150
|
-
* `message.body` - sent message
|
151
|
-
* `message.sender` - user who sent message
|
152
|
-
* `message.mentions` - array of @mentions inside message, without bot
|
153
|
-
* `room.name` - name of the current room
|
154
|
-
|
466
|
+
### Custom response helpers
|
155
467
|
You can define your own helpers and use them inside responses like this:
|
156
|
-
|
157
468
|
```ruby
|
158
|
-
module
|
469
|
+
module MyHipbotHelpers
|
159
470
|
def project_name
|
160
471
|
"#{room.name}-project"
|
161
472
|
end
|
@@ -164,42 +475,40 @@ end
|
|
164
475
|
class Bot < Hipbot::Bot
|
165
476
|
configure do |c|
|
166
477
|
# ...
|
167
|
-
c.helpers =
|
478
|
+
c.helpers = MyHipbotHelpers
|
168
479
|
end
|
169
480
|
|
170
|
-
on
|
481
|
+
on /^what's the project name\?$/ do
|
171
482
|
reply(project_name)
|
172
483
|
end
|
173
484
|
end
|
174
485
|
```
|
175
486
|
|
176
|
-
|
177
|
-
|
178
|
-
To define a plugin, include `Hipbot::Plugin` and add responses like in bot:
|
179
|
-
|
487
|
+
### Plugins
|
488
|
+
To define a plugin, include `Hipbot::Plugin` module in your class:
|
180
489
|
```ruby
|
181
490
|
class GreeterPlugin
|
182
491
|
include Hipbot::Plugin
|
183
|
-
|
184
|
-
|
492
|
+
|
493
|
+
on /^hello$/ do
|
494
|
+
reply('Hello there!')
|
185
495
|
end
|
186
496
|
end
|
187
497
|
```
|
188
498
|
|
189
|
-
You can
|
190
|
-
|
499
|
+
You can access plugin data inside reaction with `plugin` helper:
|
191
500
|
```ruby
|
192
501
|
class GreeterPlugin
|
193
502
|
include Hipbot::Plugin
|
194
503
|
|
195
504
|
attr_accessor :language
|
196
505
|
|
197
|
-
on /^hello
|
506
|
+
on /^hello$/ do
|
198
507
|
case plugin.language
|
199
508
|
when :en
|
200
|
-
reply("
|
509
|
+
reply("Hello!")
|
201
510
|
when :pl
|
202
|
-
reply("
|
511
|
+
reply("Cześć!")
|
203
512
|
when :jp
|
204
513
|
reply("おはよう!")
|
205
514
|
end
|
@@ -210,27 +519,112 @@ GreeterPlugin.configure do |c|
|
|
210
519
|
c.language = :jp
|
211
520
|
end
|
212
521
|
```
|
522
|
+
For more examples, check out [hipbot-plugins](https://github.com/netguru/hipbot-plugins).
|
213
523
|
|
214
|
-
|
524
|
+
### Exception handling
|
525
|
+
Define `on_exception` block in your Hipbot class to handle runtime exceptions:
|
526
|
+
```ruby
|
527
|
+
class MyBot < Hipbot::Bot
|
528
|
+
on_exception do |e|
|
529
|
+
hipbot_room = Hipbot::Room.find_by(name: 'hipbot room')
|
530
|
+
reply(e.message, hipbot_room)
|
531
|
+
# If exception was raised in reaction, there are some context variables available:
|
532
|
+
reply("#{e.message} raised by #{message.body} from #{sender} in #{room}", hipbot_room)
|
533
|
+
end
|
534
|
+
end
|
535
|
+
```
|
215
536
|
|
216
|
-
###
|
537
|
+
### Preloader for EventMachine
|
538
|
+
In order to use EventMachine runtime methods, define them within `on_preload` block in your Hipbot class:
|
539
|
+
```ruby
|
540
|
+
class MyBot < Hipbot::Bot
|
541
|
+
on_preload do
|
542
|
+
EM::add_periodic_timer(60) do
|
543
|
+
Updater::update_stock_prices
|
544
|
+
Updater::update_server_statuses
|
545
|
+
end
|
546
|
+
end
|
547
|
+
end
|
548
|
+
```
|
217
549
|
|
218
|
-
|
550
|
+
### Storage
|
551
|
+
Hipbot uses in-memory hash storage by default, however you can use persistent
|
552
|
+
storage adapter to speed up boot time and extend the functionality.
|
219
553
|
|
554
|
+
#### MongoDB
|
555
|
+
In order to use MongoDB storage, enable Mongoid adapter and add `allow_dynamic_fields: true` to your Mongoid config:
|
556
|
+
```ruby
|
557
|
+
require 'hipbot/storages/mongoid'
|
558
|
+
configure do |c|
|
559
|
+
# ...
|
560
|
+
c.storage = Hipbot::Storages::Mongoid
|
561
|
+
end
|
220
562
|
```
|
221
|
-
|
563
|
+
Sample config file:
|
564
|
+
```yaml
|
565
|
+
sessions:
|
566
|
+
default:
|
567
|
+
hosts:
|
568
|
+
- localhost:27017
|
569
|
+
database: hipbot
|
570
|
+
options:
|
571
|
+
allow_dynamic_fields: true
|
222
572
|
```
|
573
|
+
You can optionally override user and room classes with these base models:
|
574
|
+
```ruby
|
575
|
+
module Hipbot
|
576
|
+
class User
|
577
|
+
include Mongoid::Document
|
578
|
+
|
579
|
+
has_and_belongs_to_many :rooms, class_name: 'Hipbot::User', inverse_of: :users
|
580
|
+
|
581
|
+
field :email, type: String
|
582
|
+
field :mention, type: String
|
583
|
+
field :phone, type: String
|
584
|
+
field :photo, type: String
|
585
|
+
field :title, type: String
|
586
|
+
field :is_online, type: Boolean
|
587
|
+
end
|
588
|
+
end
|
589
|
+
```
|
590
|
+
```ruby
|
591
|
+
module Hipbot
|
592
|
+
class Room
|
593
|
+
include Mongoid::Document
|
223
594
|
|
224
|
-
|
595
|
+
has_and_belongs_to_many :users, class_name: 'Hipbot::User', inverse_of: :rooms
|
225
596
|
|
226
|
-
|
597
|
+
field :archived, type: Boolean
|
598
|
+
field :guest_url, type: String
|
599
|
+
field :hipchat_id, type: String
|
600
|
+
field :privacy, type: String
|
601
|
+
field :topic, type: String
|
602
|
+
end
|
603
|
+
end
|
604
|
+
```
|
605
|
+
#### Other storage
|
606
|
+
Storage adapter is included in room and user classes upon loading.
|
607
|
+
Make sure your adapter implements all methods from [Hipbot::Storages::Base](https://github.com/pewniak747/hipbot/blob/master/lib/hipbot/storages/base.rb)
|
608
|
+
```ruby
|
609
|
+
module MyStorageAdapter
|
610
|
+
include Hipbot::Storages::Base
|
611
|
+
# ...
|
612
|
+
end
|
227
613
|
|
228
|
-
|
614
|
+
configure do |c|
|
615
|
+
# ...
|
616
|
+
c.storage = MyStorageAdapter
|
617
|
+
end
|
618
|
+
```
|
229
619
|
|
230
|
-
##
|
620
|
+
## Contributing
|
621
|
+
### To do:
|
231
622
|
|
232
|
-
|
623
|
+
* add tests for Match class
|
624
|
+
* add testing adapter for testing custom responses with RSpec
|
625
|
+
* add HipChat API integration (?)
|
233
626
|
|
627
|
+
### Done:
|
234
628
|
* ~~add extended logging~~
|
235
629
|
* ~~add plugins support~~
|
236
630
|
* ~~rewrite SimpleMUCClient~~
|