hipchat 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,111 @@
1
+ require 'hipchat/api_version'
2
+
3
+ module HipChat
4
+
5
+ class Client
6
+ include HTTParty
7
+
8
+ format :json
9
+
10
+ def initialize(token, options={})
11
+ @token = token
12
+ @api_version = options[:api_version]
13
+ @api = HipChat::ApiVersion::Client.new(@api_version)
14
+ self.class.base_uri(@api.base_uri)
15
+ http_proxy = options[:http_proxy] || ENV['http_proxy']
16
+ setup_proxy(http_proxy) if http_proxy
17
+ end
18
+
19
+ def rooms
20
+ @rooms ||= _rooms
21
+ end
22
+
23
+ def [](name)
24
+ Room.new(@token, :room_id => name, :api_version => @api_version)
25
+ end
26
+
27
+ def create_room(name, options={})
28
+ if @api.version == 'v1' && options[:owner_user_id].nil?
29
+ raise RoomMissingOwnerUserId, "V1 API Requres owner_user_id"
30
+ end
31
+
32
+ if name.length > 50
33
+ raise RoomNameTooLong, "Room name #{name} is #{name.length} characters long. Limit is 50."
34
+ end
35
+ unless options[:guest_access].nil?
36
+ options[:guest_access] = @api.bool_val(options[:guest_access])
37
+ end
38
+
39
+ response = self.class.post(@api.create_room_config[:url],
40
+ :query => { :auth_token => @token },
41
+ :body => {
42
+ :name => name
43
+ }.merge(options).send(@api.create_room_config[:body_format]),
44
+ :headers => @api.headers
45
+ )
46
+
47
+ case response.code
48
+ when 201, 200 #CREATED
49
+ response.parsed_response
50
+ when 400
51
+ raise UnknownRoom, "Error: #{response.message}"
52
+ when 401
53
+ raise Unauthorized, "Access denied"
54
+ else
55
+ raise UnknownResponseCode, "Unexpected error #{response.code}"
56
+ end
57
+ end
58
+
59
+ def user(name)
60
+ User.new(@token, :user_id => name, :api_version => @api_version)
61
+ end
62
+
63
+ def users
64
+ @users ||= _users
65
+ end
66
+
67
+ private
68
+ def setup_proxy(proxy_url)
69
+ proxy_url = URI.parse(proxy_url)
70
+
71
+ self.class.http_proxy(proxy_url.host, proxy_url.port,
72
+ proxy_url.user, proxy_url.password)
73
+ HipChat::Room.http_proxy(proxy_url.host, proxy_url.port,
74
+ proxy_url.user, proxy_url.password)
75
+ end
76
+
77
+ def _rooms
78
+ response = self.class.get(@api.rooms_config[:url],
79
+ :query => {
80
+ :auth_token => @token
81
+ },
82
+ :headers => @api.headers
83
+ )
84
+ case response.code
85
+ when 200
86
+ response[@api.rooms_config[:data_key]].map do |r|
87
+ Room.new(@token, r.merge(:api_version => @api_version, :room_id => r['id']))
88
+ end
89
+ else
90
+ raise UnknownResponseCode, "Unexpected #{response.code} for room"
91
+ end
92
+ end
93
+
94
+ def _users
95
+ response = self.class.get(@api.users_config[:url],
96
+ :query => {
97
+ :auth_token => @token
98
+ },
99
+ :headers => @api.headers
100
+ )
101
+ case response.code
102
+ when 200
103
+ response[@api.users_config[:data_key]].map do |r|
104
+ Room.new(@token, r.merge(:api_version => @api_version, :user_id => r['id']))
105
+ end
106
+ else
107
+ raise UnknownResponseCode, "Unexpected #{response.code} for room"
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,10 @@
1
+ module HipChat
2
+ class UnknownRoom < StandardError; end
3
+ class RoomNameTooLong < StandardError; end
4
+ class RoomMissingOwnerUserId < StandardError; end
5
+ class Unauthorized < StandardError; end
6
+ class UsernameTooLong < StandardError; end
7
+ class UnknownResponseCode < StandardError; end
8
+ class UnknownUser < StandardError; end
9
+ class InvalidApiVersion < StandardError; end
10
+ end
@@ -12,6 +12,7 @@ namespace :hipchat do
12
12
  :user => ENV['HIPCHAT_USER'],
