nexmo 7.0.0 → 7.2.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.
@@ -1,8 +1,10 @@
1
- # typed: false
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Nexmo
5
5
  class Conversations < Namespace
6
+ extend T::Sig
7
+
6
8
  self.authentication = BearerToken
7
9
 
8
10
  self.request_body = JSON
@@ -33,6 +35,7 @@ module Nexmo
33
35
  #
34
36
  # @see https://developer.nexmo.com/api/conversation#createConversation
35
37
  #
38
+ sig { params(params: T::Hash[Symbol, T.untyped]).returns(Nexmo::Response) }
36
39
  def create(params)
37
40
  request('/beta/conversations', params: params, type: Post)
38
41
  end
@@ -63,6 +66,7 @@ module Nexmo
63
66
  #
64
67
  # @see https://developer.nexmo.com/api/conversation#replaceConversation
65
68
  #
69
+ sig { params(params: T.nilable(T::Hash[Symbol, T.untyped])).returns(Nexmo::Response) }
66
70
  def list(params = nil)
67
71
  request('/beta/conversations', params: params)
68
72
  end
@@ -78,6 +82,7 @@ module Nexmo
78
82
  #
79
83
  # @see https://developer.nexmo.com/api/conversation#retrieveConversation
80
84
  #
85
+ sig { params(id: String).returns(Nexmo::Response) }
81
86
  def get(id)
82
87
  request('/beta/conversations/' + id)
83
88
  end
@@ -110,6 +115,10 @@ module Nexmo
110
115
  #
111
116
  # @see https://developer.nexmo.com/api/conversation#replaceConversation
112
117
  #
118
+ sig { params(
119
+ id: String,
120
+ params: T::Hash[Symbol, T.untyped]
121
+ ).returns(Nexmo::Response) }
113
122
  def update(id, params)
114
123
  request('/beta/conversations/' + id, params: params, type: Put)
115
124
  end
@@ -125,6 +134,7 @@ module Nexmo
125
134
  #
126
135
  # @see https://developer.nexmo.com/api/conversation#deleteConversation
127
136
  #
137
+ sig { params(id: String).returns(Nexmo::Response) }
128
138
  def delete(id)
129
139
  request('/beta/conversations/' + id, type: Delete)
130
140
  end
@@ -156,31 +166,44 @@ module Nexmo
156
166
  #
157
167
  # @see https://developer.nexmo.com/api/conversation#recordConversation
158
168
  #
169
+ sig { params(
170
+ id: String,
171
+ params: T::Hash[Symbol, T.untyped]
172
+ ).returns(Nexmo::Response) }
159
173
  def record(id, params)
160
174
  request('/v1/conversations/' + id + '/record', params: params, type: Put)
161
175
  end
162
176
 
163
177
  # @return [Events]
164
178
  #
179
+ sig { returns(T.nilable(Nexmo::Conversations::Events)) }
165
180
  def events
181
+ @events = T.let(@events, T.nilable(Nexmo::Conversations::Events))
182
+ @config = T.let(@config, T.nilable(Nexmo::Config))
166
183
  @events ||= Events.new(@config)
167
184
  end
168
185
 
169
186
  # @return [Legs]
170
187
  #
188
+ sig { returns(T.nilable(Nexmo::Conversations::Legs)) }
171
189
  def legs
190
+ @legs = T.let(@legs, T.nilable(Nexmo::Conversations::Legs))
172
191
  @legs ||= Legs.new(@config)
173
192
  end
174
193
 
175
194
  # @return [Members]
176
195
  #
196
+ sig { returns(T.nilable(Nexmo::Conversations::Members)) }
177
197
  def members
198
+ @members = T.let(@members, T.nilable(Nexmo::Conversations::Members))
178
199
  @members ||= Members.new(@config)
179
200
  end
180
201
 
181
202
  # @return [Users]
182
203
  #
204
+ sig { returns(T.nilable(Nexmo::Conversations::Users)) }
183
205
  def users
206
+ @users = T.let(@users, T.nilable(Nexmo::Conversations::Users))
184
207
  @users ||= Users.new(@config)
185
208
  end
186
209
  end
@@ -1,4 +1,4 @@
1
- # typed: false
1
+ # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Nexmo
@@ -1,4 +1,4 @@
1
- # typed: false
1
+ # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Nexmo
@@ -1,4 +1,4 @@
1
- # typed: false
1
+ # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Nexmo
@@ -1,4 +1,4 @@
1
- # typed: false
1
+ # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Nexmo
@@ -1,14 +1,17 @@
1
- # typed: false
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Nexmo
5
5
  class Conversions < Namespace
