vonage 7.17.0 → 7.19.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,36 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class NumberInsight2 < Namespace
6
+ extend T::Sig
7
+
8
+ self.authentication = Basic
9
+
10
+ self.request_body = JSON
11
+
12
+ # Make fraud check requests with a phone number by looking up fraud score and/or by checking sim swap status.
13
+ #
14
+ # @example
15
+ # response = client.number_insight_2.fraud_check(type: 'phone', phone: '447900000000', insights: ['fraud_score'])
16
+ #
17
+ # @param [required, String] :type The type of number to check.
18
+ # Accepted value is “phone” when a phone number is provided.
19
+ #
20
+ # @param [required, String] :phone A single phone number that you need insight about in the E.164 format.
21
+ #
22
+ # @param [required, Array] :insights An array of strings indicating the fraud check insights required for the number.
23
+ # Must be least one of: `fraud_score`, `sim_swap`
24
+ #
25
+ # @return [Response]
26
+ #
27
+ # @see https://developer.vonage.com/en/api/number-insight.v2#fraud_check
28
+ #
29
+ sig { params(type: String, phone: String, insights: T::Array[String]).returns(Vonage::Response) }
30
+ def fraud_check(type:, phone:, insights:)
31
+ raise ArgumentError.new("`insights` must not be an empty") if insights.empty?
32
+
33
+ request('/v2/ni', params: {type: type, phone: phone, insights: insights}, type: Post)
34
+ end
35
+ end
36
+ end
@@ -27,24 +27,24 @@ module Vonage
27
27
  #
28
28
  # @see https://developer.nexmo.com/concepts/guides/signing-messages
29
29
  #
30
- def check(params, signature_method: @config.signature_method)
30
+ def check(params, signature_secret: @config.signature_secret, signature_method: @config.signature_method)
31
31
  params = params.dup
32
32
 
33
33
  signature = params.delete('sig')
34
34
 
35
- ::JWT::Algos::Hmac::SecurityUtils.secure_compare(signature, digest(params, signature_method))
35
+ ::JWT::Algos::Hmac::SecurityUtils.secure_compare(signature, digest(params, signature_secret, signature_method))
36
36
  end
37
37
 
38
38
  private
39
39
 
40
- def digest(params, signature_method)
40
+ def digest(params, signature_secret, signature_method)
41
41
  digest_string = params.sort.map { |k, v| "&#{k}=#{v.tr('&=', '_')}" }.join
42
42
 
43
43
  case signature_method
44
44
  when 'md5', 'sha1', 'sha256', 'sha512'
45
- OpenSSL::HMAC.hexdigest(signature_method, @config.signature_secret, digest_string).upcase
45
+ OpenSSL::HMAC.hexdigest(signature_method, signature_secret, digest_string).upcase
46
46
  when 'md5hash'
47
- Digest::MD5.hexdigest("#{digest_string}#{@config.signature_secret}")
47
+ Digest::MD5.hexdigest("#{digest_string}#{signature_secret}")
48
48
  else
49
49
  raise ArgumentError, "Unknown signature algorithm: #{signature_method}. Expected: md5hash, md5, sha1, sha256, or sha512."
50
50
  end
data/lib/vonage/sms.rb CHANGED
@@ -91,11 +91,31 @@ module Vonage
91
91
  response
92
92
  end
93
93
 
94
+ # Validate a Signature from an SMS API Webhook.
95
+ #
96
+ # @param [Hash, required] :webhook_params The parameters from the webhook request body
97
+ # @param [String, optional] :signature_secret The account signature secret. Required, unless `signature_secret`
98
+ # is set in `Config`
99
+ # @param [String, optional] :signature_method The account signature method. Required, unless `signature_method`
100
+ # is set in `Config`
101
+ #
102
+ # @return [Boolean] true, if the JWT is verified, false otherwise
103
+ def verify_webhook_sig(webhook_params:, signature_secret: @config.signature_secret, signature_method: @config.signature_method)
104
+ signature.check(webhook_params, signature_secret: signature_secret, signature_method: signature_method)
105
+ end
106
+
94
107
  private
95
108
 
96
109
  sig { params(text: String).returns(T::Boolean) }
97
110
  def unicode?(text)
98
111
  !Vonage::GSM7.encoded?(text)
99
112
  end
113
+
114
+ # @return [Signature]
115
+ #
116
+ sig { returns(T.nilable(Vonage::Signature)) }
117
+ def signature
118
+ @signature ||= T.let(Signature.new(@config), T.nilable(Vonage::Signature))
119
+ end
100
120
  end
