nexmo 1.0.0 → 1.1.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.
- data/README.md +71 -14
- data/lib/nexmo.rb +23 -15
- data/nexmo.gemspec +4 -3
- data/spec/nexmo_spec.rb +81 -41
- metadata +21 -6
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
A
|
2
|
-
|
1
|
+
A Ruby wrapper for the [Nexmo](http://nexmo.com/) API
|
2
|
+
=====================================================
|
3
3
|
|
4
4
|
|
5
5
|
Installation
|
@@ -8,32 +8,89 @@ Installation
|
|
8
8
|
$ gem install nexmo
|
9
9
|
|
10
10
|
|
11
|
-
Quick
|
12
|
-
|
11
|
+
Quick start (sending a message)
|
12
|
+
-------------------------------
|
13
13
|
|
14
|
-
|
14
|
+
First you need to load up the gem and construct a Nexmo::Client object
|
15
|
+
with your API credentials, like this:
|
15
16
|
|
16
17
|
```ruby
|
17
18
|
require 'nexmo'
|
18
19
|
|
19
20
|
nexmo = Nexmo::Client.new('...API KEY...', '...API SECRET...')
|
21
|
+
```
|
22
|
+
|
23
|
+
Then you have a choice. For a "fire and forget" approach to sending a message,
|
24
|
+
use the `send_message!` method, like this:
|
20
25
|
|
26
|
+
```ruby
|
21
27
|
nexmo.send_message!({:to => '...NUMBER...', :from => 'Ruby', :text => 'Hello world'})
|
22
28
|
```
|
23
29
|
|
24
30
|
This method call returns the message id if the message was sent successfully,
|
25
|
-
or raises an exception if there was an error.
|
26
|
-
use the `send_message` method instead
|
27
|
-
|
31
|
+
or raises an exception if there was an error. If you need more robust error
|
32
|
+
handling use the `send_message` method instead, like this:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
response = nexmo.send_message({:to => '...NUMBER...', :from => 'Ruby', :text => 'Hello world'})
|
36
|
+
|
37
|
+
if response.ok?
|
38
|
+
# do something with response.object
|
39
|
+
else
|
40
|
+
# handle the error
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
This method call returns a `Nexmo::Response` object, which wraps the underlying
|
45
|
+
Net::HTTP response and adds a few convenience methods. Additional methods are
|
46
|
+
also provided for managing your account and messages.
|
47
|
+
|
48
|
+
|
49
|
+
Authenticating with OAuth (beta)
|
50
|
+
--------------------------------
|
51
|
+
|
52
|
+
If you are building an app that needs access to Nexmo resources on behalf of
|
53
|
+
other accounts then you will want to use OAuth to authenticate your requests.
|
54
|
+
Authorizing access and fetching access tokens can be achieved using the
|
55
|
+
[oauth gem](http://rubygems.org/gems/oauth) directly. You can then use an
|
56
|
+
OAuth::AccessToken object together with a Nexmo::Client object to make calls
|
57
|
+
to the API that are authenticated using OAuth. For example:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
require 'nexmo'
|
61
|
+
require 'oauth'
|
62
|
+
|
63
|
+
nexmo = Nexmo::Client.new
|
64
|
+
nexmo.oauth_access_token = OAuth::AccessToken.new(consumer, token, secret)
|
65
|
+
|
66
|
+
response = nexmo.get_balance
|
67
|
+
|
68
|
+
if response.ok?
|
69
|
+
# do something with response.object
|
70
|
+
else
|
71
|
+
# handle the error
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
The OAuth::Consumer object should be pointed at `rest.nexmo.com` with the `:scheme` option set to `:header`, like this:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
OAuth::Consumer.new(consumer_key, consumer_secret, {
|
79
|
+
:site => 'https://rest.nexmo.com',
|
80
|
+
:scheme => :header
|
81
|
+
})
|
82
|
+
```
|
83
|
+
|
84
|
+
Using the `:body` or `:query_string` authorization mechanisms is not supported.
|
28
85
|
|
29
86
|
|
30
|
-
JSON
|
31
|
-
|
87
|
+
Switching JSON implementations
|
88
|
+
------------------------------
|
32
89
|
|
33
|
-
|
34
|
-
standard library, and as a gem for Ruby 1.8.
|
35
|
-
implementation that you wish to use explicitly when
|
36
|
-
object. For example, to use [multi_json](https://rubygems.org/gems/multi_json):
|
90
|
+
By default the "json" library is used to encode request bodies and decode response
|
91
|
+
bodies. This is available in the Ruby 1.9 standard library, and as a gem for Ruby 1.8.
|
92
|
+
You can specify an alternate implementation that you wish to use explicitly when
|
93
|
+
constructing a client object. For example, to use [multi_json](https://rubygems.org/gems/multi_json):
|
37
94
|
|
38
95
|
```ruby
|
39
96
|
require 'nexmo'
|
data/lib/nexmo.rb
CHANGED
@@ -5,7 +5,7 @@ require 'cgi'
|
|
5
5
|
|
6
6
|
module Nexmo
|
7
7
|
class Client
|
8
|
-
def initialize(key, secret, options = {})
|
8
|
+
def initialize(key = ENV['NEXMO_API_KEY'], secret = ENV['NEXMO_API_SECRET'], options = {})
|
9
9
|
@key, @secret = key, secret
|
10
10
|
|
11
11
|
@json = options.fetch(:json) { JSON }
|
@@ -15,7 +15,7 @@ module Nexmo
|
|
15
15
|
@http.use_ssl = true
|
16
16
|
end
|
17
17
|
|
18
|
-
attr_accessor :key, :secret, :http
|
18
|
+
attr_accessor :key, :secret, :http, :oauth_access_token
|
19
19
|
|
20
20
|
def send_message(params)
|
21
21
|
post('/sms/json', params)
|
@@ -40,49 +40,57 @@ module Nexmo
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def get_balance
|
43
|
-
get(
|
43
|
+
get('/account/get-balance')
|
44
44
|
end
|
45
45
|
|
46
46
|
def get_country_pricing(country_code)
|
47
|
-
get(
|
47
|
+
get('/account/get-pricing/outbound', {:country => country_code})
|
48
48
|
end
|
49
49
|
|
50
50
|
def get_prefix_pricing(prefix)
|
51
|
-
get(
|
51
|
+
get('/account/get-prefix-pricing/outbound', {:prefix => prefix})
|
52
52
|
end
|
53
53
|
|
54
54
|
def get_account_numbers(params)
|
55
|
-
get(
|
55
|
+
get('/account/numbers', params)
|
56
56
|
end
|
57
57
|
|
58
58
|
def number_search(country_code, params = {})
|
59
|
-
get(
|
59
|
+
get('/number/search', {:country => country_code}.merge(params))
|
60
60
|
end
|
61
61
|
|
62
62
|
def get_message(id)
|
63
|
-
get(
|
63
|
+
get('/search/message', {:id => id})
|
64
64
|
end
|
65
65
|
|
66
66
|
def get_message_rejections(params)
|
67
|
-
get(
|
67
|
+
get('/search/rejections', params)
|
68
68
|
end
|
69
69
|
|
70
70
|
def search_messages(params)
|
71
|
-
get(
|
71
|
+
get('/search/messages', Hash === params ? params : {:ids => Array(params)})
|
72
72
|
end
|
73
73
|
|
74
74
|
private
|
75
75
|
|
76
76
|
def get(path, params = {})
|
77
|
-
|
77
|
+
http_response = if oauth_access_token
|
78
|
+
oauth_access_token.get(request_uri(path, params))
|
79
|
+
else
|
80
|
+
@http.get(request_uri(path, params.merge(:api_key => @key, :api_secret => @secret)))
|
81
|
+
end
|
82
|
+
|
83
|
+
Response.new(http_response, :json => @json)
|
78
84
|
end
|
79
85
|
|
80
86
|
def post(path, params)
|
81
|
-
|
82
|
-
|
87
|
+
http_response = if oauth_access_token
|
88
|
+
oauth_access_token.post(path, @json.dump(params), {'Content-Type' => 'application/json'})
|
89
|
+
else
|
90
|
+
@http.post(path, @json.dump(params.merge(:api_key => @key, :api_secret => @secret)), {'Content-Type' => 'application/json'})
|
91
|
+
end
|
83
92
|
|
84
|
-
|
85
|
-
JSON.dump(params.merge(:username => @key, :password => @secret))
|
93
|
+
Response.new(http_response, :json => @json)
|
86
94
|
end
|
87
95
|
|
88
96
|
def request_uri(path, hash = {})
|
data/nexmo.gemspec
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'nexmo'
|
3
|
-
s.version = '1.
|
3
|
+
s.version = '1.1.0'
|
4
4
|
s.platform = Gem::Platform::RUBY
|
5
5
|
s.authors = ['Tim Craft']
|
6
6
|
s.email = ['mail@timcraft.com']
|
7
7
|
s.homepage = 'http://github.com/timcraft/nexmo'
|
8
|
-
s.description = 'A
|
8
|
+
s.description = 'A Ruby wrapper for the Nexmo API'
|
9
9
|
s.summary = 'See description'
|
10
10
|
s.files = Dir.glob('{lib,spec}/**/*') + %w(README.md nexmo.gemspec)
|
11
11
|
s.add_development_dependency('rake', '>= 0.9.3')
|
12
|
-
s.add_development_dependency('mocha', '~> 0.
|
12
|
+
s.add_development_dependency('mocha', '~> 0.13.2')
|
13
13
|
s.add_development_dependency('multi_json', '~> 1.3.6')
|
14
|
+
s.add_development_dependency('oauth', '~> 0.4.7')
|
14
15
|
s.require_path = 'lib'
|
15
16
|
|
16
17
|
if RUBY_VERSION == '1.8.7'
|
data/spec/nexmo_spec.rb
CHANGED
@@ -1,53 +1,51 @@
|
|
1
1
|
require 'minitest/autorun'
|
2
|
-
require 'mocha'
|
2
|
+
require 'mocha/setup'
|
3
3
|
require 'multi_json'
|
4
4
|
require 'nexmo'
|
5
|
+
require 'oauth'
|
5
6
|
|
6
7
|
describe 'Nexmo::Client' do
|
7
8
|
before do
|
9
|
+
@json_encoded_body = regexp_matches(/\{".+?":".+?"(,".+?":".+?")+\}/)
|
10
|
+
|
11
|
+
@http_header_hash = has_entry('Content-Type', 'application/json')
|
12
|
+
|
13
|
+
@example_message_hash = {:from => 'ruby', :to => 'number', :text => 'Hey!'}
|
14
|
+
|
8
15
|
@client = Nexmo::Client.new('key', 'secret')
|
9
16
|
end
|
10
17
|
|
18
|
+
def expects_http_get(request_uri)
|
19
|
+
@client.http.expects(:get).with(has_equivalent_query_string(request_uri)).returns(stub)
|
20
|
+
end
|
21
|
+
|
11
22
|
describe 'http method' do
|
12
23
|
it 'returns a net http object that uses ssl' do
|
13
24
|
@client.http.must_be_instance_of(Net::HTTP)
|
25
|
+
|
14
26
|
@client.http.use_ssl?.must_equal(true)
|
15
27
|
end
|
16
28
|
end
|
17
29
|
|
18
30
|
describe 'send_message method' do
|
19
31
|
it 'posts to the sms json resource and returns a response object' do
|
20
|
-
|
32
|
+
@client.http.expects(:post).with('/sms/json', @json_encoded_body, @http_header_hash).returns(stub)
|
21
33
|
|
22
|
-
|
23
|
-
|
24
|
-
params = {:from => 'ruby', :to => 'number', :text => 'Hey!'}
|
25
|
-
|
26
|
-
@client.http.expects(:post).with('/sms/json', data, headers).returns(stub)
|
27
|
-
|
28
|
-
@client.send_message(params).must_be_instance_of(Nexmo::Response)
|
34
|
+
@client.send_message(@example_message_hash).must_be_instance_of(Nexmo::Response)
|
29
35
|
end
|
30
36
|
end
|
31
37
|
|
32
38
|
describe 'send_message bang method' do
|
33
39
|
before do
|
34
|
-
@
|
35
|
-
|
36
|
-
@http_response = mock()
|
37
|
-
@http_response.stubs(:[]).with('Content-Type').returns('application/json;charset=utf-8')
|
38
|
-
@http_response.stubs(:code).returns('200')
|
40
|
+
@http_response = stub(:code => '200', :[] => 'application/json;charset=utf-8')
|
39
41
|
end
|
40
42
|
|
41
43
|
it 'posts to the sms json resource and returns the message id' do
|
42
|
-
data = regexp_matches(/\{".+?":".+?"(,".+?":".+?")+\}/)
|
43
|
-
|
44
|
-
headers = has_entry('Content-Type', 'application/json')
|
45
|
-
|
46
44
|
@http_response.stubs(:body).returns('{"messages":[{"status":0,"message-id":"id"}]}')
|
47
45
|
|
48
|
-
@client.http.expects(:post).with('/sms/json',
|
46
|
+
@client.http.expects(:post).with('/sms/json', @json_encoded_body, @http_header_hash).returns(@http_response)
|
49
47
|
|
50
|
-
@client.send_message!(@
|
48
|
+
@client.send_message!(@example_message_hash).must_equal('id')
|
51
49
|
end
|
52
50
|
|
53
51
|
it 'raises an exception if the response code is not expected' do
|
@@ -55,7 +53,7 @@ describe 'Nexmo::Client' do
|
|
55
53
|
|
56
54
|
@client.http.stubs(:post).returns(@http_response)
|
57
55
|
|
58
|
-
proc { @client.send_message!(@
|
56
|
+
proc { @client.send_message!(@example_message_hash) }.must_raise(Nexmo::Error)
|
59
57
|
end
|
60
58
|
|
61
59
|
it 'raises an exception if the response body contains an error' do
|
@@ -63,13 +61,13 @@ describe 'Nexmo::Client' do
|
|
63
61
|
|
64
62
|
@client.http.stubs(:post).returns(@http_response)
|
65
63
|
|
66
|
-
proc { @client.send_message!(@
|
64
|
+
proc { @client.send_message!(@example_message_hash) }.must_raise(Nexmo::Error)
|
67
65
|
end
|
68
66
|
end
|
69
67
|
|
70
68
|
describe 'get_balance method' do
|
71
69
|
it 'fetches the account balance resource and returns a response object' do
|
72
|
-
|
70
|
+
expects_http_get '/account/get-balance?api_key=key&api_secret=secret'
|
73
71
|
|
74
72
|
@client.get_balance.must_be_instance_of(Nexmo::Response)
|
75
73
|
end
|
@@ -77,7 +75,7 @@ describe 'Nexmo::Client' do
|
|
77
75
|
|
78
76
|
describe 'get_country_pricing method' do
|
79
77
|
it 'fetches the outbound pricing resource for the given country and returns a response object' do
|
80
|
-
|
78
|
+
expects_http_get '/account/get-pricing/outbound?api_key=key&api_secret=secret&country=CA'
|
81
79
|
|
82
80
|
@client.get_country_pricing(:CA).must_be_instance_of(Nexmo::Response)
|
83
81
|
end
|
@@ -85,7 +83,7 @@ describe 'Nexmo::Client' do
|
|
85
83
|
|
86
84
|
describe 'get_prefix_pricing method' do
|
87
85
|
it 'fetches the outbound pricing resource for the given prefix and returns a response object' do
|
88
|
-
|
86
|
+
expects_http_get '/account/get-prefix-pricing/outbound?api_key=key&api_secret=secret&prefix=44'
|
89
87
|
|
90
88
|
@client.get_prefix_pricing(44).must_be_instance_of(Nexmo::Response)
|
91
89
|
end
|
@@ -93,7 +91,7 @@ describe 'Nexmo::Client' do
|
|
93
91
|
|
94
92
|
describe 'get_account_numbers method' do
|
95
93
|
it 'fetches the account numbers resource with the given parameters and returns a response object' do
|
96
|
-
|
94
|
+
expects_http_get '/account/numbers?api_key=key&api_secret=secret&size=25&pattern=33'
|
97
95
|
|
98
96
|
@client.get_account_numbers(:size => 25, :pattern => 33).must_be_instance_of(Nexmo::Response)
|
99
97
|
end
|
@@ -101,7 +99,7 @@ describe 'Nexmo::Client' do
|
|
101
99
|
|
102
100
|
describe 'number_search method' do
|
103
101
|
it 'fetches the number search resource for the given country with the given parameters and returns a response object' do
|
104
|
-
|
102
|
+
expects_http_get '/number/search?api_key=key&api_secret=secret&country=CA&size=25'
|
105
103
|
|
106
104
|
@client.number_search(:CA, :size => 25).must_be_instance_of(Nexmo::Response)
|
107
105
|
end
|
@@ -109,7 +107,7 @@ describe 'Nexmo::Client' do
|
|
109
107
|
|
110
108
|
describe 'get_message method' do
|
111
109
|
it 'fetches the message search resource for the given message id and returns a response object' do
|
112
|
-
|
110
|
+
expects_http_get '/search/message?api_key=key&api_secret=secret&id=00A0B0C0'
|
113
111
|
|
114
112
|
@client.get_message('00A0B0C0').must_be_instance_of(Nexmo::Response)
|
115
113
|
end
|
@@ -117,7 +115,7 @@ describe 'Nexmo::Client' do
|
|
117
115
|
|
118
116
|
describe 'get_message_rejections method' do
|
119
117
|
it 'fetches the message rejections resource with the given parameters and returns a response object' do
|
120
|
-
|
118
|
+
expects_http_get '/search/rejections?api_key=key&api_secret=secret&date=YYYY-MM-DD'
|
121
119
|
|
122
120
|
@client.get_message_rejections(:date => 'YYYY-MM-DD').must_be_instance_of(Nexmo::Response)
|
123
121
|
end
|
@@ -125,17 +123,59 @@ describe 'Nexmo::Client' do
|
|
125
123
|
|
126
124
|
describe 'search_messages method' do
|
127
125
|
it 'fetches the search messages resource with the given parameters and returns a response object' do
|
128
|
-
|
126
|
+
expects_http_get '/search/messages?api_key=key&api_secret=secret&date=YYYY-MM-DD&to=1234567890'
|
129
127
|
|
130
128
|
@client.search_messages(:date => 'YYYY-MM-DD', :to => 1234567890).must_be_instance_of(Nexmo::Response)
|
131
129
|
end
|
132
130
|
|
133
131
|
it 'should encode a non hash argument as a list of ids' do
|
134
|
-
|
132
|
+
expects_http_get '/search/messages?api_key=key&api_secret=secret&ids=id1&ids=id2'
|
135
133
|
|
136
134
|
@client.search_messages(%w(id1 id2))
|
137
135
|
end
|
138
136
|
end
|
137
|
+
|
138
|
+
describe 'when initialized with an oauth access token' do
|
139
|
+
before do
|
140
|
+
@oauth_consumer = OAuth::Consumer.new('key', 'secret', {:site => 'https://rest.nexmo.com', :scheme => :header})
|
141
|
+
|
142
|
+
@oauth_access_token = OAuth::AccessToken.new(@oauth_consumer, 'access_token', 'access_token_secret')
|
143
|
+
|
144
|
+
@client = Nexmo::Client.new
|
145
|
+
|
146
|
+
@client.oauth_access_token = @oauth_access_token
|
147
|
+
|
148
|
+
@client.http = mock()
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'makes get requests through the access token and returns a response object' do
|
152
|
+
@oauth_access_token.expects(:get).with('/account/get-pricing/outbound?country=CA').returns(stub)
|
153
|
+
|
154
|
+
@client.get_country_pricing(:CA).must_be_instance_of(Nexmo::Response)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'makes post requests through the access token and returns a response object' do
|
158
|
+
@oauth_access_token.expects(:post).with('/sms/json', @json_encoded_body, @http_header_hash).returns(stub)
|
159
|
+
|
160
|
+
@client.send_message(@example_message_hash).must_be_instance_of(Nexmo::Response)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe 'when initialized with a different json implementation' do
|
165
|
+
before do
|
166
|
+
@client = Nexmo::Client.new('key', 'secret', :json => MultiJson)
|
167
|
+
end
|
168
|
+
|
169
|
+
describe 'send_message method' do
|
170
|
+
it 'encodes the request body using the alternative json implementation' do
|
171
|
+
MultiJson.expects(:dump).with(instance_of(Hash))
|
172
|
+
|
173
|
+
@client.http.stubs(:post)
|
174
|
+
|
175
|
+
@client.send_message(@example_message_hash)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
139
179
|
end
|
140
180
|
|
141
181
|
describe 'Nexmo::Response' do
|
@@ -187,20 +227,20 @@ describe 'Nexmo::Response' do
|
|
187
227
|
@response.object.must_equal({'value' => 0})
|
188
228
|
end
|
189
229
|
end
|
190
|
-
end
|
191
230
|
|
192
|
-
describe '
|
193
|
-
|
194
|
-
|
231
|
+
describe 'when initialized with a different json implementation' do
|
232
|
+
before do
|
233
|
+
@response = Nexmo::Response.new(@http_response, :json => MultiJson)
|
234
|
+
end
|
195
235
|
|
196
|
-
|
197
|
-
|
236
|
+
describe 'object method' do
|
237
|
+
it 'decodes the response body using the alternative json implementation' do
|
238
|
+
MultiJson.expects(:load).with('{"value":0.0}')
|
198
239
|
|
199
|
-
|
200
|
-
it 'decodes the response body as json and returns a hash' do
|
201
|
-
@http_response.expects(:body).returns('{"value":0.0}')
|
240
|
+
@http_response.stubs(:body).returns('{"value":0.0}')
|
202
241
|
|
203
|
-
|
242
|
+
@response.object
|
243
|
+
end
|
204
244
|
end
|
205
245
|
end
|
206
246
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nexmo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-02-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 0.
|
37
|
+
version: 0.13.2
|
38
38
|
type: :development
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 0.
|
45
|
+
version: 0.13.2
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: multi_json
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,7 +59,23 @@ dependencies:
|
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 1.3.6
|
62
|
-
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: oauth
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.4.7
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.4.7
|
78
|
+
description: A Ruby wrapper for the Nexmo API
|
63
79
|
email:
|
64
80
|
- mail@timcraft.com
|
65
81
|
executables: []
|
@@ -95,4 +111,3 @@ signing_key:
|
|
95
111
|
specification_version: 3
|
96
112
|
summary: See description
|
97
113
|
test_files: []
|
98
|
-
has_rdoc:
|