13
13
  :notify => ENV['NOTIFY'],
14
14
  :room => ENV['ROOM'],
15
+ :color => ENV['COLOR'],
15
16
  :token => ENV['TOKEN'],
16
17
  :api_version => ENV['API_VERSION']
17
18
  }.reject { |k, v| v.blank? }
@@ -40,6 +41,6 @@ namespace :hipchat do
40
41
 
41
42
  client = HipChat::Client.new(options[:token], options)
42
43
 
43
- client[options[:room]].send(options[:user], options[:message], :notify => options[:notify])
44
+ client[options[:room]].send(options[:user], options[:message], { :color => options[:color], :notify => options[:notify] })
44
45
  end
45
46
  end
@@ -0,0 +1,193 @@
1
+ require 'httparty'
2
+ require 'ostruct'
3
+
4
+ module HipChat
5
+
6
+ class Room < OpenStruct
7
+ include HTTParty
8
+
9
+ format :json
10
+
11
+ def initialize(token, params)
12
+ @token = token
13
+ @api = HipChat::ApiVersion::Room.new(params[:room_id],
14
+ params.delete(:api_version))
15
+ self.class.base_uri(@api.base_uri)
16
+ super(params)
17
+ end
18
+
19
+ # Retrieve data for this room
20
+ def get_room
21
+ response = self.class.get(@api.get_room_config[:url],
22
+ :query => {:auth_token => @token },
23
+ :headers => @api.headers
24
+ )
25
+
26
+ case response.code
27
+ when 200
28
+ response.parsed_response
29
+ when 404
30
+ raise UnknownRoom, "Unknown room: `#{room_id}'"
31
+ when 401
32
+ raise Unauthorized, "Access denied to room `#{room_id}'"
33
+ else
34
+ raise UnknownResponseCode, "Unexpected #{response.code} for room `#{room_id}'"
35
+ end
36
+ end
37
+
38
+ # Invite user to this room
39
+ def invite(user, reason="")
40
+ response = self.class.post(@api.invite_config[:url]+"/#{user}",
41
+ :query => { :auth_token => @token },
42
+ :body => {
43
+ :reason => reason
44
+ }.to_json,
45
+ :headers => @api.headers)
46
+
47
+ case response.code
48
+ when 200, 204; true
49
+ when 404
50
+ raise UnknownRoom, "Unknown room: `#{room_id}'"
51
+ when 401
52
+ raise Unauthorized, "Access denied to room `#{room_id}'"
53
+ else
54
+ raise UnknownResponseCode, "Unexpected #{response.code} for room `#{room_id}'"
55
+ end
56
+ end
57
+
58
+
59
+ # Send a message to this room.
60
+ #
61
+ # Usage:
62
+ #
63
+ # # Default
64
+ # send 'nickname', 'some message'
65
+ #
66
+ # # Notify users and color the message red
67
+ # send 'nickname', 'some message', :notify => true, :color => 'red'
68
+ #
69
+ # # Notify users (deprecated)
70
+ # send 'nickname', 'some message', true
71
+ #
72
+ # Options:
73
+ #
74
+ # +color+:: "yellow", "red", "green", "purple", or "random"
75
+ # (default "yellow")
76
+ # +notify+:: true or false
77
+ # (default false)
78
+ def send(from, message, options_or_notify = {})
79
+ if from.length > 15
80
+ raise UsernameTooLong, "Username #{from} is `#{from.length} characters long. Limit is 15'"
81
+ end
82
+ options = if options_or_notify == true or options_or_notify == false
83
+ warn "DEPRECATED: Specify notify flag as an option (e.g., :notify => true)"
84
+ { :notify => options_or_notify }
85
+ else
86
+ options_or_notify || {}
87
+ end
88
+
89
+ options = { :color => 'yellow', :notify => false }.merge options
90
+
91
+ response = self.class.post(@api.send_config[:url],
92
+ :query => { :auth_token => @token },
93
+ :body => {
94
+ :room_id => room_id,
95
+ :from => from,
96
+ :message => message,
97
+ :message_format => options[:message_format] || 'html',
98
+ :color => options[:color],
99
+ :notify => @api.bool_val(options[:notify])
100
+ }.send(@api.send_config[:body_format]),
101
+ :headers => @api.headers
102
+ )
103
+
104
+ case response.code
105
+ when 200, 204; true
106
+ when 404
107
+ raise UnknownRoom, "Unknown room: `#{room_id}'"
108
+ when 401
109
+ raise Unauthorized, "Access denied to room `#{room_id}'"
110
+ else
111
+ raise UnknownResponseCode, "Unexpected #{response.code} for room `#{room_id}'"
112
+ end
113
+ end
114
+
115
+ # Change this room's topic
116
+ #
117
+ # Usage:
118
+ #
119
+ # # Default
120
+ # topic 'my awesome topic'
121
+ #
122
+ # Options:
123
+ #
124
+ # +from+:: the name of the person changing the topic
125
+ # (default "API")
126
+ def topic(new_topic, options = {})
127
+
128
+ options = { :from => 'API' }.merge options
129
+
130
+ response = self.class.send(@api.topic_config[:method], @api.topic_config[:url],
131
+ :query => { :auth_token => @token },
132
+ :body => {
133
+ :room_id => room_id,
134
+ :from => options[:from],
135
+ :topic => new_topic
136
+ }.send(@api.topic_config[:body_format]),
137
+ :headers => @api.headers
138
+ )
139
+
140
+ case response.code
141
+ when 204,200; true
142
+ when 404
143
+ raise UnknownRoom, "Unknown room: `#{room_id}'"
144
+ when 401
145
+ raise Unauthorized, "Access denied to room `#{room_id}'"
146
+ else
147
+ raise UnknownResponseCode, "Unexpected #{response.code} for room `#{room_id}'"
148
+ end
149
+ end
150
+
151
+ # Pull this room's history
152
+ #
153
+ # Usage
154
+ #
155
+ # # Default
156
+ #
157
+ #
158
+ # Options
159
+ #
160
+ # +date+:: Whether to return a specific day (YYYY-MM-DD format) or recent
161
+ # (default "recent")
162
+ # +timezone+:: Your timezone. Supported timezones are at: https://www.hipchat.com/docs/api/timezones
163
+ # (default "UTC")
164
+ # +format+:: Format to retrieve the history in. Valid options are JSON and XML
165
+ # (default "JSON")
166
+ def history(options = {})
167
+
168
+ options = { :date => 'recent', :timezone => 'UTC', :format => 'JSON' }.merge options
169
+
170
+ response = self.class.get(@api.history_config[:url],
171
+ :query => {
172
+ :room_id => room_id,
173
+ :date => options[:date],
174
+ :timezone => options[:timezone],
175
+ :format => options[:format],
176
+ :auth_token => @token,
177
+ },
178
+ :headers => @api.headers
179
+ )
180
+
181
+ case response.code
182
+ when 200
183
+ response.body
184
+ when 404
185
+ raise UnknownRoom, "Unknown room: `#{room_id}'"
186
+ when 401
187
+ raise Unauthorized, "Access denied to room `#{room_id}'"
188
+ else
189
+ raise UnknownResponseCode, "Unexpected #{response.code} for room `#{room_id}'"
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,62 @@
1
+ require 'httparty'
2
+ require 'ostruct'
3
+
4
+ module HipChat
5
+
6
+ class User < OpenStruct
7
+ include HTTParty
8
+
9
+ format :json
10
+
11
+ def initialize(token, params)
12
+ @token = token
13
+ @api = HipChat::ApiVersion::User.new(params[:user_id],
14
+ params.delete(:api_version))
15
+ self.class.base_uri(@api.base_uri)
16
+ super(params)
17
+ end
18
+
19
+ #
20
+ # Send a private message to user.
21
+ #
22
+ def send(message)
23
+ response = self.class.post(@api.send_config[:url],
24
+ :query => { :auth_token => @token },
25
+ :body => {
26
+ :message => message
27
+ }.send(@api.send_config[:body_format]),
28
+ :headers => @api.headers
29
+ )
30
+
31
+ case response.code
32
+ when 200, 204; true
33
+ when 404
34
+ raise UnknownUser, "Unknown user: `#{user_id}'"
35
+ when 401
36
+ raise Unauthorized, "Access denied to user `#{user_id}'"
37
+ else
38
+ raise UnknownResponseCode, "Unexpected #{response.code} for private message to `#{user_id}'"
39
+ end
40
+ end
41
+
42
+ #
43
+ # Get a user's details.
44
+ #
45
+ def view
46
+ puts "#{@api.base_uri}#{@api.view_config[:url]}"
47
+ response = self.class.post(@api.view_config[:url],
48
+ :query => { :auth_token => @token },
49
+ :headers => @api.headers
50
+ )
51
+
52
+ case response.code
53
+ when 200
54
+ response[@api.users_config[:data_key]].map do |r|
55
+ User.new(@token, r.merge(:api_version => @api_version))
56
+ end
57
+ else
58
+ raise UnknownResponseCode, "Unexpected #{response.code} for view message to `#{user_id}'"
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,3 +1,3 @@
1
1
  module HipChat
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -0,0 +1,172 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "HipChat (API V1)" do
4
+
5
+ subject { HipChat::Client.new("blah", :api_version => @api_version) }
6
+
7
+ let(:room) { subject["Hipchat"] }
8
+
9
+ describe "#history" do
10
+ include_context "HipChatV1"
11
+ it "is successful without custom options" do
12
+ mock_successful_history()
13
+
14
+ room.history().should be_true
15
+ end
16
+
17
+ it "is successful with custom options" do
18
+ mock_successful_history(:timezone => 'America/Los_Angeles', :date => '2010-11-19')
19
+ room.history(:timezone => 'America/Los_Angeles', :date => '2010-11-19').should be_true
20
+ end
21
+
22
+ it "fails when the room doen't exist" do
23
+ mock(HipChat::Room).get(anything, anything) {
24
+ OpenStruct.new(:code => 404)
25
+ }
26
+
27
+ lambda { room.history }.should raise_error(HipChat::UnknownRoom)
28
+ end
29
+
30
+ it "fails when we're not allowed to do so" do
31
+ mock(HipChat::Room).get(anything, anything) {
32
+ OpenStruct.new(:code => 401)
33
+ }
34
+
35
+ lambda { room.history }.should raise_error(HipChat::Unauthorized)
36
+ end
37
+
38
+ it "fails if we get an unknown response code" do
39
+ mock(HipChat::Room).get(anything, anything) {
40
+ OpenStruct.new(:code => 403)
41
+ }
42
+
43
+ lambda { room.history }.
44
+ should raise_error(HipChat::UnknownResponseCode)
45
+ end
46
+ end
47
+
48
+ describe "#topic" do
49
+ include_context "HipChatV1"
50
+ it "is successful without custom options" do
51
+ mock_successful_topic_change("Nice topic")
52
+
53
+ room.topic("Nice topic").should be_true
54
+ end
55
+
56
+ it "is successful with a custom from" do
57
+ mock_successful_topic_change("Nice topic", :from => "Me")
58
+
59
+ room.topic("Nice topic", :from => "Me").should be_true
60
+ end
61
+
62
+ it "fails when the room doesn't exist" do
63
+ mock(HipChat::Room).post(anything, anything) {
64
+ OpenStruct.new(:code => 404)
65
+ }
66
+
67
+ lambda { room.topic "" }.should raise_error(HipChat::UnknownRoom)
68
+ end
69
+
70
+ it "fails when we're not allowed to do so" do
71
+ mock(HipChat::Room).post(anything, anything) {
72
+ OpenStruct.new(:code => 401)
73
+ }
74
+
75
+ lambda { room.topic "" }.should raise_error(HipChat::Unauthorized)
76
+ end
77
+
78
+ it "fails if we get an unknown response code" do
79
+ mock(HipChat::Room).post(anything, anything) {
80
+ OpenStruct.new(:code => 403)
81
+ }
82
+
83
+ lambda { room.topic "" }.
84
+ should raise_error(HipChat::UnknownResponseCode)
85
+ end
86
+ end
87
+
88
+ describe "#send" do
89
+ include_context "HipChatV1"
90
+ it "successfully without custom options" do
91
+ mock_successful_send 'Dude', 'Hello world'
92
+
93
+ room.send("Dude", "Hello world").should be_true
94
+ end
95
+
96
+ it "successfully with notifications on as option" do
97
+ mock_successful_send 'Dude', 'Hello world', :notify => 1
98
+
99
+ room.send("Dude", "Hello world", :notify => 1).should be_true
100
+ end
101
+
102
+ it "successfully with custom color" do
103
+ mock_successful_send 'Dude', 'Hello world', :color => 'red'
104
+
105
+ room.send("Dude", "Hello world", :color => 'red').should be_true
106
+ end
107
+
108
+ it "successfully with text message_format" do
109
+ mock_successful_send 'Dude', 'Hello world', :message_format => 'text'
110
+
111
+ room.send("Dude", "Hello world", :message_format => 'text').should be_true
112
+ end
113
+
114
+ it "but fails when the room doesn't exist" do
115
+ mock(HipChat::Room).post(anything, anything) {
116
+ OpenStruct.new(:code => 404)
117
+ }
118
+
119
+ lambda { room.send "", "" }.should raise_error(HipChat::UnknownRoom)
120
+ end
121
+
122
+ it "but fails when we're not allowed to do so" do
123
+ mock(HipChat::Room).post(anything, anything) {
124
+ OpenStruct.new(:code => 401)
125
+ }
126
+
127
+ lambda { room.send "", "" }.should raise_error(HipChat::Unauthorized)
128
+ end
129
+
130
+ it "but fails if the username is more than 15 chars" do
131
+ lambda { room.send "a very long username here", "a message" }.should raise_error(HipChat::UsernameTooLong)
132
+ end
133
+
134
+ it "but fails if we get an unknown response code" do
135
+ mock(HipChat::Room).post(anything, anything) {
136
+ OpenStruct.new(:code => 403)
137
+ }
138
+
139
+ lambda { room.send "", "" }.
140
+ should raise_error(HipChat::UnknownResponseCode)
141
+ end
142
+ end
143
+
144
+ describe "#create" do
145
+ include_context "HipChatV1"
146
+
147
+ it "successfully with room name" do
148
+ mock_successful_room_creation("A Room", :owner_user_id => "123456")
149
+
150
+ subject.create_room("A Room", {:owner_user_id => "123456"}).should be_true
151
+ end
152
+
153
+ it "successfully with custom parameters" do
154
+ mock_successful_room_creation("A Room", {:owner_user_id => "123456", :privacy => "private", :guest_access => "1"})
155
+
156
+ subject.create_room("A Room", {:owner_user_id => "123456", :privacy => "private", :guest_access =>true}).should be_true
157
+ end
158
+
159
+ it "but fails if we dont pass owner_user_id" do
160
+ lambda { subject.create_room("A Room", {:privacy => "private", :guest_access =>true}) }.
161
+ should raise_error(HipChat::RoomMissingOwnerUserId)
162
+ end
163
+ end
164
+
165
+ describe "#send user message" do
166
+ it "fails because API V1 doesn't support user operations" do
167
+
168
+ lambda { HipChat::Client.new("blah", :api_version => @api_version).user('12345678') }.
169
+ should raise_error(HipChat::InvalidApiVersion)
170
+ end
171
+ end
172
+ end