nexmo 6.1.0 → 7.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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +24 -4
  4. data/lib/nexmo.rb +12 -14
  5. data/lib/nexmo/abstract_authentication.rb +2 -0
  6. data/lib/nexmo/account.rb +6 -1
  7. data/lib/nexmo/alerts.rb +6 -1
  8. data/lib/nexmo/applications.rb +24 -3
  9. data/lib/nexmo/applications/list_response.rb +2 -0
  10. data/lib/nexmo/authentication_error.rb +2 -0
  11. data/lib/nexmo/basic.rb +2 -0
  12. data/lib/nexmo/bearer_token.rb +1 -0
  13. data/lib/nexmo/client.rb +46 -23
  14. data/lib/nexmo/client_error.rb +2 -0
  15. data/lib/nexmo/config.rb +49 -9
  16. data/lib/nexmo/conversations.rb +24 -0
  17. data/lib/nexmo/conversations/events.rb +1 -0
  18. data/lib/nexmo/conversations/legs.rb +1 -0
  19. data/lib/nexmo/conversations/members.rb +1 -0
  20. data/lib/nexmo/conversations/users.rb +1 -0
  21. data/lib/nexmo/conversions.rb +4 -0
  22. data/lib/nexmo/entity.rb +5 -3
  23. data/lib/nexmo/error.rb +2 -0
  24. data/lib/nexmo/errors.rb +8 -0
  25. data/lib/nexmo/files.rb +7 -2
  26. data/lib/nexmo/form_data.rb +2 -0
  27. data/lib/nexmo/gsm7.rb +2 -0
  28. data/lib/nexmo/http.rb +12 -3
  29. data/lib/nexmo/json.rb +4 -0
  30. data/lib/nexmo/jwt.rb +5 -1
  31. data/lib/nexmo/key_secret_params.rb +10 -2
  32. data/lib/nexmo/keys.rb +7 -1
  33. data/lib/nexmo/logger.rb +14 -4
  34. data/lib/nexmo/messages.rb +7 -1
  35. data/lib/nexmo/namespace.rb +15 -18
  36. data/lib/nexmo/number_insight.rb +21 -6
  37. data/lib/nexmo/numbers.rb +24 -20
  38. data/lib/nexmo/numbers/list_response.rb +2 -0
  39. data/lib/nexmo/numbers/response.rb +1 -0
  40. data/lib/nexmo/params.rb +1 -0
  41. data/lib/nexmo/pricing.rb +2 -1
  42. data/lib/nexmo/pricing_types.rb +1 -0
  43. data/lib/nexmo/redact.rb +2 -1
  44. data/lib/nexmo/response.rb +2 -0
  45. data/lib/nexmo/secrets.rb +1 -0
  46. data/lib/nexmo/secrets/list_response.rb +2 -0
  47. data/lib/nexmo/server_error.rb +2 -0
  48. data/lib/nexmo/signature.rb +1 -0
  49. data/lib/nexmo/sms.rb +16 -10
  50. data/lib/nexmo/tfa.rb +2 -1
  51. data/lib/nexmo/user_agent.rb +1 -0
  52. data/lib/nexmo/verify.rb +93 -17
  53. data/lib/nexmo/version.rb +3 -1
  54. data/lib/nexmo/{calls.rb → voice.rb} +12 -11
  55. data/lib/nexmo/{calls → voice}/dtmf.rb +2 -1
  56. data/lib/nexmo/{calls → voice}/list_response.rb +3 -1
  57. data/lib/nexmo/{calls → voice}/stream.rb +2 -1
  58. data/lib/nexmo/{calls → voice}/talk.rb +2 -1
  59. data/nexmo.gemspec +2 -7
  60. metadata +17 -85
  61. data/lib/nexmo/key_secret_query.rb +0 -20
  62. data/lib/nexmo/number_insight/response.rb +0 -5
  63. data/lib/nexmo/sms/response.rb +0 -7
  64. data/lib/nexmo/verify/response.rb +0 -5
@@ -1,3 +1,5 @@
1
+ # typed: true
2
+
1
3
  module Nexmo
2
4
  class Response
3
5
  def initialize(entity=nil, http_response=nil)
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Nexmo
@@ -1,3 +1,5 @@
1
+ # typed: ignore
2
+
1
3
  class Nexmo::Secrets::ListResponse < Nexmo::Response
