nexmo 4.8.0 → 5.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nexmo
4
+ class Conversions < Namespace
5
+ include Keys
6
+
7
+ def track_sms(params)
8
+ request('/conversions/sms', params: hyphenate(params), type: Post)
9
+ end
10
+
11
+ def track_voice(params)
12
+ request('/conversions/voice', params: hyphenate(params), type: Post)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,53 @@
1
+ module Nexmo
2
+ class Entity
3
+ def initialize(**kwargs)
4
+ @attributes = kwargs
5
+ end
6
+
7
+ def []=(key, value)
8
+ name = self.class.attribute_names[key]
9
+
10
+ @attributes[name] = value
11
+ end
12
+
13
+ def respond_to_missing?(name, include_private = false)
14
+ @attributes.key?(name) or super
15
+ end
16
+
17
+ def method_missing(name, *args)
18
+ return super unless @attributes.key?(name)
19
+
20
+ @attributes[name]
21
+ end
22
+
23
+ def ==(entity)
24
+ entity.class == self.class && entity.attributes == @attributes
25
+ end
26
+
27
+ def to_h
28
+ @attributes
29
+ end
30
+
31
+ attr_reader :attributes
32
+
33
+ protected :attributes
34
+
35
+ private
36
+
37
+ def self.attribute_names
38
+ @attribute_names ||= Hash.new do |hash, key|
39
+ hash[key] = attribute_name(key)
40
+ end
41
+ end
42
+
43
+ def self.attribute_name(key)
44
+ return key if key.is_a?(Symbol)
45
+
46
+ key.split(PATTERN).join(UNDERSCORE).downcase.to_sym
47
+ end
48
+
49
+ PATTERN = /[\-_]|(?<=\w)(?=[A-Z])/
50
+
51
+ UNDERSCORE = '_'
52
+ end
53
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nexmo
4
+ class Files < Namespace
5
+ def get(id)
6
+ request('/v1/files/' + id.split('/').last)
7
+ end
8
+
9
+ def save(id, filename)
10
+ request('/v1/files/' + id.split('/').last) do |response|
11
+ File.open(filename, 'wb') do |file|
12
+ response.read_body do |chunk|
13
+ file.write(chunk)
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def authorization_header?
22
+ true
23
+ end
24
+ end
25
+ end
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  require 'securerandom'
2
3
  require 'openssl'
3
4
  require 'jwt'
4
5
 
5
6
  module Nexmo
6
7
  module JWT
7
- def self.auth_token(payload, private_key)
8
+ def self.generate(payload, private_key)
8
9
  payload[:iat] = iat = Time.now.to_i unless payload.key?(:iat) || payload.key?('iat')
9
10
  payload[:exp] = iat + 60 unless payload.key?(:exp) || payload.key?('exp')
