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 +4 -4
- data/README.md +125 -27
- data/lib/nexmo/client.rb +42 -3
- data/lib/nexmo/params.rb +2 -0
- data/lib/nexmo/signature.rb +2 -0
- data/lib/nexmo/version.rb +1 -1
- data/spec/nexmo/client_spec.rb +58 -12
- data/spec/nexmo/params_spec.rb +18 -0
- data/spec/nexmo/signature_spec.rb +20 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8c6620dc24f8cb8e4260f28df8d33775a796624
|
4
|
+
data.tar.gz: f19674fb59e52953d0c690edba86fccc2e29a793
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
47
|
-
|
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
|
-
|
54
|
-
|
55
|
-
environment
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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://
|
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.
|
data/lib/nexmo/client.rb
CHANGED
@@ -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 ||
|
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
|
data/lib/nexmo/params.rb
CHANGED
data/lib/nexmo/signature.rb
CHANGED
data/lib/nexmo/version.rb
CHANGED
data/spec/nexmo/client_spec.rb
CHANGED
@@ -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 '
|
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
|
-
|
480
|
-
@
|
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
|
-
@
|
494
|
+
@client.get_file(recording_id).must_equal(recording_content)
|
495
|
+
end
|
483
496
|
|
484
|
-
|
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
|
-
@
|
500
|
+
@client.get_file(recording_url).must_equal(recording_content)
|
487
501
|
end
|
502
|
+
end
|
488
503
|
|
489
|
-
|
490
|
-
|
504
|
+
describe 'save_file method' do
|
505
|
+
after { File.unlink(recording_filename) if File.exist?(recording_filename) }
|
491
506
|
|
492
|
-
|
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
|
496
|
-
@request = stub_request(:get,
|
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.
|
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.
|
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-
|
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.
|
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
|