2
4
  include Enumerable
3
5
 
@@ -1,3 +1,5 @@
1
+ # typed: strong
2
+
1
3
  module Nexmo
2
4
  class ServerError < Error
3
5
  end
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
  require 'openssl'
3
4
  require 'digest/md5'
@@ -1,21 +1,19 @@
1
+ # typed: strict
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Nexmo
4
5
  class SMS < Namespace
6
+ extend T::Sig
5
7
  include Keys
6
8
 
7
- self.host = 'rest.nexmo.com'
9
+ self.host = :rest_host
8
10
 
9
11
  # Send an outbound SMS from your Nexmo account.
10
12
  #
11
13
  # @example
12
14
  # response = client.sms.send(from: 'Ruby', to: '447700900000', text: 'Hello world')
13
15
  #
14
- # if response.success?
15
- # puts "Sent message id=#{response.messages.first.message_id}"
16
- # else
17
- # puts "Error: #{response.messages.first.error_text}"
18
- # end
16
+ # puts "Sent message id=#{response.messages.first.message_id}"
19
17
  #
20
18
  # @option params [required, String] :from
21
19
  # The name or number the message should be sent from.
@@ -94,22 +92,30 @@ module Nexmo
94
92
  #
95
93
  # @see https://developer.nexmo.com/api/sms#send-an-sms
96
94
  #
95
+ sig { params(params: T::Hash[Symbol, T.untyped]).returns(Nexmo::Response) }
97
96
  def send(params)
98
- if unicode?(params[:text]) && params[:type] != 'unicode'
97
+ if unicode?(params.fetch(:text)) && params[:type] != 'unicode'
99
98
  message = 'Sending unicode text SMS without setting the type parameter to "unicode". ' \
100
99
  'See https://developer.nexmo.com/messaging/sms for details, ' \
101
100
  'or email support@nexmo.com if you have any questions.'
102
101
 
103
- @logger.warn(message)
102
+ logger.warn(message)
104
103
  end
105
104
 
106
- request('/sms/json', params: hyphenate(params), type: Post, response_class: Response)
105
+ response = request('/sms/json', params: hyphenate(params), type: Post)
106
+
107
+ unless response.messages.first.status == '0'
108
+ raise Error, response.messages.first[:error_text]
109
+ end
110
+
111
+ response
107
112
  end
108
113
 
109
114
  private
110
115
 
116
+ sig { params(text: String).returns(T::Boolean) }
111
117
  def unicode?(text)
112
- !GSM7.encoded?(text)
118
+ !Nexmo::GSM7Test::GSM7.encoded?(text)
113
119
  end
114
120
  end
115
121
  end
@@ -1,10 +1,11 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Nexmo
4
5
  class TFA < Namespace
5
6
  include Keys
6
7
 
7
- self.host = 'rest.nexmo.com'
8
+ self.host = :rest_host
8
9
 
9
10
  def send(params)
10
11
  request('/sc/us/2fa/json', params: hyphenate(params), type: Post)
@@ -1,3 +1,4 @@
1
+ # typed: ignore
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Nexmo
@@ -1,13 +1,13 @@
1
+ # typed: strict
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Nexmo
4
5
  class Verify < Namespace
6
+ extend T::Sig
5
7
  alias_method :http_request, :request
6
8
 
7
9
  private :http_request
8
10
 
9
- self.response_class = Response
10
-
11
11
  # Generate and send a PIN to your user.
12
12
  #
13
13
  # @note You can make a maximum of one Verify request per second.
@@ -15,11 +15,7 @@ module Nexmo
15
15
  # @example
16
16
  # response = client.verify.request(number: '447700900000', brand: 'Acme Inc')
17
17
  #
18
- # if response.success?
19
- # puts "Started verification request_id=#{response.request_id}"
20
- # else
21
- # puts "Error: #{response.error_text}"
22
- # end
18
+ # puts "Started verification request_id=#{response.request_id}"
23
19
  #
24
20
  # @option params [required, String] :number
25
21
  # The mobile or landline phone number to verify.
@@ -64,8 +60,13 @@ module Nexmo
64
60
  #
