vonage 7.8.2 → 7.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +880 -87
  3. data/lib/vonage/account.rb +2 -0
  4. data/lib/vonage/api_error.rb +33 -0
  5. data/lib/vonage/applications.rb +12 -4
  6. data/lib/vonage/basic.rb +1 -1
  7. data/lib/vonage/basic_and_bearer_token.rb +18 -0
  8. data/lib/vonage/basic_and_signature.rb +22 -0
  9. data/lib/vonage/bearer_token.rb +1 -1
  10. data/lib/vonage/client.rb +79 -0
  11. data/lib/vonage/client_error.rb +1 -1
  12. data/lib/vonage/config.rb +11 -1
  13. data/lib/vonage/conversation/event/list_response.rb +11 -0
  14. data/lib/vonage/conversation/event.rb +108 -0
  15. data/lib/vonage/conversation/list_response.rb +11 -0
  16. data/lib/vonage/conversation/member/list_response.rb +11 -0
  17. data/lib/vonage/conversation/member.rb +134 -0
  18. data/lib/vonage/conversation/user/conversations_list_response.rb +11 -0
  19. data/lib/vonage/conversation/user/sessions_list_response.rb +11 -0
  20. data/lib/vonage/conversation/user.rb +67 -0
  21. data/lib/vonage/conversation.rb +164 -0
  22. data/lib/vonage/conversations/events.rb +12 -0
  23. data/lib/vonage/conversations/legs.rb +6 -0
  24. data/lib/vonage/conversations/members.rb +15 -0
  25. data/lib/vonage/conversations/users.rb +15 -0
  26. data/lib/vonage/conversations.rb +30 -0
  27. data/lib/vonage/conversions.rb +2 -0
  28. data/lib/vonage/errors.rb +37 -20
  29. data/lib/vonage/http.rb +3 -3
  30. data/lib/vonage/identity_insights/insights_builder.rb +75 -0
  31. data/lib/vonage/identity_insights.rb +75 -0
  32. data/lib/vonage/jwt.rb +17 -0
  33. data/lib/vonage/key_secret_params.rb +3 -2
  34. data/lib/vonage/keys.rb +24 -1
  35. data/lib/vonage/logger.rb +0 -3
  36. data/lib/vonage/meetings/applications.rb +28 -0
  37. data/lib/vonage/meetings/dial_in_numbers/list_response.rb +11 -0
  38. data/lib/vonage/meetings/dial_in_numbers.rb +26 -0
  39. data/lib/vonage/meetings/recordings.rb +42 -0
  40. data/lib/vonage/meetings/rooms/list_response.rb +11 -0
  41. data/lib/vonage/meetings/rooms.rb +167 -0
  42. data/lib/vonage/meetings/sessions/list_response.rb +11 -0
  43. data/lib/vonage/meetings/sessions.rb +31 -0
  44. data/lib/vonage/meetings/themes/list_response.rb +11 -0
  45. data/lib/vonage/meetings/themes.rb +239 -0
  46. data/lib/vonage/meetings.rb +50 -0
  47. data/lib/vonage/messaging/channels/messenger.rb +2 -0
  48. data/lib/vonage/messaging/channels/mms.rb +13 -3
  49. data/lib/vonage/messaging/channels/rcs.rb +44 -0
  50. data/lib/vonage/messaging/channels/sms.rb +2 -0
  51. data/lib/vonage/messaging/channels/viber.rb +11 -2
  52. data/lib/vonage/messaging/channels/whats_app.rb +5 -1
  53. data/lib/vonage/messaging/message.rb +4 -1
  54. data/lib/vonage/messaging.rb +43 -4
  55. data/lib/vonage/namespace.rb +152 -69
  56. data/lib/vonage/network_authentication/client_authentication.rb +39 -0
  57. data/lib/vonage/network_authentication/server_authentication.rb +47 -0
  58. data/lib/vonage/network_authentication.rb +22 -0
  59. data/lib/vonage/network_number_verification.rb +92 -0
  60. data/lib/vonage/network_sim_swap.rb +84 -0
  61. data/lib/vonage/number_insight.rb +1 -0
  62. data/lib/vonage/number_insight_2.rb +21 -0
  63. data/lib/vonage/numbers.rb +40 -17
  64. data/lib/vonage/proactive_connect/events/list_response.rb +11 -0
  65. data/lib/vonage/proactive_connect/events.rb +71 -0
  66. data/lib/vonage/proactive_connect/item.rb +116 -0
  67. data/lib/vonage/proactive_connect/items/file_response.rb +32 -0
  68. data/lib/vonage/proactive_connect/items/list_response.rb +11 -0
  69. data/lib/vonage/proactive_connect/items.rb +116 -0
  70. data/lib/vonage/proactive_connect/list.rb +186 -0
  71. data/lib/vonage/proactive_connect/lists/list_response.rb +11 -0
  72. data/lib/vonage/proactive_connect/lists.rb +38 -0
  73. data/lib/vonage/proactive_connect.rb +43 -0
  74. data/lib/vonage/server_error.rb +1 -1
  75. data/lib/vonage/signature.rb +29 -6
  76. data/lib/vonage/sms.rb +25 -0
  77. data/lib/vonage/subaccounts/balance_transfers/list_response.rb +11 -0
  78. data/lib/vonage/subaccounts/credit_transfers/list_response.rb +11 -0
  79. data/lib/vonage/subaccounts/list_response.rb +15 -0
  80. data/lib/vonage/subaccounts.rb +203 -0
  81. data/lib/vonage/users/list_response.rb +11 -0
  82. data/lib/vonage/users.rb +156 -0
  83. data/lib/vonage/verify.rb +2 -0
  84. data/lib/vonage/verify2/channels/email.rb +36 -0
  85. data/lib/vonage/verify2/channels/silent_auth.rb +46 -0
  86. data/lib/vonage/verify2/channels/sms.rb +63 -0
  87. data/lib/vonage/verify2/channels/voice.rb +32 -0
  88. data/lib/vonage/verify2/channels/whats_app.rb +45 -0
  89. data/lib/vonage/verify2/channels/whats_app_interactive.rb +32 -0
  90. data/lib/vonage/verify2/start_verification_options.rb +63 -0
  91. data/lib/vonage/verify2/template_fragments/list_response.rb +11 -0
  92. data/lib/vonage/verify2/template_fragments.rb +125 -0
  93. data/lib/vonage/verify2/templates/list_response.rb +11 -0
  94. data/lib/vonage/verify2/templates.rb +86 -0
  95. data/lib/vonage/verify2/workflow.rb +39 -0
  96. data/lib/vonage/verify2/workflow_builder.rb +25 -0
  97. data/lib/vonage/verify2.rb +112 -0
  98. data/lib/vonage/version.rb +1 -1
  99. data/lib/vonage/video/archives/list_response.rb +11 -0
  100. data/lib/vonage/video/archives.rb +164 -0
  101. data/lib/vonage/video/broadcasts/list_response.rb +11 -0
  102. data/lib/vonage/video/broadcasts.rb +75 -0
  103. data/lib/vonage/video/captions.rb +67 -0
  104. data/lib/vonage/video/connections/list_response.rb +11 -0
  105. data/lib/vonage/video/connections.rb +29 -0
  106. data/lib/vonage/video/moderation.rb +58 -0
  107. data/lib/vonage/video/renders/list_response.rb +11 -0
  108. data/lib/vonage/video/renders.rb +107 -0
  109. data/lib/vonage/video/signals.rb +50 -0
  110. data/lib/vonage/video/sip.rb +48 -0
  111. data/lib/vonage/video/streams/list_response.rb +11 -0
  112. data/lib/vonage/video/streams.rb +70 -0
  113. data/lib/vonage/video/web_socket.rb +68 -0
  114. data/lib/vonage/video.rb +134 -0
  115. data/lib/vonage/voice/actions/connect.rb +45 -9
  116. data/lib/vonage/voice/actions/conversation.rb +10 -4
  117. data/lib/vonage/voice/actions/input.rb +26 -3
  118. data/lib/vonage/voice/actions/notify.rb +8 -3
  119. data/lib/vonage/voice/actions/record.rb +52 -4
  120. data/lib/vonage/voice/actions/stream.rb +7 -3
  121. data/lib/vonage/voice/actions/talk.rb +29 -4
  122. data/lib/vonage/voice/actions/transfer.rb +83 -0
  123. data/lib/vonage/voice/actions/wait.rb +43 -0
  124. data/lib/vonage/voice/ncco.rb +3 -1
  125. data/lib/vonage/voice/talk.rb +11 -1
  126. data/lib/vonage/voice.rb +24 -0
  127. data/lib/vonage.rb +4 -0
  128. data/vonage.gemspec +3 -1
  129. metadata +119 -9
  130. data/lib/vonage/voice/actions/pay.rb +0 -107
