nexmo 0.4.0 → 0.5.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 +1 -1
- data/lib/nexmo.rb +43 -37
- data/nexmo.gemspec +3 -3
- data/spec/nexmo_spec.rb +27 -32
- metadata +11 -11
data/README.md
CHANGED
@@ -41,7 +41,7 @@ Troubleshooting
|
|
41
41
|
|
42
42
|
Phone numbers should be specified in international format.
|
43
43
|
|
44
|
-
The Nexmo documentation contains a [list of error codes](http://nexmo.com/documentation/index.html#
|
44
|
+
The Nexmo documentation contains a [list of error codes](http://nexmo.com/documentation/index.html#response_code)
|
45
45
|
which may be useful if you have problems sending a message.
|
46
46
|
|
47
47
|
|
data/lib/nexmo.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
require 'net/http'
|
2
|
-
require 'net/https'
|
3
2
|
require 'json'
|
4
3
|
require 'uri'
|
4
|
+
require 'cgi'
|
5
5
|
|
6
6
|
module Nexmo
|
7
7
|
class Client
|
8
|
-
def initialize(key, secret)
|
8
|
+
def initialize(key, secret, options = {})
|
9
9
|
@key, @secret = key, secret
|
10
10
|
|
11
|
+
@json = options.fetch(:json) { JSON }
|
12
|
+
|
11
13
|
@headers = {'Content-Type' => 'application/x-www-form-urlencoded'}
|
12
14
|
|
13
15
|
@http = Net::HTTP.new('rest.nexmo.com', 443)
|
@@ -20,22 +22,22 @@ module Nexmo
|
|
20
22
|
def send_message(data)
|
21
23
|
response = @http.post('/sms/json', encode(data), headers)
|
22
24
|
|
23
|
-
if
|
24
|
-
object =
|
25
|
+
if response.code.to_i == 200 && response['Content-Type'].split(?;).first == 'application/json'
|
26
|
+
object = @json.load(response.body)['messages'].first
|
25
27
|
|
26
28
|
status = object['status'].to_i
|
27
29
|
|
28
30
|
if status == 0
|
29
|
-
|
31
|
+
Success.new(object['message-id'])
|
30
32
|
else
|
31
33
|
error = Error.new("#{object['error-text']} (status=#{status})")
|
32
34
|
|
33
|
-
|
35
|
+
Failure.new(error, response, status)
|
34
36
|
end
|
35
37
|
else
|
36
38
|
error = Error.new("Unexpected HTTP response (code=#{response.code})")
|
37
39
|
|
38
|
-
|
40
|
+
Failure.new(error, response)
|
39
41
|
end
|
40
42
|
end
|
41
43
|
|
@@ -67,28 +69,42 @@ module Nexmo
|
|
67
69
|
get("/search/rejections/#{key}/#{secret}", params)
|
68
70
|
end
|
69
71
|
|
72
|
+
def search_messages(params)
|
73
|
+
get("/search/messages/#{key}/#{secret}", Hash === params ? params : {ids: Array(params)})
|
74
|
+
end
|
75
|
+
|
70
76
|
private
|
71
77
|
|
72
78
|
def get(path, params = {})
|
73
|
-
Response.new(@http.get(
|
79
|
+
Response.new(@http.get(request_uri(path, params)), json: @json)
|
74
80
|
end
|
75
81
|
|
76
|
-
def
|
77
|
-
|
82
|
+
def encode(data)
|
83
|
+
URI.encode_www_form data.merge(:username => @key, :password => @secret)
|
78
84
|
end
|
79
85
|
|
80
|
-
def
|
81
|
-
|
86
|
+
def request_uri(path, hash = {})
|
87
|
+
if hash.empty?
|
88
|
+
path
|
89
|
+
else
|
90
|
+
query_params = hash.map do |key, values|
|
91
|
+
Array(values).map { |value| "#{escape(key)}=#{escape(value)}" }
|
92
|
+
end
|
93
|
+
|
94
|
+
path + '?' + query_params.flatten.join(?&)
|
95
|
+
end
|
82
96
|
end
|
83
97
|
|
84
|
-
def
|
85
|
-
|
98
|
+
def escape(component)
|
99
|
+
CGI.escape(component.to_s)
|
86
100
|
end
|
87
101
|
end
|
88
102
|
|
89
103
|
class Response
|
90
|
-
def initialize(http_response)
|
104
|
+
def initialize(http_response, options = {})
|
91
105
|
@http_response = http_response
|
106
|
+
|
107
|
+
@json = options.fetch(:json) { JSON }
|
92
108
|
end
|
93
109
|
|
94
110
|
def method_missing(name, *args, &block)
|
@@ -104,37 +120,27 @@ module Nexmo
|
|
104
120
|
end
|
105
121
|
|
106
122
|
def object
|
107
|
-
|
123
|
+
@object ||= @json.load(body)
|
108
124
|
end
|
109
125
|
end
|
110
126
|
|
111
|
-
class
|
112
|
-
def
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
|
-
def [](name)
|
117
|
-
@attributes[name]
|
118
|
-
end
|
119
|
-
|
120
|
-
def []=(name, value)
|
121
|
-
@attributes[name.to_s.tr(?-, ?_).to_sym] = value
|
127
|
+
class Success < Struct.new(:message_id)
|
128
|
+
def success?
|
129
|
+
true
|
122
130
|
end
|
123
131
|
|
124
|
-
def
|
125
|
-
|
132
|
+
def failure?
|
133
|
+
false
|
126
134
|
end
|
135
|
+
end
|
127
136
|
|
128
|
-
|
129
|
-
|
137
|
+
class Failure < Struct.new(:error, :http, :status)
|
138
|
+
def success?
|
139
|
+
false
|
130
140
|
end
|
131
141
|
|
132
|
-
def
|
133
|
-
|
134
|
-
@attributes[name]
|
135
|
-
else
|
136
|
-
super name, *args, &block
|
137
|
-
end
|
142
|
+
def failure?
|
143
|
+
true
|
138
144
|
end
|
139
145
|
end
|
140
146
|
|
data/nexmo.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'nexmo'
|
3
|
-
s.version = '0.
|
3
|
+
s.version = '0.5.0'
|
4
4
|
s.platform = Gem::Platform::RUBY
|
5
5
|
s.authors = ['Tim Craft']
|
6
6
|
s.email = ['mail@timcraft.com']
|
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.description = 'A simple 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
|
-
s.
|
12
|
-
s.add_development_dependency('
|
11
|
+
s.add_development_dependency('mocha', '~> 0.9.12')
|
12
|
+
s.add_development_dependency('oj', '~> 1.3.7')
|
13
13
|
s.require_path = 'lib'
|
14
14
|
end
|
data/spec/nexmo_spec.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'minitest/autorun'
|
2
2
|
require 'mocha'
|
3
|
+
require 'oj'
|
3
4
|
|
4
5
|
require_relative '../lib/nexmo'
|
5
6
|
|
6
|
-
describe Nexmo::Client do
|
7
|
+
describe 'Nexmo::Client' do
|
7
8
|
before do
|
8
9
|
@client = Nexmo::Client.new('key', 'secret')
|
9
10
|
end
|
@@ -134,9 +135,23 @@ describe Nexmo::Client do
|
|
134
135
|
@client.get_message_rejections(date: 'YYYY-MM-DD').must_be_instance_of(Nexmo::Response)
|
135
136
|
end
|
136
137
|
end
|
138
|
+
|
139
|
+
describe 'search_messages method' do
|
140
|
+
it 'fetches the search messages resource with the given parameters and returns a response object' do
|
141
|
+
@client.http.expects(:get).with('/search/messages/key/secret?date=YYYY-MM-DD&to=1234567890').returns(stub)
|
142
|
+
|
143
|
+
@client.search_messages(date: 'YYYY-MM-DD', to: 1234567890).must_be_instance_of(Nexmo::Response)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should encode a non hash argument as a list of ids' do
|
147
|
+
@client.http.expects(:get).with('/search/messages/key/secret?ids=id1&ids=id2').returns(stub)
|
148
|
+
|
149
|
+
@client.search_messages(%w(id1 id2))
|
150
|
+
end
|
151
|
+
end
|
137
152
|
end
|
138
153
|
|
139
|
-
describe Nexmo::Response do
|
154
|
+
describe 'Nexmo::Response' do
|
140
155
|
before do
|
141
156
|
@http_response = mock()
|
142
157
|
|
@@ -178,46 +193,26 @@ describe Nexmo::Response do
|
|
178
193
|
end
|
179
194
|
|
180
195
|
describe 'object method' do
|
181
|
-
it 'decodes the response body as json and returns
|
182
|
-
@http_response.expects(:body).returns('{}')
|
196
|
+
it 'decodes the response body as json and returns a hash' do
|
197
|
+
@http_response.expects(:body).returns('{"value":0.0}')
|
183
198
|
|
184
|
-
@response.object.
|
199
|
+
@response.object.must_equal({'value' => 0})
|
185
200
|
end
|
186
201
|
end
|
187
202
|
end
|
188
203
|
|
189
|
-
describe Nexmo::
|
204
|
+
describe 'Nexmo::Response initialized with a different json implementation' do
|
190
205
|
before do
|
191
|
-
@
|
192
|
-
|
193
|
-
@object = Nexmo::Object.new(message_id: @value)
|
194
|
-
end
|
206
|
+
@http_response = mock()
|
195
207
|
|
196
|
-
|
197
|
-
@object.message_id.must_equal(@value)
|
208
|
+
@response = Nexmo::Response.new(@http_response, json: Oj)
|
198
209
|
end
|
199
210
|
|
200
|
-
describe '
|
201
|
-
it '
|
202
|
-
@
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
describe 'square brackets equals method' do
|
207
|
-
it 'sets the value of the given attribute' do
|
208
|
-
@object['message_id'] = 'abc'
|
209
|
-
@object.message_id.wont_equal(@value)
|
210
|
-
end
|
211
|
-
|
212
|
-
it 'replaces dashes in keys with underscores' do
|
213
|
-
@object['message-id'] = 'abc'
|
214
|
-
@object.message_id.wont_equal(@value)
|
215
|
-
end
|
216
|
-
end
|
211
|
+
describe 'object method' do
|
212
|
+
it 'decodes the response body as json and returns a hash' do
|
213
|
+
@http_response.expects(:body).returns('{"value":0.0}')
|
217
214
|
|
218
|
-
|
219
|
-
it 'returns a hash containing the object attributes' do
|
220
|
-
@object.to_hash.must_equal({message_id: @value})
|
215
|
+
@response.object.must_equal({'value' => 0})
|
221
216
|
end
|
222
217
|
end
|
223
218
|
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: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,40 +9,40 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: mocha
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
22
|
-
type: :
|
21
|
+
version: 0.9.12
|
22
|
+
type: :development
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 0.9.12
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
31
|
+
name: oj
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
|
-
- -
|
35
|
+
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
37
|
+
version: 1.3.7
|
38
38
|
type: :development
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: 1.3.7
|
46
46
|
description: A simple wrapper for the Nexmo API
|
47
47
|
email:
|
48
48
|
- mail@timcraft.com
|