65
61
  # @see https://developer.nexmo.com/api/verify#verifyRequest
66
62
  #
67
- def request(params)
68
- http_request('/verify/json', params: params, type: Post)
63
+ sig { params(params: T.untyped, uri: T.untyped).returns(T.untyped) }
64
+ def request(params, uri = '/verify/json')
65
+ response = http_request(uri, params: params, type: Post)
66
+
67
+ raise Error, response[:error_text] if error?(response)
68
+
69
+ response
69
70
  end
70
71
 
71
72
  # Confirm that the PIN you received from your user matches the one sent by Nexmo in your verification request.
@@ -73,11 +74,7 @@ module Nexmo
73
74
  # @example
74
75
  # response = client.verify.check(request_id: request_id, code: '1234')
75
76
  #
76
- # if response.success?
77
- # puts "Verification complete, event_id=#{response.event_id}"
78
- # else
79
- # puts "Error: #{response.error_text}"
80
- # end
77
+ # puts "Verification complete, event_id=#{response.event_id}"
81
78
  #
82
79
  # @option params [required, String] :request_id
83
80
  # The Verify request to check.
@@ -96,8 +93,13 @@ module Nexmo
96
93
  #
97
94
  # @see https://developer.nexmo.com/api/verify#verifyCheck
98
95
  #
96
+ sig { params(params: T::Hash[Symbol, T.untyped]).returns(Nexmo::Response) }
99
97
  def check(params)
100
- http_request('/verify/check/json', params: params, type: Post)
98
+ response = http_request('/verify/check/json', params: params, type: Post)
99
+
100
+ raise Error, response[:error_text] if error?(response)
101
+
102
+ response
101
103
  end
102
104
 
103
105
  # Check the status of past or current verification requests.
@@ -118,8 +120,13 @@ module Nexmo
118
120
  #
119
121
  # @see https://developer.nexmo.com/api/verify#verifySearch
120
122
  #
123
+ sig { params(params: T::Hash[Symbol, T.untyped]).returns(T.any(T::Hash[Symbol, T.untyped], Nexmo::Response)) }
121
124
  def search(params)
122
- http_request('/verify/search/json', params: params)
125
+ response = http_request('/verify/search/json', params: params)
126
+
127
+ raise Error, response[:error_text] if error?(response)
128
+
129
+ response
123
130
  end
124
131
 
125
132
  # Control the progress of your verification requests.
@@ -140,8 +147,13 @@ module Nexmo
140
147
  #
141
148
  # @see https://developer.nexmo.com/api/verify#verifyControl
142
149
  #
150
+ sig { params(params: T::Hash[Symbol, T.untyped]).returns(T.untyped) }
143
151
  def control(params)
144
- http_request('/verify/control/json', params: params, type: Post)
152
+ response = http_request('/verify/control/json', params: params, type: Post)
153
+
154
+ raise Error, response[:error_text] if error?(response)
155
+
156
+ response
145
157
  end
146
158
 
147
159
  # Cancel an existing verification request.
@@ -155,6 +167,7 @@ module Nexmo
155
167
  #
156
168
  # @see https://developer.nexmo.com/api/verify#verifyControl
157
169
  #
170
+ sig { params(id: String).returns(Nexmo::Response) }
158
171
  def cancel(id)
159
172
  control(request_id: id, cmd: 'cancel')
160
173
  end
@@ -170,8 +183,71 @@ module Nexmo
170
183
  #
171
184
  # @see https://developer.nexmo.com/api/verify#verifyControl
172
185
  #
186
+ sig { params(id: String).returns(Nexmo::Response) }
173
187
  def trigger_next_event(id)
174
188
  control(request_id: id, cmd: 'trigger_next_event')
175
189
  end