101
121
  end
@@ -10,16 +10,14 @@ module Vonage
10
10
  def initialize(to:, from: nil)
11
11
  self.channel = 'email'
12
12
  self.to = to
13
- self.from = from if from
13
+ self.from = from unless from.nil?
14
14
  end
15
15
 
16
16
  def to=(to)
17
- # TODO: add validation
18
17
  @to = to
19
18
  end
20
19
 
21
20
  def from=(from)
22
- # TODO: add validation
23
21
  @from = from
24
22
  end
25
23
 
@@ -1,15 +1,18 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
  require 'phonelib'
4
+ require 'uri'
4
5
 
5
6
  module Vonage
6
7
  class Verify2::Channels::SilentAuth
7
8
 
8
- attr_reader :channel, :to
9
+ attr_reader :channel, :to, :sandbox, :redirect_url
9
10
 
10
- def initialize(to:)
11
+ def initialize(to:, redirect_url: nil, sandbox: nil)
11
12
  self.channel = 'silent_auth'
12
13
  self.to = to
14
+ self.redirect_url = redirect_url unless redirect_url.nil?
15
+ self.sandbox = sandbox unless sandbox.nil?
13
16
  end
14
17
 
15
18
  def to=(to)
@@ -17,6 +20,16 @@ module Vonage
17
20
  @to = to
18
21
  end
19
22
 
23
+ def redirect_url=(redirect_url)
24
+ raise ArgumentError, "Invalid 'to' value #{redirect_url}. Expected to be a valid URL" unless URI.parse(redirect_url).is_a?(URI::HTTP)
25
+ @redirect_url = redirect_url
26
+ end
27
+
28
+ def sandbox=(sandbox)
29
+ raise ArgumentError, "Invalid 'sandbox' value #{sandbox}. Expected to be boolean value" unless [true, false].include? sandbox
30
+ @sandbox = sandbox
31
+ end
32
+
20
33
  def to_h
21
34
  hash = Hash.new
22
35
  self.instance_variables.each do |ivar|
@@ -11,7 +11,7 @@ module Vonage
11
11
  def initialize(to:, app_hash: nil)
12
12
  self.channel = 'sms'
13
13
  self.to = to
14
- self.app_hash = app_hash if app_hash
14
+ self.app_hash = app_hash unless app_hash.nil?
15
15
  end
16
16
 
17
17
  def to=(to)
@@ -10,7 +10,7 @@ module Vonage
10
10
  def initialize(to:, from: nil)
11
11
  self.channel = 'whatsapp'
12
12
  self.to = to
13
- self.from = from if from
13
+ self.from = from unless from.nil?
14
14
  end
15
15
 
16
16
  def to=(to)
@@ -10,7 +10,7 @@ module Vonage
10
10
  # Request a verification be sent to a user.
11
11
  #
12
12
  # @example
13
- # verification_request = verify.start_verification(
13
+ # verification_request = client.verify2.start_verification(
14
14
  # brand: 'Acme',
15
15
  # workflow: [{channel: 'sms', to: '447000000000'}],
16
16
  # code_length: 6
@@ -41,7 +41,7 @@ module Vonage
41
41
  # Check a supplied code against a request to see if it is valid.
42
42
  #
43
43
  # @example
44
- # code_check = verify.check_code(request_id: '7e8c5965-0a3f-44df-8a14-f1486209d8a2', code: '1234')
44
+ # code_check = client.verify2.check_code(request_id: '7e8c5965-0a3f-44df-8a14-f1486209d8a2', code: '1234')
45
45
  #
46
46
  # @param [required, String] :request_id The request_id of the verification request being checked
47
47
  #
@@ -56,7 +56,7 @@ module Vonage
56
56
  # Cancel a verifiction. If a verification request is still active, calling this method aborts the workflow.
57
57
  #
58
58
  # @example
59
- # verify.cancel_verification_request(request_id: '7e8c5965-0a3f-44df-8a14-f1486209d8a2')
59
+ # client.verify2.cancel_verification_request(request_id: '7e8c5965-0a3f-44df-8a14-f1486209d8a2')
60
60
  #
61
61
  # @param [required, String] :request_id The request_id of the verification request to be cancelled
62
62
  #
@@ -1,5 +1,5 @@
1
1
  # typed: strong
2
2
 
3
3
  module Vonage
4
- VERSION = "7.17.0"
4
+ VERSION = '7.19.0'
5
5
  end