@@ -0,0 +1,58 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class Video::Moderation < Namespace
6
+ self.authentication = BearerToken
7
+
8
+ self.request_body = JSON
9
+
10
+ self.host = :video_host
11
+
12
+ # Force a client to disconnect from a session.
13
+ #
14
+ # @param [required, String] :session_id
15
+ #
16
+ # @param [required, String] :connection_id The connection ID of the specific participant to be disconnected from the session.
17
+ #
18
+ # @return [Response]
19
+ #
20
+ # @see TODO: add docs link
21
+ #
22
+ def force_disconnect(session_id:, connection_id:)
23
+ request('/v2/project/' + @config.application_id + '/session/' + session_id + '/connection/' + connection_id, type: Delete)
24
+ end
25
+
26
+ # Force mute a specific publisher stream in a session.
27
+ #
28
+ # @param [required, String] :session_id
29
+ #
30
+ # @param [required, String] :stream_id The stream ID of the specific stream to be muted.
31
+ #
32
+ # @return [Response]
33
+ #
34
+ # @see TODO: add docs link
35
+ #
36
+ def mute_single_stream(session_id:, stream_id:)
37
+ request('/v2/project/' + @config.application_id + '/session/' + session_id + '/stream/' + stream_id + '/mute', type: Post)
38
+ end
39
+
40
+ # Force mute all publisher stream for a specific session.
41
+ #
42
+ # @param [required, String] :session_id
43
+ #
44
+ # @param [required, String] :active
45
+ #
46
+ # @param [required, Array<String>] :excludedStreamIds
47
+ #
48
+ # @return [Response]
49
+ #
50
+ # @see TODO: add docs link
51
+ #
52
+ def mute_multiple_streams(session_id:, **params)
53
+ request('/v2/project/' + @config.application_id + '/session/' + session_id + '/mute', params: params, type: Post)
54
+ end
55
+
56
+ # TODO: add disable_force_mute ??
57
+ end
58
+ end
@@ -0,0 +1,11 @@
1
+ # typed: true
2
+
3
+ class Vonage::Video::Renders::ListResponse < Vonage::Response
4
+ include Enumerable
5
+
6
+ def each
7
+ return enum_for(:each) unless block_given?
8
+
9
+ @entity.items.each { |item| yield item }
10
+ end
11
+ end
@@ -0,0 +1,107 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class Video::Renders < Namespace
6
+ include Keys
7
+
8
+ self.authentication = BearerToken
9
+
10
+ self.request_body = JSON
11
+
12
+ self.host = :video_host
13
+
14
+ # Start an Experience Composer Render
15
+ #
16
+ # @example
17
+ # response = client.video.renders.start(
18
+ # session_id: "12312312-3811-4726-b508-e41a0f96c68f",
19
+ # token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJp...",
20
+ # url: 'https://example.com/',
21
+ # max_duration: 1800,
22
+ # resolution: '1280x720',
23
+ # properties: {
24
+ # name: 'foo'
25
+ # }
26
+ # )
27
+ #
28
+ # @params [required, String] :session_id The session ID of the Vonage Video session you are working with.
29
+ #
30
+ # @param [required, String] :token A valid OpenTok JWT token with a Publisher role and (optionally) connection data to be associated with the output stream.
31
+ #
32
+ # @params [required, String] :url A publicly reachable URL controlled by the customer and capable of generating the content to be rendered without user intervention.
33
+ #
34
+ # @params [optional, Integer] :max_duration The maximum duration of the rendered video in seconds.
35
+ # - After this time, it is stopped automatically, if it is still running.
36
+ # - Min: 60
37
+ # - Max: 3600
38
+ # - Default: 3600
39
+ #
40
+ # @params [optional, String] :resolution The resolution of the Experience Composer render.
41
+ # - Must be one of: '640x480', '480x640', '1280x720', '720x1280', '1080x1920', '1920x1080'
42
+ #
43
+ # @params [optional, Hash] :properties The initial configuration of Publisher properties for the composed output stream.
44
+ # @option properties [required, String] :name The name of the composed output stream which is published to the session.
45
+ #
46
+ # @return [Response]
47
+ #
48
+ # @see TODO: Add document link here
49
+ #
50
+ def start(session_id:, token:, url:, **params)
51
+ request(
52
+ '/v2/project/' + @config.application_id + '/render',
53
+ params: camelcase(params.merge({sessionId: session_id, token: token, url: url})),
54
+ type: Post)
55
+ end
56
+
57
+ # Stop an Experience Composer render
58
+ #
59
+ # @example
60
+ # response = client.video.renders.stop(experience_composer_id: "1248e7070b81464c9789f46ad10e7764")
61
+ #
62
+ # @params [required, String] :experience_composer_id ID of the Experience Composer instance that you want to stop.
63
+ #
64
+ # @return [Response]
65
+ #
66
+ # @see TODO: Add document link here
67
+ #
68
+ def stop(experience_composer_id:)
69
+ request('/v2/project/' + @config.application_id + '/render/' + experience_composer_id, type: Delete)
70
+ end
71
+
72
+ # Get information about an Experience Composer session
73
+ #
74
+ # @example
75
+ # response = client.video.renders.info(experience_composer_id: "1248e7070b81464c9789f46ad10e7764")
76
+ #
77
+ # @params [required, String] :experience_composer_id ID of the Experience Composer instance for which you are requesitng information.
78
+ #
79
+ # @return [Response]
80
+ #
81
+ # @see TODO: Add document link here
82
+ #
83
+ def info(experience_composer_id:)
84
+ request('/v2/project/' + @config.application_id + '/render/' + experience_composer_id)
85
+ end
86
+
87
+ # List all Experience Composer renders in an application
88
+ #
89
+ # @example
90
+ # response = client.video.renders.list
91
+ #
92
+ # @params [optional, Integer] :offset Specify the index offset of the first experience composer. 0 is offset of the most recently started render.
93
+ #
94
+ # @params [optional, Integer] :count Limit the number of experience composers to be returned.
95
+ #
96
+ # @return [Video::Renders::ListResponse]
97
+ #
98
+ # @see TODO: Add document link here
99
+ #
100
+ def list(**params)
101
+ path = '/v2/project/' + @config.application_id + '/render'
102
+ path += "?#{Params.encode(camelcase(params))}" unless params.empty?
103
+
104
+ request(path, response_class: ListResponse)
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,50 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class Video::Signals < Namespace
6
+ self.authentication = BearerToken
7
+
8
+ self.request_body = JSON
9
+
10
+ self.host = :video_host
11
+
12
+ # Send a signal to a specific participant in an active Vonage Video session.
13
+ #
14
+ # @param [optional, String] :application_id (Required unless already set at Client instantiation or set in ENV)
15
+ #
16
+ # @param [required, String] :session_id
17
+ #
18
+ # @param [required, String] :connection_id The connection ID of the specific participant.
19
+ #
20
+ # @param [required, String] :type Type of data that is being sent to the client.
21
+ #
22
+ # @param [required, String] :data Payload that is being sent to the client.
23
+ #
24
+ # @return [Response]
25
+ #
26
+ # @see TODO: add docs link
27
+ #
28
+ def send_to_one(session_id:, connection_id:, **params)
29
+ request('/v2/project/' + @config.application_id + '/session/' + session_id + '/connection/' + connection_id + '/signal', params: params, type: Post)
30
+ end
31
+
32
+ # Send a signal to all participants in an active Vonage Video session.
33
+ #
34
+ # @param [optional, String] :application_id (Required unless already set at Client instantiation or set in ENV)
35
+ #
36
+ # @param [required, String] :session_id
37
+ #
38
+ # @param [required, String] :type Type of data that is being sent to the client.
39
+ #
40
+ # @param [required, String] :data Payload that is being sent to the client.
41
+ #
42
+ # @return [Response]
43
+ #
44
+ # @see TODO: add docs link
45
+ #
46
+ def send_to_all(session_id:, **params)
47
+ request('/v2/project/' + @config.application_id + '/session/' + session_id + '/signal', params: params, type: Post)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,48 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class Video::SIP < Namespace
6
+ include Keys
7
+
8
+ self.authentication = BearerToken
9
+
10
+ self.request_body = JSON
11
+
12
+ self.host = :video_host
13
+
14
+ # Initiate an outbound SIP call.
15
+ #
16
+ def dial(session_id:, token:, sip_uri:, **params)
17
+ request(
18
+ '/v2/project/' + @config.application_id + '/dial',
19
+ params: camelcase({
20
+ session_id: session_id,
21
+ token: token,
22
+ sip: params.merge({uri: sip_uri})
23
+ }),
24
+ type: Post
25
+ )
26
+ end
27
+
28
+ # Play DTMF tones into a SIP call.
29
+ #
30
+ def play_dtmf_to_session(session_id:, dtmf_digits:)
31
+ request(
32
+ '/v2/project/' + @config.application_id + '/session/' + session_id + '/play-dtmf',
33
+ params: {digits: dtmf_digits},
34
+ type: Post
35
+ )
36
+ end
37
+
38
+ # Play DMTF tones into a specific connection.
39
+ #
40
+ def play_dtmf_to_connection(session_id:, connection_id:, dtmf_digits:)
41
+ request(
42
+ '/v2/project/' + @config.application_id + '/session/' + session_id + '/connection/' + connection_id + '/play-dtmf',
43
+ params: {digits: dtmf_digits},
44
+ type: Post
45
+ )
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,11 @@
1
+ # typed: true
2
+
3
+ class Vonage::Video::Streams::ListResponse < Vonage::Response
4
+ include Enumerable
5
+
6
+ def each
7
+ return enum_for(:each) unless block_given?
8
+
9
+ @entity.items.each { |item| yield item }
10
+ end
11
+ end
@@ -0,0 +1,70 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class Video::Streams < Namespace
6
+
7
+ self.authentication = BearerToken
8
+
9
+ self.request_body = JSON
10
+
11
+ self.host = :video_host
12
+
13
+ # Get a list of streams for a specified session.
14
+ #
15
+ # @param [optional, String] :application_id (Required unless already set at Client instantiation or set in ENV)
16
+ #
17
+ # @param [required, String] :session_id
18
+ #
19
+ # TODO: add auto_advance option
20
+ #
21
+ # @return [ListResponse]
22
+ #
23
+ # @see TODO: add docs link
24
+ #
25
+ def list(session_id:)
26
+ request('/v2/project/' + @config.application_id + '/session/' + session_id + '/stream', response_class: ListResponse)
27
+ end
28
+
29
+ # Get information about a specified stream.
30
+ #
31
+ # @param [optional, String] :application_id (Required unless already set at Client instantiation or set in ENV)
32
+ #
33
+ # @param [required, String] :session_id
34
+ #
35
+ # @param [required, String] :stream_id
36
+ #
37
+ # @return [Response]
38
+ #
39
+ # @see TODO: add docs link
40
+ #
41
+ def info(session_id:, stream_id:)
42
+ request('/v2/project/' + @config.application_id + '/session/' + session_id + '/stream/' + stream_id)
43
+ end
44
+
45
+ # Change the layout for a list of specified streams.
46
+ #
47
+ # @param [optional, String] :application_id (Required unless already set at Client instantiation or set in ENV)
48
+ #
49
+ # @param [required, String] :session_id
50
+ #
51
+ # @param [optional, Array<Hash>] :items An array of hashes representing streams and the layout classes for those streams
52
+ #
53
+ # @option items [required, String] :id The stream ID
54
+ #
55
+ # @option items [required, Array<String>] :layoutClassList Array of CSS class names as strings
56
+ #
57
+ # @return [Response]
58
+ #
59
+ # @see TODO: add docs link
60
+ #
61
+ def change_layout(session_id:, **params)
62
+ # TODO camelcase layout_class_list
63
+ # if params[:items]
64
+ # params[:items] = params[:items].map {|item| camelcase(item)}
65
+ # end
66
+
67
+ request('/v2/project/' + @config.application_id + '/session/' + session_id + '/stream', params: params, type: Put)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,68 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class Video::WebSocket < Namespace
6
+ include Keys
7
+
8
+ self.authentication = BearerToken
9
+
10
+ self.request_body = JSON
11
+
12
+ self.host = :video_host
13
+
14
+ # Start an audio connector websocket connection
15
+ #
16
+ # @example
17
+ # response = client.video.web_socket.connect(
18
+ # session_id: "12312312-3811-4726-b508-e41a0f96c68f",
19
+ # token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJp...",
20
+ # websocket: {
21
+ # uri: 'wss://example.com/ws-endpoint',
22
+ # streams: ["8b732909-0a06-46a2-8ea8-074e64d43422"],
23
+ # headers: { property1: 'foo', property2: 'bar' },
24
+ # audio_rate: 16000
25
+ # }
26
+ # )
27
+ #
28
+ # @params [required, String] :session_id The Vonage Video session ID that includes the Vonage Video streams you want to include in the WebSocket stream.
29
+ # - The Audio Connector feature is only supported in routed sessions
30
+ #
31
+ # @param [required, String] :token A valid Vonage Video token for the Audio Connector connection to the Vonage Video Session.
32
+ # - You can add additional data to the JWT to identify that the connection is the Audio Connector endpoint or for any other identifying data.
33
+ #
34
+ # @params [required, Hash] :websocket The WebSocket configuration for the Audio Connector connection.
35
+ # @option websocket [required, String] :uri A publicly reachable WebSocket URI to be used for the destination of the audio stream
36
+ # @option websocket [optional, String] :streams An array of stream IDs for the Vonage Video streams you want to include in the WebSocket audio.
37
+ # - If you omit this property, all streams in the session will be included.
38
+ # @option websocket [optional, Hash] :headers An object of key-value pairs of headers to be sent to your WebSocket server with each message, with a maximum length of 512 bytes.
39
+ # @option websocket [optional, Integer] :audio_rate A number representing the audio sampling rate in Hz
40
+ # - Must be one of: 8000, 16000, 24000
41
+ # @option websocket [optional, Boolean] :bidirectional Whether to send audio data from the WebSocket connection to a stream published in the session.
42
+ # @option websocket [optional, Hash] :audio_transport The configuration for the audio transport over the WebSocket connection.
43
+ # @option websocket[:audio_transport] [String] :transport (optional) The transport type for the audio data. Must be one of: "json", "binary".
44
+ # @option websocket[:audio_transport] [String] :encoding (optional) The encoding type for the audio data. Required when transport is "json". Must be one of: "base64".
45
+ # @option websocket[:audio_transport] [String] :audio_field (optional) The JSON key for the outbound audio data. The default value is "audio".
46
+ # @option websocket[:audio_transport] [String] :receive_audio_field (optional) The JSON key for inbound audio data (when bidirectional is enabled). Defaults to the same value as `audio_field`.
47
+ # @option websocket[:audio_transport] [Hash] :static_fields (optional) An optional hash of extra key-value pairs included in every outbound JSON audio message.
48
+ #
49
+ # @return [Response]
50
+ #
51
+ # @see TODO: Add document link here
52
+ #
53
+ def connect(session_id:, token:, websocket:)
54
+ raise ArgumentError, 'websocket must be a Hash' unless websocket.is_a?(Hash)
55
+ raise ArgumentError, 'websocket must contain a uri' unless websocket.key?(:uri)
56
+
57
+ request(
58
+ '/v2/project/' + @config.application_id + '/connect',
59
+ params: {
60
+ sessionId: session_id,
61
+ token: token,
62
+ websocket: camelcase(websocket)
63
+ },
64
+ type: Post
65
+ )
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,134 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class Video < Namespace
6
+ include Keys
7
+
8
+ self.authentication = BearerToken
9
+
10
+ self.host = :video_host
11
+
12
+ # Generate a new session.
13
+ #
14
+ # @example
15
+ # session = client.video.create_session({
16
+ # archive_mode: 'always',
17
+ # location: '10.1.200.30',
18
+ # media_mode: 'routed'
19
+ # })
20
+ #
21
+ # @params [optional, String] :archive_mode (either 'always' or 'manual')
22
+ #
23
+ # @param [optional, String] :location
24
+ #
25
+ # @params [optional, String] :media_mode (either 'routed' or 'relayed')
26
+ #
27
+ # @return [Response]
28
+ #
29
+ # @see TODO: Add document link here
30
+ #
31
+ def create_session(**params)
32
+ request_params = params.clone
33
+ request_params[:archive_mode] ||= 'manual'
34
+ media_mode = request_params.delete(:media_mode) || 'routed'
35
+
36
+ if media_mode == 'relayed' && request_params[:archive_mode] == 'manual'
37
+ request_params['p2p.preference'] = 'enabled'
38
+ else
39
+ request_params['p2p.preference'] = 'disabled'
40
+ end
41
+
42
+ response = request('/session/create', params: camelcase(request_params), type: Post)
43
+
44
+ public_response_data = {
45
+ session_id: response.entity.first.session_id,
46
+ archive_mode: request_params[:archive_mode],
47
+ media_mode: media_mode,
48
+ location: request_params[:location]
49
+ }
50
+
51
+ entity = Entity.new(public_response_data)
52
+
53
+ response.class.new(entity, response.http_response)
54
+ end
55
+
56
+ def generate_client_token(session_id:, scope: 'session.connect', role: 'publisher', **params)
57
+ valid_roles = %w[publisher subscriber moderator publisheronly]
58
+ raise ArgumentError, "Invalid role: #{role}" unless valid_roles.include?(role)
59
+
60
+ claims = {
61
+ application_id: @config.application_id,
62
+ scope: scope,
63
+ session_id: session_id,
64
+ role: role,
65
+ initial_layout_class_list: '',
66
+ sub: 'video',
67
+ acl: {
68
+ paths: {'/session/**' => {}}
69
+ }
70
+ }
71
+
72
+
73
+ claims[:data] = params[:data] if params[:data]
74
+ claims[:initial_layout_class_list] = params[:initial_layout_class_list].join(' ') if params[:initial_layout_class_list]
75
+ claims[:exp] = params[:expire_time].to_i if params[:expire_time]
76
+
77
+ JWT.generate(claims, @config.private_key)
78
+ end
79
+
80
+ # @return [Archives]
81
+ #
82
+ def archives
83
+ @archives ||= Archives.new(@config)
84
+ end
85
+
86
+ # @return [Broadcasts]
87
+ #
88
+ def broadcasts
89
+ @broadcasts ||= Broadcasts.new(@config)
90
+ end
91
+
92
+ # @return [Moderation]
93
+ #
94
+ def moderation
95
+ @moderation ||= Moderation.new(@config)
96
+ end
97
+
98
+ # @return [Signals]
99
+ #
100
+ def signals
101
+ @signals ||= Signals.new(@config)
102
+ end
103
+
104
+ # @return [Streams]
105
+ #
106
+ def streams
107
+ @streams ||= Streams.new(@config)
108
+ end
109
+
110
+ # @return [Connections]
111
+ #
112
+ def connections
113
+ @connections ||= Connections.new(@config)
114
+ end
115
+
116
+ # @return [Captions]
117
+ #
118
+ def captions
119
+ @captions ||= Captions.new(@config)
120
+ end
121
+
122
+ # @return [Renders]
123
+ #
124
+ def renders
125
+ @renders ||= Renders.new(@config)
126
+ end
127
+
128
+ # @return [WebSocket]
129
+ #
130
+ def web_socket
131
+ @web_socket ||= WebSocket.new(@config)
132
+ end
133
+ end
134
+ end
@@ -2,9 +2,9 @@
2
2
  # frozen_string_literal: true
