nexmo 6.0.1 → 7.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +24 -4
- data/lib/nexmo.rb +12 -14
- data/lib/nexmo/abstract_authentication.rb +2 -0
- data/lib/nexmo/account.rb +6 -1
- data/lib/nexmo/alerts.rb +6 -1
- data/lib/nexmo/applications.rb +24 -3
- data/lib/nexmo/applications/list_response.rb +2 -0
- data/lib/nexmo/authentication_error.rb +2 -0
- data/lib/nexmo/basic.rb +2 -0
- data/lib/nexmo/bearer_token.rb +1 -0
- data/lib/nexmo/client.rb +46 -23
- data/lib/nexmo/client_error.rb +2 -0
- data/lib/nexmo/config.rb +52 -9
- data/lib/nexmo/conversations.rb +24 -0
- data/lib/nexmo/conversations/events.rb +1 -0
- data/lib/nexmo/conversations/legs.rb +1 -0
- data/lib/nexmo/conversations/members.rb +1 -0
- data/lib/nexmo/conversations/users.rb +1 -0
- data/lib/nexmo/conversions.rb +4 -0
- data/lib/nexmo/entity.rb +5 -3
- data/lib/nexmo/error.rb +2 -0
- data/lib/nexmo/errors.rb +10 -0
- data/lib/nexmo/files.rb +7 -2
- data/lib/nexmo/form_data.rb +2 -0
- data/lib/nexmo/gsm7.rb +2 -0
- data/lib/nexmo/http.rb +12 -3
- data/lib/nexmo/json.rb +4 -0
- data/lib/nexmo/jwt.rb +6 -2
- data/lib/nexmo/key_secret_params.rb +10 -2
- data/lib/nexmo/keys.rb +7 -1
- data/lib/nexmo/logger.rb +14 -4
- data/lib/nexmo/messages.rb +7 -1
- data/lib/nexmo/namespace.rb +15 -18
- data/lib/nexmo/number_insight.rb +21 -6
- data/lib/nexmo/numbers.rb +24 -20
- data/lib/nexmo/numbers/list_response.rb +2 -0
- data/lib/nexmo/numbers/response.rb +1 -0
- data/lib/nexmo/params.rb +1 -0
- data/lib/nexmo/pricing.rb +2 -1
- data/lib/nexmo/pricing_types.rb +1 -0
- data/lib/nexmo/redact.rb +2 -1
- data/lib/nexmo/response.rb +2 -0
- data/lib/nexmo/secrets.rb +1 -0
- data/lib/nexmo/secrets/list_response.rb +2 -0
- data/lib/nexmo/server_error.rb +2 -0
- data/lib/nexmo/signature.rb +19 -13
- data/lib/nexmo/sms.rb +16 -10
- data/lib/nexmo/tfa.rb +2 -1
- data/lib/nexmo/user_agent.rb +1 -0
- data/lib/nexmo/verify.rb +93 -17
- data/lib/nexmo/version.rb +3 -1
- data/lib/nexmo/{calls.rb → voice.rb} +12 -11
- data/lib/nexmo/{calls → voice}/dtmf.rb +2 -1
- data/lib/nexmo/{calls → voice}/list_response.rb +3 -1
- data/lib/nexmo/{calls → voice}/stream.rb +2 -1
- data/lib/nexmo/{calls → voice}/talk.rb +2 -1
- data/nexmo.gemspec +2 -7
- metadata +17 -85
- data/lib/nexmo/key_secret_query.rb +0 -20
- data/lib/nexmo/number_insight/response.rb +0 -5
- data/lib/nexmo/sms/response.rb +0 -7
- data/lib/nexmo/verify/response.rb +0 -5
data/lib/nexmo/json.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
|
+
# typed: strict
|
1
2
|
# frozen_string_literal: true
|
2
3
|
require 'json'
|
3
4
|
|
4
5
|
module Nexmo
|
5
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 }
|
6
10
|
def self.update(http_request, params)
|
7
11
|
http_request['Content-Type'] = 'application/json'
|
8
12
|
http_request.body = ::JSON.generate(params)
|
data/lib/nexmo/jwt.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# typed: strict
|
1
2
|
# frozen_string_literal: true
|
2
3
|
require 'securerandom'
|
3
4
|
require 'openssl'
|
@@ -5,6 +6,8 @@ require 'jwt'
|
|
5
6
|
|
6
7
|
module Nexmo
|
7
8
|
module JWT
|
9
|
+
extend T::Sig
|
10
|
+
|
8
11
|
# Generate an encoded JSON Web Token.
|
9
12
|
#
|
10
13
|
# By default the Nexmo Ruby SDK generates a short lived JWT per request.
|
@@ -23,16 +26,17 @@ module Nexmo
|
|
23
26
|
#
|
24
27
|
# private_key = File.read('path/to/private.key')
|
25
28
|
#
|
26
|
-
# client.token = Nexmo::JWT.generate(claims, private_key)
|
29
|
+
# client.config.token = Nexmo::JWT.generate(claims, private_key)
|
27
30
|
#
|
28
31
|
# @param [Hash] payload
|
29
32
|
# @param [String, OpenSSL::PKey::RSA] private_key
|
30
33
|
#
|
31
34
|
# @return [String]
|
32
35
|
#
|
36
|
+
sig { params(payload: T::Hash[T.any(Symbol, String), T.any(String, Integer)], private_key: T.any(OpenSSL::PKey::RSA, String)).returns(String) }
|
33
37
|
def self.generate(payload, private_key)
|
34
38
|
payload[:iat] = iat = Time.now.to_i unless payload.key?(:iat) || payload.key?('iat')
|
35
|
-
payload[:exp] = iat + 60 unless payload.key?(:exp) || payload.key?('exp')
|
39
|
+
payload[:exp] = T.must(iat) + 60 unless payload.key?(:exp) || payload.key?('exp')
|
36
40
|
payload[:jti] = SecureRandom.uuid unless payload.key?(:jti) || payload.key?('jti')
|
37
41
|
|
38
42
|
private_key = OpenSSL::PKey::RSA.new(private_key) unless private_key.respond_to?(:sign)
|
@@ -1,10 +1,18 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
1
3
|
module Nexmo
|
2
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 }
|
3
10
|
def update(object)
|
4
11
|
return unless object.is_a?(Hash)
|
5
12
|
|
6
|
-
|
7
|
-
object[:
|
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
|
8
16
|
end
|
9
17
|
end
|
10
18
|
|
data/lib/nexmo/keys.rb
CHANGED
@@ -1,16 +1,21 @@
|
|
1
|
+
# typed: strict
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Nexmo
|
4
5
|
module Keys
|
6
|
+
extend T::Sig
|
7
|
+
|
8
|
+
sig { params(hash: T::Hash[T.untyped, T.untyped]).returns(T::Hash[String, T.untyped]) }
|
5
9
|
def hyphenate(hash)
|
6
10
|
hash.transform_keys { |k| k.to_s.tr('_', '-') }
|
7
11
|
end
|
8
12
|
|
13
|
+
sig { params(hash: T::Hash[T.untyped, T.untyped]).returns(T::Hash[String, T.untyped]) }
|
9
14
|
def camelcase(hash)
|
10
15
|
hash.transform_keys { |k| k.to_s.gsub(/_(\w)/) { $1.upcase } }
|
11
16
|
end
|
12
17
|
|
13
|
-
ATTRIBUTE_KEYS = Hash.new { |h, k| h[k] = k.split(PATTERN).join('_').downcase.to_sym }
|
18
|
+
ATTRIBUTE_KEYS = T.let(Hash.new { |h, k| h[k] = k.split(PATTERN).join('_').downcase.to_sym }, T::Hash[T.untyped, T.untyped])
|
14
19
|
|
15
20
|
PATTERN = /[\-_]|(?<=\w)(?=[A-Z])/
|
16
21
|
|
@@ -18,6 +23,7 @@ module Nexmo
|
|
18
23
|
|
19
24
|
private_constant :PATTERN
|
20
25
|
|
26
|
+
sig { params(k: T.any(Symbol, String)).returns(Symbol) }
|
21
27
|
def attribute_key(k)
|
22
28
|
return k if k.is_a?(Symbol)
|
23
29
|
|
data/lib/nexmo/logger.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
+
# typed: false
|
1
2
|
# frozen_string_literal: true
|
2
3
|
require 'logger'
|
3
4
|
require 'forwardable'
|
4
5
|
|
5
6
|
module Nexmo
|
6
7
|
class Logger
|
8
|
+
extend T::Sig
|
9
|
+
|
10
|
+
sig { params(logger: T.nilable(T.any(::Logger, Nexmo::Logger))).void }
|
7
11
|
def initialize(logger)
|
8
12
|
@logger = logger || ::Logger.new(nil)
|
9
13
|
end
|
@@ -14,8 +18,11 @@ module Nexmo
|
|
14
18
|
def_delegator :@logger, name, name
|
15
19
|
end
|
16
20
|
|
21
|
+
sig { params(request: T.any(Net::HTTP::Post, Net::HTTP::Get, Net::HTTP::Delete, Net::HTTP::Put)).void }
|
17
22
|
def log_request_info(request)
|
18
|
-
|
23
|
+
@logger = T.let(@logger, T.nilable(T.any(::Logger, Nexmo::Logger)))
|
24
|
+
|
25
|
+
T.must(@logger).info do
|
19
26
|
format('Nexmo API request', {
|
20
27
|
method: request.method,
|
21
28
|
path: request.uri.path
|
@@ -23,8 +30,12 @@ module Nexmo
|
|
23
30
|
end
|
24
31
|
end
|
25
32
|
|
33
|
+
sig { params(
|
34
|
+
response: T.any(Net::HTTPOK, Net::HTTPNoContent, Net::HTTPBadRequest, Net::HTTPInternalServerError, Net::HTTPResponse),
|
35
|
+
host: String
|
36
|
+
).void }
|
26
37
|
def log_response_info(response, host)
|
27
|
-
info do
|
38
|
+
T.must(@logger).info do
|
28
39
|
format('Nexmo API response', {
|
29
40
|
host: host,
|
30
41
|
status: response.code,
|
@@ -37,6 +48,7 @@ module Nexmo
|
|
37
48
|
|
38
49
|
private
|
39
50
|
|
51
|
+
sig { params(message: String, hash: T::Hash[Symbol, T.untyped]).returns(String) }
|
40
52
|
def format(message, hash)
|
41
53
|
return message if hash.nil?
|
42
54
|
|
@@ -45,6 +57,4 @@ module Nexmo
|
|
45
57
|
fields.join(' ')
|
46
58
|
end
|
47
59
|
end
|
48
|
-
|
49
|
-
private_constant :Logger
|
50
60
|
end
|
data/lib/nexmo/messages.rb
CHANGED
@@ -1,17 +1,23 @@
|
|
1
|
+
# typed: strict
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Nexmo
|
4
5
|
class Messages < Namespace
|
5
|
-
|
6
|
+
extend T::Sig
|
6
7
|
|
8
|
+
self.host = :rest_host
|
9
|
+
|
10
|
+
sig { params(id: String).returns(Nexmo::Response) }
|
7
11
|
def get(id)
|
8
12
|
request('/search/message', params: {id: id})
|
9
13
|
end
|
10
14
|
|
15
|
+
sig { params(params: T::Hash[Symbol, T.untyped]).returns(Nexmo::Response) }
|
11
16
|
def search(params)
|
12
17
|
request('/search/messages', params: params)
|
13
18
|
end
|
14
19
|
|
20
|
+
sig { params(params: T::Hash[Symbol, T.untyped]).returns(Nexmo::Response) }
|
15
21
|
def rejections(params)
|
16
22
|
request('/search/rejections', params: params)
|
17
23
|
end
|
data/lib/nexmo/namespace.rb
CHANGED
@@ -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
|
-
@
|
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 ||=
|
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
|
-
|
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:
|
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
|
-
|
82
|
+
logger.log_request_info(message)
|
90
83
|
|
91
84
|
response = @http.request(message, &block)
|
92
85
|
|
93
|
-
|
86
|
+
logger.log_response_info(response, @host)
|
94
87
|
|
95
88
|
return if block
|
96
89
|
|
97
|
-
|
90
|
+
logger.debug(response.body) if response.body
|
98
91
|
|
99
|
-
parse(response, 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
|
data/lib/nexmo/number_insight.rb
CHANGED
@@ -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
|
data/lib/nexmo/numbers.rb
CHANGED
@@ -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 =
|
8
|
+
self.host = :rest_host
|
8
9
|
|
9
10
|
# Retrieve all the inbound numbers associated with your Nexmo account.
|
10
11
|
#
|
@@ -14,11 +15,16 @@ module Nexmo
|
|
14
15
|
# puts "#{item.msisdn} #{item.country} #{item.type}"
|
15
16
|
# end
|
16
17
|
#
|
17
|
-
# @option params [
|
18
|
-
#
|
18
|
+
# @option params [String] :application_id
|
19
|
+
# The application that you want to return the numbers for.
|
19
20
|
#
|
20
|
-
# @option params [
|
21
|
-
#
|
21
|
+
# @option params [Boolean] :has_application
|
22
|
+
# Set this optional field to `true` to restrict your results to numbers associated with an application (any application).
|
23
|
+
# Set to `false` to find all numbers not associated with any application.
|
24
|
+
# Omit the field to avoid filtering on whether or not the number is assigned to an application.
|
25
|
+
#
|
26
|
+
# @option params [String] :country
|
27
|
+
# The two character country code to filter on (in ISO 3166-1 alpha-2 format).
|
22
28
|
#
|
23
29
|
# @option params [String] :pattern
|
24
30
|
# The number pattern you want to search for. Use in conjunction with **:search_pattern**.
|
@@ -29,13 +35,11 @@ module Nexmo
|
|
29
35
|
# - `1` - Search for numbers that contain **:pattern**
|
30
36
|
# - `2` - Search for numbers that end with **:pattern**
|
31
37
|
#
|
32
|
-
# @option params [
|
33
|
-
#
|
34
|
-
# Set to `false` to find all numbers not associated with any application.
|
35
|
-
# Omit the field to avoid filtering on whether or not the number is assigned to an application.
|
38
|
+
# @option params [Integer] :size
|
39
|
+
# Page size.
|
36
40
|
#
|
37
|
-
# @option params [
|
38
|
-
#
|
41
|
+
# @option params [Integer] :index
|
42
|
+
# Page index.
|
39
43
|
#
|
40
44
|
# @param [Hash] params
|
41
45
|
#
|
@@ -102,6 +106,10 @@ module Nexmo
|
|
102
106
|
# @option params [required, String] :msisdn
|
103
107
|
# An available inbound virtual number.
|
104
108
|
#
|
109
|
+
# @option params [String] :target_api_key
|
110
|
+
# If you'd like to perform an action on a subaccount, provide the `api_key` of that account here.
|
111
|
+
# If you'd like to perform an action on your own account, you do not need to provide this field.
|
112
|
+
#
|
105
113
|
# @param [Hash] params
|
106
114
|
#
|
107
115
|
# @return [Response]
|
@@ -123,6 +131,10 @@ module Nexmo
|
|
123
131
|
# @option params [required, String] :msisdn
|
124
132
|
# An available inbound virtual number.
|
125
133
|
#
|
134
|
+
# @option params [String] :target_api_key
|
135
|
+
# If you'd like to perform an action on a subaccount, provide the `api_key` of that account here.
|
136
|
+
# If you'd like to perform an action on your own account, you do not need to provide this field.
|
137
|
+
#
|
126
138
|
# @param [Hash] params
|
127
139
|
#
|
128
140
|
# @return [Response]
|
@@ -160,16 +172,8 @@ module Nexmo
|
|
160
172
|
# @option params [String] :mo_smpp_sys_type
|
161
173
|
# The associated system type for your SMPP client.
|
162
174
|
#
|
163
|
-
# @option params [String] :messages_callback_type
|
164
|
-
# The SMS webhook type (always `app`).
|
165
|
-
# Must be used with the **:messages_callback_value** option.
|
166
|
-
#
|
167
|
-
# @option params [String] :messages_callback_value
|
168
|
-
# A Nexmo Application ID.
|
169
|
-
# Must be used with the **:messages_callback_type** option.
|
170
|
-
#
|
171
175
|
# @option params [String] :voice_callback_type
|
172
|
-
#
|
176
|
+
# Specify whether inbound voice calls on your number are handled by your Application configuration, or forwarded to a SIP or a telephone number.
|
173
177
|
# Must be used with the **:voice_callback_value** option.
|
174
178
|
#
|
175
179
|
# @option params [String] :voice_callback_value
|
data/lib/nexmo/params.rb
CHANGED