190
+
191
+ # Send a PSD2-compliant payment token to a user for payment authorization
192
+ #
193
+ # @example
194
+ # response = client.verify.psd2(number: '447700900000', payee: 'Acme Inc', amount: 48.00)
195
+ #
196
+ # @option params [required, String] :number
197
+ # The mobile or landline phone number to verify.
198
+ # Unless you are setting **:country** explicitly, this number must be in E.164 format.
199
+ #
200
+ # @option params [String] :country
201
+ # If you do not provide **:number** in international format or you are not sure if **:number** is correctly formatted, specify the two-character country code in **:country**.
202
+ # Verify will then format the number for you.
203
+ #
204
+ # @option params [required, String] :payee
205
+ # An alphanumeric string to indicate to the user the name of the recipient that they are confirming a payment to.
206
+ #
207
+ # @option params [required, Float] :amount
208
+ # The decimal amount of the payment to be confirmed, in Euros
209
+ #
210
+ # @option params [Integer] :code_length
211
+ # The length of the verification code.
212
+ #
213
+ # @option params [String] :lg
214
+ # By default, the SMS or text-to-speech (TTS) message is generated in the locale that matches the **:number**.
215
+ # For example, the text message or TTS message for a `33*` number is sent in French.
216
+ # Use this parameter to explicitly control the language, accent and gender used for the Verify request.
217
+ #
218
+ # @option params [Integer] :pin_expiry
219
+ # How log the generated verification code is valid for, in seconds.
220
+ # When you specify both **:pin_expiry** and **:next_event_wait** then **:pin_expiry** must be an integer multiple of **:next_event_wait** otherwise **:pin_expiry** is defaulted to equal **:next_event_wait**.
221
+ # See [changing the event timings](https://developer.nexmo.com/verify/guides/changing-default-timings).
222
+ #
223
+ # @option params [Integer] :next_event_wait
224
+ # Specifies the wait time in seconds between attempts to deliver the verification code.
225
+ #
226
+ # @option params [Integer] :workflow_id
227
+ # Selects the predefined sequence of SMS and TTS (Text To Speech) actions to use in order to convey the PIN to your user.
228
+ # For example, an id of 1 identifies the workflow SMS - TTS - TTS.
229
+ # For a list of all workflows and their associated ids, please visit the [developer portal](https://developer.nexmo.com/verify/guides/workflows-and-events).
230
+ #
231
+ # @param [Hash] params
232
+ #
233
+ # @return [Response]
234
+ #
235
+ # @see https://developer.nexmo.com/api/verify#verifyRequestWithPSD2
236
+ #
237
+ sig { params(params: T.untyped, uri: T.untyped).returns(T.any(Nexmo::Error, Nexmo::Response)) }
238
+ def psd2(params, uri = '/verify/psd2/json')
239
+ response = http_request(uri, params: params, type: Post)
240
+
241
+ raise Error, response[:error_text] if error?(response)
242
+
243
+ response
244
+ end
245
+
246
+ private
247
+
248
+ sig { params(response: T.untyped).returns(T::Boolean) }
249
+ def error?(response)
250
+ response.respond_to?(:error_text)
251
+ end
176
252
  end
177
253
  end
@@ -1,3 +1,5 @@
1
+ # typed: strong
2
+
1
3
  module Nexmo
2
- VERSION = '6.1.0'
4
+ VERSION = '7.1.1'
3
5
  end
@@ -1,7 +1,8 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Nexmo
4
- class Calls < Namespace
5
+ class Voice < Namespace
5
6
  self.authentication = BearerToken
6
7
 
7
8
  self.request_body = JSON
@@ -9,7 +10,7 @@ module Nexmo
9
10
  # Create an outbound Call.
10
11
  #
11
12
  # @example
12
- # response = client.calls.create({
13
+ # response = client.voice.create({
13
14
  # to: [{type: 'phone', number: '14843331234'}],
14
15
  # from: {type: 'phone', number: '14843335555'},
15
16
  # answer_url: ['https://example.com/answer']
@@ -60,7 +61,7 @@ module Nexmo
60
61
  # Get details of your calls.
61
62
  #
62
63
  # @example
63
- # response = client.calls.list
64
+ # response = client.voice.list
64
65
  # response.each do |item|
65
66
  # puts "#{item.uuid} #{item.direction} #{item.status}"
66
67
  # end
@@ -99,7 +100,7 @@ module Nexmo
99
100
  # Get detail of a specific call.
100
101
  #
101
102
  # @example
102
- # response = client.calls.get(id)
103
+ # response = client.voice.get(id)
103
104
  #
104
105
  # @param [String] id
105
106
  #
@@ -114,7 +115,7 @@ module Nexmo
114
115
  # Modify an in progress call.
115
116
  #