6
+ extend T::Sig
6
7
  include Keys
7
8
 
9
+ sig { params(params: T::Hash[Symbol, T.untyped]).returns(Nexmo::Response) }
8
10
  def track_sms(params)
9
11
  request('/conversions/sms', params: hyphenate(params), type: Post)
10
12
  end
11
13
 
14
+ sig { params(params: T::Hash[Symbol, T.untyped]).returns(Nexmo::Response) }
12
15
  def track_voice(params)
13
16
  request('/conversions/voice', params: hyphenate(params), type: Post)
14
17
  end
@@ -1,4 +1,4 @@
1
- # typed: false
1
+ # typed: true
2
2
 
3
3
  module Nexmo
4
4
  class Entity
@@ -48,4 +48,4 @@ module Nexmo
48
48
 
49
49
  include Enumerable
50
50
  end
51
- end
51
+ end
@@ -1,9 +1,12 @@
1
- # typed: ignore
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
  require 'json'
4
4
 
5
5
  module Nexmo
6
6
  module Errors
7
+ extend T::Sig
8
+
9
+ sig {params(response: T.any(Net::HTTPUnauthorized, Net::HTTPClientError, Net::HTTPServerError, T.untyped)).returns(Nexmo::Error)}
7
10
  def self.parse(response)
8
11
  exception_class = case response
9
12
  when Net::HTTPUnauthorized
@@ -33,10 +36,12 @@ module Nexmo
33
36
  exception_class.new(message)
34
37
  end
35
38
 
39
+ sig { params(hash: T::Hash[String, T.untyped]).returns(T::Boolean) }
36
40
  def self.problem_details?(hash)
37
41
  hash.key?('title') && hash.key?('detail') && hash.key?('type')
38
42
  end
39
43
 
44
+ sig { params(hash: T::Hash[String, T.untyped]).returns(String) }
40
45
  def self.problem_details_message(hash)
41
46
  "#{hash['title']}. #{hash['detail']} See #{hash['type']} for more info, or email support@nexmo.com if you have any questions."
42
47
  end
@@ -1,16 +1,20 @@
1
- # typed: false
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Nexmo
5
5
  class Files < Namespace
6
+ extend T::Sig
7
+
6
8
  self.authentication = BearerToken
7
9
 
10
+ sig { params(id: String).returns(T.nilable(Nexmo::Response)) }
8
11
  def get(id)
9
- request('/v1/files/' + id.split('/').last)
12
+ request('/v1/files/' + T.must(id.split('/').last))
10
13
  end
11
14
 
15
+ sig { params(id: String, filename: String).returns(T.nilable(Nexmo::Response)) }
12
16
  def save(id, filename)
13
- request('/v1/files/' + id.split('/').last) do |response|
17
+ request('/v1/files/' + T.must(id.split('/').last)) do |response|
14
18
  File.open(filename, 'wb') do |file|
15
19
  response.read_body do |chunk|
16
20
  file.write(chunk)
@@ -10,6 +10,4 @@ module Nexmo
10
10
  REGEXP =~ string
11
11
  end
12
12
  end
13
-
14
- private_constant :GSM7
15
13
  end
@@ -1,12 +1,18 @@
1
- # typed: ignore
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
  require 'net/http'
4
4
 
5
5
  module Nexmo
6
6
  module HTTP
7
7
  class Options
8
+ extend T::Sig
9
+
10
+ sig { params(hash: T::Hash[Symbol, T.untyped]).void }
8
11
  def initialize(hash)
9
- @hash = hash || {}
12
+ raise ArgumentError, 'hash parameter cannot be empty or nil' if hash == {} || hash.nil?
13
+
14
+ @hash = T.let(@hash, T::Hash[Symbol, T.untyped]) if defined? @hash
15
+ @hash = hash
10
16
 
11
17
  @hash.each_key do |name|
12
18
  next if defined_options.key?(name)
@@ -15,6 +21,7 @@ module Nexmo
15
21
  end
16
22
  end
17
23
 
24
+ sig { params(http: Net::HTTP).returns(T::Hash[Symbol, T.untyped]) }
18
25
  def set(http)
19
26
  @hash.each do |name, value|