10
11
  payload[:jti] = SecureRandom.uuid unless payload.key?(:jti) || payload.key?('jti')
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nexmo
4
+ module Keys
5
+ if {}.respond_to?(:transform_keys)
6
+ def hyphenate(hash)
7
+ hash.transform_keys { |k| hyphenate_key(k) }
8
+ end
9
+
10
+ def camelcase(hash)
11
+ hash.transform_keys { |k| camelcase_key(k) }
12
+ end
13
+ else
14
+ def hyphenate(hash)
15
+ hash.each_with_object({}) { |(k, v), h| h[hyphenate_key(k)] = v }
16
+ end
17
+
18
+ def camelcase(hash)
19
+ hash.each_with_object({}) { |(k, v), h| h[camelcase_key(k)] = v }
20
+ end
21
+ end
22
+
23
+ def hyphenate_key(k)
24
+ k.to_s.tr('_', '-')
25
+ end
26
+
27
+ def camelcase_key(k)
28
+ k.to_s.gsub(/_(\w)/) { $1.upcase }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nexmo
4
+ class Messages < Namespace
5
+ def get(id)
6
+ request('/search/message', params: {id: id})
7
+ end
8
+
9
+ def search(params)
10
+ request('/search/messages', params: params)
11
+ end
12
+
13
+ def rejections(params)
14
+ request('/search/rejections', params: params)
15
+ end
16
+
17
+ private
18
+
19
+ def host
20
+ 'rest.nexmo.com'
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,83 @@
1
+ require 'net/http'
2
+ require 'json'
3
+
4
+ module Nexmo
5
+ class Namespace
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ private
11
+
12
+ Get = Net::HTTP::Get
13
+ Put = Net::HTTP::Put
14
+ Post = Net::HTTP::Post
15
+ Delete = Net::HTTP::Delete
16
+
17
+ def host
18
+ 'api.nexmo.com'
19
+ end
20
+
21
+ def authorization_header?
22
+ false
23
+ end
24
+
25
+ def request(path, params: nil, type: Get, &block)
26
+ uri = URI('https://' + host + path)
27
+
28
+ unless authorization_header?
29
+ params ||= {}
30
+ params[:api_key] = @client.api_key
31
+ params[:api_secret] = @client.api_secret
32
+ end
33
+
34
+ unless type::REQUEST_HAS_BODY || params.nil? || params.empty?
35
+ uri.query = Params.encode(params)
36
+ end
37
+
38
+ message = type.new(uri.request_uri)
39
+
40
+ if type::REQUEST_HAS_BODY
41
+ message['Content-Type'] = 'application/json'
42
+ message.body = JSON.generate(params)
43
+ end
44
+
45
+ message['Authorization'] = @client.authorization if authorization_header?
46
+ message['User-Agent'] = @client.user_agent
47
+
48
+ http = Net::HTTP.new(uri.host, Net::HTTP.https_default_port)
49
+ http.use_ssl = true
50
+
51
+ response = http.request(message)
52
+
53
+ parse(response, &block)
54
+ end
55
+
56
+ def parse(response, &block)
57
+ case response
58
+ when Net::HTTPNoContent
59
+ :no_content
60
+ when Net::HTTPSuccess
61
+ parse_success(response, &block)
62
+ when Net::HTTPUnauthorized
63
+ raise AuthenticationError, "#{response.code} response from #{host}"
64
+ when Net::HTTPClientError
65
+ raise ClientError, "#{response.code} response from #{host}"
66
+ when Net::HTTPServerError
67
+ raise ServerError, "#{response.code} response from #{host}"
68
+ else
69
+ raise Error, "#{response.code} response from #{host}"
70
+ end
71
+ end
72
+
73
+ def parse_success(response)
74
+ if response['Content-Type'].split(';').first == 'application/json'
75
+ JSON.parse(response.body, object_class: Nexmo::Entity)
76
+ elsif block_given?
77
+ yield response
78
+ else
79
+ response.body
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nexmo
4
+ class NumberInsight < Namespace
5
+ def basic(params)
6
+ request('/ni/basic/json', params: params)
7
+ end
8
+
9
+ def standard(params)
10
+ request('/ni/standard/json', params: params)
11
+ end
12
+
13
+ def advanced(params)
14
+ request('/ni/advanced/json', params: params)
15
+ end
16
+
17
+ def advanced_async(params)
18
+ request('/ni/advanced/async/json', params: params)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nexmo
4
+ class Numbers < Namespace
5
+ include Keys
6
+
7
+ def list(params)
8
+ request('/account/numbers', params: params)
9
+ end
10
+
11
+ def search(params)
12
+ request('/number/search', params: params)
13
+ end
14
+
15
+ def buy(params)
16
+ request('/number/buy', params: params, type: Post)
17
+ end
18
+
19
+ def cancel(params)
20
+ request('/number/cancel', params: params, type: Post)
21
+ end
22
+
23
+ def update(params)
24
+ request('/number/update', params: camelcase(params), type: Post)
25
+ end
26
+
27
+ private
28
+
29
+ def host
30
+ 'rest.nexmo.com'
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nexmo
4
+ class Pricing < Namespace
5
+ def initialize(client, type: nil)
6
+ raise ArgumentError if type.nil?
7
+
8
+ @client, @type = client, type
9
+ end
10
+
11
+ attr_reader :type
12
+
13
+ def get(country)
14
+ request('/get-pricing/outbound/' + @type, params: {country: country})
15
+ end
16
+
17
+ def list
18
+ request('/get-full-pricing/outbound/' + @type)
19
+ end
20
+
21
+ def prefix(prefix)
22
+ request('/get-prefix-pricing/outbound/' + @type, params: {prefix: prefix})
23
+ end
24
+
25
+ private
26
+
27
+ def host
28
+ 'rest.nexmo.com'
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nexmo
4
+ class PricingTypes
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def sms
10
+ @sms ||= Pricing.new(@client, type: 'sms')
11
+ end
12
+
13
+ def voice
14
+ @voice ||= Pricing.new(@client, type: 'voice')
15
+ end
16
+ end
17
+ end
@@ -2,7 +2,7 @@ require 'digest/md5'
2
2
  require 'jwt'
3
3
 
4
4
  module Nexmo
5
- module Signature
5
+ class Signature
6
6
  def self.check(params, secret)
7
7
  params = params.dup
8
8
 
@@ -11,6 +11,14 @@ module Nexmo
11
11
  secure_compare(signature, digest(params, secret))
12
12
  end
13
13
 
14
+ def initialize(client)
15
+ @client = client
16
+ end
17
+
18
+ def check(params)
19
+ self.class.check(params, @client.signature_secret)
20
+ end
21
+
14
22
  private
15
23
 
16
24
  if defined?(::JWT::SecurityUtils) # ruby-jwt v2
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nexmo
4
+ class SMS < Namespace
5
+ include Keys
6
+
7
+ def send(params)
8
+ request('/sms/json', params: hyphenate(params), type: Post)
9
+ end
10
+
11
+ private
12
+
13
+ def host
14
+ 'rest.nexmo.com'
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nexmo
4
+ module UserAgent
5
+ def self.string(app_name, app_version)
6
+ identifiers = []
7
+ identifiers << 'nexmo-ruby/' + VERSION
8
+ identifiers << 'ruby/' + RUBY_VERSION
9
+ identifiers << app_name + '/' + app_version if app_name && app_version
10
+ identifiers.join(' ')
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nexmo
4
+ class Verify < Namespace
5
+ alias_method :http_request, :request
6
+
7
+ def request(params)
8
+ http_request('/verify/json', params: params, type: Post)
9
+ end
10
+
11
+ def check(params)
12
+ http_request('/verify/check/json', params: params, type: Post)
13
+ end
14
+
15
+ def search(params)
16
+ http_request('/verify/search/json', params: params)
17
+ end
18
+
19
+ def control(params)
20
+ http_request('/verify/control/json', params: params, type: Post)
21
+ end
22
+
23
+ def cancel(id)
24
+ control(request_id: id, cmd: 'cancel')
25
+ end
26
+
27
+ def trigger_next_event(id)
28
+ control(request_id: id, cmd: 'trigger_next_event')
29
+ end
30
+ end
31
+ end