3
3
  require 'phonelib'
4
4
 
5
- module Vonage
5
+ module Vonage
6
6
  class Voice::Actions::Connect
7
- attr_accessor :endpoint, :from, :eventType, :timeout, :limit, :machineDetection, :eventUrl, :eventMethod, :ringbackTone
7
+ attr_accessor :endpoint, :from, :eventType, :timeout, :limit, :machineDetection, :advanced_machine_detection, :eventUrl, :eventMethod, :ringbackTone
8
8
 
9
9
  def initialize(attributes = {})
10
10
  @endpoint = attributes.fetch(:endpoint)
@@ -13,6 +13,7 @@ module Vonage
13
13
  @timeout = attributes.fetch(:timeout, nil)
14
14
  @limit = attributes.fetch(:limit, nil)
15
15
  @machineDetection = attributes.fetch(:machineDetection, nil)
16
+ @advanced_machine_detection = attributes.fetch(:advanced_machine_detection, nil)
16
17
  @eventUrl = attributes.fetch(:eventUrl, nil)
17
18
  @eventMethod = attributes.fetch(:eventMethod, nil)
18
19
  @ringbackTone = attributes.fetch(:ringbackTone, nil)
@@ -39,6 +40,10 @@ module Vonage
39
40
  verify_machine_detection
