nexmo 6.2.0 → 7.1.2

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -3
  3. data/lib/nexmo.rb +2 -0
  4. data/lib/nexmo/abstract_authentication.rb +2 -2
  5. data/lib/nexmo/account.rb +6 -1
  6. data/lib/nexmo/alerts.rb +6 -1
  7. data/lib/nexmo/applications.rb +24 -3
  8. data/lib/nexmo/applications/list_response.rb +2 -0
  9. data/lib/nexmo/authentication_error.rb +2 -0
  10. data/lib/nexmo/basic.rb +2 -0
  11. data/lib/nexmo/bearer_token.rb +1 -0
  12. data/lib/nexmo/client.rb +46 -23
  13. data/lib/nexmo/client_error.rb +2 -0
  14. data/lib/nexmo/config.rb +49 -9
  15. data/lib/nexmo/conversations.rb +24 -0
  16. data/lib/nexmo/conversations/events.rb +1 -0
  17. data/lib/nexmo/conversations/legs.rb +1 -0
  18. data/lib/nexmo/conversations/members.rb +1 -0
  19. data/lib/nexmo/conversations/users.rb +1 -0
  20. data/lib/nexmo/conversions.rb +4 -0
  21. data/lib/nexmo/entity.rb +3 -1
  22. data/lib/nexmo/error.rb +2 -0
  23. data/lib/nexmo/errors.rb +8 -0
  24. data/lib/nexmo/files.rb +7 -2
  25. data/lib/nexmo/form_data.rb +2 -0
  26. data/lib/nexmo/gsm7.rb +2 -2
  27. data/lib/nexmo/http.rb +12 -3
  28. data/lib/nexmo/json.rb +4 -0
  29. data/lib/nexmo/jwt.rb +5 -1
  30. data/lib/nexmo/key_secret_params.rb +10 -2
  31. data/lib/nexmo/keys.rb +7 -1
  32. data/lib/nexmo/logger.rb +14 -4
  33. data/lib/nexmo/messages.rb +7 -1
  34. data/lib/nexmo/namespace.rb +15 -18
  35. data/lib/nexmo/number_insight.rb +21 -6
  36. data/lib/nexmo/numbers.rb +2 -1
  37. data/lib/nexmo/numbers/list_response.rb +2 -0
  38. data/lib/nexmo/numbers/response.rb +1 -0
  39. data/lib/nexmo/params.rb +1 -0
  40. data/lib/nexmo/pricing.rb +2 -1
  41. data/lib/nexmo/pricing_types.rb +1 -0
  42. data/lib/nexmo/redact.rb +1 -0
  43. data/lib/nexmo/response.rb +2 -0
  44. data/lib/nexmo/secrets.rb +1 -0
  45. data/lib/nexmo/secrets/list_response.rb +2 -0
  46. data/lib/nexmo/server_error.rb +2 -0
  47. data/lib/nexmo/signature.rb +1 -0
  48. data/lib/nexmo/sms.rb +16 -10
  49. data/lib/nexmo/tfa.rb +2 -1
  50. data/lib/nexmo/user_agent.rb +1 -0
  51. data/lib/nexmo/verify.rb +93 -17
  52. data/lib/nexmo/version.rb +3 -1
  53. data/lib/nexmo/{calls.rb → voice.rb} +12 -11
  54. data/lib/nexmo/{calls → voice}/dtmf.rb +2 -1
  55. data/lib/nexmo/{calls → voice}/list_response.rb +3 -1
  56. data/lib/nexmo/{calls → voice}/stream.rb +2 -1
  57. data/lib/nexmo/{calls → voice}/talk.rb +2 -1
  58. data/nexmo.gemspec +1 -0
  59. metadata +22 -11
  60. data/lib/nexmo/number_insight/response.rb +0 -5
  61. data/lib/nexmo/sms/response.rb +0 -7
  62. data/lib/nexmo/verify/response.rb +0 -5
@@ -1,3 +1,4 @@
1
+ # typed: ignore
1
2
  # frozen_string_literal: true
2
3
  require 'net/http'
3
4
  require 'json'
@@ -7,9 +8,7 @@ module Nexmo
7
8
  def initialize(config)
8
9
  @config = config
9
10
 
10
- @logger = config.logger
11
-
12
- @host = self.class.host
11
+ @host = self.class.host == :api_host ? @config.api_host : @config.rest_host
13
12
 
14
13
  @http = Net::HTTP.new(@host, Net::HTTP.https_default_port, p_addr = nil)
15
14
  @http.use_ssl = true
@@ -18,10 +17,12 @@ module Nexmo
18
17
  end
19
18
 
20
19
  def self.host
21
- @host ||= 'api.nexmo.com'
20
+ @host ||= :api_host
22
21
  end
23
22
 
24
23
  def self.host=(host)
24
+ raise ArgumentError unless host == :rest_host
25
+
25
26
  @host = host
26
27
  end
27
28
 
@@ -45,22 +46,14 @@ module Nexmo
45
46
  @request_headers ||= {}
46
47
  end
47
48
 