20
27
  http.public_send(defined_options.fetch(name), value)
@@ -23,13 +30,14 @@ module Nexmo
23
30
 
24
31
  private
25
32
 
33
+ sig { returns(T::Hash[Symbol, T.untyped]) }
26
34
  def defined_options
35
+ @defined_options = T.let(@defined_options, T.nilable(T::Hash[Symbol, T.untyped]))
36
+
27
37
  @defined_options ||= Net::HTTP.instance_methods.grep(/\w=\z/).each_with_object({}) do |name, hash|
28
38
  hash[name.to_s.chomp('=').to_sym] = name
29
39
  end
30
40
  end
31
41
  end
32
42
  end
33
-
34
- private_constant :HTTP
35
43
  end
@@ -1,9 +1,12 @@
1
- # typed: ignore
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
  require 'json'
4
4
 
5
5
  module Nexmo
6
6
  module JSON
7
+ extend T::Sig
8
+
9
+ sig { params(http_request: T.any(Net::HTTP::Put, Net::HTTP::Post), params: T::Hash[Symbol, T.untyped]).void }
7
10
  def self.update(http_request, params)
8
11
  http_request['Content-Type'] = 'application/json'
9
12
  http_request.body = ::JSON.generate(params)
@@ -2,10 +2,10 @@
2
2
  # frozen_string_literal: true
3
3
  require 'securerandom'
4
4
  require 'openssl'
5
- require 'jwt'
5
+ require 'nexmo-jwt'
6
6
 
7
7
  module Nexmo
8
- module JWT
8
+ class JWT
9
9
  # Generate an encoded JSON Web Token.
10
10
  #
11
11
  # By default the Nexmo Ruby SDK generates a short lived JWT per request.
@@ -14,12 +14,14 @@ module Nexmo
14
14
  # directly call {Nexmo::JWT.generate} to generate a token, and set the token
15
15
  # attribute on the client object.
16
16
  #
17
+ # Documentation for the Nexmo Ruby JWT generator gem can be found at
18
+ # https://www.rubydoc.info/github/nexmo/nexmo-jwt-ruby
19
+ #
17
20
  # @example
18
21
  # claims = {
19
22
  # application_id: application_id,
20
- # nbf: 1483315200,
21
- # exp: 1514764800,
22
- # iat: 1483228800
23
+ # ttl: 800,
24
+ # subject: 'My_Subject'
23
25
  # }
24
26
  #
25
27
  # private_key = File.read('path/to/private.key')
@@ -31,14 +33,11 @@ module Nexmo
31
33
  #
32
34
  # @return [String]
33
35
  #
34
- def self.generate(payload, private_key)
35
- payload[:iat] = iat = Time.now.to_i unless payload.key?(:iat) || payload.key?('iat')
36
- payload[:exp] = iat + 60 unless payload.key?(:exp) || payload.key?('exp')
37
- payload[:jti] = SecureRandom.uuid unless payload.key?(:jti) || payload.key?('jti')
38
-
39
- private_key = OpenSSL::PKey::RSA.new(private_key) unless private_key.respond_to?(:sign)
36
+ def self.generate(payload, private_key = nil)
37
+ raise "Expecting 'private_key' in either the payload or as a separate parameter" if !payload[:private_key] && !private_key
40
38
 
41
- ::JWT.encode(payload, private_key, 'RS256')
39
+ payload[:private_key] = private_key if private_key && !payload[:private_key]
40
+ @token = Nexmo::JWTBuilder.new(payload).jwt.generate
42
41
  end
43
42
  end
44
43
  end
@@ -1,12 +1,18 @@
1
- # typed: ignore
1
+ # typed: strict
2
2
 
3
3
  module Nexmo
4
4
  class KeySecretParams < AbstractAuthentication
5
+ extend T::Sig
6
+
7
+ sig { params(
8
+ object: T.any(T::Hash[T.untyped, T.untyped], URI::HTTPS, Net::HTTP::Post, Net::HTTP::Get)
9
+ ).void }
5
10
  def update(object)
6
11
  return unless object.is_a?(Hash)
7
12
 
8
- object[:api_key] = @config.api_key
9
- object[:api_secret] = @config.api_secret
13
+ @config = T.let(@config, T.nilable(Nexmo::Config))
14
+ object[:api_key] = T.must(@config).api_key
15
+ object[:api_secret] = T.must(@config).api_secret
10
16
  end
