nexmo 4.6.0 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fcd725644e13c80c7c86b80e347c0bef98c8805d
4
- data.tar.gz: 7c0eafc7558cb0d68c9faa93d1f3e9776ddf221c
3
+ metadata.gz: b8c6620dc24f8cb8e4260f28df8d33775a796624
4
+ data.tar.gz: f19674fb59e52953d0c690edba86fccc2e29a793
5
5
  SHA512:
6
- metadata.gz: 29d45a64e0aeaec4c647c54d1db995b9c22a58b071a815f3e46d52648eff3a216c73dfb72e67777a19c9ae6499957a7e6d3900ae641a829fcef174884071d196
7
- data.tar.gz: da8b6ec8aaaa5b55645940e2d6b0b59260c17bf717cf8191bf430687636a147e26b885a23ccdcff82fbfd1cbee20c084a553ed217be82ae42582fe6f36e481e9
6
+ metadata.gz: 441b7447fbe1e1a0452ed3f82cb531376b09e97e1c6241bfb5db59f2374f755db299ee56b41f475fa0d1f6ce13469c52a50c891a59e558d4818d4632764ec8f2
7
+ data.tar.gz: c085d5cae72f90a22c6d8e7912d52e2e43a910b658282c770d9cb44e15e2586bc9fab6258ede4f2daa943458e2efa88aa1961bcc50c64bc34226fa9c09dc238c
data/README.md CHANGED
@@ -10,7 +10,9 @@ need a Nexmo account. Sign up [for free at nexmo.com][signup].
10
10
  * [SMS API](#sms-api)
11
11
  * [Voice API](#voice-api)
12
12
  * [Verify API](#verify-api)
13
+ * [Number Insight API](#number-insight-api)
13
14
  * [Application API](#application-api)
15
+ * [Numbers API](#numbers-api)
14
16
  * [Coverage](#api-coverage)
15
17
  * [License](#license)
16
18
 
@@ -40,19 +42,36 @@ Then construct a client object with your key and secret:
40
42
  client = Nexmo::Client.new(key: 'YOUR-API-KEY', secret: 'YOUR-API-SECRET')
41
43
  ```
42
44
 
45
+ You can now use the client object to [send a text message](#send-a-text-message),
46
+ [start a verification](#start-a-verification), or [create an application](#create-an-application).
47
+
43
48
  For production you can specify the `NEXMO_API_KEY` and `NEXMO_API_SECRET`
44
- environment variables instead of specifying the key and secret explicitly.
49
+ environment variables instead of specifying the key and secret explicitly,
50
+ keeping your credentials out of source control.
51
+
45
52
 
46
- For newer endpoints that support JWT authentication such as the Voice API,
47
- you can also specify the `application_id` and `private_key` arguments:
53
+ ## Credentials
54
+
55
+ To check signatures for incoming webhook requests you'll also need to specify
56
+ the `signature_secret` argument:
57
+
58
+ ```ruby
59
+ client = Nexmo::Client.new(signature_secret: 'secret')
60
+ ```
61
+
62
+ Alternatively you can set the `NEXMO_SIGNATURE_SECRET` environment variable.
63
+
64
+ To call newer endpoints that support JWT authentication such as the Voice API you'll
65
+ also need to specify the `application_id` and `private_key` arguments. For example:
48
66
 
49
67
  ```ruby
50
68
  client = Nexmo::Client.new(application_id: application_id, private_key: private_key)
51
69
  ```
52
70
 
53
- In order to check signatures for incoming webhook requests, you'll also need
54
- to specify the `signature_secret` argument (or the `NEXMO_SIGNATURE_SECRET`
55
- environment variable).
71
+ Both arguments should have string values corresponding to the `id` and `private_key`
72
+ values returned in a ["create an application"](#create-an-application) response. These
73
+ credentials can be stored in a datastore, in environment variables, on disk outside
74
+ of source control, or in some kind of key management infrastructure.
56
75
 
57
76
 
58
77
  ## SMS API
@@ -69,7 +88,7 @@ else
69
88
  end
70
89
  ```
71
90
 
72
- Docs: [https://docs.nexmo.com/messaging/sms-api/api-reference#request](https://docs.nexmo.com/messaging/sms-api/api-reference#request?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
91
+ Docs: [https://developer.nexmo.com/api/sms#request](https://developer.nexmo.com/api/sms?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#request)
73
92
 
74
93
 
75
94
  ## Voice API
@@ -84,7 +103,7 @@ response = client.create_call({
84
103
  })
85
104
  ```
86
105
 
87
- Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#call_create](https://docs.nexmo.com/voice/voice-api/api-reference#call_create?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
106
+ Docs: [https://developer.nexmo.com/api/voice#create-an-outbound-call](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#create-an-outbound-call)
88
107
 
89
108
  ### Retrieve a list of calls
90
109
 
@@ -92,7 +111,7 @@ Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#call_create](https:/
92
111
  response = client.get_calls
93
112
  ```
94
113
 
95
- Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#call_retrieve](https://docs.nexmo.com/voice/voice-api/api-reference#call_retrieve?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
114
+ Docs: [https://developer.nexmo.com/api/voice#retrieve-information-about-all-your-calls](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#retrieve-information-about-all-your-calls)
96
115
 
97
116
  ### Retrieve a single call
98
117
 
@@ -100,7 +119,7 @@ Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#call_retrieve](https
100
119
  response = client.get_call(uuid)
101
120
  ```
102
121
 
103
- Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#call_retrieve_single](https://docs.nexmo.com/voice/voice-api/api-reference#call_retrieve_single?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
122
+ Docs: [https://developer.nexmo.com/api/voice#retrieve-information-about-a-single-call](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#retrieve-information-about-a-single-call)
104
123
 
105
124
  ### Update a call
106
125
 
@@ -108,7 +127,7 @@ Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#call_retrieve_single
108
127
  response = client.update_call(uuid, action: 'hangup')
109
128
  ```
110
129
 
111
- Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#call_modify_single](https://docs.nexmo.com/voice/voice-api/api-reference#call_modify_single?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
130
+ Docs: [https://developer.nexmo.com/api/voice#modify-an-existing-call](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#modify-an-existing-call)
112
131
 
113
132
  ### Stream audio to a call
114
133
 
@@ -118,7 +137,7 @@ stream_url = 'https://nexmo-community.github.io/ncco-examples/assets/voice_api_a
118
137
  response = client.send_audio(uuid, stream_url: stream_url)
119
138
  ```
120
139
 
121
- Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#stream_put](https://docs.nexmo.com/voice/voice-api/api-reference#stream_put?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
140
+ Docs: [https://developer.nexmo.com/api/voice#stream-an-audio-file-to-an-active-call](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#stream-an-audio-file-to-an-active-call)
122
141
 
123
142
  ### Stop streaming audio to a call
124
143
 
@@ -126,7 +145,7 @@ Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#stream_put](https://
126
145
  response = client.stop_audio(uuid)
127
146
  ```
128
147
 
129
- Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#stream_delete](https://docs.nexmo.com/voice/voice-api/api-reference#stream_delete?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
148
+ Docs: [https://developer.nexmo.com/api/voice#stop-streaming-an-audio-file-to-an-active-call](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#stop-streaming-an-audio-file-to-an-active-call)
130
149
 
131
150
  ### Send a synthesized speech message to a call
132
151
 
@@ -134,7 +153,7 @@ Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#stream_delete](https
134
153
  response = client.send_speech(uuid, text: 'Hello')
135
154
  ```
136
155
 
137
- Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#talk_put](https://docs.nexmo.com/voice/voice-api/api-reference#talk_put?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
156
+ Docs: [https://developer.nexmo.com/api/voice#send-a-synthesized-speech-message-to-an-active-call](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#send-a-synthesized-speech-message-to-an-active-call)
138
157
 
139
158
  ### Stop sending a synthesized speech message to a call
140
159
 
@@ -142,7 +161,7 @@ Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#talk_put](https://do
142
161
  response = client.stop_speech(uuid)
143
162
  ```
144
163
 
145
- Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#talk_delete](https://docs.nexmo.com/voice/voice-api/api-reference#talk_delete?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
164
+ Docs: [https://developer.nexmo.com/api/voice#stop-sending-a-synthesized-speech-message-to-an-active-call](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#stop-sending-a-synthesized-speech-message-to-an-active-call)
146
165
 
147
166
  ### Send DTMF tones to a call
148
167
 
@@ -150,7 +169,7 @@ Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#talk_delete](https:/
150
169
  response = client.send_dtmf(uuid, digits: '1234')
151
170
  ```
152
171
 
153
- Docs: [https://docs.nexmo.com/voice/voice-api/api-reference#dtmf_put](https://docs.nexmo.com/voice/voice-api/api-reference#dtmf_put?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
172
+ Docs: [https://developer.nexmo.com/api/voice#send-dual-tone-multi-frequency-dtmf-tones-to-an-active-call](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#send-dual-tone-multi-frequency-dtmf-tones-to-an-active-call)
154
173
 
155
174
 
156
175
  ## Verify API
@@ -167,7 +186,7 @@ else
167
186
  end
168
187
  ```
169
188
 
170
- Docs: [https://docs.nexmo.com/verify/api-reference/api-reference#vrequest](https://docs.nexmo.com/verify/api-reference/api-reference#vrequest?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
189
+ Docs: [https://developer.nexmo.com/api/verify#verify-request](https://developer.nexmo.com/api/verify?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#verify-request)
171
190
 
172
191
  The response contains a verification request id which you will need to store temporarily.
173
192
 
@@ -183,7 +202,7 @@ else
183
202
  end
184
203
  ```
185
204
 
186
- Docs: [https://docs.nexmo.com/verify/api-reference/api-reference#check](https://docs.nexmo.com/verify/api-reference/api-reference#check?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
205
+ Docs: [https://developer.nexmo.com/api/verify#verify-check](https://developer.nexmo.com/api/verify?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#verify-check)
187
206
 
188
207
  The verification request id comes from the call to the start_verification method.
189
208
 
@@ -195,7 +214,7 @@ The PIN code is entered into your application by the user.
195
214
  client.cancel_verification('00e6c3377e5348cdaf567e1417c707a5')
196
215
  ```
197
216
 
198
- Docs: [https://docs.nexmo.com/verify/api-reference/api-reference#control](https://docs.nexmo.com/verify/api-reference/api-reference#control?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
217
+ Docs: [https://developer.nexmo.com/api/verify#verify-control](https://developer.nexmo.com/api/verify?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#verify-control)
199
218
 
200
219
  ### Trigger next verification step
201
220
 
@@ -203,7 +222,43 @@ Docs: [https://docs.nexmo.com/verify/api-reference/api-reference#control](https:
203
222
  client.trigger_next_verification_event('00e6c3377e5348cdaf567e1417c707a5')
204
223
  ```
205
224
 
206
- Docs: [https://docs.nexmo.com/verify/api-reference/api-reference#control](https://docs.nexmo.com/verify/api-reference/api-reference#control?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
225
+ Docs: [https://developer.nexmo.com/api/verify#verify-control](https://developer.nexmo.com/api/verify?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#verify-control)
226
+
227
+ ## Number Insight API
228
+
229
+ ### Basic Number Insight
230
+
231
+ ```ruby
232
+ client.get_basic_number_insight(number: '447700900000')
233
+ ```
234
+
235
+ Docs: [https://developer.nexmo.com/api/number-insight#request](https://developer.nexmo.com/api/number-insight?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#request)
236
+
237
+ ### Standard Number Insight
238
+
239
+ ```ruby
240
+ client.get_standard_number_insight(number: '447700900000')
241
+ ```
242
+
243
+ Docs: [https://developer.nexmo.com/api/number-insight#request](https://developer.nexmo.com/api/number-insight?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#request)
244
+
245
+ ### Advanced Number Insight
246
+
247
+ ```ruby
248
+ client.get_advanced_number_insight(number: '447700900000')
249
+ ```
250
+
251
+ Docs: [https://developer.nexmo.com/api/number-insight#request](https://developer.nexmo.com/api/number-insight?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#request)
252
+
253
+ ### Advanced Number Insight Async
254
+
255
+ ```ruby
256
+ client.get_advanced_number_insight(number: '447700900000', callback: webhook_url)
257
+ ```
258
+
259
+ The results of the API call will be sent via HTTP POST to the webhook URL specified in the callback parameter.
260
+
261
+ Docs: [https://developer.nexmo.com/api/number-insight#request](https://developer.nexmo.com/api/number-insight?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#request)
207
262
 
208
263
 
209
264
  ## Application API
@@ -211,10 +266,10 @@ Docs: [https://docs.nexmo.com/verify/api-reference/api-reference#control](https:
211
266
  ### Create an application
212
267
 
213
268
  ```ruby
214
- response = client.create_application(name: 'Example App', type: 'voice', answer_url: answer_url)
269
+ response = client.create_application(name: 'Example App', type: 'voice', answer_url: answer_url, event_url: event_url)
215
270
  ```
216
271
 
217
- Docs: [https://docs.nexmo.com/tools/application-api/api-reference#create](https://docs.nexmo.com/tools/application-api/api-reference#create?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
272
+ Docs: [https://developer.nexmo.com/api/application#create-an-application](https://developer.nexmo.com/api/application?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#create-an-application)
218
273
 
219
274
  ### Retrieve a list of applications
220
275
 
@@ -222,7 +277,7 @@ Docs: [https://docs.nexmo.com/tools/application-api/api-reference#create](https:
222
277
  response = client.get_applications
223
278
  ```
224
279
 
225
- Docs: [https://docs.nexmo.com/tools/application-api/api-reference#list](https://docs.nexmo.com/tools/application-api/api-reference#list?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
280
+ Docs: [https://developer.nexmo.com/api/application#retrieve-your-applications](https://developer.nexmo.com/api/application?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#retrieve-your-applications)
226
281
 
227
282
  ### Retrieve a single application
228
283
 
@@ -230,7 +285,7 @@ Docs: [https://docs.nexmo.com/tools/application-api/api-reference#list](https://
230
285
  response = client.get_application(uuid)
231
286
  ```
232
287
 
233
- Docs: [https://docs.nexmo.com/tools/application-api/api-reference#retrieve](https://docs.nexmo.com/tools/application-api/api-reference#retrieve?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
288
+ Docs: [https://developer.nexmo.com/api/application#retrieve-an-application](https://developer.nexmo.com/api/application?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#retrieve-an-application)
234
289
 
235
290
  ### Update an application
236
291
 
@@ -238,7 +293,7 @@ Docs: [https://docs.nexmo.com/tools/application-api/api-reference#retrieve](http
238
293
  response = client.update_application(uuid, answer_method: 'POST')
239
294
  ```
240
295
 
241
- Docs: [https://docs.nexmo.com/tools/application-api/api-reference#update](https://docs.nexmo.com/tools/application-api/api-reference#update?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
296
+ Docs: [https://developer.nexmo.com/api/application#update-an-application](https://developer.nexmo.com/api/application?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#update-an-application)
242
297
 
243
298
  ### Delete an application
244
299
 
@@ -246,7 +301,50 @@ Docs: [https://docs.nexmo.com/tools/application-api/api-reference#update](https:
246
301
  response = client.delete_application(uuid)
247
302
  ```
248
303
 
249
- Docs: [https://docs.nexmo.com/tools/application-api/api-reference#delete](https://docs.nexmo.com/tools/application-api/api-reference#delete?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
304
+ Docs: [https://developer.nexmo.com/api/application#destroy-an-application](https://developer.nexmo.com/api/application?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#destroy-an-application)
305
+
306
+
307
+ ## Numbers API
308
+
309
+ ### List owned numbers
310
+
311
+ ```ruby
312
+ client.get_account_numbers
313
+ ```
314
+
315
+ Docs: [https://developer.nexmo.com/api/developer/numbers#list-owned-numbers](https://developer.nexmo.com/api/developer/numbers?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#list-owned-numbers)
316
+
317
+ ### Search available numbers
318
+
319
+ ```ruby
320
+ client.get_available_numbers('GB')
321
+ ```
322
+
323
+ Docs: [https://developer.nexmo.com/api/developer/numbers#search-available-numbers](https://developer.nexmo.com/api/developer/numbers?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#search-available-numbers)
324
+
325
+ ### Buy a number
326
+
327
+ ```ruby
328
+ client.buy_number(country: 'GB', msisdn: '447700900000')
329
+ ```
330
+
331
+ Docs: [https://developer.nexmo.com/api/developer/numbers#buy-a-number](https://developer.nexmo.com/api/developer/numbers?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#buy-a-number)
332
+
333
+ ### Cancel a number
334
+
335
+ ```ruby
336
+ client.cancel_number(country: 'GB', msisdn: '447700900000')
337
+ ```
338
+
339
+ Docs: [https://developer.nexmo.com/api/developer/numbers#cancel-a-number](https://developer.nexmo.com/api/developer/numbers?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#cancel-a-number)
340
+
341
+ ### Update a number
342
+
343
+ ```ruby
344
+ client.update_number(country: 'GB', msisdn: '447700900000', voiceCallbackType: 'app', voiceCallbackValue: application_id)
345
+ ```
346
+
347
+ Docs: [https://developer.nexmo.com/api/developer/numbers#update-a-number](https://developer.nexmo.com/api/developer/numbers?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#update-a-number)
250
348
 
251
349
 
252
350
  ## JWT authentication
@@ -285,7 +383,7 @@ else
285
383
  end
286
384
  ```
287
385
 
288
- Docs: [https://docs.nexmo.com/messaging/signing-messages](https://docs.nexmo.com/messaging/signing-messages?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
386
+ Docs: [https://developer.nexmo.com/concepts/guides/signing-messages](https://developer.nexmo.com/concepts/guides/signing-messages?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library)
289
387
 
290
388
  Note: you'll need to contact support@nexmo.com to enable message signing on
291
389
  your account before you can validate webhook signatures.
@@ -255,7 +255,24 @@ module Nexmo
255
255
  api_request(Net::HTTP::Get, "/v1/files/#{id.split('/').last}")
256
256
  end
257
257
 
258
+ def save_file(id, filename)
259
+ api_request(Net::HTTP::Get, "/v1/files/#{id.split('/').last}") do |response|
260
+ File.open(filename, 'wb') do |file|
261
+ response.read_body do |chunk|
262
+ file.write(chunk)
263
+ end
264
+ end
265
+ end
266
+ end
267
+
258
268
  def check_signature(params)
269
+ unless @signature_secret
270
+ raise AuthenticationError.new('No signature_secret provided. ' \
271
+ 'You can find your signature secret in the Nexmo dashboard. ' \
272
+ 'See https://developer.nexmo.com/concepts/guides/signing-messages for details, ' \
273
+ 'or email support@nexmo.com if you have any questions.')
274
+ end
275
+
259
276
  Signature.check(params, @signature_secret)
260
277
  end
261
278
 
@@ -298,7 +315,7 @@ module Nexmo
298
315
  request(uri, message)
299
316
  end
300
317
 
301
- def api_request(message_class, path, params = nil)
318
+ def api_request(message_class, path, params = nil, &block)
302
319
  uri = URI('https://' + @api_host + path)
303
320
 
304
321
  unless message_class::REQUEST_HAS_BODY || params.nil? || params.empty?
@@ -312,11 +329,11 @@ module Nexmo
312
329
  message.body = JSON.generate(params)
313
330
  end
314
331
 
315
- token = auth_token || JWT.auth_token({application_id: @application_id}, @private_key)
332
+ token = auth_token || generate_auth_token
316
333
 
317
334
  message['Authorization'] = "Bearer #{token}"
318
335
 
319
- request(uri, message)
336
+ request(uri, message, &block)
320
337
  end
321
338
 
322
339
  def request(uri, message)
@@ -331,6 +348,8 @@ module Nexmo
331
348
  when Net::HTTPNoContent
332
349
  :no_content
333
350
  when Net::HTTPSuccess
351
+ return (yield http_response) if block_given?
352
+
334
353
  if http_response['Content-Type'].split(';').first == 'application/json'
335
354
  JSON.parse(http_response.body)
336
355
  else
@@ -346,5 +365,25 @@ module Nexmo
346
365
  raise Error, "#{http_response.code} response from #{uri.host}"
347
366
  end
348
367
  end
368
+
369
+ def generate_auth_token
370
+ unless @application_id
371
+ raise AuthenticationError.new('No application_id provided. ' \
372
+ 'Either provide an application_id, or set an auth token. ' \
373
+ 'You can add new applications from the Nexmo dashboard. ' \
374
+ 'See https://developer.nexmo.com/concepts/guides/applications for details, ' \
375
+ 'or email support@nexmo.com if you have any questions.')
376
+ end
377
+
378
+ unless @private_key
379
+ raise AuthenticationError.new('No private_key provided. ' \
380
+ 'Either provide a private_key, or set an auth token. ' \
381
+ 'You can add new applications from the Nexmo dashboard. ' \
382
+ 'See https://developer.nexmo.com/concepts/guides/applications for details, ' \
383
+ 'or email support@nexmo.com if you have any questions.')
384
+ end
385
+
386
+ JWT.auth_token({application_id: @application_id}, @private_key)
387
+ end
349
388
  end
350
389
  end
@@ -6,6 +6,8 @@ module Nexmo
6
6
  params.flat_map { |k, vs| Array(vs).map { |v| "#{escape(k)}=#{escape(v)}" } }.join('&')
7
7
  end
8
8
 
9
+ private
10
+
9
11
  def self.escape(component)
10
12
  CGI.escape(component.to_s)
11
13
  end
@@ -11,6 +11,8 @@ module Nexmo
11
11
  ::JWT.secure_compare(signature, digest(params, secret))
12
12
  end
13
13
 
14
+ private
15
+
14
16
  def self.digest(params, secret)
15
17
  md5 = Digest::MD5.new
16
18
 
@@ -1,3 +1,3 @@
1
1
  module Nexmo
2
- VERSION = '4.6.0'
2
+ VERSION = '4.7.0'
3
3
  end
@@ -25,6 +25,18 @@ describe 'Nexmo::Client' do
25
25
  @client = Nexmo::Client.new(key: @api_key, secret: @api_secret, application_id: @application_id, private_key: @private_key)
26
26
  end
27
27
 
28
+ let(:authorization_header) { {'Authorization' => /\ABearer (.+)\.(.+)\.(.+)\z/} }
29
+
30
+ let(:recording_id) { 'xx-xx-xx-xx' }
31
+
32
+ let(:recording_url) { "#@api_base_url/v1/files/xx-xx-xx-xx" }
33
+
34
+ let(:recording_content) { 'BODY' }
35
+
36
+ let(:recording_response) { {body: recording_content, headers: {'Content-Type' => 'application/octet-stream'}} }
37
+
38
+ let(:recording_filename) { 'test/file.mp3' }
39
+
28
40
  describe 'send_message method' do
29
41
  it 'posts to the sms resource and returns the response object' do
30
42
  expect_post "#@base_url/sms/json", "from=ruby&to=number&text=Hey!&api_key=#@api_key&api_secret=#@api_secret"
@@ -325,7 +337,7 @@ describe 'Nexmo::Client' do
325
337
  end
326
338
  end
327
339
 
328
- describe 'get_standard_insight method' do
340
+ describe 'get_standard_number_insight method' do
329
341
  it 'fetches the number lookup resource and returns the response object' do
330
342
  expect_get "#@api_base_url/ni/standard/json?api_key=#@api_key&api_secret=#@api_secret&number=447525856424"
331
343
 
@@ -476,26 +488,36 @@ describe 'Nexmo::Client' do
476
488
  end
477
489
 
478
490
  describe 'get_file method' do
479
- before do
480
- @url = "#@api_base_url/v1/files/xx-xx-xx-xx"
491
+ it 'fetches the file resource with the given id and returns the response body' do
492
+ @request = stub_request(:get, recording_url).with(headers: authorization_header).to_return(recording_response)
481
493
 
482
- @request_headers = {'Authorization' => /\ABearer (.+)\.(.+)\.(.+)\z/}
494
+ @client.get_file(recording_id).must_equal(recording_content)
495
+ end
483
496
 
484
- @response_body = 'BODY'
497
+ it 'fetches the file resource with the given url and returns the response body' do
498
+ @request = stub_request(:get, recording_url).with(headers: authorization_header).to_return(recording_response)
485
499
 
486
- @response = {body: @response_body, headers: {'Content-Type' => 'application/octet-stream'}}
500
+ @client.get_file(recording_url).must_equal(recording_content)
487
501
  end
502
+ end
488
503
 
489
- it 'fetches the file resource with the given id and returns the response body' do
490
- @request = stub_request(:get, @url).with(headers: @request_headers).to_return(@response)
504
+ describe 'save_file method' do
505
+ after { File.unlink(recording_filename) if File.exist?(recording_filename) }
491
506
 
492
- @client.get_file('xx-xx-xx-xx').must_equal(@response_body)
507
+ it 'fetches the file resource with the given id and streams the response body to the given filename' do
508
+ @request = stub_request(:get, recording_url).with(headers: authorization_header).to_return(recording_response)
509
+
510
+ @client.save_file(recording_id, recording_filename)
511
+
512
+ File.read(recording_filename).must_equal(recording_content)
493
513
  end
494
514
 
495
- it 'fetches the file resource with the given url and returns the response body' do
496
- @request = stub_request(:get, @url).with(headers: @request_headers).to_return(@response)
515
+ it 'fetches the file resource with the given url and streams the response body to the given filename' do
516
+ @request = stub_request(:get, recording_url).with(headers: authorization_header).to_return(recording_response)
497
517
 
498
- @client.get_file(@url).must_equal(@response_body)
518
+ @client.save_file(recording_url, recording_filename)
519
+
520
+ File.read(recording_filename).must_equal(recording_content)
499
521
  end
500
522
  end
501
523
 
@@ -507,6 +529,30 @@ describe 'Nexmo::Client' do
507
529
 
508
530
  client.check_signature(params).must_equal(true)
509
531
  end
532
+
533
+ it 'raises an authentication error exception if the signature secret was not provided' do
534
+ client = Nexmo::Client.new(key: @api_key, secret: @api_secret)
535
+
536
+ exception = proc { @client.check_signature({}) }.must_raise(Nexmo::AuthenticationError)
537
+
538
+ exception.message.must_include('No signature_secret provided.')
539
+ end
540
+ end
541
+
542
+ it 'raises an authentication error exception if the application id was not provided' do
543
+ @client = Nexmo::Client.new(key: @api_key, secret: @api_secret, private_key: @private_key)
544
+
545
+ exception = proc { @client.get_calls }.must_raise(Nexmo::AuthenticationError)
546
+
547
+ exception.message.must_include('No application_id provided.')
548
+ end
549
+
550
+ it 'raises an authentication error exception if the private key was not provided' do
551
+ @client = Nexmo::Client.new(key: @api_key, secret: @api_secret, application_id: @application_id)
552
+
553
+ exception = proc { @client.get_calls }.must_raise(Nexmo::AuthenticationError)
554
+
555
+ exception.message.must_include('No private_key provided.')
510
556
  end
511
557
 
512
558
  it 'raises an authentication error exception if the response code is 401' do
@@ -0,0 +1,18 @@
1
+ require 'minitest/autorun'
2
+ require 'nexmo'
3
+
4
+ describe 'Nexmo::Params' do
5
+ describe 'encode method' do
6
+ it 'returns a url encoded string containing the given params' do
7
+ params = {'name' => 'Example App', 'type' => 'voice'}
8
+
9
+ Nexmo::Params.encode(params).must_equal('name=Example+App&type=voice')
10
+ end
11
+
12
+ it 'flattens array values into multiple key value pairs' do
13
+ params = {'ids' => %w[00A0B0C0 00A0B0C1 00A0B0C2]}
14
+
15
+ Nexmo::Params.encode(params).must_equal('ids=00A0B0C0&ids=00A0B0C1&ids=00A0B0C2')
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ require 'minitest/autorun'
2
+ require 'nexmo'
3
+
4
+ describe 'Nexmo::Signature' do
5
+ let(:secret) { 'secret' }
6
+
7
+ describe 'check method' do
8
+ it 'returns true if the given params has the correct sig value' do
9
+ params = {'a' => '1', 'b' => '2', 'timestamp' => '1461605396', 'sig' => '6af838ef94998832dbfc29020b564830'}
10
+
11
+ Nexmo::Signature.check(params, secret).must_equal(true)
12
+ end
13
+
14
+ it 'returns false otherwise' do
15
+ params = {'a' => '1', 'b' => '2', 'timestamp' => '1461605396', 'sig' => 'xxx'}
16
+
17
+ Nexmo::Signature.check(params, secret).must_equal(false)
18
+ end
19
+ end
20
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexmo
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.6.0
4
+ version: 4.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Craft
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-07 00:00:00.000000000 Z
11
+ date: 2017-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jwt
@@ -88,6 +88,8 @@ files:
88
88
  - nexmo.gemspec
89
89
  - spec/nexmo/client_spec.rb
90
90
  - spec/nexmo/jwt_spec.rb
91
+ - spec/nexmo/params_spec.rb
92
+ - spec/nexmo/signature_spec.rb
91
93
  homepage: https://github.com/Nexmo/nexmo-ruby
92
94
  licenses:
93
95
  - MIT
@@ -108,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
110
  version: '0'
109
111
  requirements: []
110
112
  rubyforge_project:
111
- rubygems_version: 2.5.2
113
+ rubygems_version: 2.6.11
112
114
  signing_key:
113
115
  specification_version: 4
114
116
  summary: This is the Ruby client library for Nexmo's API. To use it you'll need a