opentok 3.0.3 → 4.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/metrics.yml +17 -0
  3. data/.travis.yml +3 -1
  4. data/CODE_OF_CONDUCT.md +128 -0
  5. data/README.md +312 -28
  6. data/lib/opentok/archive.rb +45 -4
  7. data/lib/opentok/archives.rb +73 -5
  8. data/lib/opentok/broadcast.rb +118 -0
  9. data/lib/opentok/broadcasts.rb +149 -0
  10. data/lib/opentok/client.rb +212 -7
  11. data/lib/opentok/connections.rb +28 -0
  12. data/lib/opentok/constants.rb +1 -1
  13. data/lib/opentok/exceptions.rb +6 -0
  14. data/lib/opentok/opentok.rb +44 -10
  15. data/lib/opentok/session.rb +5 -0
  16. data/lib/opentok/signals.rb +47 -0
  17. data/lib/opentok/sip.rb +33 -0
  18. data/lib/opentok/stream.rb +46 -0
  19. data/lib/opentok/stream_list.rb +18 -0
  20. data/lib/opentok/streams.rb +79 -0
  21. data/lib/opentok/version.rb +1 -1
  22. data/opentok.gemspec +9 -8
  23. data/sample/Broadcast/Gemfile +4 -0
  24. data/sample/Broadcast/README.md +201 -0
  25. data/sample/Broadcast/broadcast_sample.rb +97 -0
  26. data/sample/Broadcast/public/css/sample.css +64 -0
  27. data/sample/Broadcast/public/js/host.js +185 -0
  28. data/sample/Broadcast/public/js/participant.js +85 -0
  29. data/sample/Broadcast/views/host.erb +82 -0
  30. data/sample/Broadcast/views/index.erb +32 -0
  31. data/sample/Broadcast/views/layout.erb +29 -0
  32. data/sample/Broadcast/views/participant.erb +27 -0
  33. data/sample/HelloWorld/public/js/helloworld.js +4 -10
  34. data/sample/HelloWorld/views/index.erb +1 -3
  35. data/spec/cassettes/OpenTok_Archives/calls_layout_on_archive_object.yml +47 -0
  36. data/spec/cassettes/OpenTok_Archives/changes_the_layout_of_an_archive.yml +38 -0
  37. data/spec/cassettes/OpenTok_Archives/http_client_errors/.yml +34 -0
  38. data/spec/cassettes/OpenTok_Archives/should_create_archives.yml +3 -1
  39. data/spec/cassettes/OpenTok_Archives/should_create_audio_only_archives.yml +3 -1
  40. data/spec/cassettes/OpenTok_Archives/should_create_custom_layout_archives.yml +50 -0
  41. data/spec/cassettes/OpenTok_Archives/should_create_hd_archives.yml +54 -0
  42. data/spec/cassettes/OpenTok_Archives/should_create_individual_archives.yml +3 -1
  43. data/spec/cassettes/OpenTok_Archives/should_create_named_archives.yml +3 -1
  44. data/spec/cassettes/OpenTok_Archives/should_delete_an_archive_by_id.yml +3 -1
  45. data/spec/cassettes/OpenTok_Archives/should_find_archives_by_id.yml +3 -1
  46. data/spec/cassettes/OpenTok_Archives/should_find_archives_with_unknown_properties.yml +3 -1
  47. data/spec/cassettes/OpenTok_Archives/should_find_expired_archives.yml +3 -1
  48. data/spec/cassettes/OpenTok_Archives/should_find_paused_archives_by_id.yml +3 -1
  49. data/spec/cassettes/OpenTok_Archives/should_stop_archives.yml +3 -1
  50. data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_all_archives.yml +3 -1
  51. data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_archives_with_an_offset.yml +3 -1
  52. data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_count_number_of_archives.yml +3 -1
  53. data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_part_of_the_archives_when_using_offset_and_count.yml +3 -1
  54. data/spec/cassettes/OpenTok_Archives/when_many_archives_are_created/should_return_session_archives.yml +3 -1
  55. data/spec/cassettes/OpenTok_Broadcasts/calls_layout_on_broadcast_object.yml +57 -0
  56. data/spec/cassettes/OpenTok_Broadcasts/changes_the_layout_of_a_broadcast.yml +38 -0
  57. data/spec/cassettes/OpenTok_Broadcasts/fetches_a_hls_broadcast_url.yml +52 -0
  58. data/spec/cassettes/OpenTok_Broadcasts/finds_a_broadcast.yml +57 -0
  59. data/spec/cassettes/OpenTok_Broadcasts/starts_a_rtmp_broadcast.yml +61 -0
  60. data/spec/cassettes/OpenTok_Broadcasts/stops_a_broadcast.yml +47 -0
  61. data/spec/cassettes/OpenTok_Connections/forces_a_connection_to_be_terminated.yml +38 -0
  62. data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_always_archived_sessions.yml +3 -1
  63. data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_default_sessions.yml +3 -1
  64. data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_relayed_media_sessions.yml +3 -1
  65. data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_relayed_media_sessions_for_invalid_media_modes.yml +3 -1
  66. data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_relayed_media_sessions_with_a_location_hint.yml +3 -1
  67. data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_routed_media_sessions.yml +3 -1
  68. data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_routed_media_sessions_with_a_location_hint.yml +3 -1
  69. data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/_create_session/creates_sessions_with_a_location_hint.yml +3 -1
  70. data/spec/cassettes/OpenTok_OpenTok/when_initialized_properly/with_an_addendum_to_the_user_agent_string/should_append_the_addendum_to_the_user_agent_header.yml +3 -1
  71. data/spec/cassettes/OpenTok_Signals/receives_a_valid_response_for_a_connection.yml +39 -0
  72. data/spec/cassettes/OpenTok_Signals/receives_a_valid_response_for_all_connections.yml +39 -0
  73. data/spec/cassettes/OpenTok_Sip/receives_a_valid_response.yml +3 -1
  74. data/spec/cassettes/OpenTok_Streams/get_all_streams_information.yml +55 -0
  75. data/spec/cassettes/OpenTok_Streams/get_specific_stream_information.yml +44 -0
  76. data/spec/cassettes/OpenTok_Streams/layout_working_on_two_stream_list.yml +38 -0
  77. data/spec/opentok/archives_spec.rb +84 -1
  78. data/spec/opentok/broadcasts_spec.rb +171 -0
  79. data/spec/opentok/client_spec.rb +51 -0
  80. data/spec/opentok/connection_spec.rb +38 -0
  81. data/spec/opentok/opentok_spec.rb +21 -0
  82. data/spec/opentok/signal_spec.rb +50 -0
  83. data/spec/opentok/streams_spec.rb +75 -0
  84. data/spec/spec_helper.rb +2 -0
  85. metadata +84 -22