40
41
  end
41
42
 
43
+ if self.advanced_machine_detection
44
+ verify_advanced_machine_detection
45
+ end
46
+
42
47
  if self.eventUrl
43
48
  verify_event_url
44
49
  end
@@ -60,9 +65,11 @@ module Vonage
60
65
  raise ClientError.new("'user' must be defined") unless endpoint[:user]
61
66
  when 'websocket'
62
67
  raise ClientError.new("Expected 'uri' value to be a valid URI") unless URI.parse(endpoint[:uri]).kind_of?(URI::Generic)
63
- raise ClientError.new("Expected 'content-type' parameter to be either 'audio/116;rate=16000' or 'audio/116;rate=8000") unless endpoint[:'content-type'] == 'audio/116;rate=16000' || endpoint[:'content-type'] == 'audio/116;rate=8000'
68
+ raise ClientError.new("Expected 'content-type' parameter to be either 'audio/l16;rate=16000', 'audio/l16;rate=8000', or 'audio/l16;rate=24000'") unless ['audio/l16;rate=16000', 'audio/l16;rate=8000', 'audio/l16;rate=24000'].include?(endpoint[:'content-type'])
64
69
  when 'sip'
65
- raise ClientError.new("Expected 'uri' value to be a valid URI") unless URI.parse(endpoint[:uri]).kind_of?(URI::Generic)
70
+ raise ClientError.new("Expected 'uri' value to be a valid URI") unless URI.parse(endpoint[:uri]).kind_of?(URI::Generic) if endpoint[:uri]
71
+ raise ClientError.new("`uri` must not be combined with `user` and `domain`") if endpoint[:uri] && (endpoint[:user] || endpoint[:domain])
72
+ raise ClientError.new("You must provide both `user` and `domain`") if (endpoint[:user] && !endpoint[:domain]) || (endpoint[:domain] && !endpoint[:user])
66
73
  end