48
- def self.response_class
49
- @response_class ||= Response
50
- end
51
-
52
- def self.response_class=(response_class)
53
- @response_class = response_class
54
- end
55
-
56
- private
49
+ protected
57
50
 
58
51
  Get = Net::HTTP::Get
59
52
  Put = Net::HTTP::Put
60
53
  Post = Net::HTTP::Post
61
54
  Delete = Net::HTTP::Delete
62
55
 
63
- def request(path, params: nil, type: Get, response_class: nil, &block)
56
+ def request(path, params: nil, type: Get, response_class: Response, &block)
64
57
  uri = URI('https://' + @host + path)
65
58
 
66
59
  params ||= {}
@@ -86,17 +79,17 @@ module Nexmo
86
79
 
87
80
  self.class.request_body.update(message, params) if type::REQUEST_HAS_BODY
88
81
 
89
- @logger.log_request_info(message)
82
+ logger.log_request_info(message)
90
83
 
91
84
  response = @http.request(message, &block)
92
85
 
93
- @logger.log_response_info(response, @host)
86
+ logger.log_response_info(response, @host)
94
87
 
95
88
  return if block
96
89
 
97
- @logger.debug(response.body) if response.body
90
+ logger.debug(response.body) if response.body
98
91
 
99
- parse(response, response_class || self.class.response_class)
92
+ parse(response, response_class)
100
93
  end
101
94
 
102
95
  def parse(response, response_class)
@@ -115,6 +108,10 @@ module Nexmo
115
108
  raise Errors.parse(response)
116
109
  end
117
110
  end
111
+
112
+ def logger
113
+ @config.logger
114
+ end
118
115
  end
119
116
 
120
117
  private_constant :Namespace
@@ -1,9 +1,8 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Nexmo
4
5
  class NumberInsight < Namespace
5
- self.response_class = Response
6
-
7
6
  # Provides basic number insight information about a number.
8
7
  #
9
8
  # @example
@@ -24,7 +23,11 @@ module Nexmo
24
23
  # @see https://developer.nexmo.com/api/number-insight#getNumberInsightBasic
25
24
  #
26
25
  def basic(params)
27
- request('/ni/basic/json', params: params)
26
+ response = request('/ni/basic/json', params: params)
27
+
28
+ raise Error, response[:status_message] unless response.status.zero?
29
+
30
+ response
28
31
  end
29
32
 
30
33
  # Provides standard number insight information about a number.
@@ -52,7 +55,11 @@ module Nexmo
52
55
  # @see https://developer.nexmo.com/api/number-insight#getNumberInsightStandard
53
56
  #
54
57
  def standard(params)
55
- request('/ni/standard/json', params: params)
58
+ response = request('/ni/standard/json', params: params)
59
+
60
+ raise Error, response[:status_message] unless response.status.zero?
61
+
62
+ response
56
63
  end
57
64
 
58
65
  # Provides advanced number insight information about a number synchronously.
@@ -84,7 +91,11 @@ module Nexmo
84
91
  # @see https://developer.nexmo.com/api/number-insight#getNumberInsightAdvanced
85
92
  #
86
93
  def advanced(params)
87
- request('/ni/advanced/json', params: params)
94
+ response = request('/ni/advanced/json', params: params)
95
+
96
+ raise Error, response[:status_message] unless response.status.zero?
97
+
98
+ response
88
99
  end
89
100
 
90
101
  # Provides advanced number insight number information *asynchronously* using the URL specified in the callback parameter.
@@ -119,7 +130,11 @@ module Nexmo
119
130
  # @see https://developer.nexmo.com/api/number-insight#getNumberInsightAsync
120
131
  #
121
132
  def advanced_async(params)
122
- request('/ni/advanced/async/json', params: params)
133
+ response = request('/ni/advanced/async/json', params: params)
134
+
135
+ raise Error, response[:status_message] unless response.status.zero?
136
+
137
+ response
123
138
  end
124
139
  end
125
140
  end
@@ -1,10 +1,11 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Nexmo
4
5
  class Numbers < Namespace
5
6
  include Keys
6
7
 
7
- self.host = 'rest.nexmo.com'
8
+ self.host = :rest_host
8
9
 
9
10
  # Retrieve all the inbound numbers associated with your Nexmo account.
10
11
  #
@@ -1,3 +1,5 @@
1
+ # typed: ignore
2
+
1
3
  class Nexmo::Numbers::ListResponse < Nexmo::Response
2
4
  include Enumerable
3
5
 
@@ -1,3 +1,4 @@
1
+ # typed: false
1
2
  # frozen_string_literal: true
2
3
 
3
4
  class Nexmo::Numbers::Response < Nexmo::Response
@@ -1,3 +1,4 @@
1
+ # typed: ignore
1
2
  # frozen_string_literal: true
2
3
  require 'cgi'
3
4
 
@@ -1,8 +1,9 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Nexmo
4
5
  class Pricing < Namespace
5
- self.host = 'rest.nexmo.com'
6
+ self.host = :rest_host
6
7
 
7
8
  def initialize(config, type: nil)
8
9
  raise ArgumentError if type.nil?
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Nexmo
@@ -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: 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::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