@@ -12,18 +12,20 @@ module OpenTok
12
12
  class Client
13
13
  include HTTParty
14
14
 
15
- open_timeout 2 # Set HTTParty default timeout (open/read) to 2 seconds
16
-
17
15
  # TODO: expose a setting for http debugging for developers
18
16
  # debug_output $stdout
19
17
 
20
- def initialize(api_key, api_secret, api_url, ua_addendum="")
18
+ attr_accessor :api_key, :api_secret, :api_url, :ua_addendum, :timeout_length
19
+
20
+ def initialize(api_key, api_secret, api_url, ua_addendum='', opts={})
21
21
  self.class.base_uri api_url
22
22
  self.class.headers({
23
- "User-Agent" => "OpenTok-Ruby-SDK/#{VERSION}" + "-Ruby-Version-#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}" + (ua_addendum ? " #{ua_addendum}" : "")
23
+ "User-Agent" => "OpenTok-Ruby-SDK/#{VERSION}" + "-Ruby-Version-#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}" + (ua_addendum ? " #{ua_addendum}" : "")
24
24
  })
25
25
  @api_key = api_key
26
26
  @api_secret = api_secret
27
+ @timeout_length = opts[:timeout_length] || 2
28
+ self.class.open_timeout @timeout_length
27
29
  end
28
30
 
29
31
  def generate_jwt(api_key, api_secret)
@@ -164,6 +166,72 @@ module OpenTok
164
166
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
165
167
  end
166
168
 