67
74
  end
68
75
 
@@ -82,10 +89,33 @@ module Vonage
82
89
  raise ClientError.new("Invalid 'machineDetection' value, must be either: 'continue' or 'hangup' if defined") unless self.machineDetection == 'continue' || self.machineDetection == 'hangup'
83
90
  end
84
91
 
92
+ def verify_advanced_machine_detection
93
+ raise ClientError.new("Invalid 'advanced_machine_detection' value, must be a Hash") unless self.advanced_machine_detection.is_a?(Hash)
94
+ verify_advanced_machine_detection_behavior if self.advanced_machine_detection[:behavior]
95
+ verify_advanced_machine_detection_mode if self.advanced_machine_detection[:mode]
96
+ verify_advanced_machine_detection_beep_timeout if self.advanced_machine_detection[:beep_timeout]
97
+ end
98
+
99
+ def verify_advanced_machine_detection_behavior
100
+ raise ClientError.new("Invalid 'advanced_machine_detection[:behavior]' value, must be a `continue` or `hangup`") unless ['continue', 'hangup'].include?(self.advanced_machine_detection[:behavior])
101
+ end
102
+
103
+ def verify_advanced_machine_detection_mode
104
+ raise ClientError.new("Invalid 'advanced_machine_detection[:mode]' value, must be a `detect` or `detect_beep`") unless ['detect', 'detect_beep'].include?(self.advanced_machine_detection[:mode])
105
+ end
106
+
107
+ def verify_advanced_machine_detection_beep_timeout
108
+ raise ClientError.new("Invalid 'advanced_machine_detection[:beep_timeout]' value, must be between 45 and 120") unless self.advanced_machine_detection[:beep_timeout].between?(45, 120)
109
+ end
110
+
85
111
  def verify_event_url
