vonage 7.15.0 → 7.16.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe42d262916665b0528b89b25fc9094ff4009739cea53ec28a416afe2ec232c8
4
- data.tar.gz: d1bb14fcc3e8c862dedd87a32b80034d9914c0cafcc2c53f071b05a9c640a644
3
+ metadata.gz: eee7072db61e23948a8659c05fa1c1a071a231de32da5506c2a0a1f8e0dec525
4
+ data.tar.gz: 7082dab4129bb5f251f14cb5cbfc19cdd21b82da8349535194258bb95c656a88
5
5
  SHA512:
6
- metadata.gz: a52f19d149c83ff7cbc2fe73982abaf79901c146fa45d006d19ba9f32b9640bf14065e132362aae591869339109deeafa68e72349a1e6d9f2a6fba173efbf9a6
7
- data.tar.gz: 38f8d3a78930e5b13e8ed71e3bce0ee37789a506f053e9f31c543bdac10760f574dc976fca097f64f47419f9d99c4b912ce32484b389243b96c52f5fa6e7ef4c
6
+ metadata.gz: 9274d4f25c3ac03361e7024aa24685e2be658db11c57601bbc349bc3c65784ef097d836e309318e87de8f4256dab45bbe814638d708230b7463df58589968fa8
7
+ data.tar.gz: e410a075c96c179c18ca87e047c9c16c3e364c97c36c535eb946dabe4497070a3d465332756db899016ee20af2b45c09dfa846156e9392dde29dfecda4955ae0
data/README.md CHANGED
@@ -12,6 +12,7 @@ need a Vonage account. Sign up [for free at vonage.com][signup].
12
12
  * [Installation](#installation)
13
13
  * [Usage](#usage)
14
14
  * [Logging](#logging)
15
+ * [Exceptions](#exceptions)
15
16
  * [Overriding the default hosts](#overriding-the-default-hosts)
16
17
  * [JWT authentication](#jwt-authentication)
17
18
  * [Webhook signatures](#webhook-signatures)
@@ -82,6 +83,46 @@ By default the library sets the logger to `Rails.logger` if it is defined.
82
83
 
83
84
  To disable logging set the logger to `nil`.
84
85
 
86
+ ## Exceptions
87
+
88
+ Where exceptions result from an error response from the Vonage API (HTTP responses that aren't ion the range `2xx` or `3xx`), the `Net::HTTPResponse` object will be available as a property of the `Exception` object via a `http_response` getter method (where there is no `Net::HTTPResponse` object associated with the exception, the value of `http_response` will be `nil`).
89
+
90
+ You can rescue the the exception to access the `http_response`, as well as use other getters provided for specific parts of the response. For example:
91
+
92
+ ```ruby
93
+ begin
94
+ verification_request = client.verify2.start_verification(
95
+ brand: 'Acme',
96
+ workflow: [{channel: 'sms', to: '44700000000'}]
97
+ )
98
+ rescue Vonage::APIError => error
99
+ if error.http_response
100
+ error.http_response # => #<Net::HTTPUnauthorized 401 Unauthorized readbody=true>
101
+ error.http_response_code # => "401"
102
+ error.http_response_headers # => {"date"=>["Sun, 24 Sep 2023 11:08:47 GMT"], ...rest of headers}
103
+ error.http_response_body # => {"title"=>"Unauthorized", ...rest of body}
104
+ end
105
+ end
106
+ ```
107
+
108
+ For certain legacy API products, such as the [SMS API](https://developer.vonage.com/en/messaging/sms/overview), [Verify v1 API](https://developer.vonage.com/en/verify/verify-v1/overview) and [Number Insight v1 API](https://developer.vonage.com/en/number-insight/overview), a `200` response is received even in situations where there is an API-related error. For exceptions raised in these situation, rather than a `Net::HTTPResponse` object, a `Vonage::Response` object will be made available as a property of the exception via a `response` getter method. The properties on this object will depend on the response data provided by the API endpoint. For example:
109
+
110
+ ```ruby
111
+ begin
112
+ sms = client.sms.send(
113
+ from: 'Vonage',
114
+ to: '44700000000',
115
+ text: 'Hello World!'
116
+ )
117
+ rescue Vonage::Error => error
118
+ if error.is_a? Vonage::ServiceError
119
+ error.response # => #<Vonage::Response:0x0000555b2e49d4f8>
120
+ error.response.messages.first.status # => "4"
121
+ error.response.messages.first.error_text # => "Bad Credentials"
122
+ error.response.http_response # => #<Net::HTTPOK 200 OK readbody=true>
123
+ end
124
+ end
125
+ ```
85
126
 
86
127
  ## Overriding the default hosts
87
128
 
@@ -0,0 +1,33 @@
1
+ # typed: strong
2
+ require "json"
3
+
4
+ module Vonage
5
+ class APIError < Error
6
+ extend T::Sig
7
+
8
+ sig { returns(Net::HTTPResponse) }
9
+ attr_reader :http_response
10
+
11
+ sig { params(message: T.nilable(String), http_response: T.nilable(Net::HTTPResponse)).void }
12
+ def initialize(message = nil, http_response: nil)
13
+ super(message)
14
+ @http_response = http_response
15
+ end
16
+
17
+ def http_response_code
18
+ return nil unless http_response
19
+ http_response.code
20
+ end
21
+
22
+ def http_response_headers
23
+ return nil unless http_response
24
+ http_response.to_hash
25
+ end
26
+
27
+ def http_response_body
28
+ return nil unless http_response
29
+ return {} unless http_response.content_type && http_response.content_type.include?("json")
30
+ ::JSON.parse(http_response.body)
31
+ end
32
+ end
33
+ end
@@ -1,6 +1,6 @@
1
1
  # typed: strong
2
2
 
3
3
  module Vonage
4
- class ClientError < Error
4
+ class ClientError < APIError
5
5
  end
6
6
  end
data/lib/vonage/errors.rb CHANGED
@@ -27,27 +27,30 @@ module Vonage
27
27
  when Net::HTTPServerError
28
28
  ServerError
29
29
  else
30
- Error
30
+ APIError
31
31
  end
32
32
 
33
- message =
34
- if response.content_type == "application/json"
35
- hash = ::JSON.parse(response.body)
33
+ message = response.content_type.to_s.include?("json") ? set_message(response) : ""
36
34
 
37
- if hash.key?("error_title")
38
- hash["error_title"]
39
- elsif hash.key?("error-code-label")
40
- hash["error-code-label"]
41
- elsif hash.key?("description")
42
- hash["description"]
43
- elsif hash.key?("message")
44
- hash["message"]
45
- elsif problem_details?(hash)
46
- problem_details_message(hash)
47
- end
48
- end
35
+ exception_class.new(message, http_response: response)
36
+ end
37
+
38
+ def self.set_message(response)
39
+ hash = ::JSON.parse(response.body)
49
40
 
50
- exception_class.new(message)
41
+ if hash.key?("error_title")
42
+ hash["error_title"]
43
+ elsif hash.key?("error-code-label")
44
+ hash["error-code-label"]
45
+ elsif hash.key?("description")
46
+ hash["description"]
47
+ elsif hash.key?("message")
48
+ hash["message"]
49
+ elsif problem_details?(hash)
50
+ problem_details_message(hash)
51
+ else
52
+ ""
53
+ end
51
54
  end
52
55
 
53
56
  sig { params(hash: T::Hash[String, T.untyped]).returns(T::Boolean) }
@@ -57,7 +60,7 @@ module Vonage
57
60
 
58
61
  sig { params(hash: T::Hash[String, T.untyped]).returns(String) }
59
62
  def self.problem_details_message(hash)
60
- "#{hash["title"]}. #{hash["detail"]} See #{hash["type"]} for more info, or email support@nexmo.com if you have any questions."
63
+ "#{hash["title"]}. #{hash["detail"]} See #{hash["type"]} for more info, or email support@vonage.com if you have any questions."
61
64
  end
62
65
  end
63
66
 
@@ -19,7 +19,7 @@ module Vonage
19
19
  #
20
20
  # @see https://developer.vonage.com/en/api/meetings#updateApplication
21
21
  def update(default_theme_id:)
22
- request("/meetings/applications", params: {update_details: {default_theme_id: default_theme_id}}, type: Patch)
22
+ request("/v1/meetings/applications", params: {update_details: {default_theme_id: default_theme_id}}, type: Patch)
23
23
  end
24
24
  end
25
25
  end
@@ -17,7 +17,7 @@ module Vonage
17
17
  #
18
18
  # @see https://developer.vonage.com/en/api/meetings#getDialInNumbers
19
19
  def list
20
- request("/meetings/dial-in-numbers", response_class: ListResponse)
20
+ request("/v1/meetings/dial-in-numbers", response_class: ListResponse)
21
21
  end
22
22
  end
23
23
  end
@@ -19,7 +19,7 @@ module Vonage
19
19
  #
20
20
  # @see https://developer.vonage.com/en/api/meetings#getRecording
21
21
  def info(recording_id:)
22
- request("/meetings/recordings/" + recording_id)
22
+ request("/v1/meetings/recordings/" + recording_id)
23
23
  end
24
24
 
25
25
  # Delete a specified recording.
@@ -30,7 +30,7 @@ module Vonage
30
30
  #
31
31
  # @see https://developer.vonage.com/en/api/meetings#deleteRecording
32
32
  def delete(recording_id:)
33
- request("/meetings/recordings/" + recording_id, type: Delete)
33
+ request("/v1/meetings/recordings/" + recording_id, type: Delete)
34
34
  end
35
35
  end
36
36
  end
@@ -23,7 +23,7 @@ module Vonage
23
23
  #
24
24
  # @see https://developer.vonage.com/en/api/meetings#getRooms
25
25
  def list(**params)
26
- path = "/meetings/rooms"
26
+ path = "/v1/meetings/rooms"
27
27
  path += "?#{Params.encode(params)}" unless params.empty?
28
28
 
29
29
  request(path, response_class: ListResponse)
@@ -38,7 +38,7 @@ module Vonage
38
38
  #
39
39
  # @see https://developer.vonage.com/en/api/meetings#getRoom
40
40
  def info(room_id:)
41
- request("/meetings/rooms/" + room_id)
41
+ request("/v1/meetings/rooms/" + room_id)
42
42
  end
43
43
 
44
44
  # Create a new room.
@@ -96,7 +96,7 @@ module Vonage
96
96
  # @see https://developer.vonage.com/en/api/meetings#createRoom
97
97
  def create(display_name:, **params)
98
98
  request(
99
- "/meetings/rooms",
99
+ "/v1/meetings/rooms",
100
100
  params: params.merge({ display_name: display_name }),
101
101
  type: Post
102
102
  )
@@ -144,7 +144,7 @@ module Vonage
144
144
  def update(room_id:, **params)
145
145
  raise ArgumentError, 'must provide at least one other param in addition to :room_id' if params.empty?
146
146
  request(
147
- "/meetings/rooms/" + room_id,
147
+ "/v1/meetings/rooms/" + room_id,
148
148
  params: {
149
149
  update_details: params
150
150
  },
@@ -20,7 +20,7 @@ module Vonage
20
20
  # @see https://developer.vonage.com/en/api/meetings#getSessionRecordings
21
21
  def list_recordings(session_id:)
22
22
  request(
23
- "/meetings/sessions/" + session_id + "/recordings",
23
+ "/v1/meetings/sessions/" + session_id + "/recordings",
24
24
  response_class: ListResponse
25
25
  )
26
26
  end
@@ -17,7 +17,7 @@ module Vonage
17
17
  #
18
18
  # @see https://developer.vonage.com/en/api/meetings#getThemes
19
19
  def list
20
- request("/meetings/themes", response_class: ListResponse)
20
+ request("/v1/meetings/themes", response_class: ListResponse)
21
21
  end
22
22
 
23
23
  # Return information for specified theme.
@@ -28,7 +28,7 @@ module Vonage
28
28
  #
29
29
  # @see https://developer.vonage.com/en/api/meetings#getThemeById
30
30
  def info(theme_id:)
31
- request("/meetings/themes/" + theme_id)
31
+ request("/v1/meetings/themes/" + theme_id)
32
32
  end
33
33
 
34
34
  # Create a new theme.
@@ -50,7 +50,7 @@ module Vonage
50
50
  # @see https://developer.vonage.com/en/api/meetings#createTheme
51
51
  def create(main_color:, brand_text:, **params)
52
52
  request(
53
- "/meetings/themes",
53
+ "/v1/meetings/themes",
54
54
  params: params.merge(main_color: main_color, brand_text: brand_text),
55
55
  type: Post
56
56
  )
@@ -77,7 +77,7 @@ module Vonage
77
77
  # @see https://developer.vonage.com/en/api/meetings#updateTheme
78
78
  def update(theme_id:, **params)
79
79
  request(
80
- "/meetings/themes/" + theme_id,
80
+ "/v1/meetings/themes/" + theme_id,
81
81
  params: {
82
82
  update_details: params
83
83
  },
@@ -97,7 +97,7 @@ module Vonage
97
97
  # @see https://developer.vonage.com/en/api/meetings#deleteTheme
98
98
  def delete(theme_id:, force: false)
99
99
  request(
100
- "/meetings/themes/" + theme_id + "?force=#{force}",
100
+ "/v1/meetings/themes/" + theme_id + "?force=#{force}",
101
101
  type: Delete
102
102
  )
103
103
  end
@@ -116,7 +116,7 @@ module Vonage
116
116
  #
117
117
  # @see https://developer.vonage.com/en/api/meetings#getRoomsByThemeId
118
118
  def list_rooms(theme_id:, **params)
119
- path = "/meetings/themes/" + theme_id + "/rooms"
119
+ path = "/v1/meetings/themes/" + theme_id + "/rooms"
120
120
  path += "?#{Params.encode(params)}" unless params.empty?
121
121
 
122
122
  request(path, response_class: Meetings::Rooms::ListResponse)
@@ -164,7 +164,7 @@ module Vonage
164
164
  private
165
165
 
166
166
  def get_logo_upload_credentials
167
- request("/meetings/themes/logos-upload-urls", response_class: ListResponse)
167
+ request("/v1/meetings/themes/logos-upload-urls", response_class: ListResponse)
168
168
  end
169
169
 
170
170
  def upload_logo_file(filepath:, credentials:)
@@ -185,7 +185,7 @@ module Vonage
185
185
 
186
186
  def finalize_logos(theme_id:, keys: [])
187
187
  request(
188
- "/meetings/themes/" + theme_id + "/finalizeLogos",
188
+ "/v1/meetings/themes/" + theme_id + "/finalizeLogos",
189
189
  params: {
190
190
  keys: keys
191
191
  },
@@ -1,6 +1,6 @@
1
1
  # typed: strong
2
2
 
3
3
  module Vonage
4
- class ServerError < Error
4
+ class ServerError < APIError
5
5
  end
6
6
  end
@@ -1,5 +1,5 @@
1
1
  # typed: strong
2
2
 
3
3
  module Vonage
4
- VERSION = "7.15.0"
4
+ VERSION = "7.16.0"
5
5
  end
data/lib/vonage.rb CHANGED
@@ -7,6 +7,7 @@ module Vonage
7
7
  loader = Zeitwerk::Loader.new
8
8
  loader.tag = File.basename(__FILE__, '.rb')
9
9
  loader.inflector.inflect({
10
+ 'api_error' => 'APIError',
10
11
  'dtmf' => 'DTMF',
11
12
  'gsm7' => 'GSM7',
12
13
  'http' => 'HTTP',
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vonage
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.15.0
4
+ version: 7.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vonage
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-10 00:00:00.000000000 Z
11
+ date: 2023-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: vonage-jwt
@@ -113,6 +113,7 @@ files:
113
113
  - lib/vonage/abstract_authentication.rb
114
114
  - lib/vonage/account.rb
115
115
  - lib/vonage/alerts.rb
116
+ - lib/vonage/api_error.rb
116
117
  - lib/vonage/applications.rb
117
118
  - lib/vonage/applications/list_response.rb
118
119
  - lib/vonage/authentication_error.rb