169
+ def layout_archive(archive_id, opts)
170
+ opts.extend(HashExtensions)
171
+ response = self.class.put("/v2/project/#{@api_key}/archive/#{archive_id}/layout", {
172
+ :body => opts.camelize_keys!.to_json,
173
+ :headers => generate_headers("Content-Type" => "application/json")
174
+ })
175
+ case response.code
176
+ when 200
177
+ response
178
+ when 400
179
+ raise OpenTokArchiveError, "Setting the layout failed. The request was invalid or invalid layout options were given."
180
+ when 403
181
+ raise OpenTokAuthenticationError, "Authentication failed. API Key: #{@api_key}"
182
+ when 500
183
+ raise OpenTokError, "Setting the layout failed. OpenTok server error."
184
+ else
185
+ raise OpenTokArchiveError, "Setting the layout failed."
186
+ end
187
+ rescue StandardError => e
188
+ raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
189
+ end
190
+
191
+ def forceDisconnect(session_id, connection_id)
192
+ response = self.class.delete("/v2/project/#{@api_key}/session/#{session_id}/connection/#{connection_id}", {
193
+ :headers => generate_headers("Content-Type" => "application/json")
194
+ })
195
+ case response.code
196
+ when 204
197
+ response
198
+ when 400
199
+ raise ArgumentError, "Force disconnect failed. Connection ID #{connection_id} or Session ID #{session_id} is invalid"
200
+ when 403
201
+ raise OpenTokAuthenticationError, "You are not authorized to forceDisconnect, check your authentication credentials or token type is non-moderator"
202
+ when 404
203
+ raise OpenTokConnectionError, "The client specified by the connection ID: #{connection_id} is not connected to the session"
204
+ end
205
+ rescue StandardError => e
206
+ raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
207
+ end
208
+
209
+ def signal(session_id, connection_id, opts)
210
+ opts.extend(HashExtensions)
211
+ connectionPath = connection_id.to_s.empty? ? "" : "/connection/#{connection_id}"
212
+ url = "/v2/project/#{@api_key}/session/#{session_id}#{connectionPath}/signal"
213
+ response = self.class.post(url, {
214
+ :body => opts.camelize_keys!.to_json,
215
+ :headers => generate_headers("Content-Type" => "application/json")
216
+ })
217
+ case response.code
218
+ when 204
219
+ response
220
+ when 400
221
+ raise ArgumentError, "One of the signal properties — data, type, sessionId or connectionId — is invalid."
222
+ when 403
223
+ raise OpenTokAuthenticationError, "You are not authorized to send the signal. Check your authentication credentials."
224
+ when 404
225
+ raise OpenTokError, "The client specified by the connectionId property is not connected to the session."
226
+ when 413
227
+ raise OpenTokError, "The type string exceeds the maximum length (128 bytes), or the data string exceeds the maximum size (8 kB)."
228
+ else
229
+ raise OpenTokError, "The signal could not be send."
230
+ end
231
+ rescue StandardError => e
232
+ raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
233
+ end
234
+
167
235
  def dial(session_id, token, sip_uri, opts)
168
236
  opts.extend(HashExtensions)