86
- uri = URI.parse(self.eventUrl)
112
+ unless self.eventUrl.is_a?(Array) && self.eventUrl.length == 1 && self.eventUrl[0].is_a?(String)
113
+ raise ClientError.new("Expected 'eventUrl' parameter to be an Array containing a single string item")
114
+ end
115
+
116
+ uri = URI.parse(self.eventUrl[0])
87
117
 
88
- raise ClientError.new("Invalid 'eventUrl' value, must be a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
118
+ raise ClientError.new("Invalid 'eventUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
89
119
 
90
120
  self.eventUrl
91
121
  end
@@ -123,6 +153,7 @@ module Vonage
123
153
  ncco[0].merge!(timeout: builder.timeout) if builder.timeout
124
154
  ncco[0].merge!(limit: builder.limit) if builder.limit
125
155
  ncco[0].merge!(machineDetection: builder.machineDetection) if builder.machineDetection
156
+ ncco[0].merge!(advanced_machine_detection: builder.advanced_machine_detection) if builder.advanced_machine_detection
126
157
  ncco[0].merge!(eventUrl: builder.eventUrl) if builder.eventUrl
127
158
  ncco[0].merge!(eventMethod: builder.eventMethod) if builder.eventMethod
128
159
  ncco[0].merge!(ringbackTone: builder.ringbackTone) if builder.ringbackTone
@@ -155,6 +186,7 @@ module Vonage
155
186
 
156
187
  hash.merge!(dtmfAnswer: endpoint_attrs[:dtmfAnswer]) if endpoint_attrs[:dtmfAnswer]
157
188
  hash.merge!(onAnswer: endpoint_attrs[:onAnswer]) if endpoint_attrs[:onAnswer]
189
+ hash.merge!(shaken: endpoint_attrs[:shaken]) if endpoint_attrs[:shaken]
158
190
 
159
191
  hash
160
192
  end
@@ -174,17 +206,21 @@ module Vonage
174
206
  }
175
207
 
176
208
  hash.merge!(headers: endpoint_attrs[:headers]) if endpoint_attrs[:headers]
209
+ hash.merge!(authorization: endpoint_attrs[:authorization]) if endpoint_attrs[:authorization]
177
210
 
178
211
  hash
179
212
  end
180
213
 
181
214
  def sip_endpoint(endpoint_attrs)
182
215
  hash = {
183
- type: 'sip',
184
- uri: endpoint_attrs[:uri]
216
+ type: 'sip'
185
217
  }
186
218
 
219
+ hash.merge!(uri: endpoint_attrs[:uri]) if endpoint_attrs[:uri]
220
+ hash.merge!(user: endpoint_attrs[:user]) if endpoint_attrs[:user]
221
+ hash.merge!(domain: endpoint_attrs[:domain]) if endpoint_attrs[:domain]
187
222
  hash.merge!(headers: endpoint_attrs[:headers]) if endpoint_attrs[:headers]
223
+ hash.merge!(standardHeaders: endpoint_attrs[:standardHeaders]) if endpoint_attrs[:standardHeaders]
188
224
 
189
225
  hash
190
226
  end
@@ -196,4 +232,4 @@ module Vonage
196
232
  }
197
233
  end
198
234
  end
199
- end
235
+ end