@@ -0,0 +1,11 @@
1
+ # typed: true
2
+
3
+ class Vonage::Video::Archives::ListResponse < Vonage::Response
4
+ include Enumerable
5
+
6
+ def each
7
+ return enum_for(:each) unless block_given?
8
+
9
+ @entity.items.each { |item| yield item }
10
+ end
11
+ end
@@ -0,0 +1,152 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class Video::Archives < Namespace
6
+ include Keys
7
+
8
+ self.authentication = BearerToken
9
+
10
+ self.request_body = JSON
11
+
12
+ self.host = :video_host
13
+
14
+ # Get a list of archives for a specified Vonage application.
15
+ #
16
+ # @param [optional, Integer] :offset
17
+ #
18
+ # @param [optional, Integer] :count
19
+ #
20
+ # @param [optional, String] :session_id
21
+ #
22
+ # TODO: add auto_advance option
23
+ #
24
+ # @return [ListResponse]
25
+ #
26
+ # @see TODO: add docs link
27
+ #
28
+ def list(**params)
29
+ request('/v2/project/' + @config.application_id + '/archive', params: params, response_class: ListResponse)
30
+ end
31
+
32
+ # Return information for specified archive.
33
+ #
34
+ # @param [required, String] archive_id
35
+ #
36
+ # @return [Response]
37
+ #
38
+ # @see TODO: add docs link
39
+ #
40
+ def info(archive_id:)
41
+ request('/v2/project/' + @config.application_id + '/archive/' + archive_id)
42
+ end
43
+
44
+ # Create a new archive.
45
+ #
46
+ # @param [required, String] :session_id
47
+ #
48
+ # @param [optional, String] :hasAudio
49
+ #
50
+ # @param [optional, String] :hasVideo
51
+ #
52
+ # @param [optional, String] :name
53
+ #
54
+ # @param [optional, String] :outputMode
55
+ #
56
+ # @param [optional, String] :resolution
57
+ #
58
+ # @param [optional, String] :streamMode
59
+ #
60
+ # @param [optional, String] :multiArchiveTag
61
+ #
62
+ # @param [optional, Hash] :layout
63
+ #
64
+ # @option layout [optional, String] :type
65
+ #
66
+ # @option layout [optional, String] :stylesheet
67
+ #
68
+ # @option layout [optional, String] :screenshareType
69
+ #
70
+ # @return [Response]
71
+ #
72
+ # @see TODO: add docs link
73
+ #
74
+ def start(session_id:, **params)
75
+ request('/v2/project/' + @config.application_id + '/archive', params: camelcase(params.merge(session_id: session_id)), type: Post)
76
+ end
77
+
78
+ # Stop recording a specified archive.
79
+ #
80
+ # @param [required, String] archive_id
81
+ #
82
+ # @return [Response]
83
+ #
84
+ # @see TODO: add docs link
85
+ #
86
+ def stop(archive_id:)
87
+ request('/v2/project/' + @config.application_id + '/archive/' + archive_id + '/stop', type: Post)
88
+ end
89
+
90
+ # Delete a specified archive.
91
+ #
92
+ # @param [required, String] archive_id
93
+ #
94
+ # @return [Response]
95
+ #
96
+ # @see TODO: add docs link
97
+ #
98
+ def delete(archive_id:)
99
+ request('/v2/project/' + @config.application_id + '/archive/' + archive_id, type: Delete)
100
+ end
101
+
102
+ # Add a stream to a composed archive that was started with the streamMode set to "manual".
103
+ #
104
+ # @param [required, String] archive_id
105
+ #
106
+ # @param [required, String] stream_id The ID of the stream to be added
107
+ #
108
+ # @param [optional, Boolean] has_audio
109
+ #
110
+ # @param [optional, Boolean] has_video
111
+ #
112
+ # @return [Response]
113
+ #
114
+ # @see TODO: add docs link
115
+ #
116
+ def add_stream(archive_id:, stream_id:, **params)
117
+ request('/v2/project/' + @config.application_id + '/archive/' + archive_id + '/streams', params: camelcase(params.merge(addStream: stream_id)), type: Patch)
118
+ end
119
+
120
+ # Remove a stream from a composed archive that was started with the streamMode set to "manual".
121
+ #
122
+ # @param [required, String] archive_id
123
+ #
124
+ # @param [required, String] stream_id The ID of the stream to be removed
125
+ #
126
+ # @return [Response]
127
+ #
128
+ # @see TODO: add docs link
129
+ #
130
+ def remove_stream(archive_id:, stream_id:)
131
+ request('/v2/project/' + @config.application_id + '/archive/' + archive_id + '/streams', params: {removeStream: stream_id}, type: Patch)
132
+ end
133
+
134
+ # Change the layout of a composed archive while it is being recorded.
135
+ #
136
+ # @param [required, String] archive_id
137
+ #
138
+ # @param [optional, String] type
139
+ #
140
+ # @param [optional, String] stylesheet
141
+ #
142
+ # @param [optional, String] screenshare_type
143
+ #
144
+ # @return [Response]
145
+ #
146
+ # @see TODO: add docs link
147
+ #
148
+ def change_layout(archive_id:, **params)
149
+ request('/v2/project/' + @config.application_id + '/archive/' + archive_id + '/layout', params: camelcase(params), type: Put)
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,11 @@
1
+ # typed: true
2
+
3
+ class Vonage::Video::Broadcasts::ListResponse < Vonage::Response
4
+ include Enumerable
5
+
6
+ def each
7
+ return enum_for(:each) unless block_given?
8
+
9
+ @entity.items.each { |item| yield item }
10
+ end
11
+ end
@@ -0,0 +1,75 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class Video::Broadcasts < Namespace
6
+ include Keys
7
+
8
+ self.authentication = BearerToken
9
+
10
+ self.request_body = JSON
11
+
12
+ self.host = :video_host
13
+
14
+ # Get a list of live streaming broadcasts for a specified Vonage application.
15
+ #
16
+ def list(**params)
17
+ path = '/v2/project/' + @config.application_id + '/broadcast'
18
+ path += "?#{Params.encode(camelcase(params))}" unless params.empty?
19
+
20
+ request(path, response_class: ListResponse)
21
+ end
22
+
23
+ # Return information for specified broadcast.
24
+ #
25
+ def info(broadcast_id:)
26
+ request('/v2/project/' + @config.application_id + '/broadcast/' + broadcast_id)
27
+ end
28
+
29
+ # Start a new live streaming broadcast.
30
+ #
31
+ def start(session_id:, **params)
32
+ request(
33
+ '/v2/project/' + @config.application_id + '/broadcast',
34
+ params: camelcase(params.merge(session_id: session_id)),
35
+ type: Post
36
+ )
37
+ end
38
+
39
+ # Stop a specified broadcast.
40
+ #
41
+ def stop(broadcast_id:)
42
+ request('/v2/project/' + @config.application_id + '/broadcast/' + broadcast_id + '/stop', type: Post)
43
+ end
44
+
45
+ # Add a stream to a live streaming broadcast.
46
+ #
47
+
48
+ def add_stream(broadcast_id:, stream_id:, **params)
49
+ request(
50
+ '/v2/project/' + @config.application_id + '/broadcast/' + broadcast_id + '/streams',
51
+ params: camelcase(params.merge(addStream: stream_id)),
52
+ type: Patch
53
+ )
54
+ end
55
+
56
+ # Remove a stream from a live streaming broadcast.
57
+ #
58
+ def remove_stream(broadcast_id:, stream_id:)
59
+ request(
60
+ '/v2/project/' + @config.application_id + '/broadcast/' + broadcast_id + '/streams',
61
+ params: {removeStream: stream_id},
62
+ type: Patch
63
+ )
64
+ end
65
+
66
+ # Dynamically change layout of a broadcast.
67
+ #
68
+ def change_layout(broadcast_id:, **params)
69
+ request(
70
+ '/v2/project/' + @config.application_id + '/broadcast/' + broadcast_id + '/layout',
71
+ params: camelcase(params),
72
+ type: Put)
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,58 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class Video::Moderation < Namespace
6
+ self.authentication = BearerToken
7
+
8
+ self.request_body = JSON
9
+
10
+ self.host = :video_host
11
+
12
+ # Force a client to disconnect from a session.
13
+ #
14
+ # @param [required, String] :session_id
15
+ #
16
+ # @param [required, String] :connection_id The connection ID of the specific participant to be disconnected from the session.
17
+ #
18
+ # @return [Response]
19
+ #
20
+ # @see TODO: add docs link
21
+ #
22
+ def force_disconnect(session_id:, connection_id:)
23
+ request('/v2/project/' + @config.application_id + '/session/' + session_id + '/connection/' + connection_id, type: Delete)
24
+ end
25
+
26
+ # Force mute a specific publisher stream in a session.
27
+ #
28
+ # @param [required, String] :session_id
29
+ #
30
+ # @param [required, String] :stream_id The stream ID of the specific stream to be muted.
31
+ #
32
+ # @return [Response]
33
+ #
34
+ # @see TODO: add docs link
35
+ #
36
+ def mute_single_stream(session_id:, stream_id:)
37
+ request('/v2/project/' + @config.application_id + '/session/' + session_id + '/stream/' + stream_id + '/mute', type: Post)
38
+ end
39
+
40
+ # Force mute all publisher stream for a specific session.
41
+ #
42
+ # @param [required, String] :session_id
43
+ #
44
+ # @param [required, String] :active
45
+ #
46
+ # @param [required, Array<String>] :excludedStreamIds
47
+ #
48
+ # @return [Response]
49
+ #
50
+ # @see TODO: add docs link
51
+ #
52
+ def mute_multiple_streams(session_id:, **params)
53
+ request('/v2/project/' + @config.application_id + '/session/' + session_id + '/mute', params: params, type: Post)
54
+ end
55
+
56
+ # TODO: add disable_force_mute ??
57
+ end
58
+ end
@@ -0,0 +1,50 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class Video::Signals < Namespace
6
+ self.authentication = BearerToken
7
+
8
+ self.request_body = JSON
9
+
10
+ self.host = :video_host
11
+
12
+ # Send a signal to a specific participant in an active Vonage Video session.
13
+ #
14
+ # @param [optional, String] :application_id (Required unless already set at Client instantiation or set in ENV)
15
+ #
16
+ # @param [required, String] :session_id
17
+ #
18
+ # @param [required, String] :connection_id The connection ID of the specific participant.
19
+ #
20
+ # @param [required, String] :type Type of data that is being sent to the client.
21
+ #
22
+ # @param [required, String] :data Payload that is being sent to the client.
23
+ #
24
+ # @return [Response]
25
+ #
26
+ # @see TODO: add docs link
27
+ #
28
+ def send_to_one(session_id:, connection_id:, **params)
29
+ request('/v2/project/' + @config.application_id + '/session/' + session_id + '/connection/' + connection_id + '/signal', params: params, type: Post)
30
+ end
31
+
32
+ # Send a signal to all participants in an active Vonage Video session.
33
+ #
34
+ # @param [optional, String] :application_id (Required unless already set at Client instantiation or set in ENV)
35
+ #
36
+ # @param [required, String] :session_id
37
+ #
38
+ # @param [required, String] :type Type of data that is being sent to the client.
39
+ #
40
+ # @param [required, String] :data Payload that is being sent to the client.
41
+ #
42
+ # @return [Response]
43
+ #
44
+ # @see TODO: add docs link
45
+ #
46
+ def send_to_all(session_id:, **params)
47
+ request('/v2/project/' + @config.application_id + '/session/' + session_id + '/signal', params: params, type: Post)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,48 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class Video::SIP < Namespace
6
+ include Keys
7
+
8
+ self.authentication = BearerToken
9
+
10
+ self.request_body = JSON
11
+
12
+ self.host = :video_host
13
+
14
+ # Initiate an outbound SIP call.
15
+ #
16
+ def dial(session_id:, token:, sip_uri:, **params)
17
+ request(
18
+ '/v2/project/' + @config.application_id + '/dial',
19
+ params: camelcase({
20
+ session_id: session_id,
21
+ token: token,
22
+ sip: params.merge({uri: sip_uri})
23
+ }),
24
+ type: Post
25
+ )
26
+ end
27
+
28
+ # Play DTMF tones into a SIP call.
29
+ #
30
+ def play_dtmf_to_session(session_id:, dtmf_digits:)
31
+ request(
32
+ '/v2/project/' + @config.application_id + '/session/' + session_id + '/play-dtmf',
33
+ params: {digits: dtmf_digits},
34
+ type: Post
35
+ )
36
+ end
37
+
38
+ # Play DMTF tones into a specific connection.
39
+ #
40
+ def play_dtmf_to_connection(session_id:, connection_id:, dtmf_digits:)
41
+ request(
42
+ '/v2/project/' + @config.application_id + '/session/' + session_id + '/connection/' + connection_id + '/play-dtmf',
43
+ params: {digits: dtmf_digits},
44
+ type: Post
45
+ )
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,11 @@
1
+ # typed: true
2
+
3
+ class Vonage::Video::Streams::ListResponse < Vonage::Response
4
+ include Enumerable
5
+
6
+ def each
7
+ return enum_for(:each) unless block_given?
8
+
9
+ @entity.items.each { |item| yield item }
10
+ end
11
+ end