opentok 3.0.3 → 4.1.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.
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