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
@@ -1,7 +1,7 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
-
4
- module Vonage
3
+
4
+ module Vonage
5
5
  class Voice::Actions::Conversation
6
6
  attr_accessor :name, :musicOnHoldUrl, :startOnEnter, :endOnExit, :record, :canSpeak, :canHear, :mute
7
7
 
@@ -49,9 +49,15 @@
49
49
  end
50
50
 
51
51
  def verify_music_on_hold_url
52
- uri = URI.parse(self.musicOnHoldUrl)
52
+ music_on_hold_url = self.musicOnHoldUrl
53
+
54
+ unless music_on_hold_url.is_a?(Array) && music_on_hold_url.length == 1 && music_on_hold_url[0].is_a?(String)
55
+ raise ClientError.new("Expected 'musicOnHoldUrl' parameter to be an Array containing a single string item")
56
+ end
57
+
58
+ uri = URI.parse(music_on_hold_url[0])
53
59
 
54
- raise ClientError.new("Invalid 'musicOnHoldUrl' value, must be a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
60
+ raise ClientError.new("Invalid 'musicOnHoldUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
55
61
 
56
62
  self.musicOnHoldUrl
57
63
  end
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Vonage
5
5
  class Voice::Actions::Input
6
- attr_accessor :type, :dtmf, :speech, :eventUrl, :eventMethod
6
+ attr_accessor :type, :dtmf, :speech, :eventUrl, :eventMethod, :mode
7
7
 
8
8
  def initialize(attributes = {})
9
9
  @type = attributes.fetch(:type)
@@ -11,6 +11,7 @@ module Vonage
11
11
  @speech = attributes.fetch(:speech, nil)
12
12
  @eventUrl = attributes.fetch(:eventUrl, nil)
13
13
  @eventMethod = attributes.fetch(:eventMethod, nil)
14
+ @mode = attributes.fetch(:mode, nil)
14
15
 
15
16
  after_initialize!
16
17
  end
@@ -33,6 +34,10 @@ module Vonage
33
34
  if self.eventMethod
34
35
  validate_event_method
35
36
  end
37
+
38
+ if self.mode
39
+ validate_mode
40
+ end
36
41
  end
37
42
 
38
43
  def validate_type
@@ -80,12 +85,23 @@ module Vonage
80
85
  if self.speech[:maxDuration]
81
86
  raise ClientError.new("Expected 'maxDuration' to not be more than 60 seconds") unless self.speech[:maxDuration] <= 60 && self.speech[:maxDuration] >= 0
82
87
  end
88
+
89
+ if self.speech[:provider]
90
+ valid_providers = ['google']
91
+
92
+ raise ClientError.new("Invalid 'provider' value, must be one of: #{valid_providers.join(', ')}") unless valid_providers.include?(self.speech[:provider])
93
+ raise ClientError.new("The `providerOptions` parameter is required when specifying a `provider`") unless self.speech[:providerOptions]
94
+ end
83
95
  end
84
96
 
85
97
  def validate_event_url
86
- uri = URI.parse(self.eventUrl)
98
+ unless self.eventUrl.is_a?(Array) && self.eventUrl.length == 1 && self.eventUrl[0].is_a?(String)
99
+ raise ClientError.new("Expected 'eventUrl' parameter to be an Array containing a single string item")
100
+ end
101
+
102
+ uri = URI.parse(self.eventUrl[0])
87
103
 
88
- raise ClientError.new("Invalid 'eventUrl' value, must be a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
104
+ raise ClientError.new("Invalid 'eventUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
89
105
 
90
106
  self.eventUrl
91
107
  end
@@ -96,6 +112,12 @@ module Vonage
96
112
  raise ClientError.new("Invalid 'eventMethod' value. must be either: 'GET' or 'POST'") unless valid_methods.include?(self.eventMethod.upcase)
97
113
  end
98
114
 
115
+ def validate_mode
116
+ valid_modes = ['asyncronous']
117
+
118
+ raise ClientError.new("Invalid 'mode' value, must be asyncronous'") unless valid_modes.include?(self.mode)
119
+ end
120
+
99
121
  def action
100
122
  create_input!(self)
101
123
  end
@@ -112,6 +134,7 @@ module Vonage
112
134
  ncco[0].merge!(speech: builder.speech) if builder.speech
113
135
  ncco[0].merge!(eventUrl: builder.eventUrl) if builder.eventUrl
114
136
  ncco[0].merge!(eventMethod: builder.eventMethod) if builder.eventMethod
137
+ ncco[0].merge!(mode: builder.mode) if builder.mode
115
138
 
116
139
  ncco
117
140
  end
@@ -22,10 +22,15 @@ module Vonage
22
22
  end
23
23
 
24
24
  def validate_event_url
25
- uri = URI.parse(self.eventUrl[0])
25
+ event_url = self.eventUrl
26
26
 
27
- raise ClientError.new("Expected 'eventUrl' value to be an Array with a single string") unless self.eventUrl.is_a?(Array)
28
- raise ClientError.new("Invalid 'eventUrl' value, must be a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
27
+ unless event_url.is_a?(Array) && event_url.length == 1 && event_url[0].is_a?(String)
28
+ raise ClientError.new("Expected 'eventUrl' parameter to be an Array containing a single string item")
29
+ end
30
+
31
+ uri = URI.parse(event_url[0])
32
+
33
+ raise ClientError.new("Invalid 'eventUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
29
34
 
30
35
  self.eventUrl
31
36
  end
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Vonage
5
5
  class Voice::Actions::Record
6
- attr_accessor :format, :split, :channels, :endOnSilence, :endOnKey, :timeOut, :beepStart, :eventUrl, :eventMethod
6
+ attr_accessor :format, :split, :channels, :endOnSilence, :endOnKey, :timeOut, :beepStart, :eventUrl, :eventMethod, :transcription
7
7
 
8
8
  def initialize(attributes = {})
9
9
  @format = attributes.fetch(:format, nil)
@@ -15,6 +15,7 @@ module Vonage
15
15
  @beepStart = attributes.fetch(:beepStart, nil)
16
16
  @eventUrl = attributes.fetch(:eventUrl, nil)
17
17
  @eventMethod = attributes.fetch(:eventMethod, nil)
18
+ @transcription = attributes.fetch(:transcription, nil)
18
19
 
19
20
  after_initialize!
20
21
  end
@@ -55,6 +56,10 @@ module Vonage
55
56
  if self.eventMethod
56
57
  validate_event_method
57
58
  end
59
+
60
+ if self.transcription
61
+ validate_transcription
62
+ end
58
63
  end
59
64
 
60
65
  def validate_format
@@ -90,9 +95,13 @@ module Vonage
90
95
  end
91
96
 
92
97
  def validate_event_url
93
- uri = URI.parse(self.eventUrl)
98
+ unless self.eventUrl.is_a?(Array) && self.eventUrl.length == 1 && self.eventUrl[0].is_a?(String)
99
+ raise ClientError.new("Expected 'eventUrl' parameter to be an Array containing a single string item")
100
+ end
94
101
 
95
- raise ClientError.new("Invalid 'eventUrl' value, must be a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
102
+ uri = URI.parse(self.eventUrl[0])
103
+
104
+ raise ClientError.new("Invalid 'eventUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
96
105
 
97
106
  self.eventUrl
98
107
  end
@@ -100,7 +109,45 @@ module Vonage
100
109
  def validate_event_method
101
110
  valid_methods = ['GET', 'POST']
102
111
 
103
- raise ClientError.new("Invalid 'eventMethod' value. must be either: 'GET' or 'POST'") unless valid_methods.include?(self.eventMethod.upcase)
112
+ raise ClientError.new("Invalid 'eventMethod' value. Must be either: 'GET' or 'POST'") unless valid_methods.include?(self.eventMethod.upcase)
113
+ end
114
+
115
+ def validate_transcription
116
+ raise ClientError.new("Expected 'transcription' parameter to be a Hash") unless self.transcription.is_a?(Hash)
117
+
118
+ if self.transcription[:language]
119
+ raise ClientError.new("Invalid 'language' value, must be a String") unless self.transcription[:language].is_a?(String)
120
+ end
121
+
122
+ if self.transcription[:eventUrl]
123
+ event_url = self.transcription[:eventUrl]
124
+
125
+ unless event_url.is_a?(Array) && event_url.length == 1 && event_url[0].is_a?(String)
126
+ raise ClientError.new("Expected 'eventUrl' parameter to be an Array containing a single string item")
127
+ end
128
+
129
+ uri = URI.parse(event_url[0])
130
+
131
+ raise ClientError.new("Invalid 'eventUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
132
+ end
133
+
134
+ if self.transcription[:eventMethod]
135
+ event_method = self.transcription[:eventMethod]
136
+ raise ClientError.new("Invalid 'eventMethod' value, must be either: 'GET' or 'POST'") unless ['GET', 'POST'].include?(event_method.upcase)
137
+ end
138
+
139
+ if self.transcription[:sentimentAnalysis]
140
+ sentiment_analysis = self.transcription[:sentimentAnalysis]
141
+ raise ClientError.new("Invalid 'sentimentAnalysis' value, must be a Boolean") unless sentiment_analysis == true || sentiment_analysis == false
142
+ end
143
+
144
+ # if self.dtmf[:maxDigits]
145
+ # raise ClientError.new("Expected 'maxDigits' to not be more than 22") if self.dtmf[:maxDigits] > 22
146
+ # end
147
+
148
+ # if self.dtmf[:submitOnHash]
149
+ # raise ClientError.new("Invalid 'submitOnHash' value, must be a Boolean") unless self.dtmf[:submitOnHash] == true || self.dtmf[:submitOnHash] == false
150
+ # end
104
151
  end
105
152
 
106
153
  def action
@@ -123,6 +170,7 @@ module Vonage
123
170
  ncco[0].merge!(beepStart: builder.beepStart) if builder.beepStart
124
171
  ncco[0].merge!(eventUrl: builder.eventUrl) if builder.eventUrl
125
172
  ncco[0].merge!(eventMethod: builder.eventMethod) if builder.eventMethod
173
+ ncco[0].merge!(transcription: builder.transcription) if builder.transcription
126
174
 
127
175
  ncco
128
176
  end
@@ -31,9 +31,13 @@ module Vonage
31
31
  end
32
32
 
33
33
  def verify_stream_url
34
- raise ClientError.new("Expected 'streamUrl' parameter to be an Array containing a single string item") unless self.streamUrl.is_a?(Array)
34
+ stream_url = self.streamUrl
35
35
 
36
- uri = URI.parse(self.streamUrl[0])
36
+ unless stream_url.is_a?(Array) && stream_url.length == 1 && stream_url[0].is_a?(String)
37
+ raise ClientError.new("Expected 'streamUrl' parameter to be an Array containing a single string item")
38
+ end
39
+
40
+ uri = URI.parse(stream_url[0])
37
41
 
38
42
  raise ClientError.new("Invalid 'streamUrl' value, must be a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS)
39
43
  end
@@ -47,7 +51,7 @@ module Vonage
47
51
  end
48
52
 
49
53
  def verify_loop
50
- raise ClientError.new("Expected 'loop' value to be either 1 or 0") unless self.loop == 1 || self.loop == 0
54
+ raise ClientError.new("Expected 'loop' value to be either 0 or a positive integer") unless self.loop >= 0
51
55
  end
52
56
 
53
57
  def action
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
  module Vonage
4
4
  class Voice::Actions::Talk
5
- attr_accessor :text, :bargeIn, :loop, :level, :language, :style
5
+ attr_accessor :text, :bargeIn, :loop, :level, :language, :style, :premium, :provider, :providerOptions
6
6
 
7
7
  def initialize(attributes= {})
8
8
  @text = attributes.fetch(:text)
@@ -11,12 +11,15 @@ module Vonage
11
11
  @level = attributes.fetch(:level, nil)
12
12
  @language = attributes.fetch(:language, nil)
13
13
  @style = attributes.fetch(:style, nil)
14
+ @premium = attributes.fetch(:premium, nil)
15
+ @provider = attributes.fetch(:provider, nil)
16
+ @providerOptions = attributes.fetch(:providerOptions, nil)
14
17
 
15
18
  after_initialize!
16
19
  end
17
20
 
18
21
  def after_initialize!
19
- if self.bargeIn
22
+ if self.bargeIn || self.bargeIn == false
20
23
  verify_barge_in
21
24
  end
22
25
 
@@ -31,6 +34,14 @@ module Vonage
31
34
  if self.style
32
35
  verify_style
33
36
  end
37
+
38
+ if self.premium || self.premium == false
39
+ verify_premium
40
+ end
41
+
42
+ if self.provider
43
+ verify_provider
44
+ end
34
45
  end
35
46
 
36
47
  def verify_barge_in
@@ -38,7 +49,7 @@ module Vonage
38
49
  end
39
50
 
40
51
  def verify_loop
41
- raise ClientError.new("Expected 'loop' value to be either 1 or 0") unless self.loop == 1 || self.loop == 0
52
+ raise ClientError.new("Expected 'loop' value to be either 0 or a positive integer") unless self.loop >= 0
42
53
  end
43
54
 
44
55
  def verify_level
@@ -49,6 +60,17 @@ module Vonage
49
60
  raise ClientError.new("Expected 'style' value to be an Integer") unless self.style.is_a?(Integer)
50
61
  end
51
62
 
63
+ def verify_premium
64
+ raise ClientError.new("Expected 'premium' value to be a Boolean") unless self.premium == true || self.premium == false
65
+ end
66
+
67
+ def verify_provider
68
+ valid_providers = ['google']
69
+
70
+ raise ClientError.new("Invalid 'provider' value, must be one of: #{valid_providers.join(', ')}") unless valid_providers.include?(self.provider)
71
+ raise ClientError.new("The `providerOptions` parameter is required when specifying a `provider`") unless self.providerOptions
72
+ end
73
+
52
74
  def action
53
75
  create_talk!(self)
54
76
  end
@@ -66,8 +88,11 @@ module Vonage
66
88
  ncco[0].merge!(level: builder.level) if builder.level
67
89
  ncco[0].merge!(language: builder.language) if builder.language
68
90
  ncco[0].merge!(style: builder.style) if builder.style
91
+ ncco[0].merge!(premium: builder.premium) if (builder.premium || builder.premium == false)
92
+ ncco[0].merge!(provider: builder.provider) if builder.provider
93
+ ncco[0].merge!(providerOptions: builder.providerOptions) if builder.providerOptions
69
94
 
70
95
  ncco
71
96
  end
72
97
  end
73
- end
98
+ end
@@ -0,0 +1,83 @@
1
+ # typed: true
2
+ # typed: true
3
+ # frozen_string_literal: true
4
+
5
+ module Vonage
6
+ class Voice::Actions::Transfer
7
+ attr_accessor :conversation_id, :can_hear, :can_speak, :mute
8
+
9
+ def initialize(attributes = {})
10
+ @conversation_id = attributes.fetch(:conversation_id)
11
+ @can_hear = attributes.fetch(:can_hear, nil)
12
+ @can_speak = attributes.fetch(:can_speak, nil)
13
+ @mute = attributes.fetch(:mute, nil)
14
+
15
+ after_initialize!
16
+ end
17
+
18
+ def after_initialize!
19
+ validate_conversation_id
20
+ validate_can_hear if self.can_hear
21
+ validate_can_speak if self.can_speak
22
+ validate_mute if self.mute != nil
23
+ end
24
+
25
+ def validate_conversation_id
26
+ conversation_id = self.conversation_id
27
+
28
+ raise ClientError.new("Expected 'conversation_id' parameter to be a string") unless conversation_id.is_a?(String)
29
+
30
+ self.conversation_id
31
+ end
32
+
33
+ def validate_can_hear
34
+ can_hear = self.can_hear
35
+ unless can_hear.is_a?(Array) && can_hear.all? { |item| item.is_a?(String) }
36
+ raise ClientError.new("Expected 'can_hear' parameter to be an array of strings")
37
+ end
38
+
39
+ self.can_hear
40
+ end
41
+
42
+ def validate_can_speak
43
+ can_speak = self.can_speak
44
+ unless can_speak.is_a?(Array) && can_speak.all? { |item| item.is_a?(String) }
45
+ raise ClientError.new("Expected 'can_speak' parameter to be an array of strings")
46
+ end
47
+
48
+ self.can_speak
49
+ end
50
+
51
+ def validate_mute
52
+ mute = self.mute
53
+ unless [true, false].include?(mute)
54
+ raise ClientError.new("Expected 'mute' parameter to be a boolean")
55
+ end
56
+
57
+ if self.mute && self.can_speak
58
+ raise ClientError.new("The 'mute' parameter is not supported if 'can_speak' is also set")
59
+ end
60
+
61
+ self.mute
62
+ end
63
+
64
+ def action
65
+ create_transfer!(self)
66
+ end
67
+
68
+ def create_transfer!(builder)
69
+ ncco = [
70
+ {
71
+ action: 'transfer',
72
+ conversation_id: builder.conversation_id,
73
+ }
74
+ ]
75
+
76
+ ncco[0].merge!(canHear: builder.can_hear) if builder.can_hear
77
+ ncco[0].merge!(canSpeak: builder.can_speak) if builder.can_speak
78
+ ncco[0].merge!(mute: builder.mute) if builder.mute != nil
79
+
80
+ ncco
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,43 @@
1
+ # typed: true
2
+ # typed: true
3
+ # frozen_string_literal: true
4
+
5
+ module Vonage
6
+ class Voice::Actions::Wait
7
+ attr_accessor :timeout
8
+
9
+ def initialize(attributes = {})
10
+ @timeout = attributes.fetch(:timeout, nil)
11
+
12
+ after_initialize!
13
+ end
14
+
15
+ def after_initialize!
16
+ validate_timeout if self.timeout
17
+ end
18
+
19
+ def validate_timeout
20
+ timeout = self.timeout
21
+
22
+ raise ClientError.new("Expected 'timeout' parameter to be a number") unless timeout.is_a?(Numeric)
23
+
24
+ self.timeout
25
+ end
26
+
27
+ def action
28
+ create_wait!(self)
29
+ end
30
+
31
+ def create_wait!(builder)
32
+ ncco = [
33
+ {
34
+ action: 'wait'
35
+ }
36
+ ]
37
+
38
+ ncco[0].merge!(timeout: builder.timeout) if builder.timeout
39
+
40
+ ncco
41
+ end
42
+ end
43
+ end
@@ -10,7 +10,9 @@ module Vonage
10
10
  notify: Vonage::Voice::Actions::Notify,
11
11
  record: Vonage::Voice::Actions::Record,
12
12
  stream: Vonage::Voice::Actions::Stream,
13
- talk: Vonage::Voice::Actions::Talk
13
+ talk: Vonage::Voice::Actions::Talk,
14
+ wait: Vonage::Voice::Actions::Wait,
15
+ transfer: Vonage::Voice::Actions::Transfer
14
16
  }
15
17
 
16
18
  class << self
@@ -12,8 +12,18 @@ module Vonage
12
12
  # @option params [required, String] :text
13
13
  # The text to read.
14
14
  #
15
+ # @option params [String] :language
16
+ # The language to use. See {https://developer.vonage.com/en/api/voice#startTalk-req-body} for a list of valid language codes.
17
+ #
18
+ # @option params [Integer] :style
19
+ # The vocal style, as identified by an assigned integer.
20
+ # See {https://developer.vonage.com/en/voice/voice-api/concepts/text-to-speech#supported-languages} for a list of available styles.
21
+ #
22
+ # @option params [Boolean] :premium
23
+ # Set to `true` to use the premium version of the specified style if available, otherwise the standard version will be used.
24
+ #
15
25
  # @option params [String] :voice_name
16
- # The voice & language to use.
26
+ # The voice & language to use. [DEPRECATED: use `language` and `style` instead].
17
27
  #
18
28
  # @option params [Integer] :loop
19
29
  # The number of times to repeat the text the file, 0 for infinite.
data/lib/vonage/voice.rb CHANGED
@@ -18,6 +18,8 @@ module Vonage
18
18
  #
19
19
  # @option params [required, Array<Hash>] :to
20
20
  # Connect to a Phone (PSTN) number, SIP Endpoint, Websocket, or VBC extension.
21
+ # The `to` Hash can contain a number of different properties depending on the `type`.
22
+ # See the API reference for specific details.
21
23
  #
22
24
  # @option params [Hash] :from
23
25
  # Connect to a Phone (PSTN) number. Should not be set if **:random_from_number** is **true**
@@ -48,6 +50,17 @@ module Vonage
48
50
  # @option params [String] :machine_detection
49
51
  # Configure the behavior when Vonage detects that the call is answered by voicemail.
50
52
  #
53
+ # @option params [Hash] :advanced_machine_detection
54
+ # Configure the behavior of Vonage's advanced machine detection. Overrides machine_detection if both are set.
55
+ # Hash with three possible properties:
56
+ # - :behavior [String]: Must be one of `continue` or `hangup`. When hangup is used, the call will be terminated if a
57
+ # machine is detected. When continue is used, the call will continue even if a machine is detected.
58
+ # - :mode [String]: Must be one of `detect` or `detect_beep`. Detect if machine answered and sends a human or
59
+ # machine status in the webhook payload. When set to `detect_beep`, the system also attempts to detect
60
+ # voice mail beep and sends an additional parameter `sub_state` in the webhook with the value `beep_start`.
61
+ # - :beep_timeout [Integer]: Min: 45, Max: 120. Maximum time in seconds Vonage should wait for a machine beep
62
+ # to be detected. A machine event with `sub_state` set to `beep_timeout` will be sent if the timeout is exceeded.
63
+ #
51
64
  # @option params [Integer] :length_timer
52
65
  # Set the number of seconds that elapse before Vonage hangs up after the call state changes to in_progress.
53
66
  #
@@ -268,5 +281,16 @@ module Vonage
268
281
  def dtmf
269
282
  @dtmf ||= DTMF.new(@config)
270
283
  end
284
+
285
+ # Validate a JSON Web Token from a Voice API Webhook.
286
+ #
287
+ # @param [String, required] :token The JWT from the Webhook's Authorization header
288
+ # @param [String, optional] :signature_secret The account signature secret. Required, unless `signature_secret`
289
+ # is set in `Config`
290
+ #
291
+ # @return [Boolean] true, if the JWT is verified, false otherwise
292
+ def verify_webhook_token(token:, signature_secret: @config.signature_secret)
293
+ JWT.verify_hs256_signature(token: token, signature_secret: signature_secret)
294
+ end
271
295
  end
272
296
  end
data/lib/vonage.rb CHANGED
@@ -7,12 +7,16 @@ module Vonage
7
7
  loader = Zeitwerk::Loader.new
8
8
  loader.tag = File.basename(__FILE__, '.rb')
9
9
  loader.inflector.inflect({
10
+ 'api_error' => 'APIError',
10
11
  'dtmf' => 'DTMF',
11
12
  'gsm7' => 'GSM7',
12
13
  'http' => 'HTTP',
13
14
  'json' => 'JSON',
14
15
  'jwt' => 'JWT',
16
+ 'rcs' => 'RCS',
17
+ 'sip' => 'SIP',
15
18
  'sms' => 'SMS',
19
+ 'network_sim_swap' => 'NetworkSIMSwap',
16
20
  'mms' => 'MMS',
17
21
  'tfa' => 'TFA',
18
22
  'version' => 'VERSION',
data/vonage.gemspec CHANGED
@@ -12,9 +12,11 @@ Gem::Specification.new do |s|
12
12
  s.summary = 'This is the Ruby Server SDK for Vonage APIs. To use it you\'ll need a Vonage account. Sign up for free at https://www.vonage.com'
13
13
  s.files = Dir.glob('lib/**/*.rb') + %w(LICENSE.txt README.md vonage.gemspec)
14
14
  s.required_ruby_version = '>= 2.5.0'
15
- s.add_dependency('vonage-jwt', '~> 0.1.0')
15
+ s.add_dependency('vonage-jwt', '~> 0.2.0')
16
16
  s.add_dependency('zeitwerk', '~> 2', '>= 2.2')
17
17
  s.add_dependency('sorbet-runtime', '~> 0.5')
18
+ s.add_dependency('multipart-post', '~> 2.0')
19
+ s.add_dependency('net-http-persistent', '~> 4.0', '>= 4.0.2')
18
20
  s.add_runtime_dependency('rexml')
19
21
  s.add_runtime_dependency('phonelib')
20
22
  s.require_path = 'lib'