nexmo 4.6.0 → 4.7.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
  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