vonage 7.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +190 -0
- data/README.md +191 -0
- data/lib/vonage.rb +29 -0
- data/lib/vonage/abstract_authentication.rb +9 -0
- data/lib/vonage/account.rb +61 -0
- data/lib/vonage/alerts.rb +72 -0
- data/lib/vonage/applications.rb +148 -0
- data/lib/vonage/applications/list_response.rb +11 -0
- data/lib/vonage/authentication_error.rb +6 -0
- data/lib/vonage/basic.rb +13 -0
- data/lib/vonage/bearer_token.rb +14 -0
- data/lib/vonage/client.rb +134 -0
- data/lib/vonage/client_error.rb +6 -0
- data/lib/vonage/config.rb +208 -0
- data/lib/vonage/conversations.rb +210 -0
- data/lib/vonage/conversations/events.rb +73 -0
- data/lib/vonage/conversations/legs.rb +30 -0
- data/lib/vonage/conversations/members.rb +104 -0
- data/lib/vonage/conversations/users.rb +93 -0
- data/lib/vonage/conversions.rb +19 -0
- data/lib/vonage/entity.rb +51 -0
- data/lib/vonage/error.rb +6 -0
- data/lib/vonage/errors.rb +51 -0
- data/lib/vonage/files.rb +26 -0
- data/lib/vonage/form_data.rb +11 -0
- data/lib/vonage/gsm7.rb +13 -0
- data/lib/vonage/http.rb +43 -0
- data/lib/vonage/json.rb +17 -0
- data/lib/vonage/jwt.rb +43 -0
- data/lib/vonage/key_secret_params.rb +20 -0
- data/lib/vonage/keys.rb +51 -0
- data/lib/vonage/logger.rb +60 -0
- data/lib/vonage/messages.rb +25 -0
- data/lib/vonage/namespace.rb +118 -0
- data/lib/vonage/number_insight.rb +140 -0
- data/lib/vonage/numbers.rb +196 -0
- data/lib/vonage/numbers/list_response.rb +11 -0
- data/lib/vonage/numbers/response.rb +8 -0
- data/lib/vonage/params.rb +27 -0
- data/lib/vonage/pricing.rb +30 -0
- data/lib/vonage/pricing_types.rb +18 -0
- data/lib/vonage/redact.rb +37 -0
- data/lib/vonage/response.rb +25 -0
- data/lib/vonage/secrets.rb +85 -0
- data/lib/vonage/secrets/list_response.rb +11 -0
- data/lib/vonage/server_error.rb +6 -0
- data/lib/vonage/signature.rb +53 -0
- data/lib/vonage/sms.rb +121 -0
- data/lib/vonage/tfa.rb +14 -0
- data/lib/vonage/user_agent.rb +16 -0
- data/lib/vonage/verify.rb +253 -0
- data/lib/vonage/version.rb +5 -0
- data/lib/vonage/voice.rb +250 -0
- data/lib/vonage/voice/dtmf.rb +26 -0
- data/lib/vonage/voice/list_response.rb +11 -0
- data/lib/vonage/voice/stream.rb +44 -0
- data/lib/vonage/voice/talk.rb +48 -0
- data/vonage.gemspec +26 -0
- metadata +155 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
# typed: ignore
|
2
|
+
# frozen_string_literal: true
|
3
|
+
require 'cgi'
|
4
|
+
|
5
|
+
module Vonage
|
6
|
+
module Params
|
7
|
+
def self.encode(params)
|
8
|
+
params.flat_map { |k, vs| Array(vs).map { |v| "#{escape(k)}=#{escape(v)}" } }.join('&')
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.join(string, params)
|
12
|
+
encoded = encode(params)
|
13
|
+
|
14
|
+
return encoded if string.nil?
|
15
|
+
|
16
|
+
string + '&' + encoded
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.escape(component)
|
20
|
+
CGI.escape(component.to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
private_class_method :escape
|
24
|
+
end
|
25
|
+
|
26
|
+
private_constant :Params
|
27
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Vonage
|
5
|
+
class Pricing < Namespace
|
6
|
+
self.host = :rest_host
|
7
|
+
|
8
|
+
def initialize(config, type: nil)
|
9
|
+
raise ArgumentError if type.nil?
|
10
|
+
|
11
|
+
@type = type
|
12
|
+
|
13
|
+
super config
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :type
|
17
|
+
|
18
|
+
def get(country)
|
19
|
+
request('/account/get-pricing/outbound/' + @type, params: {country: country})
|
20
|
+
end
|
21
|
+
|
22
|
+
def list
|
23
|
+
request('/account/get-full-pricing/outbound/' + @type)
|
24
|
+
end
|
25
|
+
|
26
|
+
def prefix(prefix)
|
27
|
+
request('/account/get-prefix-pricing/outbound/' + @type, params: {prefix: prefix})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Vonage
|
5
|
+
class PricingTypes
|
6
|
+
def initialize(config)
|
7
|
+
@config = config
|
8
|
+
end
|
9
|
+
|
10
|
+
def sms
|
11
|
+
@sms ||= Pricing.new(@config, type: 'sms')
|
12
|
+
end
|
13
|
+
|
14
|
+
def voice
|
15
|
+
@voice ||= Pricing.new(@config, type: 'voice')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Vonage
|
5
|
+
class Redact < Namespace
|
6
|
+
extend T::Sig
|
7
|
+
|
8
|
+
self.authentication = Basic
|
9
|
+
|
10
|
+
self.request_body = JSON
|
11
|
+
|
12
|
+
# Redact a specific message.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# response = client.redact.transaction(id: '00A0B0C0', product: 'sms')
|
16
|
+
#
|
17
|
+
# @option params [required, String] :id
|
18
|
+
# The transaction ID to redact.
|
19
|
+
#
|
20
|
+
# @option params [required, String] :product
|
21
|
+
# Product name that the ID provided relates to.
|
22
|
+
#
|
23
|
+
# @option params [required, String] :type
|
24
|
+
# Required if redacting SMS data.
|
25
|
+
#
|
26
|
+
# @param [Hash] params
|
27
|
+
#
|
28
|
+
# @return [Response]
|
29
|
+
#
|
30
|
+
# @see https://developer.nexmo.com/api/redact#redact-message
|
31
|
+
#
|
32
|
+
sig { params(params: T::Hash[Symbol, T.untyped]).returns(Vonage::Response) }
|
33
|
+
def transaction(params)
|
34
|
+
request('/v1/redact/transaction', params: params, type: Post)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# typed: true
|
2
|
+
|
3
|
+
module Vonage
|
4
|
+
class Response
|
5
|
+
def initialize(entity=nil, http_response=nil)
|
6
|
+
@entity = entity
|
7
|
+
|
8
|
+
@http_response = http_response
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :http_response
|
12
|
+
|
13
|
+
def respond_to_missing?(name, include_private = false)
|
14
|
+
return super if @entity.nil?
|
15
|
+
|
16
|
+
@entity.respond_to?(name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing(name, *args)
|
20
|
+
return super if @entity.nil?
|
21
|
+
|
22
|
+
@entity.public_send(name, *args)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Vonage
|
5
|
+
class Secrets < Namespace
|
6
|
+
self.authentication = Basic
|
7
|
+
|
8
|
+
self.request_body = JSON
|
9
|
+
|
10
|
+
# Create API Secret.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# response = client.secrets.create(secret: 'T0ps3cr3t')
|
14
|
+
#
|
15
|
+
# @option params [required, String] :secret
|
16
|
+
# The new secret must follow these rules:
|
17
|
+
# - minimum 8 characters
|
18
|
+
# - maximum 25 characters
|
19
|
+
# - minimum 1 lower case character
|
20
|
+
# - minimum 1 upper case character
|
21
|
+
# - minimum 1 digit
|
22
|
+
#
|
23
|
+
# @param [Hash] params
|
24
|
+
#
|
25
|
+
# @return [Response]
|
26
|
+
#
|
27
|
+
# @see https://developer.nexmo.com/api/account#createAPISecret
|
28
|
+
#
|
29
|
+
def create(params)
|
30
|
+
request('/accounts/' + account_id + '/secrets', params: params, type: Post)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Retrieve API Secrets.
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
# response = client.secrets.list
|
37
|
+
# response.each do |item|
|
38
|
+
# puts "#{item.created_at} #{item.id}"
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# @return [ListResponse]
|
42
|
+
#
|
43
|
+
# @see https://developer.nexmo.com/api/account#retrieveAPISecrets
|
44
|
+
#
|
45
|
+
def list
|
46
|
+
request('/accounts/' + account_id + '/secrets', response_class: ListResponse)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Retrieve one API Secret.
|
50
|
+
#
|
51
|
+
# @example
|
52
|
+
# response = client.secrets.get(secret_id)
|
53
|
+
#
|
54
|
+
# @param [String] secret_id
|
55
|
+
#
|
56
|
+
# @return [Response]
|
57
|
+
#
|
58
|
+
# @see https://developer.nexmo.com/api/account#retrieveAPISecret
|
59
|
+
#
|
60
|
+
def get(secret_id)
|
61
|
+
request('/accounts/' + account_id + '/secrets/' + secret_id)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Revoke an API Secret.
|
65
|
+
#
|
66
|
+
# @example
|
67
|
+
# response = client.secrets.revoke(secret_id)
|
68
|
+
#
|
69
|
+
# @param [String] secret_id
|
70
|
+
#
|
71
|
+
# @return [Response]
|
72
|
+
#
|
73
|
+
# @see https://developer.nexmo.com/api/account#revokeAPISecret
|
74
|
+
#
|
75
|
+
def revoke(secret_id)
|
76
|
+
request('/accounts/' + account_id + '/secrets/' + secret_id, type: Delete)
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def account_id
|
82
|
+
@config.api_key
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
require 'openssl'
|
4
|
+
require 'digest/md5'
|
5
|
+
require 'jwt'
|
6
|
+
|
7
|
+
module Vonage
|
8
|
+
class Signature
|
9
|
+
def initialize(config)
|
10
|
+
@config = config
|
11
|
+
end
|
12
|
+
|
13
|
+
# Check webhook request signature.
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# client = Vonage::Client.new
|
17
|
+
# client.config.signature_secret = 'secret'
|
18
|
+
# client.config.signature_method = 'sha512'
|
19
|
+
#
|
20
|
+
# if client.signature.check(request.GET)
|
21
|
+
# # valid signature
|
22
|
+
# else
|
23
|
+
# # invalid signature
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# @param [Hash] params
|
27
|
+
#
|
28
|
+
# @see https://developer.nexmo.com/concepts/guides/signing-messages
|
29
|
+
#
|
30
|
+
def check(params, signature_method: @config.signature_method)
|
31
|
+
params = params.dup
|
32
|
+
|
33
|
+
signature = params.delete('sig')
|
34
|
+
|
35
|
+
::JWT::SecurityUtils.secure_compare(signature, digest(params, signature_method))
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def digest(params, signature_method)
|
41
|
+
digest_string = params.sort.map { |k, v| "&#{k}=#{v.tr('&=', '_')}" }.join
|
42
|
+
|
43
|
+
case signature_method
|
44
|
+
when 'md5', 'sha1', 'sha256', 'sha512'
|
45
|
+
OpenSSL::HMAC.hexdigest(signature_method, @config.signature_secret, digest_string).upcase
|
46
|
+
when 'md5hash'
|
47
|
+
Digest::MD5.hexdigest("#{digest_string}#{@config.signature_secret}")
|
48
|
+
else
|
49
|
+
raise ArgumentError, "Unknown signature algorithm: #{signature_method}. Expected: md5hash, md5, sha1, sha256, or sha512."
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/vonage/sms.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Vonage
|
5
|
+
class SMS < Namespace
|
6
|
+
extend T::Sig
|
7
|
+
include Keys
|
8
|
+
|
9
|
+
self.host = :rest_host
|
10
|
+
|
11
|
+
# Send an outbound SMS from your Vonage account.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# response = client.sms.send(from: 'Ruby', to: '447700900000', text: 'Hello world')
|
15
|
+
#
|
16
|
+
# puts "Sent message id=#{response.messages.first.message_id}"
|
17
|
+
#
|
18
|
+
# @option params [required, String] :from
|
19
|
+
# The name or number the message should be sent from.
|
20
|
+
# Alphanumeric senderID's are not supported in all countries, see [Global Messaging](https://developer.nexmo.com/messaging/sms/guides/global-messaging#country-specific-features) for more details.
|
21
|
+
# If alphanumeric, spaces will be ignored. Numbers are specified in E.164 format.
|
22
|
+
#
|
23
|
+
# @option params [required, String] :to
|
24
|
+
# The number that the message should be sent to.
|
25
|
+
# Numbers are specified in E.164 format.
|
26
|
+
#
|
27
|
+
# @option params [String] :text
|
28
|
+
# The body of the message being sent.
|
29
|
+
# If your message contains characters that can be encoded according to the GSM Standard and Extended tables then you can set the **:type** to `text`.
|
30
|
+
# If your message contains characters outside this range, then you will need to set the **:type** to `unicode`.
|
31
|
+
#
|
32
|
+
# @option params [Integer] :ttl
|
33
|
+
# The duration in milliseconds the delivery of an SMS will be attempted.
|
34
|
+
# By default Vonage attempt delivery for 72 hours, however the maximum effective value depends on the operator and is typically 24 - 48 hours.
|
35
|
+
# We recommend this value should be kept at its default or at least 30 minutes.
|
36
|
+
#
|
37
|
+
# @option params [Boolean] :status_report_req
|
38
|
+
# Boolean indicating if you like to receive a [Delivery Receipt](https://developer.nexmo.com/messaging/sms/building-blocks/receive-a-delivery-receipt).
|
39
|
+
#
|
40
|
+
# @option params [String] :callback
|
41
|
+
# The webhook endpoint the delivery receipt for this sms is sent to.
|
42
|
+
# This parameter overrides the webhook endpoint you set in Dashboard.
|
43
|
+
#
|
44
|
+
# @option params [Integer] :message_class
|
45
|
+
# The Data Coding Scheme value of the message.
|
46
|
+
#
|
47
|
+
# @option params [String] :type
|
48
|
+
# The format of the message body.
|
49
|
+
#
|
50
|
+
# @option params [String] :vcard
|
51
|
+
# A business card in [vCard format](https://en.wikipedia.org/wiki/VCard).
|
52
|
+
# Depends on **:type** option having the value `vcard`.
|
53
|
+
#
|
54
|
+
# @option params [String] :vcal
|
55
|
+
# A calendar event in [vCal format](https://en.wikipedia.org/wiki/VCal).
|
56
|
+
# Depends on **:type** option having the value `vcal`.
|
57
|
+
#
|
58
|
+
# @option params [String] :body
|
59
|
+
# Hex encoded binary data.
|
60
|
+
# Depends on **:type** option having the value `binary`.
|
61
|
+
#
|
62
|
+
# @option params [String] :udh
|
63
|
+
# Your custom Hex encoded [User Data Header](https://en.wikipedia.org/wiki/User_Data_Header).
|
64
|
+
# Depends on **:type** option having the value `binary`.
|
65
|
+
#
|
66
|
+
# @option params [Integer] :protocol_id
|
67
|
+
# The value of the [protocol identifier](https://en.wikipedia.org/wiki/GSM_03.40#Protocol_Identifier) to use.
|
68
|
+
# Ensure that the value is aligned with **:udh**.
|
69
|
+
#
|
70
|
+
# @option params [String] :title
|
71
|
+
# The title for a wappush SMS.
|
72
|
+
# Depends on **:type** option having the value `wappush`.
|
73
|
+
#
|
74
|
+
# @option params [String] :url
|
75
|
+
# The URL of your website.
|
76
|
+
# Depends on **:type** option having the value `wappush`.
|
77
|
+
#
|
78
|
+
# @option params [String] :validity
|
79
|
+
# The availability for an SMS in milliseconds.
|
80
|
+
# Depends on **:type** option having the value `wappush`.
|
81
|
+
#
|
82
|
+
# @option params [String] :client_ref
|
83
|
+
# You can optionally include your own reference of up to 40 characters.
|
84
|
+
#
|
85
|
+
# @option params [String] :account_ref
|
86
|
+
# An optional string used to identify separate accounts using the SMS endpoint for billing purposes.
|
87
|
+
# To use this feature, please email [support@nexmo.com](mailto:support@nexmo.com).
|
88
|
+
#
|
89
|
+
# @param [Hash] params
|
90
|
+
#
|
91
|
+
# @return [Response]
|
92
|
+
#
|
93
|
+
# @see https://developer.nexmo.com/api/sms#send-an-sms
|
94
|
+
#
|
95
|
+
sig { params(params: T::Hash[Symbol, T.untyped]).returns(Vonage::Response) }
|
96
|
+
def send(params)
|
97
|
+
if unicode?(params.fetch(:text)) && params[:type] != 'unicode'
|
98
|
+
message = 'Sending unicode text SMS without setting the type parameter to "unicode". ' \
|
99
|
+
'See https://developer.nexmo.com/messaging/sms for details, ' \
|
100
|
+
'or email support@nexmo.com if you have any questions.'
|
101
|
+
|
102
|
+
logger.warn(message)
|
103
|
+
end
|
104
|
+
|
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
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
sig { params(text: String).returns(T::Boolean) }
|
117
|
+
def unicode?(text)
|
118
|
+
!Vonage::GSM7.encoded?(text)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|