hiptail 0.0.1
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 +7 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/examples/integrate_sinatra/Gemfile +5 -0
- data/examples/integrate_sinatra/README.md +9 -0
- data/examples/integrate_sinatra/app.rb +58 -0
- data/examples/simple_rack_app_1/Gemfile +4 -0
- data/examples/simple_rack_app_1/README.md +9 -0
- data/examples/simple_rack_app_1/config.ru +56 -0
- data/examples/simple_rack_app_2/Gemfile +4 -0
- data/examples/simple_rack_app_2/README.md +9 -0
- data/examples/simple_rack_app_2/app.rb +42 -0
- data/examples/simple_rack_app_2/config.ru +4 -0
- data/hiptail.gemspec +53 -0
- data/lib/hiptail/atom.rb +303 -0
- data/lib/hiptail/authority/provider.rb +65 -0
- data/lib/hiptail/authority/sqlite3_provider.rb +85 -0
- data/lib/hiptail/authority.rb +258 -0
- data/lib/hiptail/event.rb +108 -0
- data/lib/hiptail/manager.rb +234 -0
- data/lib/hiptail/util.rb +78 -0
- data/lib/hiptail/version.rb +3 -0
- data/lib/hiptail/web/handler.rb +99 -0
- data/lib/hiptail/web/rack_app.rb +100 -0
- data/lib/hiptail.rb +9 -0
- metadata +126 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'hiptail/authority/provider'
|
2
|
+
require 'sqlite3'
|
3
|
+
|
4
|
+
class HipTail::SQLite3AuthorityProvider < HipTail::AuthorityProvider
|
5
|
+
# @return [HipTail::SQLite3AuthorityProvider]
|
6
|
+
def initialize(db)
|
7
|
+
@authorities = {}
|
8
|
+
@db = db
|
9
|
+
|
10
|
+
build
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [void]
|
14
|
+
def build
|
15
|
+
@db.execute_batch <<-'END_SQL'
|
16
|
+
CREATE TABLE IF NOT EXISTS hiptail_authority (
|
17
|
+
oauth_id VARCHAR(255) NOT NULL PRIMARY KEY,
|
18
|
+
oauth_secret VARCHAR(255) NOT NULL,
|
19
|
+
authorization_url VARCHAR(255) NOT NULL,
|
20
|
+
token_url VARCHAR(255) NOT NULL,
|
21
|
+
room_id INT UNSIGNED,
|
22
|
+
group_id INT UNSIGNED NOT NULL,
|
23
|
+
api_base VARCHAR(255) NOT NULL,
|
24
|
+
created_at INTEGER NOT NULL
|
25
|
+
);
|
26
|
+
END_SQL
|
27
|
+
end
|
28
|
+
|
29
|
+
SQL_GET = <<-'END_SQL'
|
30
|
+
SELECT * FROM hiptail_authority WHERE oauth_id = ? LIMIT 1
|
31
|
+
END_SQL
|
32
|
+
|
33
|
+
# @abstract
|
34
|
+
# @param [String] oauth_id
|
35
|
+
# @return [HipTail::Authority]
|
36
|
+
def get(oauth_id)
|
37
|
+
unless @authorities.include?(oauth_id)
|
38
|
+
begin
|
39
|
+
last_rah = @db.results_as_hash
|
40
|
+
@db.results_as_hash = true
|
41
|
+
@db.execute(SQL_GET, oauth_id) do |row|
|
42
|
+
data = row.to_a.select { |f| f[0].is_a?(String) }.map { |f| [ f[0].to_sym, f[1] ] }
|
43
|
+
@authorities[oauth_id] = HipTail::Authority.new(Hash[*data.flatten(1)])
|
44
|
+
break
|
45
|
+
end
|
46
|
+
ensure
|
47
|
+
@db.results_as_hash = last_rah
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
@authorities[oauth_id]
|
52
|
+
end
|
53
|
+
|
54
|
+
SQL_REGISTER = <<-'END_SQL'
|
55
|
+
REPLACE INTO hiptail_authority
|
56
|
+
( oauth_id, oauth_secret, authorization_url, token_url, room_id, group_id, api_base, created_at )
|
57
|
+
VALUES ( :oauth_id, :oauth_secret, :authorization_url, :token_url, :room_id, :group_id, :api_base, :created_at )
|
58
|
+
END_SQL
|
59
|
+
|
60
|
+
# @param [String] oauth_id
|
61
|
+
# @param [HipTail::Authority] authority
|
62
|
+
# @return [HipTail::Authority]
|
63
|
+
def register(oauth_id, authority)
|
64
|
+
@authorities[oauth_id] = authority
|
65
|
+
|
66
|
+
row_data = authority.as_hash
|
67
|
+
[ :api_base, :authorization_url, :token_url ].each do |key|
|
68
|
+
row_data[key] = row_data[key].to_s
|
69
|
+
end
|
70
|
+
row_data[:created_at] = Time.now.to_i
|
71
|
+
@db.execute(SQL_REGISTER, row_data)
|
72
|
+
end
|
73
|
+
|
74
|
+
SQL_UNREGISTER = <<-'END_SQL'
|
75
|
+
DELETE FROM hiptail_authority WHERE oauth_id = ?
|
76
|
+
END_SQL
|
77
|
+
|
78
|
+
# @param [String] oauth_id
|
79
|
+
# @return [void]
|
80
|
+
def unregister(oauth_id)
|
81
|
+
@authorities.delete(oauth_id)
|
82
|
+
|
83
|
+
@db.execute(SQL_UNREGISTER, oauth_id)
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,258 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'uri'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'net/http'
|
5
|
+
require 'oauth2'
|
6
|
+
|
7
|
+
module HipTail
|
8
|
+
class Authority
|
9
|
+
# @return [String] Returns OAuth ID.
|
10
|
+
attr_reader :oauth_id
|
11
|
+
# Returns room_id for room authority.
|
12
|
+
# Nil for global authority.
|
13
|
+
# @return [String]
|
14
|
+
# @return [nil]
|
15
|
+
attr_reader :room_id
|
16
|
+
# Returns group_id for authority.
|
17
|
+
# @return [String]
|
18
|
+
attr_reader :group_id
|
19
|
+
|
20
|
+
# @return [Boolean] Represents whether the authority is for global or not.
|
21
|
+
def for_global?
|
22
|
+
! @room_id
|
23
|
+
end
|
24
|
+
alias global? for_global?
|
25
|
+
|
26
|
+
# @return [Boolean] Represents whether the authority is for a room or not.
|
27
|
+
def for_room?
|
28
|
+
! for_global?
|
29
|
+
end
|
30
|
+
alias room? for_room?
|
31
|
+
|
32
|
+
# A new instance of HipTail::Authority.
|
33
|
+
# @param [Hash] params
|
34
|
+
# @option params [String] :oauth_id
|
35
|
+
# @option params [String] :oauth_secret
|
36
|
+
# @option params [String] :authorization_url
|
37
|
+
# @option params [String] :token_url
|
38
|
+
# @option params [String] :room_id
|
39
|
+
# @option params [String] :group_id
|
40
|
+
# @option params [String] :api_base
|
41
|
+
# @return [HipTail::Authority]
|
42
|
+
def initialize(params)
|
43
|
+
@oauth_id = params[:oauth_id]
|
44
|
+
@oauth_secret = params[:oauth_secret]
|
45
|
+
@authorization_url = params[:authorization_url]
|
46
|
+
@token_url = params[:token_url]
|
47
|
+
|
48
|
+
@room_id = params[:room_id]
|
49
|
+
@group_id = params[:group_id]
|
50
|
+
|
51
|
+
@room_id = @room_id.to_i if ! @room_id.nil?
|
52
|
+
@group_id = @group_id.to_i if ! @group_id.nil?
|
53
|
+
|
54
|
+
api_base_uri = params[:api_base].to_s
|
55
|
+
unless api_base_uri.end_with?('/')
|
56
|
+
api_base_uri += '/';
|
57
|
+
end
|
58
|
+
@api_base = URI.parse(api_base_uri)
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [Hash] Hash representation. Convenient for persistency.
|
62
|
+
def as_hash
|
63
|
+
{
|
64
|
+
:oauth_id => @oauth_id,
|
65
|
+
:oauth_secret => @oauth_secret,
|
66
|
+
:authorization_url => @authorization_url,
|
67
|
+
:token_url => @token_url,
|
68
|
+
:room_id => @room_id,
|
69
|
+
:group_id => @group_id,
|
70
|
+
:api_base => @api_base,
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
# Issues send notification API.
|
75
|
+
# @param [Hash] params Parameters for notification API with :room_id.
|
76
|
+
# @option params [String] :room_id Room ID. Optional but mandatory for global authority.
|
77
|
+
# @return [Hash] Resulting response of API.
|
78
|
+
def send_notification(params)
|
79
|
+
room_id = self.room_id || params.delete(:room_id)
|
80
|
+
raise ArgumentError.new("room_id required") unless room_id
|
81
|
+
call_api(:method => :post, :uri => @api_base.merge("room/#{room_id}/notification"), :body_params => params)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Issues reply message API.
|
85
|
+
# @param [Hash] params Parameters for reply message API with :room_id.
|
86
|
+
# @option params [String] :room_id Room ID. Optional but mandatory for global authority.
|
87
|
+
# @return [Hash] Resulting response of API.
|
88
|
+
def reply_message(params)
|
89
|
+
room_id = self.room_id || params.delete(:room_id)
|
90
|
+
raise ArgumentError.new("room_id required") unless room_id
|
91
|
+
call_api(:method => :post, :uri => @api_base.merge("room/#{room_id}/reply"), :body_params => params)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Issues get all rooms API.
|
95
|
+
# @param [Hash] params Parameters for get all rooms API.
|
96
|
+
# @return [HipTail::Rooms]
|
97
|
+
def get_all_rooms(params = {})
|
98
|
+
res = call_api(:method => :get, :uri => @api_base.merge("room"), :query_params => params)
|
99
|
+
Rooms.new(res)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Issues get room API.
|
103
|
+
# @param [Hash] params Parameters for get all room API.
|
104
|
+
# @option params [String] :room_id Room ID. Optional but mandatory for global authority.
|
105
|
+
# @return [HipTail::Room::Detail]
|
106
|
+
def get_room(params)
|
107
|
+
room_id = self.room_id || params.delete(:room_id)
|
108
|
+
raise ArgumentError.new("room_id required") unless room_id
|
109
|
+
res = call_api(:method => :get, :uri => @api_base.merge("room/#{room_id}"), :query_params => params)
|
110
|
+
Room::Detail.new(res)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Issues get all members API.
|
114
|
+
# @param [Hash] params Parameters for get all members API.
|
115
|
+
# @return [HipTail::Users]
|
116
|
+
def get_all_members(params)
|
117
|
+
room_id = self.room_id || params.delete(:room_id)
|
118
|
+
raise ArgumentError.new("room_id required") unless room_id
|
119
|
+
res = call_api(:method => :get, :uri => @api_base.merge("room/#{room_id}/member"), :query_params => params)
|
120
|
+
Users.new(res)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Issues get all participants API.
|
124
|
+
# @param [Hash] params Parameters for get all participants API.
|
125
|
+
# @return [HipTail::Users]
|
126
|
+
def get_all_participants(params)
|
127
|
+
room_id = self.room_id || params.delete(:room_id)
|
128
|
+
raise ArgumentError.new("room_id required") unless room_id
|
129
|
+
res = call_api(:method => :get, :uri => @api_base.merge("room/#{room_id}/participant"), :query_params => params)
|
130
|
+
Users.new(res)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Issues add member API.
|
134
|
+
# @param [Hash] params Parameters for add member API with :room_id.
|
135
|
+
# @option params [String] :room_id Room ID. Optional but mandatory for global authority.
|
136
|
+
# @option params [String] :user_id One of :user_id, :user_mention, :user_email is required.
|
137
|
+
# @option params [String] :user_mention
|
138
|
+
# @option params [String] :user_email
|
139
|
+
# @return [Hash] Resulting response of API.
|
140
|
+
def add_member(params)
|
141
|
+
room_id = self.room_id || params.delete(:room_id)
|
142
|
+
raise ArgumentError.new("room_id required") unless room_id
|
143
|
+
|
144
|
+
user_name = user_name_from_params(params)
|
145
|
+
raise ArgumentError.new("user_id or user_mention or user_email required") unless user_name
|
146
|
+
|
147
|
+
call_api(:method => :put, :uri => @api_base.merge("room/#{room_id}/member/#{user_name}"), :body_params => params)
|
148
|
+
end
|
149
|
+
|
150
|
+
# Issues remove member API.
|
151
|
+
# @param [Hash] params Parameters for remove member API with :room_id.
|
152
|
+
# @option params [String] :room_id Room ID. Optional but mandatory for global authority.
|
153
|
+
# @option params [String] :user_id One of :user_id, :user_mention, :user_email is required.
|
154
|
+
# @option params [String] :user_mention
|
155
|
+
# @option params [String] :user_email
|
156
|
+
# @return [Hash] Resulting response of API.
|
157
|
+
def remove_member(params)
|
158
|
+
room_id = self.room_id || params.delete(:room_id)
|
159
|
+
raise ArgumentError.new("room_id required") unless room_id
|
160
|
+
|
161
|
+
user_name = user_name_from_params(params)
|
162
|
+
raise ArgumentError.new("user_id or user_mention or user_email required") unless user_name
|
163
|
+
|
164
|
+
call_api(:method => :delete, :uri => @api_base.merge("room/#{room_id}/member/#{user_name}"), :body_params => params)
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
|
169
|
+
def user_name_from_params(params)
|
170
|
+
user_id = params.delete(:user_id)
|
171
|
+
user_mention = params.delete(:user_mention)
|
172
|
+
user_email = params.delete(:user_email)
|
173
|
+
|
174
|
+
return user_id if user_id
|
175
|
+
return "@" + user_mention if user_mention
|
176
|
+
return user_email if user_email
|
177
|
+
return
|
178
|
+
end
|
179
|
+
|
180
|
+
def call_api(args)
|
181
|
+
uri = URI.parse(args[:uri].to_s)
|
182
|
+
queries = URI.decode_www_form(uri.query || '').map { |pair| [ pair[0].to_sym, pair[1] ] }
|
183
|
+
# XXX Array or Hash, which is better?
|
184
|
+
query = Hash[*queries.flatten(1)].merge(args[:query_params] || {})
|
185
|
+
query[:auth_token] = token
|
186
|
+
uri.query = query.size > 0 ? URI.encode_www_form(query) : nil
|
187
|
+
|
188
|
+
headers = {
|
189
|
+
'Content-Type' => 'application/json; charset=UTF-8',
|
190
|
+
}
|
191
|
+
|
192
|
+
if args[:body_params]
|
193
|
+
body = JSON.generate(args[:body_params] || {})
|
194
|
+
headers['Content-Length'] = body.bytesize.to_s
|
195
|
+
else
|
196
|
+
body = nil
|
197
|
+
end
|
198
|
+
|
199
|
+
case args[:method].to_s.downcase
|
200
|
+
when 'get'
|
201
|
+
req = Net::HTTP::Get.new(uri.request_uri, headers)
|
202
|
+
when 'post'
|
203
|
+
req = Net::HTTP::Post.new(uri.request_uri, headers)
|
204
|
+
when 'put'
|
205
|
+
req = Net::HTTP::Put.new(uri.request_uri, headers)
|
206
|
+
when 'delete'
|
207
|
+
req = Net::HTTP::Delete.new(uri.request_uri, headers)
|
208
|
+
else
|
209
|
+
raise
|
210
|
+
end
|
211
|
+
|
212
|
+
req.body = body if body
|
213
|
+
|
214
|
+
res = http.start do |http|
|
215
|
+
http.request(req)
|
216
|
+
end
|
217
|
+
|
218
|
+
if res.content_type =~ %r{\A application/json}x
|
219
|
+
return JSON.parse(res.body)
|
220
|
+
else
|
221
|
+
return {}
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def token
|
226
|
+
if !@token || @token.expired?
|
227
|
+
@token = oauth2_client.client_credentials.get_token( :scope => "send_notification send_message admin_room view_group" )
|
228
|
+
end
|
229
|
+
|
230
|
+
@token.token
|
231
|
+
end
|
232
|
+
|
233
|
+
def oauth2_client
|
234
|
+
unless @client
|
235
|
+
@client = OAuth2::Client.new(
|
236
|
+
@oauth_id, @oauth_secret,
|
237
|
+
:authorize_url => @authorization_url,
|
238
|
+
:token_url => @token_url,
|
239
|
+
)
|
240
|
+
end
|
241
|
+
|
242
|
+
@client
|
243
|
+
end
|
244
|
+
|
245
|
+
def http
|
246
|
+
unless @http
|
247
|
+
@http = Net::HTTP.new(@api_base.host, @api_base.port)
|
248
|
+
@http.use_ssl = true if @api_base.scheme == 'https'
|
249
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
250
|
+
if ENV["DEBUG_HTTP"]
|
251
|
+
@http.set_debug_output($stderr)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
@http.clone
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'hiptail/atom'
|
2
|
+
|
3
|
+
module HipTail
|
4
|
+
class Event
|
5
|
+
attr_accessor :authority
|
6
|
+
attr_reader :raw
|
7
|
+
|
8
|
+
# @return [HipTail::Event]
|
9
|
+
def initialize(params)
|
10
|
+
@raw = params.dup
|
11
|
+
end
|
12
|
+
|
13
|
+
# @attribute [r] type
|
14
|
+
# @return [String]
|
15
|
+
def type
|
16
|
+
@raw['event']
|
17
|
+
end
|
18
|
+
|
19
|
+
# @attribute [r] oauth_client_id
|
20
|
+
# @return [String]
|
21
|
+
def oauth_client_id
|
22
|
+
@raw['oauth_client_id']
|
23
|
+
end
|
24
|
+
|
25
|
+
# @attribute [r] webhook_id
|
26
|
+
# @return [String]
|
27
|
+
def webhook_id
|
28
|
+
@raw['webhook_id']
|
29
|
+
end
|
30
|
+
|
31
|
+
class << self
|
32
|
+
# @param [Hash] params
|
33
|
+
# @return [HipTail::Event]
|
34
|
+
def parse(params)
|
35
|
+
type = params['event']
|
36
|
+
|
37
|
+
case params['event']
|
38
|
+
when 'room_message'
|
39
|
+
return Event::RoomMessage.new(params)
|
40
|
+
when 'room_notification'
|
41
|
+
return Event::RoomNotification.new(params)
|
42
|
+
when 'room_enter'
|
43
|
+
return Event::RoomEnter.new(params)
|
44
|
+
when 'room_exit'
|
45
|
+
return Event::RoomExit.new(params)
|
46
|
+
else
|
47
|
+
return Event.new(params)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Event::RoomMessaging < Event
|
54
|
+
# @abstract
|
55
|
+
# @attribute [r] message
|
56
|
+
# @return [HipTail::Messsage]
|
57
|
+
def message
|
58
|
+
raise
|
59
|
+
end
|
60
|
+
|
61
|
+
# @attribute [r] room
|
62
|
+
# @return [HipTail::Room]
|
63
|
+
def room
|
64
|
+
@room ||= Room.new(@raw['item']['room'])
|
65
|
+
@room
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Event::RoomMessage < Event::RoomMessaging
|
70
|
+
# @attribute [r] message
|
71
|
+
# @return [HipTail::Messsage::Talk]
|
72
|
+
def message
|
73
|
+
@message ||= Message::Talk.new(@raw['item']['message'])
|
74
|
+
@message
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class Event::RoomNotification < Event::RoomMessaging
|
79
|
+
# @attribute [r] message
|
80
|
+
# @return [HipTail::Messsage::Notification]
|
81
|
+
def message
|
82
|
+
@message ||= Message::Notification.new(@raw['item']['message'])
|
83
|
+
@message
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class Event::RoomVisiting < Event
|
88
|
+
# @attribute [r] sender
|
89
|
+
# @return [HipTail::User]
|
90
|
+
def sender
|
91
|
+
@sender ||= User.create(@raw['item']['sender'])
|
92
|
+
@sender
|
93
|
+
end
|
94
|
+
|
95
|
+
# @attribute [r] room
|
96
|
+
# @return [HipTail::Room]
|
97
|
+
def room
|
98
|
+
@room ||= Room.new(@raw['item']['room'])
|
99
|
+
@room
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class Event::RoomEnter < Event::RoomVisiting
|
104
|
+
end
|
105
|
+
|
106
|
+
class Event::RoomExit < Event::RoomVisiting
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,234 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'uri'
|
3
|
+
require 'open-uri'
|
4
|
+
|
5
|
+
require 'hiptail/event'
|
6
|
+
require 'hiptail/authority'
|
7
|
+
require 'hiptail/authority/provider'
|
8
|
+
|
9
|
+
module HipTail
|
10
|
+
class Manager
|
11
|
+
# A new instance of HipTail::Manager.
|
12
|
+
# @param [Hash] params ({})
|
13
|
+
# @option params [HipTail::AuthorityProvider] :authority_provider (new instance of HipTail::MemoryAuthorityProvider)
|
14
|
+
# @return [HipTail::Manager]
|
15
|
+
def initialize(params = {})
|
16
|
+
@authority_provider = params[:authority_provider] || MemoryAuthorityProvider.new
|
17
|
+
|
18
|
+
@authority_manager = AuthorityManager.new(@authority_provider)
|
19
|
+
|
20
|
+
@hook = {}
|
21
|
+
[
|
22
|
+
:install, :uninstall,
|
23
|
+
:event,
|
24
|
+
:room_messaging, :room_message, :room_notification,
|
25
|
+
:room_visiting, :room_enter, :room_exit,
|
26
|
+
].each do |hook_type|
|
27
|
+
@hook[hook_type] = {}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [HipTail::AuthorityProvider]
|
32
|
+
attr_reader :authority_provider
|
33
|
+
|
34
|
+
# @param [HipTail::AuthorityProvider] provider
|
35
|
+
# @return [HipTail::AuthorityProvider]
|
36
|
+
def authority_provider=(provider)
|
37
|
+
@authority_provider = @authority_manager.authority_provider = provider
|
38
|
+
end
|
39
|
+
|
40
|
+
# Retrieves authority from oauth_id
|
41
|
+
# @attribute [r] authority
|
42
|
+
# @example
|
43
|
+
# authority = manager.authority[oauth_id]
|
44
|
+
# @return [HipTail::Manager::AuthorityManager]
|
45
|
+
def authority
|
46
|
+
@authority_manager
|
47
|
+
end
|
48
|
+
|
49
|
+
# Registers hook on installation.
|
50
|
+
# @return [String] Hook ID
|
51
|
+
# @yield [authority]
|
52
|
+
# @yield [HipTail::Authority] authority
|
53
|
+
def on_install(&block)
|
54
|
+
register_hook :install, block
|
55
|
+
end
|
56
|
+
|
57
|
+
# Registers hook on uninstallation.
|
58
|
+
# @return [String] Hook ID
|
59
|
+
# @yield [oauth_id]
|
60
|
+
# @yield [String] oauth_id
|
61
|
+
def on_uninstall(&block)
|
62
|
+
register_hook :uninstall, block
|
63
|
+
end
|
64
|
+
|
65
|
+
# Registers hook on events.
|
66
|
+
# @return [String] Hook ID
|
67
|
+
# @yield [event]
|
68
|
+
# @yield [HipTail::Event] event
|
69
|
+
def on_event(&block)
|
70
|
+
register_hook :event, block
|
71
|
+
end
|
72
|
+
|
73
|
+
# Registers hook on messaging events (room_message and room_notification).
|
74
|
+
# @return [String] Hook ID
|
75
|
+
# @yield [event]
|
76
|
+
# @yield [HipTail::Event::RoomMessaging] event
|
77
|
+
def on_room_messaging(&block)
|
78
|
+
register_hook :room_messaging, block
|
79
|
+
end
|
80
|
+
|
81
|
+
# Registers hook on room_message event.
|
82
|
+
# @return [String] Hook ID
|
83
|
+
# @yield [event]
|
84
|
+
# @yield [HipTail::Event::RoomMessage] event
|
85
|
+
def on_room_message(&block)
|
86
|
+
register_hook :room_message, block
|
87
|
+
end
|
88
|
+
|
89
|
+
# Registers hook on room_notification event.
|
90
|
+
# @return [String] Hook ID
|
91
|
+
# @yield [event]
|
92
|
+
# @yield [HipTail::Event::RoomNotification] event
|
93
|
+
def on_room_notification(&block)
|
94
|
+
register_hook :room_notification, block
|
95
|
+
end
|
96
|
+
|
97
|
+
# Registers hook on room visiting event (room_enter and room_exit).
|
98
|
+
# @return [String] Hook ID
|
99
|
+
# @yield [event]
|
100
|
+
# @yield [HipTail::Event::RoomVisiting] event
|
101
|
+
def on_room_visiting(&block)
|
102
|
+
register_hook :room_visiting, block
|
103
|
+
end
|
104
|
+
|
105
|
+
# Registers hook on room_enter event.
|
106
|
+
# @return [String] Hook ID
|
107
|
+
# @yield [event]
|
108
|
+
# @yield [HipTail::Event::RoomEnter] event
|
109
|
+
def on_room_enter(&block)
|
110
|
+
register_hook :room_enter, block
|
111
|
+
end
|
112
|
+
|
113
|
+
# Registers hook on room_exit event.
|
114
|
+
# @return [String] Hook ID
|
115
|
+
# @yield [event]
|
116
|
+
# @yield [HipTail::Event::RoomExit] event
|
117
|
+
def on_room_exit(&block)
|
118
|
+
register_hook :room_exit, block
|
119
|
+
end
|
120
|
+
|
121
|
+
# Handles installing request.
|
122
|
+
# @param [Hash] params Request object (originally represented in JSON) from HipChat Server on installation.
|
123
|
+
# @return [void]
|
124
|
+
def handle_install(params)
|
125
|
+
authority = build_authority(params)
|
126
|
+
|
127
|
+
@authority_provider.register(authority.oauth_id, authority)
|
128
|
+
|
129
|
+
call_hooks :install, authority
|
130
|
+
end
|
131
|
+
|
132
|
+
# Handles uninstalling request.
|
133
|
+
# @note Uninstall event will be fired after uninstallation on the server.
|
134
|
+
# So you cannot use oauth information to do something (e.g. sending notification) on uninstallation phase.
|
135
|
+
# @param [String] oauth_id Corresponding OAuth ID
|
136
|
+
# @return [void]
|
137
|
+
def handle_uninstall(oauth_id)
|
138
|
+
call_hooks :uninstall, oauth_id
|
139
|
+
|
140
|
+
@authority_provider.unregister(oauth_id)
|
141
|
+
end
|
142
|
+
|
143
|
+
# Handles events (room_message, room_enter, etc.).
|
144
|
+
# @param [Hash] params Request object (originally represented in JSON) from HipChat Server on installation.
|
145
|
+
# @return [void]
|
146
|
+
def handle_event(params)
|
147
|
+
event = Event.parse(params)
|
148
|
+
event.authority = self.authority[event.oauth_client_id]
|
149
|
+
|
150
|
+
call_hooks :event, event
|
151
|
+
|
152
|
+
if event.is_a?(Event::RoomMessaging)
|
153
|
+
call_hooks :room_messaging, event
|
154
|
+
|
155
|
+
case event
|
156
|
+
when Event::RoomMessage
|
157
|
+
call_hooks :room_message, event
|
158
|
+
when Event::RoomNotification
|
159
|
+
call_hooks :room_notification, event
|
160
|
+
end
|
161
|
+
elsif event.is_a?(Event::RoomVisiting)
|
162
|
+
call_hooks :room_visiting, event
|
163
|
+
|
164
|
+
case event
|
165
|
+
when Event::RoomEnter
|
166
|
+
call_hooks :room_enter, event
|
167
|
+
when Event::RoomExit
|
168
|
+
call_hooks :room_exit, event
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# Registers a hook.
|
174
|
+
# @param [Symbol] hook_type
|
175
|
+
# @param [Proc] block
|
176
|
+
# @param [String] hook_id
|
177
|
+
# @return [String] Hook ID
|
178
|
+
def register_hook(hook_type, block, hook_id = nil)
|
179
|
+
hook_id ||= block.object_id.to_s
|
180
|
+
@hook[hook_type][hook_id] = block
|
181
|
+
return hook_id
|
182
|
+
end
|
183
|
+
|
184
|
+
# Unregisters a hook.
|
185
|
+
# @param [Symbol] hook_type
|
186
|
+
# @param [String] hook_id
|
187
|
+
# @return [Proc] Unregistered procedure
|
188
|
+
def unregister_hook(hook_type, hook_id = nil)
|
189
|
+
@hook[hook_type].delete(hook_id.to_s)
|
190
|
+
end
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
def call_hooks(hook_type, *args)
|
195
|
+
@hook[hook_type].values.each do |block|
|
196
|
+
block.call(*args)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def build_authority(params)
|
201
|
+
server_cap = JSON.parse(URI.parse(params['capabilitiesUrl']).read)
|
202
|
+
oauth2_info = server_cap['capabilities']['oauth2Provider']
|
203
|
+
api_base = server_cap['links']['api']
|
204
|
+
|
205
|
+
HipTail::Authority.new(
|
206
|
+
:oauth_id => params['oauthId'],
|
207
|
+
:oauth_secret => params['oauthSecret'],
|
208
|
+
:room_id => params['roomId'],
|
209
|
+
:group_id => params['groupId'],
|
210
|
+
:authorization_url => oauth2_info['authorizationUrl'],
|
211
|
+
:token_url => oauth2_info['tokenUrl'],
|
212
|
+
:api_base => server_cap['links']['api'],
|
213
|
+
)
|
214
|
+
end
|
215
|
+
|
216
|
+
# @private
|
217
|
+
class AuthorityManager
|
218
|
+
# @return [HipTail::AuthorityProvider]
|
219
|
+
attr_accessor :authority_provider
|
220
|
+
|
221
|
+
# @param [HipTail::AuthorityProvider] authority_provider
|
222
|
+
# @return [HipTail::Manager::AuthorityManager]
|
223
|
+
def initialize(authority_provider)
|
224
|
+
@authority_provider = authority_provider
|
225
|
+
end
|
226
|
+
|
227
|
+
# @param [String] oauth_id
|
228
|
+
# @return [HipTail::Authority]
|
229
|
+
def [](oauth_id)
|
230
|
+
@authority_provider.get(oauth_id)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|