116
117
  # @example
117
- # response = client.calls.update(id, action: 'hangup')
118
+ # response = client.voice.update(id, action: 'hangup')
118
119
  #
119
120
  # @option params [required, String] :action
120
121
  #
@@ -135,7 +136,7 @@ module Nexmo
135
136
  # Hangup an in progress call.
136
137
  #
137
138
  # @example
138
- # response = client.calls.hangup(id)
139
+ # response = client.voice.hangup(id)
139
140
  #
140
141
  # @param [String] id
141
142
  #
@@ -150,7 +151,7 @@ module Nexmo
150
151
  # Mute an in progress call.
151
152
  #
152
153
  # @example
153
- # response = client.calls.mute(id)
154
+ # response = client.voice.mute(id)
154
155
  #
155
156
  # @param [String] id
156
157
  #
@@ -165,7 +166,7 @@ module Nexmo
165
166
  # Unmute an in progress call.
166
167
  #
167
168
  # @example
168
- # response = client.calls.unmute(id)
169
+ # response = client.voice.unmute(id)
169
170
  #
170
171
  # @param [String] id
171
172
  #
@@ -180,7 +181,7 @@ module Nexmo
180
181
  # Earmuff an in progress call.
181
182
  #
182
183
  # @example
183
- # response = client.calls.earmuff(id)
184
+ # response = client.voice.earmuff(id)
184
185
  #
185
186
  # @param [String] id
186
187
  #
@@ -195,7 +196,7 @@ module Nexmo
195
196
  # Unearmuff an in progress call.
196
197
  #
197
198
  # @example
198
- # response = client.calls.unearmuff(id)
199
+ # response = client.voice.unearmuff(id)
199
200
  #
200
201
  # @param [String] id
201
202
  #
@@ -215,7 +216,7 @@ module Nexmo
215
216
  # url: ['https://example.com/ncco.json']
216
217
  # }
217
218
  #
218
- # response = client.calls.transfer(id, destination: destination)
219
+ # response = client.voice.transfer(id, destination: destination)
219
220
  #
220
221
  # @param [String] id
221
222
  # @param [Hash] destination
@@ -1,7 +1,8 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Nexmo
4
- class Calls::DTMF < Namespace
5
+ class Voice::DTMF < Namespace
5
6
  self.authentication = BearerToken
6
7
 
7
8
  self.request_body = JSON
@@ -1,4 +1,6 @@
1
- class Nexmo::Calls::ListResponse < Nexmo::Response
1
+ # typed: ignore
2
+
3
+ class Nexmo::Voice::ListResponse < Nexmo::Response
2
4
  include Enumerable
3
5
 
4
6
  def each
@@ -1,7 +1,8 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Nexmo
4
- class Calls::Stream < Namespace
5
+ class Voice::Stream < Namespace
5
6
  self.authentication = BearerToken
6
7
 
7
8
  self.request_body = JSON
@@ -1,7 +1,8 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Nexmo
4
- class Calls::Talk < Namespace
5
+ class Voice::Talk < Namespace
5
6
  self.authentication = BearerToken
6
7
 
7
8
  self.request_body = JSON
@@ -13,13 +13,8 @@ Gem::Specification.new do |s|
13
13
  s.files = Dir.glob('lib/**/*.rb') + %w(LICENSE.txt README.md nexmo.gemspec)
14
14
  s.required_ruby_version = '>= 2.5.0'
15
15
  s.add_dependency('jwt', '~> 2')
16
- s.add_dependency('zeitwerk', '~> 2')
17
- s.add_development_dependency('rake', '~> 13')
18
- s.add_development_dependency('yard', '~> 0.9')
19
- s.add_development_dependency('minitest', '~> 5.0')
20
- s.add_development_dependency('webmock', '~> 3.0')
21
- s.add_development_dependency('simplecov', '~> 0.16')
22
- s.add_development_dependency('coveralls', '~> 0.8.15')
16
+ s.add_dependency('zeitwerk', '~> 2', '>= 2.2')
17
+ s.add_dependency('sorbet-runtime', '~> 0.5')
23
18
  s.require_path = 'lib'
24
19
  s.metadata = {
25
20
  'homepage' => 'https://github.com/Nexmo/nexmo-ruby',