169
237
  body = { "sessionId" => session_id,
@@ -179,14 +247,151 @@ module OpenTok
179
247
  when 200
180
248
  response
181
249
  when 403
182
- raise OpenTokAuthenticationError, "Authentication failed while dialing a sip session. API Key: #{@api_key}"
250
+ raise OpenTokAuthenticationError, "Authentication failed while dialing a SIP session. API Key: #{@api_key}"
183
251
  when 404
184
- raise OpenTokSipError, "The sip session could not be dialed. The Session ID does not exist: #{session_id}"
252
+ raise OpenTokSipError, "The SIP session could not be dialed. The Session ID does not exist: #{session_id}"
253
+ else
254
+ raise OpenTokSipError, "The SIP session could not be dialed"
255
+ end
256
+ rescue StandardError => e
257
+ raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
258
+ end
259
+
260
+ def info_stream(session_id, stream_id)
261
+ streamId = stream_id.to_s.empty? ? '' : "/#{stream_id}"
262
+ url = "/v2/project/#{@api_key}/session/#{session_id}/stream#{streamId}"
263
+ response = self.class.get(url,
264
+ headers: generate_headers('Content-Type' => 'application/json'))
265
+ case response.code
266
+ when 200
267
+ response
268
+ when 400
269
+ raise ArgumentError, 'Invalid request. You did not pass in a valid session ID or stream ID.'
270
+ when 403
271
+ raise OpenTokAuthenticationError, 'Check your authentication credentials. You passed in an invalid OpenTok API key.'
272
+ when 408
273
+ raise ArgumentError, 'You passed in an invalid stream ID.'
274
+ when 500
275
+ raise OpenTokError, 'OpenTok server error.'
185
276
  else
186
- raise OpenTokSipError, "The sip session could not be dialed"
277
+ raise OpenTokError, 'Could not fetch the stream information.'
187
278
  end
188
279
  rescue StandardError => e
189
280
  raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
190
281
  end
282
+
283
+ def layout_streams(session_id, opts)
284
+ opts.extend(HashExtensions)
285
+ response = self.class.put("/v2/project/#{@api_key}/session/#{session_id}/stream", {
286
+ :body => opts.camelize_keys!.to_json,
287
+ :headers => generate_headers("Content-Type" => "application/json")
288
+ })
289
+ case response.code
290
+ when 200
291
+ response
292
+ when 400
293
+ raise OpenTokStreamLayoutError, "Setting the layout failed. The request was invalid or invalid layout options were given."
294
+ when 403
295
+ raise OpenTokAuthenticationError, "Authentication failed. API Key: #{@api_key}"
296
+ when 500
297
+ raise OpenTokError, "Setting the layout failed. OpenTok server error."
298
+ else
299
+ raise OpenTokStreamLayoutError, "Setting the layout failed."
300
+ end
301
+ rescue StandardError => e
302
+ raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
303
+ end
304
+
305
+ def start_broadcast(session_id, opts)
306
+ opts.extend(HashExtensions)
307
+ body = { :sessionId => session_id }.merge(opts.camelize_keys!)
308
+ response = self.class.post("/v2/project/#{@api_key}/broadcast", {
309
+ :body => body.to_json,
310
+ :headers => generate_headers("Content-Type" => "application/json")
311
+ })
312
+ case response.code
313
+ when 200
314
+ response
315
+ when 400
316
+ raise OpenTokBroadcastError, "The broadcast could not be started. The request was invalid or invalid layout options or exceeded the limit of five simultaneous RTMP streams."
317
+ when 403
318
+ raise OpenTokAuthenticationError, "Authentication failed while starting a broadcast. API Key: #{@api_key}"
319
+ when 409
320
+ raise OpenTokBroadcastError, "The broadcast has already been started for this session."
321
+ when 500
322
+ raise OpenTokError, "OpenTok server error."
323
+ else
324
+ raise OpenTokBroadcastError, "The broadcast could not be started"
325
+ end
326
+ rescue StandardError => e
327
+ raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
328
+ end
329
+
330
+ def get_broadcast(broadcast_id)
331
+ response = self.class.get("/v2/project/#{@api_key}/broadcast/#{broadcast_id}", {
332
+ :headers => generate_headers
333
+ })
334
+ case response.code
335
+ when 200
336
+ response
337
+ when 400
338
+ raise OpenTokBroadcastError, "The request was invalid."
339
+ when 403
340
+ raise OpenTokAuthenticationError, "Authentication failed while getting a broadcast. API Key: #{@api_key}"
341
+ when 404
342
+ raise OpenTokBroadcastError, "No matching broadcast found (with the specified ID)"
343
+ when 500
344
+ raise OpenTokError, "OpenTok server error."
345
+ else
346
+ raise OpenTokBroadcastError, "Could not fetch broadcast information."
347
+ end
348
+ rescue StandardError => e
349
+ raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
350
+ end
351
+
352
+ def stop_broadcast(broadcast_id)
353
+ response = self.class.post("/v2/project/#{@api_key}/broadcast/#{broadcast_id}/stop", {
354
+ :headers => generate_headers
355
+ })
356
+ case response.code
357
+ when 200
358
+ response
359
+ when 400
360
+ raise OpenTokBroadcastError, "The request was invalid."
361
+ when 403
362
+ raise OpenTokAuthenticationError, "Authentication failed while stopping a broadcast. API Key: #{@api_key}"
363
+ when 404
364
+ raise OpenTokBroadcastError, "No matching broadcast found (with the specified ID) or it is already stopped"
365
+ when 500
366
+ raise OpenTokError, "OpenTok server error."
367
+ else
368
+ raise OpenTokBroadcastError, "The broadcast could not be stopped."
369
+ end
370
+ rescue StandardError => e
371
+ raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
372
+ end
373
+
374
+ def layout_broadcast(broadcast_id, opts)
375
+ opts.extend(HashExtensions)
376
+ response = self.class.put("/v2/project/#{@api_key}/broadcast/#{broadcast_id}/layout", {
377
+ :body => opts.camelize_keys!.to_json,
378
+ :headers => generate_headers("Content-Type" => "application/json")
379
+ })
380
+ case response.code
381
+ when 200
382
+ response
383
+ when 400
384
+ raise OpenTokBroadcastError, "The layout operation could not be performed. The request was invalid or invalid layout options."
385
+ when 403
386
+ raise OpenTokAuthenticationError, "Authentication failed for broadcast layout. API Key: #{@api_key}"
387
+ when 500
388
+ raise OpenTokError, "OpenTok server error."
389
+ else
390
+ raise OpenTokBroadcastError, "The broadcast layout could not be performed."
391
+ end
392
+ rescue StandardError => e
393
+ raise OpenTokError, "Failed to connect to OpenTok. Response code: #{e.message}"
394
+ end
395
+
191
396
  end
192
397
  end
@@ -0,0 +1,28 @@
1
+ module OpenTok
2
+ # A class for working with OpenTok connections.
3
+ class Connections
4
+ # @private
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ # Force a client to disconnect from an OpenTok session.
10
+ #
11
+ # A client must be actively connected to the OpenTok session for you to disconnect it.
12
+ #
13
+ # @param [String] session_id The session ID of the OpenTok session.
14
+ # @param [String] connection_id The connection ID of the client in the session.
15
+ #
16
+ # @raise [ArgumentError] The connection_id or session_id is invalid.
17
+ # @raise [OpenTokAuthenticationError] You are not authorized to disconnect the connection. Check your authentication credentials.
18
+ # @raise [OpenTokConnectionError] The client specified by the connection_id property is not connected to the session.
19
+ #
20
+ def forceDisconnect(session_id, connection_id )
21
+ raise ArgumentError, "session_id not provided" if session_id.to_s.empty?
22
+ raise ArgumentError, "connection_id not provided" if connection_id.to_s.empty?
23
+ response = @client.forceDisconnect(session_id, connection_id)
24
+ (200..300).include? response.code
25
+ end
26
+
27
+ end
28
+ end
@@ -2,6 +2,6 @@ module OpenTok
2
2
  API_URL = "https://api.opentok.com"
3
3
  TOKEN_SENTINEL = "T1=="
4
4
  ROLES = { subscriber: "subscriber", publisher: "publisher", moderator: "moderator" }
5
- ARCHIVE_MODES = Set.new([:manual, :always])
5
+ ARCHIVE_MODES = ::Set.new([:manual, :always])
6
6
  AUTH_EXPIRE = 300
7
7
  end
@@ -8,5 +8,11 @@ module OpenTok
8
8
  class OpenTokSipError < OpenTokError; end
9
9
  # Defines errors raised when you attempt an operation using an invalid OpenTok API key or secret.
10
10
  class OpenTokAuthenticationError < OpenTokError; end
11
+ # Defines errors raised when you attempt a force disconnect a client and it is not connected to the session.
12
+ class OpenTokConnectionError < OpenTokError; end
13
+ # Defines errors raised when you attempt set layout classes to a stream.
14
+ class OpenTokStreamLayoutError < OpenTokError; end
15
+ # Defines errors raised when you perform Broadcast operations.
16
+ class OpenTokBroadcastError < OpenTokError; end
11
17
 
12
18
  end
@@ -2,17 +2,24 @@ require "opentok/constants"
2
2
  require "opentok/session"
3
3
  require "opentok/client"
4
4
  require "opentok/token_generator"
5
+ require "opentok/connections"
5
6
  require "opentok/archives"
6
7
  require "opentok/sip"
8
+ require "opentok/streams"
9
+ require "opentok/signals"
10
+ require "opentok/broadcasts"
7
11
 
8
12
  require "resolv"
9
13
  require "set"
10
14
 
11
15
  module OpenTok
12
- # Contains methods for creating OpenTok sessions, generating tokens, and working with archives.
16
+ # Contains methods for creating OpenTok sessions and generating tokens. It also includes
17
+ # methods for returning object that let you work with archives, work with live streaming
18
+ # broadcasts, using SIP interconnect, sending signals to sessions, disconnecting clients from
19
+ # sessions, and setting the layout classes for streams.
13
20
  #
14
21
  # To create a new OpenTok object, call the OpenTok constructor with your OpenTok API key
15
- # and the API secret from the OpenTok dashboard (https://dashboard.tokbox.com). Do not
22
+ # and the API secret for your {https://tokbox.com/account OpenTok project}. Do not
16
23
  # publicly share your API secret. You will use it with the OpenTok constructor (only on your web
17
24
  # server) to create OpenTok sessions.
18
25
  #
@@ -20,7 +27,7 @@ module OpenTok
20
27
  # @attr_reader [String] api_key @private The OpenTok API key.
21
28
  #
22
29
  #
23
- # @!method generate_token(options)
30
+ # @!method generate_token(session_id, options)
24
31
  # Generates a token for a given session.
25
32
  #
26
33
  # @param [String] session_id The session ID of the session to be accessed by the client using
@@ -45,6 +52,11 @@ module OpenTok
45
52
  # end-user. For example, you can pass the user ID, name, or other data describing the
46
53
  # end-user. The length of the string is limited to 1000 characters. This data cannot be
47
54
  # updated once it is set.
55
+ # @option options [Array] :initial_layout_class_list
56
+ # An array of class names (strings) to be used as the initial layout classes for streams
57
+ # published by the client. Layout classes are used in customizing the layout of videos in
58
+ # {https://tokbox.com/developer/guides/broadcast/live-streaming/ live streaming broadcasts}
59
+ # and {https://tokbox.com/developer/guides/archiving/layout-control.html composed archives}.
48
60
  # @return [String] The token string.
49
61
  class OpenTok
50
62
 
@@ -57,19 +69,21 @@ module OpenTok
57
69
  # @private
58
70
  # don't want these to be mutable, may cause bugs related to inconsistency since these values are
59
71
  # cached in objects that this can create
60
- attr_reader :api_key, :api_secret, :api_url, :ua_addendum
72
+ attr_reader :api_key, :api_secret, :timeout_length, :api_url, :ua_addendum
61
73
 
62
74
  ##
63
75
  # Create a new OpenTok object.
64
76
  #
65
- # @param [String] api_key Your OpenTok API key. See the OpenTok dashboard
66
- # (https://dashboard.tokbox.com).
77
+ # @param [String] api_key The OpenTok API key for your
78
+ # {https://tokbox.com/account OpenTok project}.
67
79
  # @param [String] api_secret Your OpenTok API key.
68
80
  # @option opts [Symbol] :api_url Do not set this parameter. It is for internal use by TokBox.
69
81
  # @option opts [Symbol] :ua_addendum Do not set this parameter. It is for internal use by TokBox.
82
+ # @option opts [Symbol] :timeout_length Custom timeout in seconds. If not provided, defaults to 2 seconds.
70
83
  def initialize(api_key, api_secret, opts={})
71
84
  @api_key = api_key.to_s()
72
85
  @api_secret = api_secret
86
+ @timeout_length = opts[:timeout_length] || 2
73
87
  @api_url = opts[:api_url] || API_URL
74
88
  @ua_addendum = opts[:ua_addendum]
75
89
  end
@@ -89,8 +103,8 @@ module OpenTok
89
103
  # Check the error message for details.
90
104
  #
91
105
  # You can also create a session using the OpenTok REST API (see
92
- # http://www.tokbox.com/opentok/api/#session_id_production) or the OpenTok dashboard
93
- # (see https://dashboard.tokbox.com/projects).
106
+ # http://www.tokbox.com/opentok/api/#session_id_production) or at your
107
+ # {https://tokbox.com/account OpenTok account page}.
94
108
  #
95
109
  # @param [Hash] opts (Optional) This hash defines options for the session.
96
110
  #
@@ -173,14 +187,34 @@ module OpenTok
173
187
  @archives ||= Archives.new client
174
188
  end
175
189
 
190
+ # A Broadcasts object, which lets you work with OpenTok live streaming broadcasts.
191
+ def broadcasts
192
+ @broadcasts ||= Broadcasts.new client
193
+ end
194
+
195
+ # A Sip object, which lets you use the OpenTok SIP gateway.
176
196
  def sip
177
197
  @sip ||= Sip.new client
178
198
  end
179
199
 
180
- protected
200
+ # A Streams object, which lets you work with OpenTok live streaming broadcasts.
201
+ def streams
202
+ @streams ||= Streams.new client
203
+ end
181
204
 
205
+ # A Signals object, which lets you send signals to OpenTok sessions.
206
+ def signals
207
+ @signals ||= Signals.new client
208
+ end
209
+
210
+ # A Connections object, which lets disconnect clients from an OpenTok session.
211
+ def connections
212
+ @connections ||= Connections.new client
213
+ end
214
+
215
+ protected
182
216
  def client
183
- @client ||= Client.new api_key, api_secret, api_url, ua_addendum
217
+ @client ||= Client.new api_key, api_secret, api_url, ua_addendum, timeout_length: @timeout_length
184
218
  end
185
219
 
186
220
  end
@@ -42,6 +42,11 @@ module OpenTok
42
42
  # end-user. For example, you can pass the user ID, name, or other data describing the
43
43
  # end-user. The length of the string is limited to 1000 characters. This data cannot be
44
44
  # updated once it is set.
45
+ # @option options [Array] :initial_layout_class_list
46
+ # An array of class names (strings) to be used as the initial layout classes for streams
47
+ # published by the client. Layout classes are used in customizing the layout of videos in
48
+ # {https://tokbox.com/developer/guides/broadcast/live-streaming/ live streaming broadcasts}
49
+ # and {https://tokbox.com/developer/guides/archiving/layout-control.html composed archives}.
45
50
  # @return [String] The token string.
46
51
  class Session
47
52
 
@@ -0,0 +1,47 @@
1
+ module OpenTok
2
+ # A class for working with OpenTok signals.
3
+ class Signals
4
+ # @private
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ # Sends a signal to clients connected to an OpenTok session.
10
+ #
11
+ # You can send a signal to all valid connections in a session or to a specific connection of
12
+ # a session.
13
+ #
14
+ # For more information on signaling, see
15
+ # {https://tokbox.com/developer/rest/#send_signal}.
16
+ #
17
+ # @param [String] session_id The session ID of the OpenTok session.
18
+ #
19
+ # @param [String] connection_id
20
+ # When a connection_id is specified, only that connection recieves the signal.
21
+ # Otherwise, the signal is sent to all clients connected to the session.
22
+ #
23
+ # @option options [String] :type This is the type of the signal. You can use this
24
+ # field to group and filter signals. It is a property of the Signal object received by
25
+ # the client(s).
26
+ #
27
+ # @option options [String] :data This is the data within the signal or the payload.
28
+ # Contains the main information to be sent in the signal. It is a property of the Signal object
29
+ # received by the client(s).
30
+ #
31
+ # @raise [ArgumentError]
32
+ # One of the signal properties — data, type, session_id, or connection_id — is invalid.
33
+ # @raise [OpenTokAuthenticationError]
34
+ # You are not authorized to send the signal. Check your authentication credentials.
35
+ # @raise [OpenTokError]
36
+ # The client specified by the connection_id property is not connected to the session.
37
+ # @raise [OpenTokError]
38
+ # The type string exceeds the maximum length (128 bytes), or the data string exceeds
39
+ # the maximum size (8 kB).
40
+ def send(session_id, connectionId = "", options = {})
41
+ raise ArgumentError, "session_id not provided" if session_id.to_s.empty?
42
+ response = @client.signal(session_id, connectionId, options)
43
+ (200..300).include? response.code
44
+ end
45
+
46
+ end
47
+ end