11
17
  end
12
18
 
@@ -1,17 +1,37 @@
1
- # typed: ignore
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Nexmo
5
5
  module Keys
6
+ extend T::Sig
7
+
8
+ sig { params(hash: T::Hash[T.untyped, T.untyped]).returns(T::Hash[String, T.untyped]) }
6
9
  def hyphenate(hash)
7
10
  hash.transform_keys { |k| k.to_s.tr('_', '-') }
8
11
  end
9
12
 
13
+ sig { params(hash: T::Hash[T.untyped, T.untyped]).returns(T::Hash[T.untyped, T.untyped]) }
10
14
  def camelcase(hash)
11
- hash.transform_keys { |k| k.to_s.gsub(/_(\w)/) { $1.upcase } }
15
+ exceptions = [
16
+ 'dr_call_back_url',
17
+ 'mo_http_url',
18
+ 'mo_smpp_sys_type',
19
+ 'mo_call_back_url',
20
+ 'voice_callback_type',
21
+ 'voice_callback_value',
22
+ 'voice_status_callback',
23
+ 'messages_callback_value',
24
+ 'messages_callback_type'
25
+ ]
26
+ hash.transform_keys do |k|
27
+ if exceptions.include?(k.to_s)
28
+ next k.to_s.gsub(/_(\w)/) { $1.upcase.to_s }
29
+ end
30
+ k
31
+ end
12
32
  end
13
33
 
14
- ATTRIBUTE_KEYS = Hash.new { |h, k| h[k] = k.split(PATTERN).join('_').downcase.to_sym }
34
+ ATTRIBUTE_KEYS = T.let(Hash.new { |h, k| h[k] = k.split(PATTERN).join('_').downcase.to_sym }, T::Hash[T.untyped, T.untyped])
15
35
 
16
36
  PATTERN = /[\-_]|(?<=\w)(?=[A-Z])/
17
37
 
@@ -19,6 +39,7 @@ module Nexmo
19
39
 
20
40
  private_constant :PATTERN
21
41
 
42
+ sig { params(k: T.any(Symbol, String)).returns(Symbol) }
22
43
  def attribute_key(k)
23
44
  return k if k.is_a?(Symbol)
24
45
 
@@ -1,10 +1,13 @@
1
- # typed: ignore
1
+ # typed: false
2
2
  # frozen_string_literal: true
3
3
  require 'logger'
4
4
  require 'forwardable'
5
5
 
6
6
  module Nexmo
7
7
  class Logger
8
+ extend T::Sig
9
+
10
+ sig { params(logger: T.nilable(T.any(::Logger, Nexmo::Logger))).void }
8
11
  def initialize(logger)
9
12
  @logger = logger || ::Logger.new(nil)
10
13
  end
@@ -15,8 +18,11 @@ module Nexmo
15
18
  def_delegator :@logger, name, name
16
19
  end
17
20
 
21
+ sig { params(request: T.any(Net::HTTP::Post, Net::HTTP::Get, Net::HTTP::Delete, Net::HTTP::Put)).void }
18
22
  def log_request_info(request)
19
- @logger.info do
23
+ @logger = T.let(@logger, T.nilable(T.any(::Logger, Nexmo::Logger)))
24
+
25
+ T.must(@logger).info do
20
26
  format('Nexmo API request', {
21
27
  method: request.method,
22
28
  path: request.uri.path
@@ -24,8 +30,12 @@ module Nexmo
24
30
  end
25
31
  end
26
32
 
33
+ sig { params(
34
+ response: T.any(Net::HTTPOK, Net::HTTPNoContent, Net::HTTPBadRequest, Net::HTTPInternalServerError, Net::HTTPResponse),
35
+ host: String
36
+ ).void }
27
37
  def log_response_info(response, host)
28
- @logger.info do
38
+ T.must(@logger).info do
29
39
  format('Nexmo API response', {
30
40
  host: host,
31
41
  status: response.code,
@@ -38,6 +48,7 @@ module Nexmo
38
48
 
39
49
  private
40
50
 
51
+ sig { params(message: String, hash: T::Hash[Symbol, T.untyped]).returns(String) }
41
52
  def format(message, hash)
42
53
  return message if hash.nil?
43
54
 
@@ -46,6 +57,4 @@ module Nexmo
46
57
  fields.join(' ')
47
58
  end
48
59
  end
49
-
50
- private_constant :Logger
51
60
  end